Skip to content

1831 remove windows executable functionality #1868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion doc/nvim-tree-lua.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ CONTENTS *nvim-tree*
7. Highlight Groups |nvim-tree-highlight|
8. Events |nvim-tree-events|
9. Bookmarks |nvim-tree-bookmarks|
10. OS Specific Restrictions |nvim-tree-os-specific|

==============================================================================
1. INTRODUCTION *nvim-tree-introduction*
Expand Down Expand Up @@ -1580,7 +1581,7 @@ e.g. handler for node renamed: >
{folder_name} `{string}` Absolute path to the removed folder.

==============================================================================
9. BOOKMARKS *nvim-tree-bookmarks*
9. BOOKMARKS *nvim-tree-bookmarks*

You can toggle marks on files/folders with
`require("nvim-tree.api").marks.toggle(node)` which is bound to `m` by
Expand All @@ -1601,4 +1602,15 @@ vim.keymap.set("n", "<leader>mn", require("nvim-tree.api").marks.navigate.next)
vim.keymap.set("n", "<leader>mp", require("nvim-tree.api").marks.navigate.prev)
vim.keymap.set("n", "<leader>ms", require("nvim-tree.api").marks.navigate.select)

==============================================================================
10. OS SPECIFIC RESTRICTIONS *nvim-tree-os-specific*

macOS
- Trash is unavailable

Windows WSL and PowerShell
- Trash is unavailable
- Executable file detection is disabled as this is non-performant and can
freeze nvim

vim:tw=78:ts=4:sw=4:et:ft=help:norl:
11 changes: 3 additions & 8 deletions lua/nvim-tree/actions/fs/trash.lua
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
local lib = require "nvim-tree.lib"
local notify = require "nvim-tree.notify"

local M = {
config = {
is_windows = vim.fn.has "win32" == 1 or vim.fn.has "win32unix" == 1,
is_macos = vim.fn.has "mac" == 1 or vim.fn.has "macunix" == 1,
is_unix = vim.fn.has "unix" == 1,
},
}
local M = {}

local utils = require "nvim-tree.utils"
local events = require "nvim-tree.events"
Expand All @@ -34,7 +28,7 @@ function M.fn(node)
end

-- configs
if M.config.is_unix then
if utils.is_unix then
if M.config.trash.cmd == nil then
M.config.trash.cmd = "trash"
end
Expand Down Expand Up @@ -108,6 +102,7 @@ function M.fn(node)
end

function M.setup(opts)
M.config = {}
M.config.trash = opts.trash or {}
M.enable_reload = not opts.filesystem_watchers.enable
end
Expand Down
16 changes: 6 additions & 10 deletions lua/nvim-tree/actions/node/system-open.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
local notify = require "nvim-tree.notify"
local utils = require "nvim-tree.utils"

local M = {
config = {
is_windows = vim.fn.has "win32" == 1 or vim.fn.has "win32unix" == 1,
is_macos = vim.fn.has "mac" == 1 or vim.fn.has "macunix" == 1,
is_unix = vim.fn.has "unix" == 1,
},
}
local M = {}

function M.fn(node)
if #M.config.system_open.cmd == 0 then
Expand Down Expand Up @@ -50,17 +45,18 @@ function M.fn(node)
end

function M.setup(opts)
M.config = {}
M.config.system_open = opts.system_open or {}

if #M.config.system_open.cmd == 0 then
if M.config.is_windows then
if utils.is_windows then
M.config.system_open = {
cmd = "cmd",
args = { "/c", "start", '""' },
}
elseif M.config.is_macos then
elseif utils.is_macos then
M.config.system_open.cmd = "open"
elseif M.config.is_unix then
elseif utils.is_unix then
M.config.system_open.cmd = "xdg-open"
end
end
Expand Down
6 changes: 6 additions & 0 deletions lua/nvim-tree/explorer/explore.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ local function populate_children(handle, cwd, node, git_status)
end

local abs = utils.path_join { cwd, name }

local pn = string.format("explore populate_children %s", abs)
local ps = log.profile_start(pn)

t = get_type_from(t, abs)
if not filters.should_filter(abs, filter_status) and not nodes_by_path[abs] then
local child = nil
Expand All @@ -42,6 +46,8 @@ local function populate_children(handle, cwd, node, git_status)
explorer_node.update_git_status(child, node_ignored, git_status)
end
end

log.profile_end(ps, pn)
end
end

Expand Down
30 changes: 11 additions & 19 deletions lua/nvim-tree/explorer/node-builders.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
local utils = require "nvim-tree.utils"
local watch = require "nvim-tree.explorer.watch"

