diff options
| author | Erikson Kaszubowski <erikson84@yahoo.com.br> | 2025-11-16 20:50:43 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-16 15:50:43 -0800 |
| commit | dbf98c4d15a1a8d7f620d8a558e0699eacda7582 (patch) | |
| tree | da9b36a3b321049f48edf794ab5bd2fac639efb8 | |
| parent | fix(lsp): improve ts_ls root detection for deno projects #4193 (diff) | |
| download | nvim-lspconfig-dbf98c4d15a1a8d7f620d8a558e0699eacda7582.tar nvim-lspconfig-dbf98c4d15a1a8d7f620d8a558e0699eacda7582.tar.gz nvim-lspconfig-dbf98c4d15a1a8d7f620d8a558e0699eacda7582.tar.bz2 nvim-lspconfig-dbf98c4d15a1a8d7f620d8a558e0699eacda7582.tar.lz nvim-lspconfig-dbf98c4d15a1a8d7f620d8a558e0699eacda7582.tar.xz nvim-lspconfig-dbf98c4d15a1a8d7f620d8a558e0699eacda7582.tar.zst nvim-lspconfig-dbf98c4d15a1a8d7f620d8a558e0699eacda7582.zip | |
fix(angularls): improves node_modules path resolution #4190
Problem:
Search for node_modules uses a costly call to fn.globpath; the final
path resolution was not working on Linux.
Solution:
A custom function to resolve ngserver location from CMD wrappers on
Windows; and the corrected final path.
Co-authored-by: Erikson K. <erikson23@gmail.com>
| -rw-r--r-- | lsp/angularls.lua | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/lsp/angularls.lua b/lsp/angularls.lua index ec81789f..af82b87a 100644 --- a/lsp/angularls.lua +++ b/lsp/angularls.lua @@ -16,6 +16,41 @@ -- in order to use your projects configured versions. local fs, fn, uv = vim.fs, vim.fn, vim.uv +--- Recursively solve for the original ngserver path on Windows +-- For a given ngserver path: +-- - If it is not a CMD wrapper, return the path; +-- - Or else, extract the path from the CMD wrapper. +-- +-- @param cmd_path (string) path for the ngserver executable or its CMD wrapper. +-- @return (string) the original executable path for ngserver +-- @usage +-- -- Base case: cmd_path already points to ngserver (expected behavior on Linux) +-- resolve_cmd_shim('/home/user/project/node_modules/@angular/language-server/bin/ngserver') +-- => '/home/user/project/node_modules/@angular/language-server/bin/ngserver' +-- +-- -- Recursive case: cmd_path points to a CMD wrapper (Windows) +-- resolve_cmd_shim('C:/Users/user/project/node_modules/.bin/ngserver.cmd') +-- => 'C:/Users/user/project/node_modules/@angular/language-server/bin/ngserver' +local function resolve_cmd_shim(cmd_path) + if not cmd_path:lower():match('%ngserver.cmd$') then + return cmd_path + end + + local ok, content = pcall(fn.readblob, cmd_path) + if not ok or not content then + return cmd_path + end + + local target = content:match('%s%"%%dp0%%\\([^\r\n]-ngserver[^\r\n]-)%"') + if not target then + return cmd_path + end + + local full = fs.normalize(fs.joinpath(fs.dirname(cmd_path), target)) + + return resolve_cmd_shim(full) +end + local function collect_node_modules(root_dir) local results = {} @@ -27,16 +62,8 @@ local function collect_node_modules(root_dir) local ngserver_exe = fn.exepath('ngserver') if ngserver_exe and #ngserver_exe > 0 then local realpath = uv.fs_realpath(ngserver_exe) or ngserver_exe - local candidate = fs.normalize(fs.joinpath(fs.dirname(realpath), '../../node_modules')) - if uv.fs_stat(candidate) then - table.insert(results, candidate) - end - end - - local internal_servers = fn.globpath(fn.stdpath('data'), '**/node_modules/.bin/ngserver', true, true) - for _, exe in ipairs(internal_servers) do - local realpath = uv.fs_realpath(exe) or exe - local candidate = fs.normalize(fs.joinpath(fs.dirname(realpath), '../../node_modules')) + realpath = resolve_cmd_shim(realpath) + local candidate = fs.normalize(fs.joinpath(fs.dirname(realpath), '../../..')) if uv.fs_stat(candidate) then table.insert(results, candidate) end @@ -51,13 +78,12 @@ local function get_angular_core_version(root_dir) return '' end - local ok, f = pcall(io.open, package_json, 'r') - if not ok or not f then + local ok, content = pcall(fn.readblob, package_json) + if not ok or not content then return '' end - local json = vim.json.decode(f:read('*a')) or {} - f:close() + local json = vim.json.decode(content) or {} local version = (json.dependencies or {})['@angular/core'] or '' return version:match('%d+%.%d+%.%d+') or '' |
