diff options
| author | Michael Lingelbach <m.j.lbach@gmail.com> | 2021-12-23 10:43:16 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-23 10:43:16 -0500 |
| commit | bba61ed96829c9088244ed1e83f10de1b0a01f7f (patch) | |
| tree | 8b1bf9e04082633f7a9cc3000bc0305ae489c4cf /lua | |
| parent | docs: update server_configurations.md (diff) | |
| download | nvim-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.lua | 16 | ||||
| -rw-r--r-- | lua/lspconfig/util.lua | 71 |
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 |
