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().`
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().
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.
- 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.
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.
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!`.
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.
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`.
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'.
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.
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.
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).
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).
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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).
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
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.
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>
Problem: Entering the pager fails if <ESC> is remapped to :fclose by user.
Solution: Avoid executing mappings with nvim_feedkeys() that closes expanded cmdline.
Problem:
UI tools and orchestration engines need more context than just raw
socket addresses from serverlist(). Without knowing if a server belongs
to the current instance or knowing its PID, UIs cannot display
meaningful options to users.
Solution:
- Added the `info=v:true` option to `serverlist()`.
- When `info` is requested, it implies `peer=true` and returns a list of
dictionaries (defined as `vim.ServerInfo`) with `addr`, `pid` and
`own`.
- Uses an RPC request to `getpid()` across the socket to fetch the
peer's actual process ID.
Signed-off-by: Szymon Wilczek <swilczek.lx@gmail.com>
Problem:
When using `vim.list.unique` or `vim.list.bisect`, if the `key` function is
complex, it can degrade performance, because it is invoked on every comparison
Solution:
The `key` interface convention is designed specifically to address this issue;
performance can be improved by memoizing its results.
Also added the shorthand use of the field name string as the key.