nvim-lspconfig
nvim-lspconfig copied to clipboard
Default root_dir for pyright to neovim's cwd
Description
By default, neovim starts the pyright-lspserver from $HOME, which causes pyright to recursively scan every single file in the home directory. This can lead to slow startup time and high cpu utilization (and also loud fans!).
Neovim version
NVIM v0.8.0 Build type: RelWithDebInfo LuaJIT 2.1.0-beta3 Compilation: /usr/bin/gcc -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wp,-U_FORTIFY_SOURCE -Wp,-D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -DNVIM_TS_HAS_SET_ALLOCATOR -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wdouble-promotion -Wmissing-noreturn -Wmissing-format-attribute -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/builddir/build/BUILD/neovim-0.8.0/redhat-linux-build/cmake.config -I/builddir/build/BUILD/neovim-0.8.0/src -I/usr/include -I/usr/include/luajit-2.1 -I/builddir/build/BUILD/neovim-0.8.0/redhat-linux-build/src/nvim/auto -I/builddir/build/BUILD/neovim-0.8.0/redhat-linux-build/include Compiled by mockbuild@koji
Features: +acl +iconv +tui See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim" fall-back for $VIM: "/usr/share/nvim"
Run :checkhealth for more info
Nvim-lspconfig version
f8b3c240edad68bf549cae6b133cf2cac85554e8
Operating system and version
Linux (fedora 36 x86_64)
Affected language servers
pyright
Steps to reproduce
Configure pyright...
require'lspconfig'.pyright.setup{}
...and then edit a Python file in a directory that does not contain a pyrightconfig.json file.
Actual behavior
pyright consumes 100% CPU indefinitely
Expected behavior
pyright scans only files reachable from the directory in which neovim was started
We can work around this problem by setting:
require'lspconfig'.pyright.setup{
root_dir = function()
return vim.fn.getcwd()
end,
}
But this should be the default behavior.
Minimal config
(as above)
LSP log
(not useful)
Hmm, this sounds weird given that there's multiple markers:
https://github.com/neovim/nvim-lspconfig/blob/c96ec574eacfff8ad8dd4bdb6e96a1b3dbd268fd/lua/lspconfig/server_configurations/pyright.lua#L10-L17
As well as single_file_support being enabled.
@lithammer maybe OP has one of the markers in his home directory
@ianliu there are no marker files in the home directory. The problem crops up when you edit a file in a directory that contains no marker files. E.g., if I have:
$ cd tmp/work
$ ls
foo.py
Then editing foo.py in this directory will result in pyright scanning my entire home directory.
If I drop any of the various marker files into that directory the problem goes away, but sometimes it is unavoidable that one needs to edit bare python files, and it's nice to have pyright functional in this situation.
Defaulting root_dir to neovim's cwd seems both reasonable and unsurprising.
How do you know the root_dir is your HOME? Try this:
require'lspconfig'.pyright.setup{
on_new_config = function(cfg, root)
print(root)
end
}
How do you know the root_dir is your HOME? Try this:
I know that pyright is explicit changing to the home directory because I ran strace on neovim, which shows:
849281 execve("/home/lars/bin/pyright-langserver", ["pyright-langserver", "--stdio"], 0x55da7b725540 /* 83 vars */ <unfinished ...>
[...]
849281 chdir("/home/lars") = 0
Whereas after setting root_dir as described, I see:
2106306 execve("/usr/bin/node", ["node", "/home/lars/bin/pyright-langserver", "--stdio"], 0x7ffc49a16470 /* 83 vars */ <unfinished ...>
[...]
2106306 chdir("/home/lars/tmp/work") = 0
That seems pretty clear to me.
What's the output of :LspInfo when you edit foo.py? Also, what does lsp.log say? You can find its location either from the :LspInfo popup or :lua print(vim.lsp.get_log_path()).
You could also try editing /tmp/foo.py and see if the root_dir keeps being your HOME.
I am having the same problem and the issue on my case is a file called setup.py on the same place where I opened the file.
I believe this root_dir function should change to account for this but I am unsure on what would be the best way forward.
Maybe some weight system, because for sure .git , pyproject.toml and so on should take precedence over setup.py which is such a generic name
I am also having this problem and can't for the life of me figure it out.
I tried changing the root dir in the pyright config:
root_dir = function()
return vim.fn.getcwd()
end
but it doesn't make a difference, plus that doesn't seem to be the issue anyway because :LspInfo says the home dir was correct anyway:
Client: pyright (id: 1, bufnr: [1])
filetypes: python
autostart: true
root directory: /home/ffettes/work/hm-data-utils
cmd: pyright-langserver --stdio
Happy to try any suggestions to debug this further, this makes pyright almost totally unusable.
For debuggings sake I also tried to run lunarvim and the results were exactly the same as with my regular nvim setup.
Defaulting
root_dirto neovim's cwd seems both reasonable and unsurprising.
No. Defaulting root_dir to neovim's cwd for all cases is not reasonable; it is problematic. I described why this is the case in #2697
Defaulting root_dir to neovim's cwd should only be allowed if the user sets single file support to false. For the alternative case, pyright needs to be launched in single-file mode if the appropriate root markers are not found, not be forced to use the current working directory as the root directory.
Let's say you are working on a Go project inside directory X. So you have a neovim session opened with its current working directory set to directory X. Then, all of a sudden, you need to refer to a python script called foo.py. foo.py is a standalone script (it's not part of a python project), so it's sitting in a directory that does not contain any python root markers. So, within your active neovim session, you run :e /path/to/foo.py to open a new buffer. nvim-lspconfig launches pyright as expected, but instead of launching pyright in single-file mode, it now assigns directory X as pyright's root directory, which is pointless because directory X is not even related to foo.py. It just happened to be the cwd of the active neovim session when you decided to open foo.py.
If we let root_dir default to cwd, it will lead to wasted CPU cycles and memory on a good day and Neovim outright crashing on a bad day (especially if directory X contains hundreds of files; pyright has to scan and analyze all of them for no good reason at all).