nvim-lspconfig/lsp/tsgo.lua
ryoppippi ca950017c6
fix(tsgo): prefer local node_modules binary over global #4258
Convert the cmd from a static array to a function that checks for a
locally installed tsgo binary in node_modules/.bin/ before falling
back to the global installation. This ensures projects using
@typescript/native-preview as a local dependency will use the correct
version, matching the pattern already used by biome.
2025-12-23 10:35:47 -05:00

56 lines
2.2 KiB
Lua

---@brief
---
--- https://github.com/microsoft/typescript-go
---
--- `typescript-go` is experimental port of the TypeScript compiler (tsc) and language server (tsserver) to the Go programming language.
---
--- `tsgo` can be installed via npm `npm install @typescript/native-preview`.
---
--- ### Monorepo support
---
--- `tsgo` supports monorepos by default. It will automatically find the `tsconfig.json` or `jsconfig.json` corresponding to the package you are working on.
--- This works without the need of spawning multiple instances of `tsgo`, saving memory.
---
--- It is recommended to use the same version of TypeScript in all packages, and therefore have it available in your workspace root. The location of the TypeScript binary will be determined automatically, but only once.
---
---@type vim.lsp.Config
return {
cmd = function(dispatchers, config)
local cmd = 'tsgo'
local local_cmd = (config or {}).root_dir and config.root_dir .. '/node_modules/.bin/tsgo'
if local_cmd and vim.fn.executable(local_cmd) == 1 then
cmd = local_cmd
end
return vim.lsp.rpc.start({ cmd, '--lsp', '--stdio' }, dispatchers)
end,
filetypes = {
'javascript',
'javascriptreact',
'javascript.jsx',
'typescript',
'typescriptreact',
'typescript.tsx',
},
root_dir = function(bufnr, on_dir)
-- The project root is where the LSP can be started from
-- As stated in the documentation above, this LSP supports monorepos and simple projects.
-- We select then from the project root, which is identified by the presence of a package
-- manager lock file.
local root_markers = { 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb', 'bun.lock' }
-- Give the root markers equal priority by wrapping them in a table
root_markers = vim.fn.has('nvim-0.11.3') == 1 and { root_markers, { '.git' } }
or vim.list_extend(root_markers, { '.git' })
-- exclude deno
if vim.fs.root(bufnr, { 'deno.json', 'deno.jsonc', 'deno.lock' }) then
return
end
-- We fallback to the current working directory if no project root is found
local project_root = vim.fs.root(bufnr, root_markers) or vim.fn.getcwd()
on_dir(project_root)
end,
}