Problem: Search completion may use invalid memory (after 9.1.1490).
Solution: Don't get two line pointers at the same time (zeertzjq).
closes: vim/vim#176615e34eec6f8
Problem: 'wildchar' does not work in search contexts
Solution: implement search completion when 'wildchar' is typed
(Girish Palya).
This change enhances Vim's command-line completion by extending
'wildmode' behavior to search pattern contexts, including:
- '/' and '?' search commands
- ':s', ':g', ':v', and ':vim' commands
Completions preserve the exact regex pattern typed by the user,
appending the completed word directly to the original input. This
ensures that all regex elements — such as '<', '^', grouping brackets
'()', wildcards '\*', '.', and other special characters — remain intact
and in their original positions.
---
**Use Case**
While searching (using `/` or `?`) for lines containing a pattern like
`"foobar"`, you can now type a partial pattern (e.g., `/f`) followed by
a trigger key (`wildchar`) to open a **popup completion menu** showing
all matching words.
This offers two key benefits:
1. **Precision**: Select the exact word you're looking for without
typing it fully.
2. **Memory aid**: When you can’t recall a full function or variable
name, typing a few letters helps you visually identify and complete the
correct symbol.
---
**What’s New**
Completion is now supported in the following contexts:
- `/` and `?` search commands
- `:s`, `:g`, `:v`, and `:vimgrep` ex-commands
---
**Design Notes**
- While `'wildchar'` (usually `<Tab>`) triggers completion, you'll have
to use `<CTRL-V><Tab>` or "\t" to search for a literal tab.
- **Responsiveness**: Search remains responsive because it checks for
user input frequently.
---
**Try It Out**
Basic setup using the default `<Tab>` as the completion trigger:
```vim
set wim=noselect,full wop=pum wmnu
```
Now type:
```
/foo<Tab>
```
This opens a completion popup for matches containing "foo".
For matches beginning with "foo" type `/\<foo<Tab>`.
---
**Optional: Autocompletion**
For automatic popup menu completion as you type in search or `:`
commands, include this in your `.vimrc`:
```vim
vim9script
set wim=noselect:lastused,full wop=pum wcm=<C-@> wmnu
autocmd CmdlineChanged [:/?] CmdComplete()
def CmdComplete()
var [cmdline, curpos, cmdmode] = [getcmdline(), getcmdpos(),
expand('<afile>') == ':']
var trigger_char = '\%(\w\|[*/:.-]\)$'
var not_trigger_char = '^\%(\d\|,\|+\|-\)\+$' # Exclude numeric range
if getchar(1, {number: true}) == 0 # Typehead is empty, no more
pasted input
&& !wildmenumode() && curpos == cmdline->len() + 1
&& (!cmdmode || (cmdline =~ trigger_char && cmdline !~
not_trigger_char))
SkipCmdlineChanged()
feedkeys("\<C-@>", "t")
timer_start(0, (_) => getcmdline()->substitute('\%x00', '',
'ge')->setcmdline()) # Remove <C-@>
endif
enddef
def SkipCmdlineChanged(key = ''): string
set ei+=CmdlineChanged
timer_start(0, (_) => execute('set ei-=CmdlineChanged'))
return key == '' ? '' : ((wildmenumode() ? "\<C-E>" : '') .. key)
enddef
**Optional: Preserve history recall behavior**
cnoremap <expr> <Up> SkipCmdlineChanged("\<Up>")
cnoremap <expr> <Down> SkipCmdlineChanged("\<Down>")
**Optional: Customize popup height**
autocmd CmdlineEnter : set bo+=error | exec $'set ph={max([10,
winheight(0) - 4])}'
autocmd CmdlineEnter [/?] set bo+=error | set ph=8
autocmd CmdlineLeave [:/?] set bo-=error ph&
```
closes: vim/vim#175706b49fba8c8
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: no easy way to deduplicate text
Solution: add the :uniq ex command
(Hirohito Higashi)
closes: vim/vim#1753874f0a77bb9
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Problem: ml_get error when using <Cmd> to open a terminal.
Solution: If the window changed reset the incsearch state. (closesvim/vim#7289)
f4d61bc559
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Problem: File paths change from symlink to target path after :cd command
when editing files through symbolic links
Solution: Add "~" flag to 'cpoptions' to control symlink resolution.
When not included (default), symlinks are resolved maintaining
backward compatibility. When included, symlinks are preserved
providing the improved behavior. (glepnir)
related: neovim/neovim#15695closes: vim/vim#176284ade668fb6
Make `vim.iter():take()` and `vim.iter():skip()`
optionally accept predicates to enable takewhile
and skipwhile patterns used in functional
programming.
I was initially trying to port several cmdline tests from Vim involving
test_override('char_avail') without having to rewrite entire tests in
Lua, but haven't figured out a good way achieve that yet. Nevertheless
emulating test_override('starting') is easier.
731e616a79 made it so passing `{env = nil, clear_env = true }` would
pass `{env = {}}` to `vim.uv.spawn`.
However this is not what `clear_env` is (arguably) supposed to do.
If `env=nil` then that implies the uses wants `vim.uv.spawn()` to use
the default environment. Adding `clear_env = true` simply prevents
`NVIM` (the base environment) from being added.
Fixes#34730
Problem: completion: Functions specified in the 'complete' option did
not have the leader string removed when called with findstart = 0,
unlike 'omnifunc' behavior
Solution: update behaviour and make behaviour consistent (Girish Palya)
closes: vim/vim#17636fa16c7ab3f
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: No way to compute intersection of two version ranges, which is
useful when computing version range that fits inside several reference
ranges.
Solution: Add `vim.version.intersect()`.
Problem: `vim.version.range('<=a.b.c')` is not precise when it comes to
its right hand side. This is due to version ranges using exclusive right
hand side. While `vim.version.range('>a.b.c')` is not precise when it
comes to its left hand side because left hand sides are inclusive.
Solution: For '>=a.b.c' increase `to` from 'a.b.c' to the smallest
reasonable version that is bigger than 'a.b.c'. For '<a.b.c' do the same
for `from`.
More proper solution is an explicit control over inclusivity of version
range sides, but it has more side effects and requires design decisions.
Problem: Currently terminal highlight attribute buffers are statically allocated
be the size of `TERM_ATTRS_MAX`. This unique case isn't respected in
some places in the ui_compositor. Due to this, when a terminal window
has lines longer them `TERM_ATTRS_MAX`, the compositor will go past the
end of the buffer causing a crash due to out of bounds access.
Solution: Add check to ensure we don't query terminal highlight attrs
past `TERM_ATTRS_MAX` in `win_line()`.
Fixes#30374
Problem: `tostring()` applied to version range doesn't return
human-readable text with information about the range.
Solution: Add `__tostring()` method.
Problem: tests: need a test for the new-style tutor.tutor, patch
9.1.1384 broke the expected positions for the signs
Solution: Update all number keys in tutor.tutor.json to match the
correct line numbers in tutor.tutor, replace tabs by spaces,
add a screen-dump test to verify it does not regress
(Pham Bình An)
closes: vim/vim#17416a541f1de2b
Problem: Messages routed to the pager to be shown in full, enter the
pager automatically, yielding another "press-q-prompt".
Solution: Only enter the pager when requested explicitly. Otherwise,
close the pager on the next typed mapping, unless that mapping
entered the pager.
Problem: vim._extui unconditionally creates windows, buffers and the
Vimscript cmdline highlighter when it is first loaded.
Solution: Schedule first creation of the window so that first redraw
happens sooner (still need to create at least the cmdline
window asap as it can have a different highlight through
hl-MsgArea; thus further delaying until the first event that
needs a particular target seems redundant). Load the cmdline
highlighter on the first cmdline_show event.
Problem: When a floating window with high winblend uses a highlight group
with underline (but without guisp), the underline appears red.
Solution: Only blend the special color (for underline/undercurl) if the
foreground highlight actually has underline or undercurl set.
Otherwise, ignore the special color.
Problem: Topline is preemptively updated by line() in WinResized
autocmd with 'splitkeep' != "cursor".
Solution: Set `skip_update_topline` when 'splitkeep' != "cursor".
(Luuk van Baal)
fe803c8c04
Problem: ext_messages cannot tell when the screen was cleared, which is
needed to clear visible messages. An empty message is also
never emitted, but clears messages from the message grid.
Solution: Repurpose the "msg_clear" event to be emitted when the screen
was cleared. Emit an empty message with the `empty` kind to
hint to a UI to clear the cmdline area.
- Render Lua types in api.txt.
- Added `DictAs(name)` API type which acts the same as `Dict` (no parens)
when generating the dispatchers, but acts the same as `Dict(name)`
when generating docs.
- Added `Tuple(...)` API type which is the treated the as `Array` for
generating the dispatchers, but is used to document richer types.
- Added `Enum(...)` API type to better document enums
- Improve typing of some API functions.
- Improve c_grammar to properly parse API types and replace string pattern
logic in the parsers.
- Removed all the hardcoded type overrides in gen_eval_files.lua
Problem:
In setup_env, some needed logic is bypassed when clear_env=true.
Solution:
Drop the early return in setup_env().
Co-authored-by: BirdeeHub <birdee@localhost>
Problem: ext_messages is implemented to mimic the message grid
implementation w.r.t. scrolling messages, clearing scrolled
messages, hit-enter-prompts and replacing a previous message.
Meanwhile, an ext_messages UI may not be implemented in a way
where these events are wanted. Moreover, correctness of these
events even assuming a "scrolled message" implementation
depends on fragile "currently visible messages" global state,
which already isn't correct after a previous message was
supposed to have been overwritten (because that should not only
happen when `msg_scroll == false`).
Solution: - No longer attempt to keep track of the currently visible
messages: remove the `msg_ext(_history)_visible` variables.
UIs may remove messages pre-emptively (timer based), or never
show messages that don't fit a certain area in the first place.
- No longer emit the `msg(_history)_clear` events to clear
"scrolled" messages. This opens up the `msg_clear` event to
be emitted when messages should actually be cleared (e.g.
when the screen is cleared). May also be useful to emit before
the first message in an event loop cycle as a hint to the UI
that it is a new batch of messages (vim._extui currently
schedules an event to determine that).
- Set `replace_last` explicitly at the few callsites that want
this to be set to true to replace an incomplete status message.
- Don't store a "keep" message to be re-emitted.
Problem:
Not easy to get user-input in prompt-buffer before the user submits the
input. Under the current system user/plugin needs to read the buffer
contents, figure out where the prompt is, then extract the text.
Solution:
- Add prompt_getinput().
- Extract prompt text extraction logic to a separate function
Problem: "cmdline_show" event may be emitted with an invalid cursor
position, causing a redraw that will clear the match highlight.
Solution: Mark the cursor position as valid so that a "cmdline_show"
callback that updates the screen does not clear the match highlight.
Problem:
With `formatoptions+=r`, the prompt prefix "%" is treated as
comment-start (because of global default 'comments' option contains
"%"), so it gets added to the start of the line when a new line
is input in a prompt.
Solution:
Unset the 'comments' option in prompt buffers by default.
Problem: OptionSet autocmd emitted with invalid grids after entering
tabpage with different 'cmdheight'.
Solution: First call `tabpage_check_windows()` before changing 'cmdheight'.
Add a test that exercises the `vim._extui` cmdline.
Problem: ml_get error when updating quickfix buffer with nvim_buf_attach
Solution: use correct lnume parameter in changed_lines for append mode
Fix#34610