How can I verify that the tsgo lsp will launch the correct tsgo lsp server, that should be in the current projects environment (either bun, npm, pnpm..)
How can I verify that the tsgo lsp will launch the correct tsgo lsp server, that should be in the current projects environment (either bun, npm, pnpm..)
Good question. Let me look at how the tsgo LSP is currently configured in your Neovim setup to understand the current behavior, then I can advise on verification.
Executed 1/2 tools successfully. 1 failed.Found 5 matches
/home/jm/.config/nvim/lsp/tsgo.lua:
Line 7: --- `tsgo` can be installed via npm `npm install @typescript/native-preview`.
Line 11: --- `tsgo` supports monorepos by default. It will automatically find the `tsconfig.json` or `jsconfig.json` corresponding to the package you are working on.
Line 12: --- This works without the need of spawning multiple instances of `tsgo`, saving memory.
Line 20: local cmd = 'tsgo'
Line 21: local local_cmd = (config or {}).root_dir and config.root_dir .. '/node_modules/.bin/tsgo'All 2 tools executed successfully.
Keep using the batch tool for optimal performance in your next response!<path>/home/jm/.config/nvim/lsp/tsgo.lua</path>
<type>file</type>
<content>1: ---@brief
2: ---
3: --- https://github.com/microsoft/typescript-go
4: ---
5: --- `typescript-go` is experimental port of the TypeScript compiler (tsc) and language server (tsserver) to the Go programming language.
6: ---
7: --- `tsgo` can be installed via npm `npm install @typescript/native-preview`.
8: ---
9: --- ### Monorepo support
10: ---
11: --- `tsgo` supports monorepos by default. It will automatically find the `tsconfig.json` or `jsconfig.json` corresponding to the package you are working on.
12: --- This works without the need of spawning multiple instances of `tsgo`, saving memory.
13: ---
14: --- 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.
15: ---
16:
17: ---@type vim.lsp.Config
18: return {
19: cmd = function(dispatchers, config)
20: local cmd = 'tsgo'
21: local local_cmd = (config or {}).root_dir and config.root_dir .. '/node_modules/.bin/tsgo'
22: if local_cmd and vim.fn.executable(local_cmd) == 1 then
23: cmd = local_cmd
24: end
25: return vim.lsp.rpc.start({ cmd, '--lsp', '--stdio' }, dispatchers)
26: end,
27: filetypes = {
28: 'javascript',
29: 'javascriptreact',
30: 'typescript',
31: 'typescriptreact',
32: },
33:
34: root_dir = function(bufnr, on_dir)
35: -- The project root is where the LSP can be started from
36: -- As stated in the documentation above, this LSP supports monorepos and simple projects.
37: -- We select then from the project root, which is identified by the presence of a package
38: -- manager lock file.
39: local root_markers =
40: { 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb', 'bun.lock' }
41: -- Give the root markers equal priority by wrapping them in a table
42: root_markers =...<path>/home/jm/.config/nvim/lua/config/lsp</path>
<type>directory</type>
<entries>
completion_prioritizer.lua
workspace_enhancer.lua
(2 entries)
</entries>Here's what your current lsp/tsgo.lua does and how you can verify it:
The cmd function resolves the binary in this order:
<root_dir>/node_modules/.bin/tsgo — used if it exists and is executable.tsgo from $PATH.There are several approaches, from quick to thorough:
Open a TypeScript file in your project, then run:
:lua print(vim.inspect(vim.lsp.get_clients({ name = 'tsgo' })[1].config.cmd))
However, since cmd is a function (not a table), the config won't show the resolved path directly. Instead, check the running process:
:!ps aux | grep tsgo
This will show the exact binary path that was spawned.
:lua vim.cmd('edit ' .. vim.lsp.get_log_path())
Search for tsgo — the log should show the command that was started.
From a terminal inside your project root, verify what node_modules/.bin/tsgo resolves to:
# Does the local binary exist?
ls -la node_modules/.bin/tsgo
# What version is it?
node_modules/.bin/tsgo --version
# What would the bare command resolve to?
which tsgo
Your current config only checks node_modules/.bin/tsgo — this works for npm and pnpm (which both create node_modules/.bin/ shims). However:
node_modules/.bin/, so it should work.shamefully-hoist=false or strict mode may not always have the binary there if it's a transitive dependency.The config does not use the package manager's own exec command (e.g., npx tsgo, bunx tsgo, pnpm exec tsgo). It relies purely on the node_modules/.bin/ shim existing at the root. For most setups this is fine, but if you want to be more robust, you could detect the package manager and use its exec wrapper instead.
Would you like me to plan an enhancement that detects the active package manager and uses the appropriate exec command, or is the current node_modules/.bin/ check sufficient for your workflow?
So in tsgo's lsp.ClientConfig, cmd is a function that takes in a clientConfig to use its root_dir, but root_dir could also be a function, as in this case.
What would the lua do in the case that root_dir is an unresolved function? Why does the type inference of lua also just assume it will be a string, when it could be that OR a function
Great observation. Let me look at exactly how the cmd function receives its config argument and what root_dir would be at that point.
## News - Neovim docs
https://neovim.io/doc/user/news.html
exrc".
### EXPERIMENTS
todo
### LSP vim.lsp.buf.selection\_range() now accepts an integer which specifies its direction, rather than a string `'outer'` or `'inner'`.
### OPTIONS `'completefuzzycollect'` and `'isexpand'` have been removed.
### TREESITTER
todo
### UI ... was implemented as an internal C routine).
'statusline' includes vim.diagnostic.status() Project-local configuration ( 'exrc' ) is also loaded from parent directories. Unset 'exrc' to stop further search.
Mappings: grt in Normal mode maps to vim.lsp.buf.type\_definition() 'shada' default now excludes "/tmp/" and "/private/" paths to reduce clutter in :oldfiles . ... hl-PmenuBorder hl-PmenuShadow hl-PmenuShadowThrough see 'pumborder' . ### LSP
:lsp can be used to interactively manage LSP clients. vim.lsp.ClientConfig gained `workspace\_required`. You can control the priority of vim.lsp.Config `root\_markers`. Support for `textDocument/documentColor`: lsp-document\_color ... The `textDocument/diagnostic` request now includes the previous id in its
parameters. vim.lsp.enable() start/stops clients as necessary and detaches
non-applicable LSP clients. vim.lsp.is\_enabled() checks if a LSP config is enabled (without
"resolving" it). Support for `workspace/diagnostic`: vim.lsp.buf.workspace\_diagnostics() ... Incremental selection is now supported via `textDocument/selectionRange`. `an` selects outwards and `in` selects inwards.
Support for multiline semantic tokens. Support for the `disabled` field on code actions. The function form of `cmd` in a vim.lsp.Config or vim.lsp.ClientConfig receives the resolved config as the second arg: `cmd(dispatchers, config)`.
Support for annotated text edits. `:checkhealth vim.lsp` is now available to check which buffers the active LSP features are attached to. LSP `DiagnosticRelatedInformation` is now shown in vim.diagnostic.open\_float() . It is read from the LSP diagnostic object
stored in the `user\_data` fie...Found 11 matches
/home/jm/.config/nvim/lsp/tsgo.lua:
Line 17: ---@type vim.lsp.Config
/home/jm/.config/nvim/lsp/ocamllsp.lua:
Line 32: ---@type vim.lsp.Config
/home/jm/.config/nvim/lsp/bashls.lua:
Line 2: ---@type vim.lsp.Config
/home/jm/.config/nvim/lsp/clangd.lua:
Line 66: ---@type vim.lsp.Config
/home/jm/.config/nvim/lsp/ts_ls.lua:
Line 112: ---@type vim.lsp.Config
/home/jm/.config/nvim/lsp/copilot.lua:
Line 75: ---@type vim.lsp.Config
/home/jm/.config/nvim/lsp/biome.lua:
Line 39: ---@type vim.lsp.Config
/home/jm/.config/nvim/lsp/astro.lua:
Line 16: ---@type vim.lsp.Config
/home/jm/.config/nvim/lua/lsp/resolver.lua:
Line 119: -- --- Create a cmd resolver function for vim.lsp.Config
Line 120: -- --- This function is passed directly to the `cmd` field of vim.lsp.Config
/home/jm/.config/nvim/lsp/rust_analyzer.lua:
Line 55: ---@type vim.lsp.ConfigNow let me look at the Neovim source to understand exactly what the cmd function receives as its second argument — specifically whether root_dir is already resolved to a string by the time cmd is called.
All 2 tools executed successfully.
Keep using the batch tool for optimal performance in your next response!<path>/home/jm/.config/nvim/lua/lsp/resolver.lua</path>
<type>file</type>
<content>1: --- Binary Resolution System for LSP Servers
2: --- Provides flexible binary discovery with conditional fallback mechanisms
3: -- local M = {}
4: --
5: -- --- Mapping of LSP names to Mason package names
6: -- --- @type table<string, string>
7: -- local mason_name_map = {
8: -- ts_ls = "typescript-language-server",
9: -- eslint = "eslint-language-server",
10: -- lua_ls = "lua-language-server",
11: -- ocamllsp = "ocaml-lsp",
12: -- jsonls = "vscode-json-language-server",
13: -- html = "vscode-html-language-server",
14: -- cssls = "vscode-css-language-server",
15: -- marksman = "marksman",
16: -- tailwindcss = "tailwindcss-language-server",
17: -- emmet_ls = "emmet-ls",
18: -- bashls = "bash-language-server",
19: -- yamlls = "yaml-language-server",
20: -- }
21: --
22: -- local function get_mason_package(lsp_name)
23: -- return mason_name_map[lsp_name] or lsp_name
24: -- end
25: --
26: -- --- Check if a command array is executable
27: -- --- @param cmd string[]
28: -- --- @return boolean
29: -- local function is_executable(cmd)
30: -- if #cmd == 0 then
31: -- return false
32: -- end
33: -- return vim.fn.executable(cmd[1]) == 1
34: -- end
35: --
36: -- --- Try Mason installation path
37: -- --- @param mason_package string
38: -- --- @return string[]|nil cmd The Mason command array, or nil if not found
39: -- local function try_mason(mason_package)
40: -- local mason_bin = vim.fn.stdpath("data") .. "/mason/bin/" .. mason_package
41: -- if vim.fn.executable(mason_bin) == 1 then
42: -- return { mason_bin }
43: -- end
44: -- return nil
45: -- end
46: --
47: -- --- Try PATH for binary
48: -- --- @param binary_name string
49: -- --- @return string[]|nil cmd The PATH command array, or nil if not found
50: -- local function try_path(binary_name)
51: -- if vim.fn.executable(binary_name) == 1 then
52: -- return { binary_name }
53: -- end
54:...## on_new_config for vim.lsp.config · Issue #32287 - GitHub
https://github.com/neovim/neovim/issues/32287?timeline_page=1
LSP: on\_new\_config for vim.lsp.config ·Issue #32287 ·neovim/neovim ·GitHub
Skip to content ## Navigation Menu
Toggle navigation
Sign in
Appearance settings
Search or jump to... # Search code, repositories, users, issues, pull requests...
Search
Clear
Search syntax tips # Provide feedback
We read every piece of feedback, and take your input very seriously. ... Sign up
Appearance settings
Resetting focus You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to ... {{ message }}
neovim /** neovim **Public
* ### Uh oh! ... * Notifications You must be signed in to change notification settings
* Fork6.5k * Star95.6k
# LSP: on\_new\_config for vim.lsp.config#32287
New issue
Copy link New issue
Copy link
Open
Enhancement
Open LSP: on\_new\_config for vim.lsp.config #32287
Enhancement
Copy link
Labels
lsp
Milestone
0.12
@justinmk
## Description
@justinmk justinmk
opened onFeb 1, 2025
Issue body actions
### Problem nvim-lspconfig has a`on\_new\_config`feature which is apparently not addressed by vim.lsp.config. The documentation for`on\_new\_config`is: > > Function executed after a root directory is detected. Used to modify the server configuration (including `> cmd `> itself).
> ### Expected behavior
ref neovim/nvim-lspconfig#3597 (comment) > > This could be another application for an autocmd that triggers just before the client starts. Or maybe could just be done in RTP. > Edit: maybe`root\_dir()`is already flexible enough?
## Metadata
## Metadata
### Assignees
No one assigned
### Labels lsp
### Type
Enhancement
### Projects
No projects
### Milestone
*
0.12
###
## Lsp - Neovim docs
https://neovim.io/doc/user/lsp.html
/doc/user/lsp/
## neovim/runtime/lua/vim/lsp.lua at mast...Now let me look at the actual Neovim runtime source to see exactly how cmd is called and what the config argument contains — specifically whether root_dir is resolved before being passed:
task_id: ses_36efa0554ffe1VO5wOAVuxkGFE (for resuming to continue this task if needed)
<task_result>
Now I have all the source code needed. Let me compile the complete analysis.
---
## Complete Analysis: How Neovim LSP Calls `cmd` as a Function and the State of `root_dir`
### 1. The Exact Code Where `cmd` Function Is Called
In **`client.lua`** (`runtime/lua/vim/lsp/client.lua`), inside `Client.create()`:
```lua
-- Start the RPC client.
local config_cmd = config.cmd
if type(config_cmd) == 'function' then
self.rpc = config_cmd(dispatchers, config)
else
self.rpc = lsp.rpc.start(config_cmd, dispatchers, {
cwd = config.cmd_cwd,
env = config.cmd_env,
detached = config.detached,
})
end
```
The signature is exactly `cmd(dispatchers, config)` where `config` is the **entire `vim.lsp.ClientConfig`** object that was passed to `Client.create()`.
### 2. The Code That Resolves `root_dir` from Function to String
In **`lsp.lua`** (`runtime/lua/vim/lsp.lua`), inside `lsp_enable_callback()`:
```lua
for name in vim.spairs(lsp._enabled_configs) do
local config = lsp.config[name]
if config and can_start(bufnr, config, true) then
-- Deepcopy config so changes done in the client
-- do not propagate back to the enabled configs.
config = vim.deepcopy(config)
if type(config.root_dir) == 'function' then
---@param root_dir string
config.root_dir(bufnr, function(root_dir)
config.root_dir = root_dir -- <-- RESOLVES HERE: replaces function with string
vim.schedule(function()
start_config(bufnr, config)
end)
end)
else
start_config(bufnr, config)
end
end
end
```
When `root_dir` is a function, the code:
1. Calls `config.root_dir(bufnr, on_dir_callback)`
2. Inside the callback, **overwrites** `config.root_dir` with the string value
3. Then calls `start_config()` via `vim.schedule()`
### 3. The Full Pipeline: `vim.lsp.e...This is a thorough answer. Here's the summary:
root_dir is always resolved to a string before cmd() is calledThe two types tell the story:
| Type | root_dir type |
|---|---|
vim.lsp.Config (user-facing) |
string | fun(bufnr, on_dir) |
vim.lsp.ClientConfig (internal) |
string? — never a function |
The cmd function signature is:
fun(dispatchers: vim.lsp.rpc.Dispatchers, config: vim.lsp.ClientConfig): vim.lsp.rpc.PublicClient
Note the second argument is vim.lsp.ClientConfig, not vim.lsp.Config. By the time cmd() receives it, the config has already been narrowed.
In runtime/lua/vim/lsp.lua, inside lsp_enable_callback():
if type(config.root_dir) == 'function' then
config.root_dir(bufnr, function(root_dir)
config.root_dir = root_dir -- overwrites function with the string result
vim.schedule(function()
start_config(bufnr, config) -- only proceeds AFTER resolution
end)
end)
else
start_config(bufnr, config)
end
The pipeline is:
vim.lsp.enable() triggers lsp_enable_callback() on FileTyperoot_dir is a function, it's called with (bufnr, on_dir_callback)config.root_dir with the stringstart_config() → vim.lsp.start() → Client.create() → cmd(dispatchers, config)So your tsgo config is correct — by the time cmd(dispatchers, config) runs, config.root_dir is guaranteed to be a resolved string (or nil if on_dir was never called / called with nil).
The cmd function's config parameter is typed as vim.lsp.ClientConfig where root_dir is string?. Lua's type system (via LuaLS annotations) trusts this contract. It doesn't track the runtime narrowing that happens in lsp_enable_callback() — it simply knows that by the time ClientConfig is constructed, the function form has already been eliminated. So the type inference is correct, not just an assumption.
You could add a temporary assertion in your cmd function:
cmd = function(dispatchers, config)
assert(type(config.root_dir) == 'string', 'root_dir was not resolved: ' .. type(config.root_dir))
-- rest of your logic...
end
Or check the running process with :!ps aux | grep tsgo after opening a TS file.
q[ERROR][2026-02-24 14:14:44] /home/jm/.local/share/nvim/runtime/lua/vim/lsp/log.lua:151 "rpc" "/home/jm/data/code/opencode-trees/ChyTQ/node_modules/.bin/tsgo" "stderr" "context canceled\n"
[ERROR][2026-02-24 14:14:44] /home/jm/.local/share/nvim/runtime/lua/vim/lsp/log.lua:151 "error handling method 'exit': EOF"
[WARN][2026-02-24 14:14:44] /home/jm/.local/share/nvim/runtime/lua/vim/lsp/log.lua:151 "The language server tsgo triggers a registerCapa
bility handler for workspace/didChangeConfiguration despite dynamicRegistration set to false. Report upstream, this warning is harmless"
The LSP log confirms the local binary is being resolved correctly — it's launching /home/jm/data/code/opencode-trees/ChyTQ/node_modules/.bin/tsgo.
The errors you're seeing are:
"context canceled\n" on stderr — This is the tsgo process writing to stderr as it shuts down. This typically happens when Neovim closes the LSP client (e.g., you closed the buffer/window, or the client was stopped). The Go runtime's context cancellation propagates and gets logged. This is normal shutdown behavior, not a startup failure.
"error handling method 'exit': EOF" — Neovim tried to handle the exit notification but the pipe was already closed. This is a race condition during shutdown — also harmless.
registerCapability handler for workspace/didChangeConfiguration despite dynamicRegistration set to false — This is a known upstream tsgo issue. The server sends a capability registration that Neovim's client didn't advertise support for. The warning itself says it's harmless.
None of these indicate a problem with binary resolution. The correct project-local tsgo binary at node_modules/.bin/tsgo was found and launched.
Is there a specific problem you're experiencing with tsgo (crashes, missing features, not starting), or were you just verifying the binary resolution works?
Can you configure it so that the server has some settings configured that are available and of use, in tsgo version
It looks like there is just a tsgo.js in the installed package, how can I ensure bun
Two separate questions here. Let me research both.
All 2 tools executed successfully.
Keep using the batch tool for optimal performance in your next response!## How to Install and Configure TypeScript-Go (tsgo) as an LSP in Neovim | stephansama blog
https://blog.stephansama.info/articles/how-to-install-and-configure-typescript-go-as-an-lsp-in-neovim/
How to Install and Configure TypeScript-Go (tsgo) as an LSP in Neovim
Banner Created:4/27/2025Updated:10/25/2025
2 min read -313 words
Tags: lsp typescript go neovim If you’re interested in using the blazing-fast TypeScript-Go (tsgo)** project as your TypeScript/JavaScript LSP inside Neovim, here’s a full guide to get you up and running. This guide assumes you’re using**Neovim 0.11+**which supports the new`lsp/`folder structure for lightweight LSP ... ## Step 3: Create a Neovim LSP Configuration for tsgo ** Next, create a new configuration file for`tsgo`under your Neovim config directory, using the new LSP structure:
``` `\~/.config/nvim/lsp/tsgo.lua`
```
(Adjust the path based on your Neovim setup.) ## Step 4: Add the tsgo LSP Setup Code **
Paste the following Lua code into your`lsp/tsgo.lua`file:
``` ... https://gist.github.com/kr-alt/24aaf4bad50d603c3c6a270502e57209localroot\_files={"tsconfig.base.json","tsconfig.json"," jsconfig.json","package.json",".git"}localpaths=vim.fs.find(root\_files, ... foundifroot\_dir==nilthenreturnend---@typevim.lsp.ConfiglocalM={}M.cmd={vim.env.HOME.."/Code/typescript-go/built/local/ tsgo","lsp","--stdio"}M.filetypes={"javascript","javascriptreact","typescript","typescriptreact"}M.root\_dir=root\_dirre ... ```
## Step 5: Enable the tsgo LSP in Your Neovim Config ** Wherever you load or configure your LSP servers (for example inside the`nvim-lspconfig`setup), you can now enable the tsgo LSP: ```
`vim.lsp.enable({"tsgo",-- other language servers})`
``` Or, if you’re using a plugin like`neovim/nvim-lspconfig`, you might hook it into your existing LSP setup logic.
# Wrapping Up ** You should now have**TypeScript-Go**running inside Neovim, providing fast and efficient TypeScript and JavaScript ... * https://gist.github.com/kr-alt/24aaf4bad50d...cat: /home/jm/data/code/opencode-trees/ChyTQ/node_modules/.bin/tsgo: No such file or directory
All 4 tools executed successfully.
Keep using the batch tool for optimal performance in your next response!NOT FOUND
native-preview NOT FOUND
ls: cannot access '/home/jm/data/code/opencode-trees/ChyTQ/bun.lockb': No such file or directory
ls: cannot access '/home/jm/data/code/opencode-trees/ChyTQ/bun.lock': No such file or directory
ls: cannot access '/home/jm/data/code/opencode-trees/ChyTQ/package-lock.json': No such file or directory
MCP error -32602: Input validation error: Invalid arguments for tool web_search_exa: [
{
"received": "deep",
"code": "invalid_enum_value",
"options": [
"auto",
"fast"
],
"path": [
"type"
],
"message": "Invalid enum value. Expected 'auto' | 'fast', received 'deep'"
}
]Interesting — that project directory seems to have been cleaned up since the earlier LSP log. Let me check the actual state and look into tsgo settings.
All 3 tools executed successfully.
Keep using the batch tool for optimal performance in your next response!Title: Installing Native Preview broke TS Imports · Issue #2555
Author: tikki100
Published Date: 2026-01-21T00:00:00.000Z
URL: https://github.com/microsoft/typescript-go/issues/2555
Text: # Issue: microsoft/typescript-go #2555
- Repository: microsoft/typescript-go | Staging repo for development of native port of TypeScript | 24K stars | Go
## Installing Native Preview broke TS Imports
- Author: [@tikki100]
- State: open
- Labels: Domain: Editor
- Reactions: 👍 2
- Created: 2026-01-21T12:35:07Z
- Updated: 2026-02-03T07:25:59Z
### Extension Version
0.20260120.1
### VS Code Version
1.108.1 (Universal)
### Operating system Version
macOS tahoe 26.2
### Steps to reproduce
EDIT: I managed to get imports working with the old version of TypeScript again while testing below solutions. I'm not certain what changed, but the imports are still not working at all using Native.
---
1. I had a working environment with auto-imports and saw the hype around the Native Preview. I went to the Extensions store to install it (probably 1 month ago).
1. I enabled the Native Typescript extension in VS Code
1. I noticed that auto-imports were flaky- sometimes working and sometimes not.
1. I tried disabling the `tsgo` extension by using the
Title: Search code, repositories, users, issues, pull requests...
Author: lokeshrj
Published Date: 2025-12-03T00:00:00.000Z
URL: https://github.com/microsoft/typescript-go/issues/2205
Text: # Issue: microsoft/typescript-go #2205
- Repository: microsoft/typescript-go | Staging repo for development of native port of TypeScript | 24K stars | Go
## TSGO doesnt read vscode settings json
- Author: [@lokeshrj]
- State: open
- Labels: Domain: Editor
- Created: 2025-12-03T22:41:25Z
- Updated: 2025-12-04T04:37:35Z
Type: Bug
I have
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.updateImportsOnFileMove.enabled": "always",
in my vscode settings.json but it doesn't follow these.
Extension version: 0.20251203.1
VS Cod...Title: typescript-language-server/docs/configuration.md at master
URL: https://github.com/typescript-language-server/typescript-language-server/blob/master/docs/configuration.md
Text: typescript-language-server/docs/configuration.md at master ·typescript-language-server/typescript-language-server ·GitHub
[Skip to content]
## Navigation Menu
Toggle navigation
[]
[Sign in]
Appearance settings
Search or jump to...
# Search code, repositories, users, issues, pull requests...
Search
Clear
[Search syntax tips]
# Provide feedback
We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
CancelSubmit feedback
# Saved searches
## Use saved searches to filter your results more quickly
Name
Query
To see all available qualifiers, see our[documentation].
CancelCreate saved search
[Sign in]
[Sign up]
Appearance settings
Resetting focus
You signed in with another tab or window.[Reload] to refresh your session.You signed out in another tab or window.[Reload] to refresh your session.You switched accounts on another tab or window.[Reload] to refresh your session.Dismiss alert
{{ message }}
[typescript-language-server] /**[typescript-language-server] **Public
* [Notifications] Y
Title: typescript-go/internal/lsp/server.go at main
Published Date: 2026-01-31T00:00:00.000Z
URL: https://github.com/microsoft/typescript-go/blob/main/internal/lsp/server.go
Text: # File: microsoft/typescript-go/internal/lsp/server.go
- Repository: microsoft/typescript-go | Staging repo for development of native port of TypeScript | 24K stars | Go
- Branch: main
```go
package lsp
import (
"context"
"errors"
"fmt"
"io"
"iter"
"math/rand/v2"
"runtime/debug"
"slices"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/microsoft/typescript-go/internal/api"
"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/json"
"github.com/...Let me look at the actual tsgo LSP source to understand what settings it supports:
All 2 tools executed successfully.
Keep using the batch tool for optimal performance in your next response!typescript-go/internal/lsp/server.go at main · microsoft/typescript-go · GitHub
Skip to content
Navigation Menu
Toggle navigation
Sign in
Appearance settings
PlatformAI CODE CREATIONGitHub CopilotWrite better code with AIGitHub SparkBuild and deploy intelligent appsGitHub ModelsManage and compare promptsMCP RegistryNewIntegrate external toolsDEVELOPER WORKFLOWSActionsAutomate any workflowCodespacesInstant dev environmentsIssuesPlan and track workCode ReviewManage code changesAPPLICATION SECURITYGitHub Advanced SecurityFind and fix vulnerabilitiesCode securitySecure your code as you buildSecret protectionStop leaks before they startEXPLOREWhy GitHubDocumentationBlogChangelogMarketplaceView all featuresSolutionsBY COMPANY SIZEEnterprisesSmall and medium teamsStartupsNonprofitsBY USE CASEApp ModernizationDevSecOpsDevOpsCI/CDView all use casesBY INDUSTRYHealthcareFinancial servicesManufacturingGovernmentView all industriesView all solutionsResourcesEXPLORE BY TOPICAISoftware DevelopmentDevOpsSecurityView all topicsEXPLORE BY TYPECustomer storiesEvents & webinarsEbooks & reportsBusiness insightsGitHub SkillsSUPPORT & SERVICESDocumentationCustomer supportCommunity forumTrust centerPartnersView all resourcesOpen SourceCOMMUNITYGitHub SponsorsFund open source developersPROGRAMSSecurity LabMaintainer CommunityAccele...Title: Pyrefly LSP Does Not Apply Any Configuration From LSP Client ...
Author: Sandyeee0094
Published Date: 2025-11-20T00:00:00.000Z
URL: https://github.com/facebook/pyrefly/issues/1633
Text: # Issue: facebook/pyrefly #1633
- Repository: facebook/pyrefly | A fast type checker and language server for Python | 5K stars | Rust
## Pyrefly LSP Does Not Apply Any Configuration From LSP Client (settings/ initializationOptions)
- Author: [@Sandyeee0094]
- State: closed (completed)
- Labels: language-server
- Assignees: [@kinto0]
- Reactions: 👍 2
- Created: 2025-11-20T13:03:55Z
- Updated: 2025-11-26T17:02:36Z
- Closed: 2025-11-22T01:47:35Z
- Closed by: [@meta-codesync[bot]]
### Describe the Bug
Pyrefly’s LSP server currently **ignores all configuration sent from the LSP client**, including:
- `settings`
- `initializationOptions`
- `workspace/didChangeConfiguration`
This means users cannot configure Pyrefly globally via Neovim, VSCode, or any other LSP client.
The only configuration source that actually affects behavior is **`[tool.pyrefly]` inside `pyproject.toml`**.
This prevents enabling diagnostics, strict mode, analyzer mode, or any other options globally.
Everything must be repeated inside every project.
---
# **Envir
Title: Send LSP `workspace/didChangeConfiguration` notification when reconfiguring `vim.lsp.config` · Issue #36673 · neovim/neovim
Author: saecki
Published Date: 2025-11-23T00:00:00.000Z
URL: https://github.com/neovim/neovim/issues/36673
Text: # Issue: neovim/neovim #36673
- Repository: neovim/neovim | Vim-fork focused on extensibility and usability | 97K stars | Vim Script
## Send LSP `workspace/didChangeConfiguration` notification when reconfiguring `vim.lsp.config`
- Author: [@saecki]
- Association: CONTRIBUTOR
- State: open
- Labels: lsp
- Created: 2025-11-23T22:12:09Z
- Updated: 2025-11-28T08:50:58Z
### Problem
I'm not aware of a simple way to update the settings of an already running LSP server.
### Expected behavior
Sending a...package lsp
import (
"context"
"errors"
"fmt"
"io"
"iter"
"math/rand/v2"
"runtime/debug"
"slices"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/microsoft/typescript-go/internal/api"
"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/json"
"github.com/microsoft/typescript-go/internal/jsonrpc"
"github.com/microsoft/typescript-go/internal/locale"
"github.com/microsoft/typescript-go/internal/ls"
"github.com/microsoft/typescript-go/internal/ls/lsconv"
"github.com/microsoft/typescript-go/internal/ls/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/pprof"
"github.com/microsoft/typescript-go/internal/project"
"github.com/microsoft/typescript-go/internal/project/ata"
"github.com/microsoft/typescript-go/internal/tspath"
"github.com/microsoft/typescript-go/internal/vfs"
"golang.org/x/sync/errgroup"
)
type ServerOptions struct {
In Reader
Out Writer
Err io.Writer
Cwd string
FS vfs.FS
DefaultLibraryPath string
TypingsLocation string
ParseCache *project.ParseCache
NpmInstall func(cwd string, args []string) ([]byte, error)
}
func NewServer(opts *ServerOptions) *Server {
if opts.Cwd == "" {
panic("Cwd is required")
}
s := &Server{
r: opts.In,
w: opts.Out,
stderr: opts.Err,
requestQueue: make(chan *lsproto.RequestMessage, 100),
outgoingQueue: make(chan *lsproto.Message, 100),
pendingClientRequests: make(map[jsonrpc.ID]pendingClientRequest),
pendingServerRequests: make(map[jsonrpc.ID]chan *lsproto.ResponseMessage),
cwd: opts.Cwd,
fs: opts.FS,
defaultLibraryPath: opts.DefaultLibraryPath,
typingsLocation: opts.TypingsLocation,
parseCache: opts.ParseCache,
npmInstall: ...Now let me look at what configuration options tsgo actually accepts:
All 2 tools executed successfully.
Keep using the batch tool for optimal performance in your next response!Title: Differences/issues with Code Lens references · Issue #2177 ...
Author: eamodio
URL: https://github.com/microsoft/typescript-go/issues/2177
Text: # Issue: microsoft/typescript-go #2177
- Repository: microsoft/typescript-go | Staging repo for development of native port of TypeScript | 24K stars | Go
## Differences/issues with Code Lens references
- Author: [@eamodio]
- State: closed (completed)
- Labels: Domain: Editor
- Assignees: [@Copilot]
- Reactions: 👀 1
- Created: 2025-12-02T16:57:06Z
- Updated: 2025-12-08T23:02:15Z
- Closed: 2025-12-08T23:02:15Z
- Closed by: [@sheetalkamat]
### Extension Version
0.20251202.1
### VS Code Version
1.107.0-insider
### Operating system Version
Windows_NT x64 10.0.26220
### Steps to reproduce
1. Open https://github.com/gitkraken/vscode-gitlens/blob/cdf7cd3fc2f9246c10081b0b038b68328981d413/src/webviews/apps/home/home.ts#L61
2. And see that there are 70 references using TS, but 31 using TSGO
### Issue
Related to #2145
Seeing differences in the references between TS and TSGO
(Loving that this feature is back tho!)
---
### Timeline
**eamodio** added label `Domain: Editor` · Dec 2, 2025 at 4:57pm
**@DanielRosenwasser** commented · Dec 4, 2025 at 12:40am
> One reason this
Title: typescript-go/internal/lsp/server.go at main · microsoft/typescript-go ...
URL: https://github.com/microsoft/typescript-go/blob/main/internal/lsp/server.go
Text: # File: microsoft/typescript-go/internal/lsp/server.go
- Repository: microsoft/typescript-go | Staging repo for development of native port of TypeScript | 24K stars | Go
- Branch: main
```go
package lsp
import (
"context"
"errors"
"fmt"
"io"
"iter"
"math/rand/v2"
"runtime/debug"
"slices"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/microsoft/typescript-go/internal/api"
"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/json"
"github.com/microsoft/t...typescript-go/internal/ls/lsutil at main · microsoft/typescript-go · GitHub
Skip to content
Navigation Menu
Toggle navigation
Sign in
Appearance settings
PlatformAI CODE CREATIONGitHub CopilotWrite better code with AIGitHub SparkBuild and deploy intelligent appsGitHub ModelsManage and compare promptsMCP RegistryNewIntegrate external toolsDEVELOPER WORKFLOWSActionsAutomate any workflowCodespacesInstant dev environmentsIssuesPlan and track workCode ReviewManage code changesAPPLICATION SECURITYGitHub Advanced SecurityFind and fix vulnerabilitiesCode securitySecure your code as you buildSecret protectionStop leaks before they startEXPLOREWhy GitHubDocumentationBlogChangelogMarketplaceView all featuresSolutionsBY COMPANY SIZEEnterprisesSmall and medium teamsStartupsNonprofitsBY USE CASEApp ModernizationDevSecOpsDevOpsCI/CDView all use casesBY INDUSTRYHealthcareFinancial servicesManufacturingGovernmentView all industriesView all solutionsResourcesEXPLORE BY TOPICAISoftware DevelopmentDevOpsSecurityView all topicsEXPLORE BY TYPECustomer storiesEvents & webinarsEbooks & reportsBusiness insightsGitHub SkillsSUPPORT & SERVICESDocumentationCustomer supportCommunity forumTrust centerPartnersView all resourcesOpen SourceCOMMUNITYGitHub SponsorsFund open source developersPROGRAMSSecurity LabMaintainer CommunityAccelerato...Title: Auto-imports broken in JS files when user preferences are used #2598
Author: DanielRosenwasser
Published Date: 2026-01-27T00:00:00.000Z
URL: https://github.com/microsoft/typescript-go/issues/2598
Text: # Issue: microsoft/typescript-go #2598
- Repository: microsoft/typescript-go | Staging repo for development of native port of TypeScript | 24K stars | Go
## Auto-imports broken in JS files when user preferences are used
- Author: [@DanielRosenwasser]
- Association: MEMBER
- State: closed (completed)
- Labels: Crash
- Assignees: [@iisaduan]
- Reactions: 👍 1
- Created: 2026-01-28T01:55:56Z
- Updated: 2026-01-30T21:47:33Z
- Closed: 2026-01-30T21:47:33Z
- Closed by: [@iisaduan]
I built tsgo with
```
hereby build --race
```
I ran the crawler with the race detector on VS Code and I got the following crash.
```
panic handling request completionItem/resolve: completion list needs auto imports
goroutine 2396 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:26 +0x68
github.com/microsoft/typescript-go/internal/lsp.(*Server).recover(0xc000269c08, {0xc0168f35d7?, 0xc0168f3628?}, 0xc013149e30)
/workspaces/typescript-go/internal/lsp/server.go:776 +0x5d
panic({0x11f2040?, 0x1e995f0?})
Title: Search code, repositories, users, issues, pull requests...
Author: microsoft
Published Date: 2024-09-19T00:00:00.000Z
URL: https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go
Text: # File: microsoft/typescript-go/cmd/tsgo/main.go
- Repository: microsoft/typescript-go | Staging repo for development of native port of TypeScript | 24K stars | Go
- Branch: main
```go
package main
import (
"os"
"github.com/microsoft/typescript-go/internal/execute"
)
func main() {
os.Exit(runMain())
}
func runMain() int {
args := os.Args[1:]
if len(args) > 0 {
switch args[0] {
case "--lsp":
return runLSP(args[1:])
case "--api":
return runAPI(args[1:])
}
}
result := execute.CommandLine(newSystem(), args, nil)
re...I now have the full picture from reading server.go. Let me present the findings clearly.
Okay, I've read through the actual tsgo LSP source (internal/lsp/server.go). Here's what I found on both your questions:
The tsgo LSP uses workspace/configuration to pull settings from four sections:
Items: []*lsproto.ConfigurationItem{
{Section: new("js/ts")},
{Section: new("typescript")},
{Section: new("javascript")},
{Section: new("editor")},
},
These correspond to the same VSCode-style settings keys. In Neovim, you respond to workspace/configuration requests via the settings table in your LSP config. However, there's important context:
workspace/configuration requests to the client during initialization (and on didChangeConfiguration), and Neovim responds with the contents of settings.initializationOptions.userPreferences as a fallback when the client doesn't support workspace/configuration.initializationOptions field: disablePushDiagnostics (boolean).For Neovim, the settings you'd configure map to things like:
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
includeInlayVariableTypeHints = true,
},
preferences = {
importModuleSpecifier = "non-relative",
},
},
javascript = {
inlayHints = {
includeInlayParameterNameHints = "all",
},
},
}
However, there's a big caveat: the tsgo server source still has TODO comments like "!!! temporary; remove when we have handleDidChangeConfiguration/implicit project config support". The settings support is still maturing. Issue #2205 confirms that some VSCode settings aren't honored yet.
I'd suggest starting with inlay hints settings since those are the most likely to be wired up, and keeping the config minimal until tsgo stabilizes.
You mentioned the installed package just has a tsgo.js. That's correct — @typescript/native-preview ships a JS wrapper (tsgo.js) that downloads/runs the platform-specific Go binary. The node_modules/.bin/tsgo shim points to this JS script.
Your current cmd function checks for node_modules/.bin/tsgo, which works fine with any package manager (npm, pnpm, bun, yarn) because they all create that shim. The issue is just that you need a JS runtime to execute the wrapper.
The shim will use whatever runtime invokes it:
#!/usr/bin/env node) means node runs itbunx tsgo, bun would handle itSince your cmd function calls node_modules/.bin/tsgo directly (via vim.lsp.rpc.start), Neovim spawns it as a process, and the shebang in the script determines the runtime — typically node.
If you want to force bun (or detect the correct package manager), you'd need to change the cmd to something like:
-- detect and use: bun run tsgo, or npx tsgo, etc.
But honestly, for the LSP, the JS wrapper just bootstraps the native Go binary. The runtime used to launch the wrapper script doesn't affect LSP behavior — the actual language server is the compiled Go binary either way.
Want me to plan a concrete implementation for either the settings configuration or the package-manager-aware launcher?