local M = {
is_windows = vim.fn.has "win32" == 1,
is_wsl = vim.fn.has "wsl" == 1,
}
local M = {}

function M.folder(parent, absolute_path, name)
local handle = utils.fs_scandir_profiled(absolute_path)
Expand All @@ -27,21 +24,16 @@ function M.folder(parent, absolute_path, name)
return node
end

function M.is_executable(parent, absolute_path, ext)
if M.is_windows then
return utils.is_windows_exe(ext)
elseif M.is_wsl then
if parent.is_wsl_windows_fs_path == nil then
-- Evaluate lazily when needed and do so only once for each parent
-- as 'wslpath' calls can get expensive in highly populated directories.
parent.is_wsl_windows_fs_path = utils.is_wsl_windows_fs_path(absolute_path)
end

if parent.is_wsl_windows_fs_path then
return utils.is_wsl_windows_fs_exe(ext)
end
--- path is an executable file or directory
--- @param absolute_path string
--- @return boolean
function M.is_executable(absolute_path)
if utils.is_windows or utils.is_wsl then
--- executable detection on windows is buggy and not performant hence it is disabled
return false
else
return vim.loop.fs_access(absolute_path, "X")
end
return vim.loop.fs_access(absolute_path, "X")
end

function M.file(parent, absolute_path, name)
Expand All @@ -50,7 +42,7 @@ function M.file(parent, absolute_path, name)
return {
type = "file",
absolute_path = absolute_path,
executable = M.is_executable(parent, absolute_path, ext),
executable = M.is_executable(absolute_path),
extension = ext,
fs_stat = vim.loop.fs_stat(absolute_path),
name = name,
Expand Down
2 changes: 1 addition & 1 deletion lua/nvim-tree/explorer/reload.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function M.reload(node, git_status, unloaded_bufnr)
else
local n = nodes_by_path[abs]
if n then
n.executable = builders.is_executable(n.parent, abs, n.extension or "")
n.executable = builders.is_executable(abs)
n.fs_stat = fs_stat_cached(abs)
end
end
Expand Down
62 changes: 4 additions & 58 deletions lua/nvim-tree/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ local M = {
debouncers = {},
}

M.is_windows = vim.fn.has "win32" == 1 or vim.fn.has "win32unix" == 1
M.is_unix = vim.fn.has "unix" == 1
M.is_macos = vim.fn.has "mac" == 1 or vim.fn.has "macunix" == 1
M.is_wsl = vim.fn.has "wsl" == 1
-- false for WSL
M.is_windows = vim.fn.has "win32" == 1 or vim.fn.has "win32unix" == 1

function M.path_to_matching_str(path)
return path:gsub("(%-)", "(%%-)"):gsub("(%.)", "(%%.)"):gsub("(%_)", "(%%_)")
Expand Down Expand Up @@ -152,63 +155,6 @@ function M.get_nodes_by_line(nodes_all, line_start)
return nodes_by_line
end

---Matching executable files in Windows.
---@param ext string
---@return boolean
function M.is_windows_exe(ext)
if not M.pathexts then
if not vim.env.PATHEXT then
return false
end

local wexe = vim.split(vim.env.PATHEXT:gsub("%.", ""), ";")
M.pathexts = {}
for _, v in pairs(wexe) do
M.pathexts[v] = true
end
end

return M.pathexts[ext:upper()]
end

--- Check whether path maps to Windows filesystem mounted by WSL
-- @param path string
-- @return boolean
function M.is_wsl_windows_fs_path(path)
-- Run 'wslpath' command to try translating WSL path to Windows path.
-- Consume stderr output as well because 'wslpath' can produce permission
-- errors on some files (e.g. temporary files in root of system drive).
local handle = io.popen('wslpath -w "' .. path .. '" 2>/dev/null')
if handle then
local output = handle:read "*a"
handle:close()

return string.find(output, "^\\\\wsl$\\") == nil
end

return false
end

--- Check whether extension is Windows executable under WSL
-- @param ext string
-- @return boolean
function M.is_wsl_windows_fs_exe(ext)
if not vim.env.PATHEXT then
-- Extract executable extensions from within WSL.
-- Redirect stderr to null to silence warnings when
-- Windows command is executed from Linux filesystem:
-- > CMD.EXE was started with the above path as the current directory.
-- > UNC paths are not supported. Defaulting to Windows directory.
local handle = io.popen 'cmd.exe /c "echo %PATHEXT%" 2>/dev/null'
if handle then
vim.env.PATHEXT = handle:read "*a"
handle:close()
end
end

return M.is_windows_exe(ext)
end

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels good.

function M.rename_loaded_buffers(old_path, new_path)
for _, buf in pairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_is_loaded(buf) then
Expand Down