nvim-lspconfig icon indicating copy to clipboard operation
nvim-lspconfig copied to clipboard

Default root_dir for pyright to neovim's cwd

Open larsks opened this issue 3 years ago • 10 comments

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)

larsks avatar Nov 10 '22 17:11 larsks

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 avatar Nov 11 '22 07:11 lithammer

@lithammer maybe OP has one of the markers in his home directory

ianliu avatar Nov 11 '22 12:11 ianliu

@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.

larsks avatar Nov 11 '22 13:11 larsks

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
}

ianliu avatar Nov 11 '22 13:11 ianliu

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.

larsks avatar Nov 11 '22 14:11 larsks

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()).

lithammer avatar Nov 11 '22 14:11 lithammer

You could also try editing /tmp/foo.py and see if the root_dir keeps being your HOME.

ianliu avatar Nov 11 '22 15:11 ianliu

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

dagadbm avatar Jan 19 '23 15:01 dagadbm

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.

FergusFettes avatar May 02 '23 15:05 FergusFettes

Defaulting root_dir to 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).

anthony-S93 avatar Jul 21 '23 09:07 anthony-S93