fix: skip buffers with URI schemes in root_dir#4345
fix: skip buffers with URI schemes in root_dir#4345niklaas wants to merge 4 commits intoneovim:masterfrom
Conversation
Problem: Buffers with non-file URI schemes (e.g. fugitive://, oil://) have no real file path. The root_dir function unconditionally calls on_dir(project_root or vim.fn.getcwd()), which causes ts_ls to attach to such buffers and error because LSP cannot handle non-file:// URIs. Solution: Return early from root_dir when the buffer name starts with a URI scheme, preventing attachment to buffers that LSP cannot handle.
Problem: Buffers with non-file URI schemes (e.g. fugitive://, oil://) have no real file path. The root_dir function unconditionally calls on_dir(project_root or vim.fn.getcwd()), which causes tsgo to attach to such buffers and error because LSP cannot handle non-file:// URIs. Solution: Return early from root_dir when the buffer name starts with a URI scheme, preventing attachment to buffers that LSP cannot handle.
Problem: Buffers with non-file URI schemes (e.g. fugitive://, oil://) have no real file path. The root_dir function unconditionally calls on_dir(project_root or vim.fn.getcwd()), which causes vtsls to attach to such buffers and error because LSP cannot handle non-file:// URIs. Solution: Return early from root_dir when the buffer name starts with a URI scheme, preventing attachment to buffers that LSP cannot handle.
Problem: Buffers with non-file URI schemes (e.g. fugitive://, oil://) have no real file path. The root_dir function unconditionally calls on_dir(root_dir or vim.fn.getcwd()), which causes matlab_ls to attach to such buffers and error because LSP cannot handle non-file:// URIs. Solution: Return early from root_dir when the buffer name starts with a URI scheme, preventing attachment to buffers that LSP cannot handle.
| if vim.api.nvim_buf_get_name(bufnr):match('^%a+://') then | ||
| return | ||
| end | ||
| local root_dir = vim.fs.root(bufnr, '.git') | ||
| on_dir(root_dir or vim.fn.getcwd()) |
There was a problem hiding this comment.
Thanks for the clear explanation. But I don't quite see why the solution was chosen.
I think it's more like a hint that getcwd() should not be used as a fallback. People really seem to love it though ...
There was a problem hiding this comment.
I think it's more like a hint that
getcwd()should not be used as a fallback.
Good catch, I agree. I guess I subconsciously decided to use a guard to avoid introducing a breaking change.
However, I'm happy to remove calling getcwd(). As you indicate, arguably, the issue I ran into demonstrates the function isn't the proper approach to choose there because it's brittle.
Let me know if you'd be willing to introduce a breaking change.
That may change in the future though. I guess you could future-proof your current PR by only skipping if |
|
Using |
Problem
Some LSP configs implement a custom
root_dirfunction that unconditionallycalls
on_dir(project_root or vim.fn.getcwd()). When no project root is found,this falls back to
getcwd(), causing the LSP to attach to any buffer of amatching filetype including buffers with non-file URI schemes such as
fugitive://(vim-fugitive).Once attached, the LSP sends requests using the
fugitive://URI, which is nota valid
file://URI and causes errors.The affected configs are
ts_ls,tsgo,vtsls, andmatlab_ls.Configs that use
root_markersonly (e.g.lua_ls,ruby_lsp) are naturallysafe because
vim.fs.root()returnsnilfor non-file buffers, soon_dirisnever called.
Solution
Add a guard at the top of each affected
root_dirfunction that returns earlywhen the buffer name starts with a URI scheme:
From my understanding, neovim buffer names are always plain paths (e.g.
/home/user/file.ts) for real files, never file:// URIs, so this guard only
skips genuinely non-file buffers.
I don't think the early returns trigger false positives but for sure let me know if they do.