Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Conversation

jfly
Copy link
Contributor

@jfly jfly commented Apr 29, 2025

IIUC, the intent vim.lsp.enable is for it to be called once early during startup. However, I have a noisy LSP that I'd like to be able to turn off when it's distracting and on when it's useful. I want this enable/disabling to affect all current and future buffers, and vim.lsp.enable seems like a reasonable place to put that logic.

fixes #33701
fixes #33116

Copy link
Member

@justinmk justinmk left a comment

Choose a reason for hiding this comment

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

Makes sense to me, and aligns with enable() behavior in other modules.

test/functional/plugin/lsp_spec.lua Outdated Show resolved Hide resolved
IIUC, the intent `vim.lsp.enable` is for it to be called once early
during startup. However, I have a noisy LSP that I'd like to be able to
turn off when it's distracting and on when it's useful. I want this
enable/disabling to affect all current and future buffers, and
`vim.lsp.enable` seems like a reasonable place to put that logic.

This fixes neovim#33701 and
neovim#33116.
Comment on lines +585 to +588
else
-- Only ever create autocmd once to reuse computation of config merging.
lsp_enable_autocmd_id = lsp_enable_autocmd_id
or api.nvim_create_autocmd('FileType', {
Copy link
Member

Choose a reason for hiding this comment

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

normally in favor of ternaries but in this case, is this clearer?

Suggested change
else
-- Only ever create autocmd once to reuse computation of config merging.
lsp_enable_autocmd_id = lsp_enable_autocmd_id
or api.nvim_create_autocmd('FileType', {
elseif not lsp_enable_autocmd_id then
-- Only ever create autocmd once to reuse computation of config merging.
lsp_enable_autocmd_id = api.nvim_create_autocmd('FileType', {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree the ternary is dense. I also didn't write it, and it looks like you've merged the PR :)

@justinmk justinmk merged commit 4bc7bac into neovim:master Apr 30, 2025
29 of 30 checks passed
@github-actions github-actions bot removed the request for review from MariaSolOs April 30, 2025 23:57
@neovim-backports
Copy link

Successfully created backport PR for release-0.11:

github-actions bot pushed a commit that referenced this pull request May 1, 2025
Problem:
enable() could be more flexible, so that it works even if called "late".

Solution:
- enable(true) calls `doautoall nvim.lsp.enable FileType`.
- enable(false) calls `client:stop()` on matching clients.

This will be useful for e.g. :LspStop/:LspStart also.

(cherry picked from commit 4bc7bac)
github-actions bot pushed a commit that referenced this pull request May 1, 2025
Problem:
enable() could be more flexible, so that it works even if called "late".

Solution:
- enable(true) calls `doautoall nvim.lsp.enable FileType`.
- enable(false) calls `client:stop()` on matching clients.

This will be useful for e.g. :LspStop/:LspStart also.

(cherry picked from commit 4bc7bac)
@jfly jfly deleted the issue-33701 branch May 1, 2025 01:16
bfredl added a commit that referenced this pull request May 30, 2025
This is a maintenance release, focusing on bug fixes. Some enhancements related
to vim.lsp.enable are also included.

FEATURES
--------------------------------------------------------------------------------
- 4e43264 lsp: vim.lsp.is_enabled() #33703
- c4b9bdb lsp: start/stop LSPs as necessary during vim.lsp.enable() #33702
- 216c56b lsp: detach LSP clients when 'filetype' changes #33707
- 533ec6d lsp: `root_markers` can control priority
- ad7211a checkhealth: trigger FileType event after showing report
- f25f6c8 health: summary in section heading #33388

FIXES
--------------------------------------------------------------------------------
- 710d561 lsp: don't eagerly enable LSP configs during startup #33762
- 0ed06d7 lsp: check if client is stopping before reuse #33796
- f184c56 lsp: detect if Client:request resolved synchronously #33624
- b868257 lsp: fix error with InsertReplaceEdit events #33973
- 6b69b32 lsp: improper diagnostic end_col computation
- e512c95 lsp: improve error completion message #33812
- 47686a1 lsp: only auto-detach lsp.config clients #33834
- 901eeeb lsp: use `bufnr` when getting clients in `symbols_to_items` (#33760)
- a242902 :print: don't use schar_from_ascii() for illegal byte (#34046)
- 4b6caa9 cmdline: do not move UI cursor when entering cmdline #33729
- fd8e0ae decor: extmark highlight not applied (#33858)
- 81233a4 display: adjust setting winline info for concealed lines (#33717)
- 4cb2b19 folds: adjust filler text drawing for transparent folds
- bdd8498 folds: avoid unnecessary loop with horizontal scrolling (#33932)
- 32842b0 health: checkhealth float opens extra empty buffer #33648
- dc87a0d lua: vim.validate `message` param #33675
- 334d8f5 move: consume skipcol before revealing filler lines (#34143)
- 6a87b57 runtime: 'includeexpr' with non-Nvim-style Lua modules #33867
- 2b2a344 runtime: conceal paths in help, man ToC loclist #33764
- 3db39ed runtime: cpoptions is reset in Lua file #33671
- cefc91a system: don't treat NUL at start as no input (#34167)
- 8daffd0 terminal: check size when switching buffers
- 0db8946 termkey: out-of-bounds write in array #33868
- 6563c6b treesitter: close `:InspectTree` with `q`
- 5c6ee25 treesitter: eliminate flicker for single windows #33842
- 3b3cf1d treesitter: invalidate conceal_lines marks (#33832)
- 58460e2 treesitter: parser metadata annotations
- 034d3c8 treesitter: proper tree `contains()` logic with combined injections
- 560c6ca trust: support for trusting directories #33735
- 12ae7aa tui: clear primary device callback before invoking it (#34032)
- 4296511 tui: don't process UI events when suspending or stopping (#33710)
- cf73f21 tui: don't try to add unsupported modifiers (#33799)
- 465c181 tui: forward C0 control codes literally (#33759)
- 0c2bf55 tutor: l:lang is undefined
- 3a0d376 vim.system: improve error message when cwd does not exist
- 9b34266 window: skip unfocusable and hidden floats with "{count}<C-W>w" #33810

VIM PATCHES
--------------------------------------------------------------------------------
- 9965cfb 9.1.1361: [security]: possible use-after-free when closing a buffer (#33820)
- 3c10230 9.1.1375: [security]: possible heap UAF with quickfix dummy buffer
- 1921dda 3704b5b: runtime(tutor): improve tutor.vim plugin and filetype plugin
- 4e5af2f 5a8f995: runtime(doc): remove outdated Contribution section in pi_tutor (#34094)
- 3273c59 829eda7: runtime(new-tutor): update tutor and correct comandline completion
- 3e83a33 9.1.1297: Ctrl-D scrolling can get stuck #33453
- 6417ba0 9.1.1376: quickfix dummy buffer may remain as dummy buffer
- 30fa1c5 9.1.1380: 'eventignorewin' only checked for current buffer
- 6b140ae 9.1.1384: still some problem with the new tutors filetype plugin
- f623fad 9.1.1385: inefficient loop for 'nosmoothscroll' scrolling (#33992)
- d50f71d 9.1.1387: memory leak when buflist_new() fails to reuse curbuf
- 27abf5c 9.1.1388: Scrolling one line too far with 'nosmoothscroll' page scrolling (#34023)
- 917f496 9.1.1395: search_stat not reset when pattern differs in case (#34058)
- b07bffd 9.1.1402: multi-byte mappings not properly stored in session file (#34131)
- ff83c71 9.1.1405: tests: no test for mapping with special keys in session file (#34146)
- d1ca551 9.1.1407: Can't use getpos('v') in OptionSet when using setbufvar() (#34177)

DOCUMENTATION
--------------------------------------------------------------------------------
- e5e69f7 add missing change to getcharstr() signature (#33797)
- 95ee908 backport #33549 and #33524 to 0.11 (#33678)
- 472d41b default mappings #33706
- 3a4d393 fixups (#33815)
- fa292e6 lsp, emoji, startup #33683
- 714622f lsp, lua #33682
- d68d212 provide example_init.lua #33524
- 968947b lua: typing for vim.fn.winlayout #33817
- e304677 tutor: move lesson 7.2 below lesson 7.3 #33662
})
-- Ensure any pre-existing buffers start/stop their LSP clients.
if enable ~= false then
vim.api.nvim_command('doautoall nvim.lsp.enable FileType')

Choose a reason for hiding this comment

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

This change causes the first buffer opened by Neovim to not get a filetype if a user has the following configuration

{
			"neovim/nvim-lspconfig",
			event = "BufReadPost",
			config = function()
					vim.lsp.enable({ "lua_ls" })
			end,
		},

If the call above is vim.scheduled or vim.api.nvim_command('doautoall nvim.lsp.enable FileType') is vim.scheduled, then it works correctly. I'm not sure what the desired behavior should be, that's why I'm asking here first instead of just creating an issue.

cc @justinmk (apologies for the ping, I just saw that you were mainly involved in this PR from Neovim core team). I'm just asking for how this should be dealt.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change causes the first buffer opened by Neovim to not get a filetype if a user has the following configuration

Have you been able to root cause why this is?

@dpetka2001, you shouldn't be calling vim.lsp.enable in a BufReadPost. It's meant to happen once early on when your neovim starts up.

Copy link

@dpetka2001 dpetka2001 Jun 6, 2025

Choose a reason for hiding this comment

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

The previous commit fae4abd does not have this problem. The problem was introduced because of calling directly vim.api.nvim_command('doautoall nvim.lsp.enable FileType').

From its help it mentions

enable({name}, {enable}) vim.lsp.enable()
Auto-starts LSP when a buffer is opened, based on the |lsp-config|
filetypes, root_markers, and root_dir fields.

BufReadPost gets emitted when a buffer is opened. The problem is that the filetype detection fails with the first buffer, whereas that wasn't the case previously.

In the previous commit the autocmd would still get created and left up to Neovim when it would execute.

Copy link
Member

@justinmk justinmk Jun 6, 2025

Choose a reason for hiding this comment

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

From its help it mentions

enable({name}, {enable}) vim.lsp.enable()
Auto-starts LSP when a buffer is opened, based on the |lsp-config|
filetypes, root_markers, and root_dir fields.

That help doc is explaining that enable() sets up the filetype-detection.

The problem is that the filetype detection fails with the first buffer,

That doesn't sound related to enable() in particular.

AFAICT, your setup expects BufReadPost to happen after 'filetype' is set. But on startup for buffer 1, that isn't the case:

nvim --clean --cmd "au BufReadPost * echom 'ft=' &filetype" .tmux.conf

That has nothing to do with vim.lsp.enable(). The fact that your setup accidentally worked before seems irrelevant. The core issue is that the ordering of BufReadPost and FileType are different during startup vs after startup.

Copy link

@dpetka2001 dpetka2001 Jun 6, 2025

Choose a reason for hiding this comment

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

With the following repro

vim.api.nvim_create_autocmd("BufReadPost", {
	callback = function()
		vim.lsp.enable({ "lua_ls" })
	end,
})

The problem occurs when you do nvim --clean -u repro.lua and then from the Neovim startup page you do :e repro.lua to open the buffer. If you then do set ft? you will see it prints out filetype=.

If you do nvim --clean -u repro.lua repro.lua directly and then you do set ft? you will see it prints filetype=lua. So, no problem if you open Neovim with a file argument.

If you comment out that specific line that does doautocmdall (or even vim.schedule the doautocmdall) the first case where you do nvim --clean -u repro.lua will also detect correctly the filetype.

The line that was added vim.api.nvim_command('doautoall nvim.lsp.enable FileType') causes a different behavior for the filetype detection of the first buffer in the 2 cases above.

You can verify what I said with the repro.lua provided and the steps mentioned. I also vim.scheduled the call to vim.api.nvim_command('doautoall nvim.lsp.enable FileType') and the filetype detection occurred correctly in the first case with nvim --clean -u repro.lua and then :e repro.lua and :set ft?.

Is the behavior in the 2 aforementioned cases expected? With commit fae4abd this didn't happen.

Copy link
Member

Choose a reason for hiding this comment

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

That's not how it's supposed to be used, so no wonder this doesn't work.

Choose a reason for hiding this comment

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

Yes, I'm trying to understand why this happens. I did not insinuate this is an issue. I myself wasn't sure if this was an issue or not, that's why I did not create an unnecessary issue and instead preferred to ask here.

Why does the line vim.api.nvim_command('doautoall nvim.lsp.enable FileType') affect the filetype detection as opposed to how it used to work.

I used a Vimscript script to log the execution of the events when Neovim opens. The script is available in this gist. I'm not saying someone should check it.

But with the above script and opening Neovim with nvim -c "LogAutocmds" I can see that the FileType event occurs before BufReadPost. Whereas if I open Neovim with nvim -c "LogAutocmds" some_file.lua I can see that there's only a FileType event after a BufNew event and no BufReadPost event in this case.
This is just to show how I tried to understand how the order of the 2 events gets executed when you open Neovim with a file argument or not.

Again my question here is why does the addition of line vim.api.nvim_command('doautoall nvim.lsp.enable FileType') cause different behavior with regards to filetype detection.

I would appreciate if someone can shed some light. I'm genuinely asking for information to understand. I totally understand that I'm asking for some of your personal time, so if nobody can give additional info that's totally acceptable as you can only interact with so many Neovim users.

Copy link
Contributor Author

@jfly jfly Jun 6, 2025

Choose a reason for hiding this comment

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

Totally appreciate the curiosity here, @dpetka2001. I do not know what's going on here.

Choose a reason for hiding this comment

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

@jfly If you do

vim.schedule(function()
  vim.api.nvim_command('doautoall nvim.lsp.enable FileType')
end)

Does it have any negative effect for the reason that you created this PR? Because if you use vim.schedule then the filetype detection works as expected.

Copy link
Member

Choose a reason for hiding this comment

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

we can try that change, feel free to send a pr. with a concise and clear Problem/Solution explanation. not the wall of text above.

jdhao added a commit to jdhao/nvim-config that referenced this pull request Jun 12, 2025
It seems that for nvim 0.11.2, if you open nvim and then use fzf-lua to
open a file, the filetype event is not set. This has something to do
with changes in this PR: neovim/neovim#33702.
See also this post: https://www.reddit.com/r/neovim/comments/1l7pz1l/starting_from_0112_i_have_a_weird_issue/
jdhao added a commit to jdhao/nvim-config that referenced this pull request Jun 12, 2025
It seems that for nvim 0.11.2, if you open nvim and then use fzf-lua to
open a file, the filetype event is not set. This has something to do
with changes in this PR: neovim/neovim#33702.
See also this post: https://www.reddit.com/r/neovim/comments/1l7pz1l/starting_from_0112_i_have_a_weird_issue/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: some mechanism for "turn on" and "turning off" LSPs vim.lsp.enable() works when called *from* a FileType event

4 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.