Commit Graph

181 Commits

Author SHA1 Message Date
Olivia Kinnear
4f1ef2dec1 fix(restart): keep :restart error message concise #40746 2026-07-15 19:05:46 -04:00
Justin M. Keyes
31ad7d4527 Merge #40621 fix(ui2)!: legacy 'ruler' inconsistencies 2026-07-15 08:13:37 -04:00
Justin M. Keyes
671e9d4913 feat(marks): :marks completion, list extmarks #40743
Problem:
- No UI for listing extmarks.
- `:marks` doesn't support cmdline-completion.

Solution:
- Add completion and extmarks support to `:marks`.
- Update `get_buf_local_marks` to include the ":" (prompt-buffer) mark.
2026-07-15 05:55:51 -04:00
Justin M. Keyes
9982f6e0e4 refactor(api): omit optional param 2026-07-13 19:44:15 +02:00
Sébastien Hoffmann
0ffd74ae85 fix(ui2): fix ruler on repeated messages
Problem: a long message is cropped to keep the ruler visible. But when
the message is repeated, it can be written over the ruler, while the
repetition indicator "(1)" is still placed just before the ruler, which
ends up somewhere inside the message.

Solution: currently, long messages are only cropped when setting the
'last' virttext. Make sure this happens after a repeated long message.
2026-07-11 18:44:42 +02:00
Sébastien Hoffmann
2473cb62b7 fix(ui2): correctly crop message at multibyte/multicell character 2026-07-11 18:31:54 +02:00
Sébastien Hoffmann
fcc391d89a fix(ui2): clear showcmd virt_text together with search count
Problem: when the search count is displayed, the showcmd virt_text is
set to 11 empty spaces to ensure a consistent distance between search
count and ruler, or screen edge in case of noruler. But when the search
count is removed to make place for a message, the empty dummy showcmd
remains and unnecessarily erases part of the message.

Solution: properly remove showcmd together with search count.
2026-07-11 18:31:54 +02:00
Barrett Ruth
20a4b1bc5e fix(dir): user/plugin can override default "-" mapping #40676 2026-07-10 11:52:24 -04:00
Evgeni Chasnovski
fce6d9a549 feat(lua): add cwd context to vim._with() #40653
Problem: No concise way to execute a callback with temporarily set
  working directory. This might be useful when sourcing nested files to
  allow them to assume that current working directory is their root
  directory.

Solution: Add `cwd` context to `vim._with().`
2026-07-09 07:07:14 -04:00
Justin M. Keyes
a0fd59352a Merge #40520 nvim_win_resize 2026-07-05 12:06:13 -04:00
XiaowenHu96
ce718e31f4 feat(api): add nvim_win_resize()
Ref #6645

Problem:
When a window is resized it takes space from the window right/below first,
and only falls back to the window left/above when there is no more room.
Sometimes a user wants the space to come from a specific direction.

Solution:
Add nvim_win_resize(win, width, height, {anchor}) which resizes a window
with a choosable anchor edge, letting a window grow leftwards or upwards
by taking space from the window to the left or above first. The default
anchor reproduces nvim_win_set_width()/nvim_win_set_height().
2026-07-05 21:47:34 +08:00
STG
abedbfc175 fix(cmdwin): set 'noscrollbind' #40556
Problem:
Opening cmdwin from a 'scrollbind' window makes cmdwin scrollbinded.
Legacy cmdwin set 'noscrollbind'.

Solution:
Set 'noscrollbind'.
2026-07-04 07:29:26 -04:00
Barrett Ruth
7325e3b55a fix(dir): define "-" (up/parent) mapping earlier #40531
Problem:
The dir.lua "-" mapping cannot be easily overridden (because of autocmd
ordering).

Solution:
- Move it to defaults.lua.
- Also to be extra polite: fall back to builtin `-` motion if the user
  disabled the `dir.lua` plugin.
2026-07-02 15:55:48 -04:00
Justin M. Keyes
34efdadb4e feat(health): report ulimit info
Problem:
Nvim shows `(libuv) kqueue(): Too many open files` on macos.
ref https://github.com/neovim/neovim/issues/40238

Solution:
Add a healthcheck for this situation.
2026-07-01 13:26:21 +02:00
zeertzjq
6c5f0cf29f fix(cmdwin): handle control characters properly #40488
- Replace newlines in the current cmdline with NULs when opening cmdwin,
  and do the reverse when putting a cmdwin line back into the cmdline.
