Commit Graph

52 Commits

Author SHA1 Message Date
Justin M. Keyes
16f7440cc7 feat(help): super K (":help!") guesses tag at cursor #36205
Problem:
`K` in help files may fail in some noisy text. Example:

      (`fun(config: vim.lsp.ClientConfig): boolean`)
                            ^cursor

Solution:
- `:help!` (bang, no args) activates DWIM behavior: tries `<cWORD>`,
  then trims punctuation until a valid tag is found.
- Set `keywordprg=:help!` by default.
- Does not affect `CTRL-]`, that is still fully "tags" based.
2026-03-15 19:02:49 -04:00
nikolightsaber
fd1e019e90 refactor(treesitter)!: get_parser return nil on error #37276 2026-03-13 15:57:36 -04:00
Justin M. Keyes
017d8aa298 refactor: rename _ensure_integer => _assert_integer 2026-03-13 20:32:01 +01:00
Justin M. Keyes
682c77805c docs: misc 2026-03-13 20:32:01 +01:00
luukvbaal
52dd62aa6e fix(ui2): use pager to list consecutively typed commands #38272
Problem:  Mimicked block mode for cmdline entered while expanded
          does not work intuitively for repeated commands yielding
          messages exceeding the screen height. The expanded cmdline
          resizes and scrolls to bottom/top when appending a message
          and entering the cmdline. Also includes the entered command,
          as opposed to the UI1 behavior.
          Crash when scrolling to bottom of pager due to recursive
          uv_run after shell message callback executes `nvim_command()`
          with 'showcmd'.

Solution: Still mimic block mode when entering the expanded cmdline,
          but when the entered command emits a message open the pager
          with the current message content in the expanded cmdline.
          Always route typed commands to the pager when it is open.
          Use `nvim_buf_set_cursor()` instead of `nvim_command()`.
2026-03-12 18:38:39 -04:00
Lewis Russell
ce1154048b refactor: integer functions, optimize asserts #34112
refactor(lua): add integer coercion helpers

Add vim._tointeger() and vim._ensure_integer(), including optional base
support, and switch integer-only tonumber()/assert call sites in the Lua
runtime to use them.

This also cleans up related integer parsing in LSP, health, loader, URI,
tohtml, and Treesitter code.

supported by AI
2026-03-12 11:04:05 -04:00
Justin M. Keyes
7ea148a1dc docs: use "ev" convention in event-handlers
Problem:
In autocmd examples, using "args" as the event-object name is vague and
may be confused with a user-command.

Solution:
Use "ev" as the conventional event-object name.
2026-03-12 11:12:56 +01:00
anondeveg
32aee065a8 feat(startup): warn if NVIM_LOG_FILE is inaccessible #38070
Problem:
If NVIM_LOG_FILE, or the default fallback, is inaccessible (e.g.
directory is owned by root), users get confused.

Solution:
Show a warning when $NVIM_LOG_FILE or $XDG_STATE_HOME are inaccessible.

Also fix a latent memory leak: `os_mkdir_recurse` returns a uv error
code (int), but it was stored as `bool`, causing `os_strerror` to
receive an invalid error code and leak memory.

See: https://docs.libuv.org/en/v1.x/errors.html#c.uv_strerror

Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-03-12 04:40:07 -04:00
Justin M. Keyes
a3058abf30 docs: deprecate hit-enter 2026-03-11 18:17:46 +01:00
Justin M. Keyes
b8a976afda docs: api, messages, lsp, trust
gen_vimdoc.lua: In prepare for the upcoming release, comment-out the
"Experimental" warning for prerelease features.
2026-03-11 18:00:18 +01:00
Justin M. Keyes
2c5266429c Merge #37926 msg_show UI event indicates user-interactive 2026-03-10 17:53:11 -04:00
Ayaan
c8693051a8 feat(terminal): surface exit code via virttext + nvim_get_chan_info #37987
Problem:
When a terminal process exits, "[Process Exited]" text is added
to the buffer contents.

