Skip to content

Commit

Permalink
fix: autostart=false: attach when editing new, nonexistent file #2712
Browse files Browse the repository at this point in the history
## Problem
Currently, `nvim-lspconfig` tries to attach servers automatically via two autocommands:
1. Created if `config.autostart == true` and triggered by `FileType`, if `config.filetypes` is set, else `BufReadPost`. Calls `try_add()`.
2. Created for each workspace root, triggered by `BufReadPost` matching paths starting with the root. Calls `try_add_wrapper()`.

`BufReadPost` does not fire when creating a buffer for a file that doesn't exist. This means that if `config.autostart == true` and `config.filetypes` is set and includes the detected filetype for the buffer, the server is attached automatically regardless of whether the file exists, but in all other cases the server is only attached for existing files.

## Solution
1. Where these autocommands trigger on `BufReadPost`, also trigger on `BufNewFile`.
2. Wrap the autocommand callbacks in `vim.schedule()` to ensure `filetype` is set first, as the `BufReadPost`/`BufNewFile` autocommands will trigger before `FileType` if `nvim-lspconfig` is set up early enough during Nvim init (see neovim/neovim#7367 and #2712 (comment)).

I did consider including a test with this PR, but there doesn't seem to be any existing test infrastructure for tests involving actually running a language server (or a mock of one).

Fixes #2711
  • Loading branch information
Diomendius authored Oct 3, 2024
1 parent 5408121 commit fb453a1
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions lua/lspconfig/configs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,15 @@ function configs.__newindex(t, config_name, config_def)

if config.autostart == true then
local event_conf = config.filetypes and { event = 'FileType', pattern = config.filetypes }
or { event = 'BufReadPost' }
or { event = { 'BufReadPost', 'BufNewFile' } }
api.nvim_create_autocmd(event_conf.event, {
pattern = event_conf.pattern or '*',
callback = function(opt)
M.manager:try_add(opt.buf)
-- Use vim.schedule() to ensure filetype detection happens first.
-- Sometimes, BufNewFile triggers before 'filetype' is set.
vim.schedule(function()
M.manager:try_add(opt.buf)
end)
end,
group = lsp_group,
desc = string.format(
Expand Down Expand Up @@ -142,13 +146,18 @@ function configs.__newindex(t, config_name, config_def)
end

if root_dir then
api.nvim_create_autocmd('BufReadPost', {
api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile' }, {
pattern = fn.fnameescape(root_dir) .. '/*',
callback = function(arg)
if #M.manager:clients() == 0 then
return true
end
M.manager:try_add_wrapper(arg.buf, root_dir)

-- Use vim.schedule() to ensure filetype detection happens first.
-- Sometimes, BufNewFile triggers before 'filetype' is set.
vim.schedule(function()
M.manager:try_add_wrapper(arg.buf, root_dir)
end)
end,
group = lsp_group,
desc = string.format(
Expand Down

2 comments on commit fb453a1

@BrunoKrugel
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Facing the following error, after this commit:

Error executing vim.schedule lua callback: ...share/nvim/lazy/nvim-lspconfig/lua/lspconfig/manager.lua:247: Invalid buffer id: 7
stack traceback:
	[C]: in function '__index'
	...share/nvim/lazy/nvim-lspconfig/lua/lspconfig/manager.lua:247: in function 'try_add'
	...share/nvim/lazy/nvim-lspconfig/lua/lspconfig/configs.lua:111: in function <...share/nvim/lazy/nvim-lspconfig/lua/lspconfig/configs.lua:110

@justinmk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reporting. Reverted: #3347

Please sign in to comment.