- Escape control characters with Ctrl-V when feeding cmdline.
2026-06-30 08:00:31 -04:00
Justin M. Keyes
684371ba5d fix(cmdwin): handle split/tabpage
Problem:
- If cmdwin window is split, ENTER in one does not close the others.
- If cmdwin is put into a different tabpage via <c-w>T, it stops working
  (ENTER does not execute the cmd).

Solution:
- Close the buffer instead of the window.
- In the WinClosed handler, skip `M._cleanup()` unless this is the last
  cmdwin window.
2026-06-29 23:22:52 +02:00
Justin M. Keyes
d2073d2eec refactor: cleanup, docs #40480 2026-06-29 13:10:31 -04:00
Nathan Zeng
845b66dd4a feat(:restart)!: ":restart" (no bang) saves/restores session #40321
Problem:
`:restart` does not preserve window layout, etc.

Solution:
- Change `:restart` to save/restore a session automatically.
- Introduce "bang" variant `:restart!` to restart *without* session
  save/restore.
- Introduce `v:startreason`.
- `ZR` maps to `:restart!`.
2026-06-29 10:55:23 -04:00
Justin M. Keyes
559730af0a perf(options): avoid Lua<=>API roundtrips #40477
Problem:
- Lua<=>API roundtrips
- Although we prefer Lua for most business-logic code, doing this
  conversion in C makes sense in this case because:
  1. setting options is a hot path
  2. most of the options logic lives in C
  3. the current arrangement is MORE verbose and requires MORE code

Solution:
Move conversion to a C util.
- nvim_set_option_value passes the raw Object (scalar, Array, or Dict)
  to `object_as_optval_for()` which flattens it to the canonical `:set`
  string and validates the type.
- drop `convert_value_to_vim`, eliminate its roundtrip.
2026-06-29 10:00:36 -04:00
Kyle
f34ee3da80 feat(api): nvim_set_option_value(operation=...) #39849
Problem:
`nvim_set_option_value` cannot "update" options similar to `:set opt=`,
`:set opt+=`, etc. The Lua impls of "vim.opt" / "vim.o" have incomplete,
bespoke reimplementations of those operations.

ref #38420

Solution:
- Add `operation` param to `nvim_set_option_value`, which may be "set",
  "append", "prepend", or "remove".
- Use this feature to implement `vim.opt` / `vim.o`.
2026-06-28 13:20:56 -04:00
Evgeni Chasnovski
54647e996e fix(cmdwin): do not block WinEnter events on close #40449
Problem: manual closing cmdwin blocks some events.

Solution: use `nested=true` in buffer-local `WinClosed` event.
2026-06-27 09:25:41 -04:00
Justin M. Keyes
fe4983327b fix(cmdwin): set 'buflisted'
Problem:
Legacy cmdwin set 'buflisted', but new one doesn't.
https://github.com/neovim/neovim/issues/40431#issuecomment-4811593353

'buflisted' useful for:
- "bufferline" style tablines, they usually show only listed buffers.
- some automatic actions can be conditioned on whether a buffer is
  listed; 'buflisted' signals that the buffer is "important enough".

Solution:
Set 'buflisted'.
2026-06-26 21:18:14 +02:00
Justin M. Keyes
496af49bda fix(cmdwin): implement Enter/Ctrl-C as builtins
What echasnovski wants, echasnovski gets.
2026-06-26 21:18:14 +02:00
Justin M. Keyes
5675c11910 fix(cmdwin): space in cmdwin-char 'statuscolumn'
To match the old behavior, the cmdwin-char should not be followed by
a space char.
2026-06-26 21:04:10 +02:00
Justin M. Keyes
ac623bd417 fix(cmdwin): duplicate line in history
Problem:
After ctrl-f from the cmdline, the last 2 lines of cmdwin are redundant.

Solution:
In `open_cmdwin`, clear the live cmdline so that unwinding it (via
Ctrl_C) does not add it to history.
2026-06-26 21:04:10 +02:00
Justin M. Keyes
5ddb4b672e fix(ui2): "msg_history_show" error while in cmdwin
Problem:
Executing :messages while in cmdwin fails:

    Error in "msg_history_show" UI event handler (ns=nvim.ui2):
    Lua: …/_core/ui2/messages.lua:699: Invalid 'height': expected positive Integer
    stack traceback:
    [C]: in function 'nvim_win_set_config'
    …/_core/ui2/messages.lua:699: in function 'set_pos'
    …/_core/ui2/messages.lua:329: in function 'set_target_pos'
    …/_core/ui2/messages.lua:389: in function 'show_msg'
    …/_core/ui2/messages.lua:553: in function 'handler'
    …/_core/ui2.lua:161: in function 'ui_callback'
    …/_core/ui2.lua:210: in function <…/_core/ui2.lua:202>

