fix(#1555): incorrect exe highlight in Windows filesystem from WSL (#1557)

This commit is contained in:
Piotr Doan 2022-08-29 02:53:23 +02:00 committed by GitHub
parent ce5d0a6b7d
commit 4a725c0ca5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 5 deletions

View File

@ -4,6 +4,7 @@ local watch = require "nvim-tree.explorer.watch"
local M = {
is_windows = vim.fn.has "win32" == 1,
is_wsl = vim.fn.has "wsl" == 1,
}
function M.folder(parent, absolute_path, name)
@ -24,9 +25,19 @@ function M.folder(parent, absolute_path, name)
}
end
function M.is_executable(absolute_path, ext)
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
return uv.fs_access(absolute_path, "X")
end
@ -37,7 +48,7 @@ function M.file(parent, absolute_path, name)
return {
type = "file",
absolute_path = absolute_path,
executable = M.is_executable(absolute_path, ext),
executable = M.is_executable(parent, absolute_path, ext),
extension = ext,
fs_stat = uv.fs_stat(absolute_path),
name = name,

View File

@ -86,7 +86,7 @@ function M.reload(node, status)
else
local n = nodes_by_path[abs]
if n then
n.executable = builders.is_executable(abs, n.extension or "")
n.executable = builders.is_executable(n.parent, abs, n.extension or "")
n.fs_stat = fs_stat_cached(abs)
end
end

View File

@ -10,6 +10,7 @@ local M = {
}
M.is_windows = vim.fn.has "win32" == 1 or vim.fn.has "win32unix" == 1
M.is_wsl = vim.fn.has "wsl" == 1
function M.path_to_matching_str(path)
return path:gsub("(%-)", "(%%-)"):gsub("(%.)", "(%%.)"):gsub("(%_)", "(%%_)")
@ -171,8 +172,11 @@ end
---@return boolean
function M.is_windows_exe(ext)
if not M.pathexts then
local PATHEXT = vim.env.PATHEXT or ""
local wexe = vim.split(PATHEXT:gsub("%.", ""), ";")
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
@ -182,6 +186,44 @@ function M.is_windows_exe(ext)
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(a.nvim_list_bufs()) do
if a.nvim_buf_is_loaded(buf) then