Commit Graph

560 Commits

Author SHA1 Message Date
Maria José Solano
cb4559bc32 feat(lsp): workspace diagnostic support (#34262)
* refactor(lsp): remove underscore prefix from local variables

* feat(lsp): workspace diagnostic support
2025-06-09 13:02:00 -04:00
Maria José Solano
d75ffa5934 feat(lsp): static registration support (#34371) 2025-06-09 13:01:26 -04:00
Justin M. Keyes
80753332d1 docs: news, intro, lsp, api #33687 2025-06-01 14:13:50 -07:00
brianhuster
41c850e2c8 vim-patch:2323f22: runtime(new-tutor): add chapter two to the interactive tutorial
closes: vim/vim#16803

2323f225ca

Co-authored-by: RestorerZ <restorer@mail2k.ru>
2025-05-23 09:34:39 +07:00
Evan Hahn
927927e143 fix(lsp): fix error with InsertReplaceEdit events #33973
Problem:
Some LSPs cause the following completion error (reformatted slightly):

    Error executing vim.schedule lua callback:
    .../runtime/lua/vim/lsp/completion.lua:373
    attempt to index field 'range' (a nil value)

This is because an internal function assumes edits are either missing
or of type `TextEdit`, but there's a third [possibility][0] that's not
handled: the `InsertReplaceEdit`.

This was previously reported in at least two issues:

- https://github.com/neovim/neovim/issues/33142
- https://github.com/neovim/neovim/issues/33224

Solution:
Don't assume the edit is a `TextEdit`. This implicitly handles
`InsertReplaceEdit`s.

Also, add a test case for this, which previously caused an error.

[0]: 2c07428966/runtime/lua/vim/lsp/_meta/protocol.lua (L1099)
2025-05-22 06:22:47 -07:00
Yochem van Rosmalen
62ba6e8a76 fix: use nvim namespace convention #34010 2025-05-22 03:40:08 -07:00
Phạm Bình An
dd43eb445a docs(tutor): move lesson 7.2 below lesson 7.3 #33662
Problem:

- Lesson 7.3 (Cmdline Completion) teaches an important way to discover
  Nvim features. I think users should learn it before they start
  configuring Nvim
- Nvim can be configured in Lua as well, but lesson 7.2 (Configuring
  Nvim) only mentions init.vim. And I think Nvim is promoting Lua more

Solution:

- Move lesson 7.2 to be after lesson 7.3
- Lesson 7.2 should teach about init.lua

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2025-05-21 02:26:57 -07:00
Justin M. Keyes
40351bbbbe fix(lua): vim.validate message param #33675
Problem:
vim.validate does not handle `message` param.

Solution:
Add the missing logic.
2025-05-04 16:36:32 -07:00
Eike
0862c1036a fix(lsp): check if client is stopping before reuse #33796
Problem:
Stopping a language server and then calling vim.lsp.start() with the same name/root will return the old language server that's in the middle of shutting down. vim.lsp.start() won't return a new server until the old process has terminated.

Solution:
Introducing a client._is_stopping field that tracks the shutdown phase, preventing the client from being reused.
2025-05-04 14:38:01 -07:00
Justin M. Keyes
fc2dee1736 feat(messages): cleanup Lua error messages
"Error" in error messages is redundant. Just provide the context, don't
say "Error ...".
2025-05-04 11:22:57 -04:00
Maria José Solano
8f5bd569c5 feat(lsp): support documentColor dynamic registration #33800 2025-05-04 07:00:21 -07:00
Jeremy Fleischman
b877aa34cf feat(lsp): detach LSP clients when 'filetype' changes #33707
Problem:
When the buffer 'filetype' changes, invalid or non-applicable LSP
clients are not detached.

https://github.com/neovim/neovim/issues/33443
https://github.com/neovim/nvim-lspconfig/issues/3326

Solution:
In the enable() routine, check can_start() on _existing_ clients.
2025-05-03 14:57:59 -07:00
Jeremy Fleischman
03d378fda6 feat(lsp): vim.lsp.is_enabled() #33703
Problem:
No way to check if a LSP config is enabled without causing it to
resolve. E.g. `vim.lsp.config['…'] ~= nil` will resolve the config,
which could be an unwanted and somewhat expensive side-effect.

Solution:
Introduce `vim.lsp.is_enabled()`.
2025-05-03 10:25:58 -07:00
Riley Bruins
5d1fd4aca5 fix(lsp): improper diagnostic end_col computation
**Problem:** For multiline diagnostics, the end column was improperly
calculated by checking the byte index of the character position on the
*start* line.

**Solution:** Calculate the byte index for end_col using the *end* line.
2025-05-03 10:01:20 +02:00
bfredl
da401ca25b Merge pull request #28344 from bfredl/wonderland
feat(build): build.zig MVP: build and run functionaltests on linux
2025-05-02 10:34:25 +02:00
bfredl
1f004970f0 feat(build): build.zig MVP: build and run functionaltests on linux
NEW BUILD SYSTEM!

This is a MVP implementation which supports building the "nvim" binary,
including cross-compilation for some targets.
As an example, you can build a aarch64-macos binary from
an x86-64-linux-gnu host, or vice versa

Add CI target for build.zig currently for functionaltests on linux
x86_64 only

Follow up items:

-  praxis for version and dependency bumping
-  windows 💀
-  full integration of libintl and gettext (or a desicion not to)
-  update help and API metadata files
-  installation into a $PREFIX
-  more tests and linters
2025-05-02 09:28:50 +02:00
Jeremy Fleischman
4bc7bac884 feat(lsp): start/stop LSPs as necessary during vim.lsp.enable() #33702
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.
2025-04-30 16:57:29 -07:00
Lorenzo Bellina
6577d72d81 feat(lsp): root_markers can control priority #33485
Problem:
root_markers cannot specify "equal priority filenames.

Solution:
Support nesting:

    {
      ...
      root_markers = { { ".stylua.toml", ".luarc.json" }, { ".git "} }
      ...
    }


Co-authored-by: Maria José Solano <majosolano99@gmail.com>
Co-authored-by: Gregory Anders <github@gpanders.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2025-04-30 06:43:32 -07:00
Justin M. Keyes
63323a9c81 feat(checkhealth): trigger FileType event after showing report #33677
Problem:
`FileType` event is fired before checkhealth report is finished, so
user can't override report settings or contents.
https://github.com/neovim/neovim/pull/33172#issuecomment-2833513916

Solution:
- Trigger FileType event later.
- Document how to remove emojis.
2025-04-27 10:32:25 -07:00
Phạm Bình An
86b34ad073 docs: provide example_init.lua #33524
Problem:
There are some "boilerplate" steps for new users. Although we are
constantly improving defaults and lifting patterns into core, users
eventually want to know how to start their own config, add plugins, etc.

Solution:
Add `runtime/example_init.lua` and refer to it from docs.
2025-04-27 08:11:02 -07:00
Justin M. Keyes
dd18ab1691 test: drop redundant clear() #33654
followup to #33647 after overlapping merge
2025-04-26 09:42:13 -07:00
Justin M. Keyes
e7410048fa test: drop redundant clear() #33647
Problem:
Tests call `clear()` even though `clear_notrace()` is already called in
a `before_each()` handler, wasting precious milliseconds!

Solution:
Remove redundant `clear()` calls.
2025-04-26 09:39:32 -07:00
Yi Ming
f486f1742e perf(lsp): include previousResultId in DocumentDiagnosticParams #32887
Problem:
Users of the Roslyn (C#) LSP have encountered significant delays when
retrieving pull diagnostics in large documents while using Neovim. For
instance, diagnostics in a 2000-line .cs file can take over 20 seconds
to display after edits in Neovim, whereas in VS Code, diagnostics for
the same file are displayed almost instantly.

As [mparq noted](https://github.com/seblj/roslyn.nvim/issues/93#issuecomment-2508940330)
in https://github.com/seblj/roslyn.nvim/issues/93, VS Code leverages
additional parameters specified in the [LSP documentation for
textDocument/diagnostic](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#documentDiagnosticParams),
specifically:

- previousResultId
- identifier

Solution:
When requesting diagnostics, Neovim should include the
`previousResultId` and `identifier` parameters as part of the request.
These parameters enable the server to utilize caching and return
incremental results.

Support for maintaining state is already present in the
[textDocument/semanticTokens implementation](8f84167c30/runtime/lua/vim/lsp/semantic_tokens.lua (L289)).
A similar mechanism can be implemented in `textDocument/diagnostic` handler.
2025-04-26 09:09:20 -07:00
Bartłomiej Maryńczak
8315697449 fix(lsp): detect if Client:request resolved synchronously #33624
Problem:
In cases when the (in-process) LSP server responds to the request
immediately and calls `notify_reply_callback` the request will still be
marked as pending, because the code assumes that the response will occur
asynchronously. Then the request will be pending forever, because it was
already set as "completed" before we even set it as "pending".

A workaround is to wrap `notify_replay_callback` in `vim.shedule` ([like
so](https://github.com/neovim/neovim/pull/24338#issuecomment-2809568617)]
but that seems counterintuitive.

Solution:
Handle this case in Client:request().
2025-04-26 07:08:03 -07:00
Maria José Solano
8495d96238 fix(lsp): ensure bufstate when calling vim.lsp.document_color.is_enabled 2025-04-24 21:03:44 +02:00
Maria José Solano
9ff1239634 feat(lsp): support textDocument/documentColor
test(lsp): add tests form `vim.lsp.document_color`
2025-04-24 18:48:19 +02:00
Christian Clason
8c81ed8678 feat(runtime): revert cfilter, ccomplete to legacy Vim
Problem: Transpiled Lua code from vim9script is not amenable to static
analysis, requiring manual cleanup or ignoring parts of our codebase.

Solution: Revert to pre-rewrite version of (low-impact) legacy plugins
and remove the vim9jit shim.
2025-04-22 11:03:05 +02:00
Shadman
28e31f5d3d feat(options): default statusline expression #33036
Problem:
Default 'statusline' is implemented in C and not representable as
a statusline expression. This makes it hard for user configs/plugins to
extend it.

Solution:
- Change the default 'statusline' slightly to a statusline expression.
- Remove the C implementation.
2025-04-21 15:05:34 -07:00
Au.
6926fc1615 fix(lsp): opts.reuse_win does not jump if buf is already open #33476
Problem:
`vim.lsp.buf.[implementation|definition|...]({ reuse_win = true })` does not
jump cursor to existing window if buffer is already open.

Steps to reproduce:
1. `nvim repro.lua`
2. Insert anything that lsp can read to open the library definition/implementation, e.g., `vim.keymap.set`
3. open `repro.lua` buffer and the library buffer side by side.
4. type `gd` over `set` to jump to the library definition.

The open buffer is scrolled to the target line, but cursor does not jump.

Solution:
Call nvim_set_current_win if necessary.
2025-04-17 07:46:18 -07:00
João Bettencourt
5333d6371b fix(man.lua): E95 when piping to :Man #33068
Problem: When piping raw manpage content into `:Man!`, buf name is
set to 'man://.. ref', but the check only matches the prefix.
Allows duplicate buffers to be created, triggering E95.

Solution: Match full buf name instead of only 'man://' prefix.
If the buffer already exists, generate a unique name with
'man://' .. 'ref' .. '?new=' format.

Refs: #30132
2025-04-15 06:27:51 -07:00
Phạm Bình An
c58c650adf vim-patch:829eda7: runtime(new-tutor): update tutor and correct comandline completion (#33449)
Problem: Some parts of the tutor are outdated.

- For example, pressing `<Tab>` after typing `:e` does not complete the
command `:edit`, but shows a completion menu with the first entry being
`:earlier`.

closes: vim/vim#17107

829eda7d38
2025-04-15 15:11:17 +08:00
Yochem van Rosmalen
5a94edad70 feat(health): summary in section heading #33388
Problem:
As checkhealth grows, it is increasingly hard to quickly glance through
the information.

Solution:
Show a summary of ok, warn, and error outputs per section.
2025-04-09 04:13:20 -07:00
tstsrt
d9405c7935 test(plugin/shada_spec): failure if timezone isn't a whole hour ahead of UTC (#33257)
Problem: When running functional tests locally, test `syntax/shada.vim works`
fails if the local timezone is not a whole number of hours ahead of UTC.

Solution: Use '!%M' for minute format so that UTC is used in the expected
timestamp instead of the local timezone, just like '%H' for hours.
2025-04-04 11:59:29 +08:00
Lewis Russell
2ee896201c fix(lsp): better handling of "*" configs
Problem:

If a config name contains "*" it causes rtp discovery of `lsp/` to
consider the `*` as a wildcard and could lead to strange and unintended
behaviour. For example, accessing the `'*'` config from a `lsp/` file
would cause an infinite loop.

Solution:

- Explicitly disallow a config name from containing wildcards, with the
  exception of `'*'`.
- When Resolving `'*'` config, skip the rtp step.
2025-03-31 16:42:25 +01:00
Michael Strobel
90d15227c5 feat(lsp): workspace_required #31824
Problem:
Some language servers do not work properly without a workspace folder.

Solution:
Add `workspace_required`, which skips starting the lsp client if no
workspace folder is found.

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2025-03-30 11:07:53 -07:00
Bartłomiej Maryńczak
49756ebc70 fix(vim.lsp.inlay_hint): requesting inlay_hints even when disabled #32999
Problem:
Nvim needlessly requests inlay_hints even if they are disabled for a given buffer.

Solution:
Add the missing `enabled` check in `on_refresh`.
Rest of the code has this check already so that's the only needed one to fix this.
2025-03-30 08:39:10 -07:00
Justin M. Keyes
75fe540500 feat(checkhealth): emoji for OK/WARN/ERROR #33172
Problem:
Health status can be much more visually distinct.

Solution:
Use emoji next to each status.
2025-03-30 06:33:12 -07:00
Eisuke Kawashima
07f048a8d7 fix(health): message should mention "vim.provider" #33095 2025-03-27 16:19:54 -07:00
phanium
c982608226 test(checkhealth): nested path 'runtimepath' #33034 2025-03-23 16:30:08 -07:00
Au.
5187be81c2 fix(lsp): handle using array as open_floating_preview title (#33016) 2025-03-22 10:43:06 +08:00
Lewis Russell
d0cda9d6c5 Merge pull request #32871 from ofseed/test-lsp
test(lsp): add some tests for LSP bugs
2025-03-17 09:11:05 +00:00
Yi Ming
96e5b61be1 test(lsp): add a test for refreshing hints after being requested 2025-03-17 14:44:55 +08:00
Yi Ming
648b7f6101 test(lsp): add a test for resetting the active request after receiving error 2025-03-17 14:44:51 +08:00
Mathias Fußenegger
3e3775961f refactor(lsp)!: rename lsp.completion.trigger() to get() (#32911)
Problem: `trigger` is a custom word not yet used in APIs. 

Solution: Use `get` instead because the main effect is that the 
completion candidates will be collected (and shown by default,
but follow-up commits are planned to add an `on_result` callback
that allows more general handling).

---------

Co-authored-by: Christian Clason <c.clason@uni-graz.at>
2025-03-16 13:58:38 +01:00
phanium
f5dd30948e fix(checkhealth): handle nested lua/ directory #32918
Problem: :checkhealth fails if plugin has nested "lua/" directory

Solution: trim `{runtimepath}/lua` from fullpath to get subpath
(`./**/{health, health/init.lua}`)
2025-03-16 05:49:05 -07:00
dundargoc
026cfa28d0 docs: misc
Co-authored-by: Au. <acehinnnqru@gmail.com>
Co-authored-by: Daniel Rainer <daniel.rainer@localhost>
Co-authored-by: Evgeni Chasnovski <evgeni.chasnovski@gmail.com>
Co-authored-by: Lewis Russell <lewis6991@gmail.com>
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
Co-authored-by: Pierre Barbin <pierre@heitzsystem.com>
Co-authored-by: Riley Bruins <ribru17@hotmail.com>
Co-authored-by: Yinzuo Jiang <jiangyinzuo@foxmail.com>
Co-authored-by: phanium <91544758+phanen@users.noreply.github.com>
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
2025-03-15 15:00:44 +01:00
zeertzjq
a25ce5762d test: do not dedent() in feed() (#32884)
Most callers of feed() do not expect feed() to dedent.
Now use a literal space in tests where it looks better.
2025-03-14 09:12:35 +00:00
Mathias Fußenegger
123f8d229e feat(snippet): set snippet keymaps permanent instead of dynamic (#31887)
Problem:

Given that `vim.snippet.expand()` sets temporary `<tab>`/`<s-tab>`
keymaps there is no way to build "smart-tab" functionality where `<tab>`
chooses the next completion candidate if the popup menu is visible.

Solution:

Set the keymap permanent in `_defaults`.

The downside of this approach is that users of multiple snippet engine's
need to adapt their keymaps to handle all their engines that are in use.
For example:

    vim.keymap.set({ 'i', 's' }, "<Tab>", function()
      if foreign_snippet.active() then
        return "<Cmd>lua require('foreign_snippet').jump()<CR>"
      elseif vim.snippet.active({ direction = 1 }) then
        return "<Cmd>lua vim.snippet.jump(1)<CR>"
      else
        return key
      end
    end, { expr = true })

Upside is that using `vim.keymap.set` to override keymaps is a well
established pattern and `vim.snippet.expand` calls made by nvim itself
or plugins have working keymaps out of the box.


Co-authored-by: Maria José Solano <majosolano99@gmail.com>
2025-03-14 09:51:52 +01:00
Lewis Russell
ed07167261 fix(lsp): handle non-existent configs in lsp.config/enable 2025-03-12 09:06:28 +00:00
glepnir
a14fca432b fix(lsp): improve LSP floating preview window cleanup #31353
Problem: The current implementation creates a unique autocommand group for each floating preview window, which is inefficient and can lead to numerous autocommand groups.

Solution: Use a single shared autocommand group with improved window validation to properly clean up LSP floating preview windows.
2025-03-11 05:10:09 -07:00