fix(#1831): remove windows executable functionality due to occasional vim freeze and performance concerns (#1868)

* #1831 exploratory testing: disable file executable checks

* fix(#1831): remove windows executable functionality
This commit is contained in:
Alexander Courtis 2022-12-31 12:34:55 +11:00 committed by GitHub
parent 9e4c39572f
commit 3c4958ab3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 44 additions and 97 deletions

View File

@ -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*
@ -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:

View File

@ -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"
@ -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
@ -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

View File

@ -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
@ -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

View File

@ -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
@ -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

View File

@ -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)
@ -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
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
end
function M.file(parent, absolute_path, name)
@ -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,

View File

@ -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

View File

@ -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("(%_)", "(%%_)")
@ -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
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