The bug: when `texth.all` is small (e.g. 0 from a hidden pager whose new
content isn't laid out yet), or when the available height after
subtracting the cmdwin is small, `math.min(min, …)` can yield 0, and
`nvim_win_set_config` rejects `height=0`.

Solution:
Floor at 1.
2026-06-25 18:36:24 +02:00
Justin M. Keyes
b2bf7bcfb1 feat(cmdwin): implement cmdwin as a normal buf+win
Problem:

cmdwin (the `:q` cmdline buffer) has various limitations which require
special-casing all over the codebase.

Besides complicating the code, it also breaks async plugins if they try
to create buffers/windows after some work is done, if the user happens
to open cmdwin at the wrong the moment:

    Lua callback: …/guh.nvim/lua/guh/util.lua:531:
    E11: Invalid in command-line window; <CR> executes, CTRL-C quits
    stack traceback:
        [C]: in function 'nvim_buf_delete'
        …/guh.nvim/lua/guh/util.lua:531: in function <…/guh.nvim/lua/guh/util.lua:526>

Solution:

Just say no to "inception". Reimplement cmdwin as a normal buffer+window.

All of the cmdwin contortions (in both core, and innocent plugins) exist
literally only to support "inception": recursive
cmdwin-in-cmdline-things, like `<c-r>=`, `/`, search-during-substitute,
`:input()`, etc. So we just won't support that (though I have
a potential plan for that later, which I call "modal parking lot").

The benefit is that plugins, and core, no longer have to care about
cmdwin.

BONUS:
- mouse-drag on vertical separators works (it only worked for
  horizontal/statusline before)
