-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: autostart=false: attach when editing new, nonexistent file #2712
Conversation
@@ -100,7 +100,7 @@ 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' } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BufNewFile
run before FileType
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
au FileType * echo 'FileType ' . &ft
au BufNewFile * echo 'BufNewFile ' . &ft
au BufReadPost * echo 'BufReadPost ' . &ft
Using the above for testing, both BufNewFile
and BufReadPost
run before FileType
. Weirdly, when I run these commands with my usual config loaded, FileType
actually executes first. I have no idea what part of my config changes the order.
If there's any issue with this callback triggering before FileType
, it affects BufReadPost
as well. I'm not sure if it matters here, since BufReadPost
and BufNewFile
are only used if config.filetypes
is unset. Does it make sense for a server to be configured without config.filetypes
if it matters what filetype
is when try_add()
runs?
At line 139 it's definitely important that try_add_wrapper()
runs after filetype
is set, however.
vim.schedule()
seems to be enough to defer a function until after FileType
, but this seems like a hacky solution to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the following in test.lua
:
vim.api.nvim_create_autocmd({ "BufReadPost", "FileType", "BufNewFile" }, {
callback = function(e)
print(vim.o.ft, vim.inspect(e))
end,
})
If I run XDG_DATA_HOME=xdg_data XDG_STATE_HOME=xdg_state nvim -u test.lua
, BufReadPost
/BufNewFile
triggers first.
If I run XDG_DATA_HOME=xdg_data XDG_STATE_HOME=xdg_state nvim -u NORC +source\ test.lua
, FileType
triggers first.
If I wrap the entire contents of test.lua
in vim.schedule()
, FileType
always triggers first regardless of whether I :source
test.lua
or load it as the rc file with -u
.
BufReadPost
and BufNewFile
autocommands only seem to trigger earlier than FileType
if they were set up sufficiently early during startup. This seems weird to me, but I can reproduce it consistently. I don't know what the intended execution order of these events is, or if there is even meant to be a guaranteed order at all.
0aa499d
to
2ccafd1
Compare
I can't think of a better solution than It'd be nice to have an explicit guarantee that the callback will run only after filetype detection. The other idea I had was to create a one-shot I looked at the Nvim source to try to confirm that |
this seems fine, can you rebase it. also would help to have a clear Problem/Solution summary. |
BufReadPost does not trigger when editing a nonexistent file, so language servers would not automatically attach when editing a new file if autostart was disabled or if the server had no associated filetypes. This fixes that by adding BufNewFile to autocommands hooked to BufReadPost.
Sometimes, BufNewFile triggers before 'filetype' is set. Using vim.schedule() should ensure filetype detection runs before the callback.
2ccafd1
to
52346b1
Compare
I've rebased this and expanded the OP to better describe this PR. It looks like neovim/neovim#7367 already describes the issue with |
Had to revert: #3347 But, if you can find a solution then we can try again. |
That's a shame. @glepnir said something about this causing an invalid buffer ID, but it's not obvious to me what would trigger that or in what context. If someone could give instructions to reproduce, I'd appreciate it. |
My working hypothesis is that the buffer could be wiped out after The real-world cause might not be so contrived, but assuming the buffer ID is still valid when the scheduled callback runs is clearly wrong. Thankfully, the solution is probably just to do nothing in the callback if the buffer isn't valid; a buffer that doesn't exist obviously can't have a language server attach to it, so nothing needs to be done. |
Repro for my case: -- fb453a1.lua
vim.env.LAZY_STDPATH = '.repro'
load(vim.fn.system('curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua'))()
require('lazy.minit').repro({
spec = {
{
'neovim/nvim-lspconfig',
commit = 'fb453a1', -- https://github.com/neovim/nvim-lspconfig/pull/2712
config = function()
local lspconfig = require 'lspconfig'
lspconfig.lua_ls.setup({
autostart = true,
})
end
}
},
}) Steps To Reproduce (NVIM
Error executing vim.schedule lua callback: .../nvim-data/lazy/nvim-lspconfig/lua/lspconfig/manager.lua:247: Invalid buffer id: 3
stack traceback:
[C]: in function '__index'
.../nvim-data/lazy/nvim-lspconfig/lua/lspconfig/manager.lua:247: in function 'try_add'
.../nvim-data/lazy/nvim-lspconfig/lua/lspconfig/configs.lua:111: in function <.../nvim-data/lazy/nvim-lspconfig/lua/lspconfig/configs.lua:110> |
Thanks for that, @AlexMasterov. Details of causeSo, this bug only occurs when It happens when When using local cur_cs = vim.filetype.get_option(ft, 'commentstring')
ft_option_cache[filetype][option] = api.nvim_get_option_value(option, { filetype = filetype }) That then calls buf_T *ftbuf = do_ft_buf(filetype, &aco, err);
-- … --
wipe_buffer(ftbuf, false); So it wasn't exactly a plugin triggering this, but rather a side effect of a function in Neovim proper (see The obvious solution still seems to be to bail early if the buffer isn't valid. I've pushed a fix and opened #3355. |
Problem
Currently,
nvim-lspconfig
tries to attach servers automatically via two autocommands:config.autostart == true
and triggered byFileType
, ifconfig.filetypes
is set, elseBufReadPost
. Callstry_add()
.BufReadPost
matching paths starting with the root. Callstry_add_wrapper()
.BufReadPost
does not fire when creating a buffer for a file that doesn't exist. This means that ifconfig.autostart == true
andconfig.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
BufReadPost
, also trigger onBufNewFile
.vim.schedule()
to ensurefiletype
is set first, as theBufReadPost
/BufNewFile
autocommands will trigger beforeFileType
ifnvim-lspconfig
is set up early enough during Nvim init (see startup: precedence of :syntax/:filetype autocmds neovim#7367 and fix: autostart=false: attach when editing new, nonexistent file #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