aboutsummaryrefslogtreecommitdiffstats
path: root/lua
diff options
context:
space:
mode:
authorMichael Lingelbach <m.j.lbach@gmail.com>2021-12-23 10:43:16 -0500
committerGitHub <noreply@github.com>2021-12-23 10:43:16 -0500
commitbba61ed96829c9088244ed1e83f10de1b0a01f7f (patch)
tree8b1bf9e04082633f7a9cc3000bc0305ae489c4cf /lua
parentdocs: update server_configurations.md (diff)
downloadnvim-lspconfig-bba61ed96829c9088244ed1e83f10de1b0a01f7f.tar
nvim-lspconfig-bba61ed96829c9088244ed1e83f10de1b0a01f7f.tar.gz
nvim-lspconfig-bba61ed96829c9088244ed1e83f10de1b0a01f7f.tar.bz2
nvim-lspconfig-bba61ed96829c9088244ed1e83f10de1b0a01f7f.tar.lz
nvim-lspconfig-bba61ed96829c9088244ed1e83f10de1b0a01f7f.tar.xz
nvim-lspconfig-bba61ed96829c9088244ed1e83f10de1b0a01f7f.tar.zst
nvim-lspconfig-bba61ed96829c9088244ed1e83f10de1b0a01f7f.zip
fix: internally use forward delineated paths cross-platform (#1593)
* Escape paths used to autocommands * Always normalize windows path to forward slash for internal use
Diffstat (limited to 'lua')
-rw-r--r--lua/lspconfig/configs.lua16
-rw-r--r--lua/lspconfig/util.lua71
2 files changed, 46 insertions, 41 deletions
diff --git a/lua/lspconfig/configs.lua b/lua/lspconfig/configs.lua
index da50c5fd..3723df1f 100644
--- a/lua/lspconfig/configs.lua
+++ b/lua/lspconfig/configs.lua
@@ -79,19 +79,19 @@ function configs.__newindex(t, config_name, config_def)
function M.launch()
local root_dir
if get_root_dir then
- root_dir = get_root_dir(api.nvim_buf_get_name(0), api.nvim_get_current_buf())
+ root_dir = get_root_dir(util.path.sanitize(api.nvim_buf_get_name(0)), api.nvim_get_current_buf())
end
if root_dir then
api.nvim_command(
string.format(
- "autocmd %s unsilent lua require'lspconfig'[%q].manager.try_add_wrapper()",
- 'BufReadPost ' .. root_dir .. '/*',
+ "autocmd BufReadPost %s/* unsilent lua require'lspconfig'[%q].manager.try_add_wrapper()",
+ vim.fn.fnameescape(root_dir),
config.name
)
)
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
- local buf_dir = api.nvim_buf_get_name(bufnr)
+ local buf_dir = util.path.sanitize(api.nvim_buf_get_name(bufnr))
if buf_dir:sub(1, root_dir:len()) == root_dir then
M.manager.try_add_wrapper(bufnr)
end
@@ -101,7 +101,7 @@ function configs.__newindex(t, config_name, config_def)
-- Effectively this is the root from lspconfig's perspective, as we use
-- this to attach additional files in the same parent folder to the same server.
-- We just no longer send rootDirectory or workspaceFolders during initialization.
- local pseudo_root = util.path.dirname(api.nvim_buf_get_name(0))
+ local pseudo_root = util.path.dirname(util.path.sanitize(api.nvim_buf_get_name(0)))
M.manager.add(pseudo_root, true)
else
vim.notify(
@@ -209,14 +209,16 @@ function configs.__newindex(t, config_name, config_def)
local id
local root_dir
+ local buf_path = util.path.sanitize(api.nvim_buf_get_name(bufnr))
+
if get_root_dir then
- root_dir = get_root_dir(api.nvim_buf_get_name(bufnr), bufnr)
+ root_dir = get_root_dir(buf_path, bufnr)
end
if root_dir then
id = manager.add(root_dir, false)
elseif config.single_file_support then
- local pseudo_root = util.path.dirname(api.nvim_buf_get_name(0))
+ local pseudo_root = util.path.dirname(buf_path)
id = manager.add(pseudo_root, true)
else
vim.notify(
diff --git a/lua/lspconfig/util.lua b/lua/lspconfig/util.lua
index 917cc765..05d844ae 100644
--- a/lua/lspconfig/util.lua
+++ b/lua/lspconfig/util.lua
@@ -87,6 +87,16 @@ end
-- Some path utilities
M.path = (function()
+ local is_windows = uv.os_uname().version:match 'Windows'
+
+ local function sanitize(path)
+ if is_windows then
+ path = path:sub(1, 1):upper() .. path:sub(2)
+ path = path:gsub('\\', '/')
+ end
+ return path
+ end
+
local function exists(filename)
local stat = uv.fs_stat(filename)
return stat and stat.type or false
@@ -100,16 +110,10 @@ M.path = (function()
return exists(filename) == 'file'
end
- local is_windows = uv.os_uname().version:match 'Windows'
- local path_sep = is_windows and '\\' or '/'
-
- local is_fs_root
- if is_windows then
- is_fs_root = function(path)
+ local function is_fs_root(path)
+ if is_windows then
return path:match '^%a:$'
- end
- else
- is_fs_root = function(path)
+ else
return path == '/'
end
end
@@ -122,25 +126,25 @@ M.path = (function()
end
end
- local dirname
- do
- local strip_dir_pat = path_sep .. '([^' .. path_sep .. ']+)$'
- local strip_sep_pat = path_sep .. '$'
- dirname = function(path)
- if not path or #path == 0 then
- return
- end
- local result = path:gsub(strip_sep_pat, ''):gsub(strip_dir_pat, '')
- if #result == 0 then
+ local function dirname(path)
+ local strip_dir_pat = '/([^/]+)$'
+ local strip_sep_pat = '/$'
+ if not path or #path == 0 then
+ return
+ end
+ local result = path:gsub(strip_sep_pat, ''):gsub(strip_dir_pat, '')
+ if #result == 0 then
+ if is_windows then
+ return path:sub(1, 2):upper()
+ else
return '/'
end
- return result
end
+ return result
end
local function path_join(...)
- local result = table.concat(vim.tbl_flatten { ... }, path_sep):gsub(path_sep .. '+', path_sep)
- return result
+ return table.concat(vim.tbl_flatten { ... }, '/')
end
-- Traverse the path calling cb along the way.
@@ -199,9 +203,9 @@ M.path = (function()
is_file = is_file,
is_absolute = is_absolute,
exists = exists,
- sep = path_sep,
dirname = dirname,
join = path_join,
+ sanitize = sanitize,
traverse_parents = traverse_parents,
iterate_parents = iterate_parents,
is_descendant = is_descendant,
@@ -215,18 +219,17 @@ function M.server_per_root_dir_manager(_make_config)
local single_file_clients = {}
local manager = {}
- function manager.add(root_dir, single_file_support)
+ function manager.add(root_dir, single_file)
local client_id
- if single_file_support then
+ -- This is technically unnecessary, as lspconfig's path utilities should be hermetic,
+ -- however users are free to return strings in custom root resolvers.
+ root_dir = M.path.sanitize(root_dir)
+ if single_file then
client_id = single_file_clients[root_dir]
- else
- if not root_dir then
- return
- end
- if not M.path.is_dir(root_dir) then
- return
- end
+ elseif root_dir and M.path.is_dir(root_dir) then
client_id = clients[root_dir]
+ else
+ return
end
-- Check if we have a client already or start and store it.
@@ -260,7 +263,7 @@ function M.server_per_root_dir_manager(_make_config)
-- Sending rootDirectory and workspaceFolders as null is not explicitly
-- codified in the spec. Certain servers crash if initialized with a NULL
-- root directory.
- if single_file_support then
+ if single_file then
new_config.root_dir = nil
new_config.workspace_folders = nil
end
@@ -271,7 +274,7 @@ function M.server_per_root_dir_manager(_make_config)
return
end
- if single_file_support then
+ if single_file then
single_file_clients[root_dir] = client_id
else
clients[root_dir] = client_id