Conversation
b59ccc9 to
a495b35
Compare
So there are two different cases here:
As you point out, I will look into how to add some form of a timeout utility
Does this happen when
Looks like this is a regression I'll look into. From my tests, local functions are still completed.
Take a look at the code for the current Also, you probably want to use A couple other questions I have:
|
The server would only index all the files if the connection is needing to be started for a request, which might be happening in your case if the client is dropping the connection after a request completes. Try making sure that the tail -f (fish-lsp info --log-file) |
Hey @ndonfris , I did some more testing on this issue. It looks like On a simple repro:
I see that it takes about 9 seconds to load the variable definition. Here's what that looks like: Screen.Recording.2025-11-16.at.1.25.32.PM.mp4I also tried it on a file that's 4000 lines long and it took 46 seconds. I think there's something O(n^2) going on with fish-lsp's parser, which is making it painfully slow on large files. Do you have any idea what that is / would you mind profiling fish-lsp when it's loading a large file? I can also file this as a formal ticket on https://github.com/ndonfris/fish-lsp. big.fishfunction big
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
echo hello
end
set -l foo
echo $foo |
|
After some quick testing locally, I have trouble reproducing such long input. What does your server tail -f (fish-lsp info --log-file) # will incrementally show logs Also, fish-lsp info --time-startupThese should give clearer insight into what exactly is causing the server to take long. Also, here's how long startup takes on my config which has more than 35,000 total lines (although separated among multiple files) Opening a ticket on https://github.com/ndonfris/fish-lsp is encouraged for visibility in case others are experiencing similar issues. |
|
I did some more testing today, and it looks like the main bottleneck is in the diagnostic validation step. There are a couple locations that implement their own parser logic in the server, so this was not clear to me initially. In particular, diagnostic checks like unreachable block validation (error code 5555) seem to be a large part of the cost. I’ll dig into this further, but there may be some room for optimization there. For very large files (4,000+ lines), there’s also a practical limit to how fast diagnostics can reasonably be computed. On my machine, a single pass over a ~4k-line document using tree-sitter, with generators and every applicable optimization I can think of (and without doing any higher-level analysis like building Here is what I used to test the server:
|
|
This is amazing to see at least some of LSP stuff working right in VS Code. 😄 I expected it to happen for a long time and working LSP for me is a great argument to start using Fish again. |




I tried out
fish-lspand it mostly worked! Putting this PR out to show it off a bit & see if anyone has any ideas on how to fix the issues. They're probably solvable with a bit of time.This is pretty awesome, thanks @ndonfris. Lmk if you know anything about these issues.
Fixes #36.
Things that work
Issue: it's slow
Some actions take 5-10 seconds to run which is kind of slow. Since it indexes everything to begin with I don't really understand how looking up the definition of
cdin the indexed location/opt/homebrew/Cellar/fish/4.1.2/share/fish/funtions/cd.fishcould take 5-10 seconds, you'd think it'd just be some dictionary lookup.If it hangs, that's the end of fish-lsp until you reload the window.
Something simple like adding
set -l unusedin config.fish takes 5-10 seconds to show "unused variable". Something fishy is going on. I am not sure what to run to diagnose why this is taking a while.It may be indexing some big systems path location that might be too big.
fish-lsp info --time-startupshows:I wonder if it's indexing all of these on every query.
Issue: slow formatter
This replaces the formatter, but the previous formatter ran almost instantly so it feels a lot slower. I might disable the formatting to use
fish_indentagain. This is mostly on me to figure out how to do that in vscode / disable it from fish-lsp.Could have
In order of how much I want it:
[Error - 9:10:55 PM] Request textDocument/definition failed. Message: Request textDocument/definition failed with message: Command failed: fish --command type -ap prompt_command Code: -32603. When I runfish --command type -ap prompt_commandI get the errorfish: -ap: unknown option. I'm on the latest release 4.1.2. This is probably a bug infish-lsp[Error - 9:47:25 PM] Request textDocument/hover failed. Message: Request textDocument/hover failed with message: ENOENT: no such file or directory, unlink '/var/folders/2k/ljy_ph75655_xk1lwbhlfrq80000gn/T/get-documentation.fish' Code: -32603. This is probably a bug infish-lspSettings:
Many of these can be set with env variables like
fish_lsp_foo=bar fish-lsp. I'll make a new setting to set env variables for fish-lsp.sourcecommands by default.Related