Solution:
- Return `exitcode` field from `nvim_get_chan_info`.
- Show it in the default 'statusline'.
- Show exitcode as virtual text in the terminal buffer.
2026-03-10 08:02:50 -04:00
altermo
72d3a57f27 feat(treesitter): incremental selection
Co-authored-by: György Andorka <gyorgy.andorka@protonmail.com>
2026-03-08 11:07:49 +01:00
luukvbaal
b6c020eb59 fix(ui2): ensure expanded cmdline is closed after :<Esc> (#38187)
Problem:  Expanded cmdline is left open after entering the cmdline again
          without entering a command that emits another message (after 301c7065).
Solution: Wait for msg_show to reinstate the vim.on_key() handler.
          If there was no message close the expanded cmdline.
2026-03-07 00:40:01 +00:00
luukvbaal
301c7065ca fix(ui2): only highlight Ex command lines in the cmdline #38182
Problem:  Prompts and message text (in block mode) in the cmdline are
          parsed and highlighted as if it is Vimscript.
          Entering the cmdline while it is expanded can work more like
          it does with UI1, where the press enter prompt is replaced
          and previous messages stay on the message grid, while
          subsequent messages are placed below it.
Solution: Highlight manually with string parser on lines starting with ':'.
          Spoof cmdline block mode when the cmdline is entered while it
          is expanded.
2026-03-06 13:29:20 -05:00
luukvbaal
6275f533d1 fix(ui2): immediately open target windows on new tabpage (#38170)
Problem:  Previous tests for this relied on other events opening the
          targets, which are not guaranteed to happen.
Solution: Open target windows when entering a new tabpage.
2026-03-06 17:32:17 +01:00
Luuk van Baal
875212c5b3 feat(ui2): support routing "typed_cmd" trigger to target
Problem:  Unable to immediately open a typed command in the pager.
Solution: Support mapping msg_show "typed_cmd" trigger in
          cfg.msg.targets (e.g. `targets = { typed_cmd = 'pager' }`).
2026-03-04 15:07:38 +01:00
zeertzjq
dea8430d59 test: suppress DSR wait warning when running tests (#38126)
Problem:
The DSR wait warning causes any test that involves Nvim TUI to become
flaky on Windows. Example:

FAILED   test/functional/terminal/cursor_spec.lua @ 367: :terminal cursor can be positioned arbitrarily
test/functional/terminal\cursor_spec.lua:377: Row 1 did not match.
Expected:
  |*^                                                  |
  |*~                                                 |
  |*~                                                 |
  |*~                                                 |
  |*~                                                 |
  |*                                                  |
  |{5:-- TERMINAL --}                                    |
Actual:
  |*                                                  |
  |*                                                  |
  |*{2:                                                  }|
  |*{103:defaults.lua: Did not detect DSR response from ter}|
  |*{103:minal. This results in a slower startup time.     }|
  |*{UNEXPECTED foreground = tonumber('0x000006'):Press ENTER or type command to continue^           }|
  |{5:-- TERMINAL --}                                    |

Solution:
Don't show the DSR wait warning when running tests.
2026-03-02 20:34:11 +08:00
luukvbaal
32e0d05d53 feat(ui2): configure targets per message kind #38091
Problem:  Unable to configure message targets based on message kind.
Solution: Add cfg.msg.targets mapping message kinds to "cmd/msg/pager".
          Check the configured target when writing the message.
          cfg.msg = { target = 'cmd', targets = { progress = 'msg', list_cmd = 'pager' } }
          will for example use the 'msg' target for progress messages,
          immediately open the pager for 'list_cmd' and use the cmdline
          for all other message kinds.
2026-02-28 08:31:02 -05:00
Yochem van Rosmalen
4a4de73043 fix(help): better align local-additions #38097
Problem:
Descriptions of plugins often contain taglinks which are generally
concealed. This misaligns them by 2 characters with descriptions that
don't have a taglink in them.

Solution:
Don't count "bar" characters (`|`) for the description width.

Example:

Actual buffer content:
```
myplugin.txt                  |lsp| is cool
myplugin.txt        this is a nice plugin
```

Rendered as:
```
myplugin.txt                  lsp is cool
myplugin.txt        this is a nice plugin
```
2026-02-27 17:50:51 -05:00
Kyle
5cbb9d613b fix(startup): wait for bg detection before user config #37075
Problem:
Automatic background detection sets the background option too late,
which loads colorschemes twice and causes problems when the user's
terminal background doesn't match the default (#32109, #36211, #36416).

Solution:
Use a DA1 query to determine whether the TTY supports OSC 11. Wait for
background detection and setting to complete before processing user
config.

Note: To preserve the existing behavior as much as possible, this triggers
OptionSet manually on VimEnter (since it won't trigger automatically if
we set bg during startup). However, I'm unsure if this behavior is
truly desired given that the documentation says OptionSet is triggered
"After setting an option (except during |startup|)."

Also fixes flickering issue #28667. To check for flickering:

    nvim --clean --cmd "set termguicolors" --cmd "echo \"foo\"" --cmd "sleep 10"

On master, this gives me a black screen for 10 seconds, but on this
branch, the background is dark or light depending on the terminal
background (since the option is now set during startup rather than after
VimEnter).
2026-02-27 04:52:52 -05:00
luukvbaal
4ef217e272 fix(ui2): leftover empty lines in msg window #38059
Problem:  Timer removing a message from the msg buffer does not remove
          empty lines if window is closed (col([ui.wins.msg]) fails).
Solution: Use nvim_buf_get_text() to check if line is empty.
2026-02-25 13:21:30 -05:00
luukvbaal
844caca881 fix(ui2): multiline/color replaced message, expanded cmdline, error messages #38044
Problem:  - Unintentionally inserting lines for a replaced multiline
          message that also has multiple highlights.
          - Scheduled check to see if the expanded cmdline window was
          entered makes it difficult to keep track of what happens when
          the key pressed to dismiss it results in a message.
          - Reading the first line of an error message should be enough
          notice for something going wrong.
          - "search_cmd" messages should not be shown with 0 'cmdheight'.
          - Unable to configure dynamically changed pager height.
          - Enabling UI2 doesn't make sense with no UIs attached.

Solution: - Only insert a line for the first chunk after a newline.
          - Use getmousepos() to check if the expanded cmdline was
          clicked to enter the pager.
          entering the pager to serve as a configuration interface.
          - Don't expand the cmdline for error messages; user can press g<.
          - Don't show "search_cmd" messages with 'cmdheight' set to 0.
          - Change 'eventignorewin' to ensure WinEnter is fired when
          - Have enable() return early when no UIs are attached.
2026-02-24 17:05:38 -05:00
Justin M. Keyes
ce5c7111f4 refactor: defer_fn return type #37999 2026-02-23 03:24:14 -05:00
luukvbaal
29a46a11aa fix(ui2): don't change configured message target implicitly #37924
Problem:  Implicitly setting message target when 'cmdheight' changes.
Solution: Just use the user configured target. Support "cmd" target
          with 'cmdheight' set to 0.
2026-02-17 13:12:49 -05:00
luukvbaal
e268760e46 feat(ui2): show active paging keys in dialog float title #37919
Problem:  Paging keys being consumed without obvious indicator
          in the dialog window can be surprising.
Solution: Display a hint with paging keys in the dialog window title
          when paging is active. Recognize <Esc> as mapping to stop
          paging.
2026-02-17 07:28:56 -05:00
luukvbaal
16495e6863 fix(ui2): only set dialog on_key callback once #37905
Problem:  vim.on_key() called for each message while cmdline is open.
          Cursor is on a seemingly random column when pager is entered.
          Entering the pager while the cmdline is expanded can be more
          convenient than pressing "g<".
          Pager window is unnecessarily clamped to half the shell height.
          Setting 'laststatus' while pager is open does not adjust its
          dimensions.
Solution: Only call vim.on_key() once when dialog window is opened.
          Ensure cursor is at the start of the first message when
          entering the pager.
          Enter the pager window when "<CR>" is pressed while the
          cmdline is expanded.
          Don't clamp the pager window height.
          Set message windows dimensions when 'laststatus' changes.
2026-02-16 17:11:32 -05:00
Maria Solano
05bd4398c5 feat(lsp): support textDocument/documentLink (#37644) 2026-02-16 11:05:33 -08:00
Yochem van Rosmalen
b5ce7e74dc refactor(help): move local-additions to Lua #37831
Problem:
- ~200 line function of hard-to-maintain C code.
- Local Addition section looks messy because of the varying description
  formats.

Solution:
- Move code to Lua.
- Have a best-effort approach where short descriptions are right
  aligned, giving a cleaner look. Long descriptions are untouched.
2026-02-14 05:30:18 -05:00
phanium
179e7fccd7 fix(ui2): incomplete :echon message in g< pager #37819
Problem:
`:echo 1 | echon 2<cr>g<` shows "2", but should be "12".

Solution:
Don't clear temp msg (g<) if we are appending.
2026-02-12 11:10:37 -05:00
Olivia Kinnear
0c46ea7d38 feat(lua): add Iter:unique() (#37592) 2026-02-10 11:43:47 -06:00
Yochem van Rosmalen
a6252c6683 refactor(help): move escaping logic to Lua #37757
Problem:
Escaping logic for {subject} in ex cmd `:help {subject}` is done in a
messy 200+ lines C function which is hard to maintain and improve.

Solution:
Rewrite in Lua. Use `string.gsub()` instead of looping over characters
to improve clarity and add many more tests to be able to confidently
improve current code later on.
2026-02-10 07:43:17 -05:00
luukvbaal
e198037148 fix(ui2): always route to dialog when cmdline is open #37730
Problem:  Messages emitted while cmdline is open are not shown with
          cmdline message target.
Solution: Route to dialog window when cmdline is open.
2026-02-05 14:54:22 -05:00
luukvbaal
bf68ba40a0 refactor: rename _extui => _core.ui2 #37692
Problem:
_extui module name is confusing and should eventually end up in _core/.

Solution:
Move it there and name it ui2.
2026-02-05 07:45:45 -05:00
zeertzjq
1906da52db fix(lua): close vim.defer_fn() timer if vim.schedule() failed (#37647)
Problem:
Using vim.defer_fn() just before Nvim exit leaks luv handles.

Solution:
Make vim.schedule() return an error message if scheduling failed.
Make vim.defer_fn() close timer if vim.schedule() failed.
2026-02-01 21:29:19 +08:00
phanium
dfa5d79d05 fix: misc typos #37471 2026-01-27 09:18:02 -05:00
Christian Clason
647d3dc454 build(deps): bump luv to 1.51.0-2 2026-01-23 09:30:37 +01:00
Olivia Kinnear
c39d18ee93 fix(lsp): raise error when lsp config is invalid type (#37508) 2026-01-22 15:44:04 -08:00
Olivia Kinnear
34116bbd9b fix(lsp): fix nil-index error for :lsp enable (#37411)
Problem:
`:lsp enable` with no arguments will fail if there is a invalid config
in `lsp/`, or if `vim.lsp.config[...]` returns nil for any other reason.

Solution:
Add a nil-check to `:lsp enable`.
2026-01-22 12:27:03 -08:00
zeertzjq
94144d4678 fix(lua): vim._with() doesn't save boolean options properly (#37354)
Problem:  vim._with() doesn't save boolean options with false values
          properly.
Solution: Use vim.F.if_nil().
2026-01-11 20:04:32 +08:00
benarcher2691
55a0843b7c feat(editor): :source can run Lua codeblock / ts injection #36799
Problem:
Can't use `:source` to run a Lua codeblock (treesitter injection) in
a help (vimdoc) file.

Solution:
Use treesitter to parse the range and treat it as Lua if detected as
such.
2026-01-07 20:20:53 -05:00
Olivia Kinnear
a03ab03a10 fix(lsp): :lsp restart restarts on client exit #37125
Problem:
`:lsp restart` detects when a client has exited by using the `LspDetach`
autocommand. This works correctly in common cases, but breaks when
restarting a client which is not attached to any buffer. It also breaks
if a client is detached in between `:lsp restart` and the actual
stopping of the client.

Solution:
Move restart logic into `vim/lsp/client.lua`, so it can hook in to
`_on_exit()`. The public `on_exit` callback cannot be used for this, as
`:lsp restart` needs to ensure the restart only happens once, even if
the command is run multiple times on the same client.
2026-01-02 01:58:10 -05:00
Justin M. Keyes
1d70c96e5b build: move shared.lua to _core/ 2025-12-30 01:44:52 -05:00
Justin M. Keyes
20e77c5d88 build: ship "_core/*" as bytecode (built-into Nvim binary)
Problem:
We want to encourage implementing core features in Lua instead of C, but
it's clumsy because:
- Core Lua code (built into `nvim` so it is available even if VIMRUNTIME
  is missing/invalid) requires manually updating CMakeLists.txt, or
  stuffing it into `_editor.lua`.
- Core Lua modules are not organized similar to C modules, `_editor.lua`
  is getting too big.

Solution:
- Introduce `_core/` where core Lua code can live. All Lua modules added
  there will automatically be included as bytecode in the `nvim` binary.
- Move these core modules into `_core/*`:
  ```
  _defaults.lua
  _editor.lua
  _options.lua
  _system.lua
  shared.lua
  ```

TODO:
- Move `_extui/ => _core/ui2/`
2025-12-30 01:44:24 -05:00
Olivia Kinnear
29494f042c fix(ex): error handling for :lsp #37061 2025-12-25 03:19:12 -05:00
Olivia Kinnear
bd225422a5 fix(lsp): tests for :lsp, rename start/stop
- Rename :lsp start/stop to enable/disable
- Move lua section of `:lsp` to `vim/_core`
- Add tests
2025-12-16 13:46:08 -05:00
€šm̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰�Ř§Ů Â£╟©舐æØ¢£ðsÞ¥¿—
ed9abb1851 fix(exrc): ensure consistent 'exrc' loading sequence #35148
Problem:
The execution of startup scripts in parent directories are too late
compared to scripts in current direcctory.

Solution:
Execute all startup scripts with `lua/_core/exrc.lua`.

closes: #35147
2025-12-08 22:22:10 -05:00
Tomas Slusny
c6113da5a9 fix(difftool): fully resolve symlinks when comparing paths #36147
Fixes issue on mac where it was constantly reloading buffers as paths
were not being normalized and resolved correctly (in relation to buffer
name).

Quickfix entry:
/var/folders/pt/2s7dzyw12v36tsslrghfgpkr0000gn/T/git-difftool.m95lj8/right/app.vue

Buffer name:
/private/var/folders/pt/2s7dzyw12v36tsslrghfgpkr0000gn/T/git-difftool.m95lj8/right/app.vue

/var was synlinked to /private/var and this was not being properly
handled.

Also added lazy redraw to avoid too many redraws when this happens in
future and added test for symlink handling.

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
2025-10-12 18:25:14 +00:00
Tomas Slusny
fec02ae8e4 feat(plugins): nvim.difftool can compare directories #35448
Problem:
Built-in diff mode (nvim -d) does not support directory diffing
as required by git difftool -d. This makes it difficult to compare
entire directories, detect renames, and navigate changes efficiently.

Solution:
Add a DiffTool plugin and command that enables side-by-side diffing of
files and directories in Neovim. The plugin supports rename detection,
highlights changes in the quickfix list, and provides a user command for
easy invocation. This allows proper integration with git difftool -d for
directory comparison.

Example git config:

```ini
[diff]
    tool = nvim_difftool

[difftool "nvim_difftool"]
    cmd = nvim -c "packadd nvim.difftool" -c "DiffTool $LOCAL $REMOTE"
```

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
Co-authored-by: Phạm Bình An <111893501+brianhuster@users.noreply.github.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2025-10-11 19:24:39 -07:00
Siddhant Agarwal
7a71235399 fix(server): serverlist({peer=true}) does not find peer servers #35506 2025-08-28 06:41:31 -07:00