- inccommand-in-cmdwin now works correctly, for free (thus don't need
  #40077).

POTENTIAL FOLLOWUPS
- Drop `CHECK_CMDWIN` ("E11: Invalid in command-line window"), allow chaos.
- Unify `BUFLOCK_OK` / `LOCK_OK` ?

DESIGN:
- Eliminate lots of C globals, `EX_CMDWIN`, etc.
- `text_locked()` no longer reports true for cmdwin.
- cmdwin = a normal window with 'winfixbuf', 'bufhidden=wipe',
  'buftype=nofile'. Invariants come from those options rather than
  special cases throughout the codebase.
- `nv_record` for q:/q//q? calls Lua
  `nlua_call_vimfn("vim._core.cmdwin", …)`. No `K_CMDWIN`
  / cmdline-reader detour.
- `cedit_key` (`c_CTRL-F`) schedules a deferred event that calls
  `vim._core.cmdwin.open(type, content, pos)` and returns `Ctrl_C` so
  the in-flight cmdline cancels. Reader state is not serialized; instead
  the captured `(type, line, col)` is replayed via
  `nvim_feedkeys(type..line.."<CR>", "nt", …)` after user confirms.
- On confirm/cancel: `<CR>` / `<C-C>` calls into Lua which closes the
  window and re-feeds the cmdline.

BREAKING CHANGES:
- Expression-register cmdline (`<C-R>=` from insert-mode) no longer
  supports cmdwin. Same applies to `input()` / `inputlist()` (already
  covered by `text_locked`).
- Usage of cmdwin in macros/mappings will probably break (assuming they
  ever worked).
2026-06-25 18:36:24 +02:00
Barrett Ruth
8bf7fc810a fix(tty): filter terminal probes by channel #40356
Problem:
Terminal probes sent with `nvim_ui_send()` can reach more than one stdout TTY
UI. Probes with a known TTY UI owner should not accept `TermResponse`s from
unrelated UI channels. 

Solution:
Thread the existing `chan` filter through owned terminal probes. This covers
startup/attach background detection, fallback truecolor detection, and
`vim.tty.query()` forwarding opts to `vim.tty.request()`.

Note: Not every terminal escape path is updated here. I only passed `chan` when
the caller already knows which TTY UI owns the probe. For example, this does
not include:
- (Followup) OSC 52 (system clipboard) detection. It needs to capture the
  `UIEnter` channel. Adding `{ chan = ... }` only to the nested query would be
  half a fix.
- OSC 52 _paste_ is left global because the provider callback does not have
  a UI channel (paste is invoked without a ui channel/tty ui object).
2026-06-24 10:40:36 -04:00
Barrett Ruth
db30608058 fix(tui): attribute TermResponse to source channel #40330
Problem: Attach-time terminal probes cannot distinguish responses from
different attached UIs.

Solution: Identify the UI by RPC channel id in `TermResponse` and make
`vim.tty.request()` filter responses by channel.
2026-06-23 06:19:56 -04:00
Luuk van Baal
e542b42903 fix(ui2): message before empty prompt not shown
Problem:  Message before empty input() is not visible.
Solution: Route to dialog window with active prompt (hl_id >= 0).
2026-06-22 15:56:26 +02:00
Luuk van Baal
60a46036c0 fix(ui2): clear search_count after clearing the screen
Problem:  Clearing the screen doesn't clear the "last" virtual text.
          Dupe counter virtual text is not increased beyond 1.
Solution: Clear "last" virtual text when clearing the screen.
          Restore assignment lost in a previous commit.
2026-06-22 15:14:53 +02:00
Barrett Ruth
74f163c67d fix(defaults): detect 'background'/'termguicolors' on UI attach #40175
Problem:  Terminal background and truecolor detection runs only at startup,
          gated on a UI being attached. A headless server has no UI then, so
          `'background'` and `'termguicolors'` are never detected and remote
          UIs ignore the terminal's theme.
Solution: Also (re)detect on UIEnter. The most recently attached terminal
          wins; an explicit user value is preserved.
2026-06-20 20:09:34 -04:00
luukvbaal
9618032936 perf(ui2): accumulate message lines #40338
Problem:  Writing a message with a large number of newlines
          (:echo "foo\n"->repeat(1000000)) takes longer than it has to
          (since c973c7ae).
Solution: Accumulate newlines in a single API call when possible.
2026-06-20 13:01:58 -04:00
Justin M. Keyes
436761cba2 fix(tui): late-arriving OSC11 response triggers OptionSet #40270
Problem:
This test is flaky since fff9897ce3 :

    FAILED   ...Xtest_xdg_terminal/test/functional/terminal/tui_spec.lua @ 4359:
    TUI bg color does not trigger OptionSet from automatic background processing
    Expected values to be equal.
    Expected:
    { true, 0 }
    Actual:
    { true, 1 }
    stack traceback:
    ...Xtest_xdg_terminal/test/functional/terminal/tui_spec.lua:4380:
    in function <...Xtest_xdg_terminal/test/functional/terminal/tui_spec.lua:4359>

`apply_optionset_autocmd_now` does not emit `OptionSet` during startup:

    void apply_optionset_autocmd_now(...) {
      // Don't do this while starting up, failure or recursively.
      if (starting || errmsg != NULL || *get_vim_var_str(VV_OPTION_TYPE) != NUL) {
        return;
      }
      ...
    }

but if OSC 11 response arrives AFTER VimEnter, then
`nvim_set_option_value('background',…)` call triggers `OptionSet`.

Solution:
Use `:noautocmd` when setting 'background'.
Per fff9897ce3, OSC11 is not intended to trigger OptionSet.

fix https://github.com/neovim/neovim/issues/40235
2026-06-15 09:12:15 -04:00
Justin M. Keyes
f5fae7aa5c docs: misc, options, pos/range 2026-05-30 12:57:24 +02:00
luukvbaal
89431707a0 fix(ui2): unable to stop display of very long message #39823
Problem:  Processing of a very long message may take a long time; there
          is no visual feedback of work being done, and no way to abort
          processing.
          Calculating text height for spill indicator inhibits
          performance for very long message.

Solution: Whenever writing part of a message is taking longer than 100ms,
          show the first part of the message, while checking for CTRL-C.
          Calculate ('wrap'-ed) text height accurately until 'lines',
          use line count beyond that.
2026-05-21 05:24:39 -04:00
Justin M. Keyes
9aa4608401 refactor: introduce nvim_on internally #39883
Problem:
`nvim_create_autocmd` is too verbose and its `callback` requires extra
"nesting".

Solution:
Introduce `nvim_on`. Start using it internally. Then we can get a feel
for how it should look before making it public.
2026-05-20 17:33:01 -04:00
Puneet Dixit
fff9897ce3 fix(startup): emitting useless OptionSet #39830
Problem:
During startup, we manually trigger a useless and misleading `OptionSet`
event, which doesn't set `v:option_*` values (this is a limitation of
`nvim_exec_autocmds`).
ad4bc2d90c/runtime/lua/vim/_core/defaults.lua (L939).

