diff options
| author | Alexis Tacnet <alexis@mistral.ai> | 2025-08-17 23:12:42 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-17 14:12:42 -0700 |
| commit | 8ad2d8d8991d868ff8e7c21a7db624f32b882531 (patch) | |
| tree | 1332a443b4832deabe9a4566f88e5a5bd35803ee /lsp/svelte.lua | |
| parent | docs: update configs.md (diff) | |
| download | nvim-lspconfig-8ad2d8d8991d868ff8e7c21a7db624f32b882531.tar nvim-lspconfig-8ad2d8d8991d868ff8e7c21a7db624f32b882531.tar.gz nvim-lspconfig-8ad2d8d8991d868ff8e7c21a7db624f32b882531.tar.bz2 nvim-lspconfig-8ad2d8d8991d868ff8e7c21a7db624f32b882531.tar.lz nvim-lspconfig-8ad2d8d8991d868ff8e7c21a7db624f32b882531.tar.xz nvim-lspconfig-8ad2d8d8991d868ff8e7c21a7db624f32b882531.tar.zst nvim-lspconfig-8ad2d8d8991d868ff8e7c21a7db624f32b882531.zip | |
feat(ts/js): improve monorepo support for Typescript, ESLint #3955
PROBLEM:
Monorepos (or "workspaces") in Typescript are more and more popular and
the associated tooling is evolving to improve the developer experience
in such setup. Especially, the `typescript-language-server` and the
`vscode-eslint-language-server` now supports monorepos, **removing the
need to spawn a different server for each package of a workspace**.
Example: with a few packages as the servers need to load every other
package to work (the `typescript-language-server`, even if spawned
multiple times with different `root_dir`, will load in memory other
packages to resolve the types), the amount of memory used grows
exponentially. But in fact, those servers support monorepos: they
support multiple configurations in subpackages and will load the correct
one to process a buffer. The ESLint server even supports loading
multiple ESLint binaries (and therefore versions), while keeping one
instance of the server.
SOLUTION:
Instead of only relying on the configuration files as `root_markers`,
discover the root of the package / monorepo by finding the Lock files
created by node package managers:
* `package-lock.json`: Npm
* `yarn.lock`: Yarn
* `pnpm-lock.yaml`: Pnpm
* `bun.lockb`: Bun
We still need to look at configuration files to enable the conditionnaly
attachment of the LSP for a buffer (for ESLint, we want to attach the
LSP only if there are ESLint configuration files) in case of LSP that
operates on files that are "generic" (like `typescript` or
`javascript`).
To do that, I replace the `root_markers` that were the configuration
files by a `root_dir` function that superseds them. It will both:
* look for a configuration file upward to check if the LSP needs to be attached
* look for the root of the "project" via the lock files to specify the `root_dir` of the LSP
PRIOR EXPERIMENTATIONS:
I've tried to play with the `reuse_client` quite a lot, trying to
understand if we need to spawn a new server or not looking at the
Typescript / ESLint binary that was loaded, but in fact it's way easier
to just have a better `root_dir` that is the true root of the project
for the LSP server: in case of those two servers, the root of the
package / monorepo.
I also tried to use the current directory opened as the `root_dir`, but
it's less powerful on nvim compared to VSCode as we navigate more inside
folders using terminal commands and then open vim.
I think this method also removes the need from a project-local config
(which could be quite useful anyway for ESLint flat config setting which
auto-detection is a bit unreliable / compute heavy) as this should work
normally accross all different setups.
Fixes #3910
Diffstat (limited to 'lsp/svelte.lua')
| -rw-r--r-- | lsp/svelte.lua | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/lsp/svelte.lua b/lsp/svelte.lua index f18baf1d..abb09e2b 100644 --- a/lsp/svelte.lua +++ b/lsp/svelte.lua @@ -13,7 +13,7 @@ return { cmd = { 'svelteserver', '--stdio' }, filetypes = { 'svelte' }, root_dir = function(bufnr, on_dir) - local root_files = { 'package.json', '.git' } + local root_files = { 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb' } local fname = vim.api.nvim_buf_get_name(bufnr) -- Svelte LSP only supports file:// schema. https://github.com/sveltejs/language-tools/issues/2777 if vim.uv.fs_stat(fname) ~= nil then |