Solution:
The `nvim_exec_autocmds('OptionSet',…)` call does not serve any purpose
since 5cbb9d613b, so just drop it.
2026-05-17 12:18:24 -04:00
Olivia Kinnear
b62c1049c0 feat(pack): :packupdate, :packdel commands #39693
Define `:packupdate` and `:packdel` as separate commands instead of a
unified `:pack {subcommand}` because the semantics between the two
commands vary differently enough that it doesn't make sense to combine
them. Additionally, `:pack! update/del` looks bad.
2026-05-16 05:15:05 -04:00
luukvbaal
70c3289290 fix(ui2): unable to configure window height of absolute 1 #39781
Problem:
- Configuring the height of one of the message targets to 1 is
  recognized as 100% of 'lines'.
- Cmdline is expanded for message exceeding 'cmdheight' even if the
  configured height is smaller than or equal to 'cmdheight'.
Solution:
- Recognize a height of 1 as absolute; a decimal number smaller than 1
  is taken as a fraction of 'lines' (replace 1 with 0.999 for the old
  behavior).
- Don't expand the cmdline if the configured height doesn't allow it.
2026-05-14 16:04:58 -04:00
luukvbaal
5f7237f54b fix(ui2): unable to route by message ID #39734
Problem:  - "bufwrite" message identifier is encoded in the message ID
            of a "progress" kind message (since ff68fd6b); UI2 does not
            allow routing by message ID.
          - No documented way to set a default message target for all
            but a few kinds (without copying all of |ui-messages| kinds
            to cfg.msg.targets).
          - A user adding a message route for the documented empty ""
            kind can result in unexpected behavior.
          - Showing duplicate message (x) indicator in msg and cmd
            targets simultaneously is unsupported.
          - Manually triggering CursorMoved autocommand to add matchparen
            highlighting in the cmdline.
Solution: - Match cfg.msg.targets keys as Lua pattern to a message ID.
          - Recognize "default" as key in cfg.msg.targets, drop the
            undocumented cfg.msg.target field.
          - Don't try to get configured target for "" message kind/trigger.
          - Maintain msg indicator virtual text for the cmd and msg target.
          - Add matchparen highlighting by directly calling the Lua module
            (possible since b813c7e0).
2026-05-11 18:17:04 -04:00
Justin M. Keyes
11084f5db3 Merge #39730 from ofseed/lsp-remove-deprecated 2026-05-11 11:34:09 -04:00
Yi Ming
fd51fb3fa0 refactor!: remove deprecated APIs 2026-05-11 16:51:58 +08:00
Justin M. Keyes
5370eb0146 fix(lua): vim.wait(0) does not call loop_poll #39679
Problem:
Regression from c822a2657c: `vim.wait(0)` does not call `loop_poll`,
so `vim.wait(1)` is needed to "yield" from Lua.

Solution:
- Ensure that `vim._core.loop_poll()` is always called, even when `time=0`.
- Document how to interrupt Lua code (ctrl-c).

ref https://github.com/neovim/neovim/issues/6800
2026-05-10 14:22:31 -04:00
Yi Ming
eb79cf5aee feat(logging): vim.log #38906 2026-05-10 11:03:15 -04:00
Nathan Zeng
db7f818728 refactor(defaults): use public treesitter select()
Problem: Default mappings use the private module.

Solution: Use the public method.
2026-05-09 10:00:03 +02:00
Justin M. Keyes
55fd73a831 perf(server): use 1 request instead of 3 #39655 2026-05-07 16:13:41 -04:00
Justin M. Keyes
b351024daf build(docs): lint more quasi-keysets #39654
Problem:
Linter missed backtick and double-quote keynames in the quasi-keyset of
the `nvim_create_user_command` docstring.

Solution:
Update the linter to check backtick-surrounded and quote-surrounded key
names.
2026-05-07 16:00:26 +00:00
Szymon Wilczek
3639f7a867 feat(server): add v:useractive, use it in serverlist(info=true) #39423
Problem:
When showing the :connect menu, it is useful to know which servers
are most-recently active. But we don't have a good way to detect that.

Solution:
- Introduce `v:useractive`.
- Include this timestamp in `serverlist({info=true})`.

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Signed-off-by: Szymon Wilczek <swilczek.lx@gmail.com>
2026-05-07 10:47:51 -04:00
Justin M. Keyes
27e7aba982 Merge #39630 from ofseed/lua-no-memoize 2026-05-06 11:15:31 -04:00