Problem: Listing submenus with :menu doesn't work.
Solution: Don't go to the parent of the return value of find_menu(), and
handle empty path at the caller.
Related #8194, which actually only fixed the problem for menu_get(), not
for :menu Ex command.
- update the netrw window to current version (and trim it slightly to 80
chars)
- remove a trailing double quote
dfed077e06
Co-authored-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Antonio Giovanni Colombo <azc100@gmail.com>
Problem: When opening a new tabpage, extui windows are initialized with
their default config. Window visiblity/dimensions on other
tabpages may get out of sync with their buffer content.
Solution: Copy the config of the window to the new tabpage.
No longer keep track of the various windows on each tabpage.
Close windows on inactive tabpages instead (moving them could
be more efficient but is currently not supported in the API).
Problem: Two separate window messages are used to get
the original console icon and set a new
one on windows, although the `WM_SETICON`
message returns the original icon itself.
Solution: Replace the two `WM_GETICON` messages with
two `WM_SETICON` messages, save the return
values and remove the call to `os_icon_set`.
Also, replace `os_icon_set` with `os_icon_reset`
as its only usage is now resetting the
icon to the original one.
Problem:
`vim.diagnostic.set()` doesn't actually accept a list of
`vim.Diagnostic` as internally `vim.diagnostic.set()` normalizes the
diagnostics and this normalization is assumed throughout the module.
Solution:
- Add a new type `vim.Diagnostic.Set` which is the input to `vim.diagnostic.set()`
- `col` is now an optional field and defaults to `0` to be consistent
with `vim.diagnostic.match()`.
- Change `table.insert(t, x)` to `table[#table + 1] = x` for improved
type checking.
Fixes#34013
Problem:
when diagnostic is set right after EOL, underline handler looks
inconsistent compared to other handlers, visually underline is shown
starting from the next line. On top of that it's also inconsistent with
open_float and jump.
Solution:
clamp starting column position in underline handler to be right before
EOL to make it visible and consistent with other handlers, open_float
and jump.
Problem: "win" is cleared in float config after 96330843, even with
unchanged "relative".
Solution: Don't clear "win". Avoid erroring for deleted "win" by setting
the parent win to curwin directly when "win" is zero or not
present in config.
Problem: CTRL-X CTRL-R only completes individual words from registers,
making it difficult to insert complete register content.
Solution: Add consecutive CTRL-X CTRL-R support - first press completes
words, second press completes full register lines, similar to
CTRL-X CTRL-L and CTRL-X CTRL-P behavior (glepnir).
closes: vim/vim#17395d5fdfa5c9c
Co-authored-by: glepnir <glephunter@gmail.com>
Problem: PMenu selection broken with multi-line selection and limits
(Maxim Kim)
Solution: update completion match index when limiting the completion
sources (Girish Palya)
fixes: vim/vim#17394closes: vim/vim#174016c40df09e0
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: scheduling of complete function can be improved
Solution: call user completion functions earlier when just determining
the insertion column (Girish Palya)
This change improves the scheduling behavior of async user-defined
completion functions (such as `F{func}`, `F`, or `'o'` values in the
`'complete'` option), particularly benefiting LSP clients.
Currently, these user functions are invoked twice:
1. First with `findstart = 1` to determine the completion start
position.
2. Then with `findstart = 0` to retrieve the actual matches.
Previously, both calls were executed back-to-back. With this change, the
first call (`findstart = 1`) is performed earlier—before any matches are
gathered from other sources.
This adjustment gives event-driven completion sources (e.g., LSP
clients) more time to send their requests while Vim concurrently
collects matches from other sources like the current buffer.
Not sure about the real-world performance gains, but this approach
should, in theory, improve responsiveness and reduce latency for
asynchronous completions.
To test, try using yegappan LSP client:
```vim
set cpt+=o^10
autocmd VimEnter * g:LspOptionsSet({ autoComplete: false, omniComplete: true })
```
If you prefer to use 'native' auto-completion (without plugins), try the
following configuration:
```vim
set cot=menuone,popup,noselect,nearest
autocmd TextChangedI * InsComplete()
def InsComplete()
if getcharstr(1) == '' && getline('.')->strpart(0, col('.') - 1) =~ '\k$'
SkipTextChangedI()
feedkeys("\<c-n>", "n")
endif
enddef
inoremap <silent> <c-e> <c-r>=<SID>SkipTextChangedI()<cr><c-e>
inoremap <silent> <c-y> <c-r>=<SID>SkipTextChangedI()<cr><c-y>
def SkipTextChangedI(): string
set eventignore+=TextChangedI
timer_start(1, (_) => {
set eventignore-=TextChangedI
})
return ''
enddef
inoremap <silent><expr> <tab> pumvisible() ? "\<c-n>" : "\<tab>"
inoremap <silent><expr> <s-tab> pumvisible() ? "\<c-p>" : "\<s-tab>"
```
closes: vim/vim#1739698c29dbfd1
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: using f-flag in 'complete' conflicts with Neovims filename
completion (glepnir, after v9.1.1301).
Solution: use upper-case "F" flag for completion functions
(Girish Palya).
fixes: vim/vim#17347closes: vim/vim#1737814f6da5ba8
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: compile warning about uninitialized value
(Tony Mechelynck, after v9.1.1311)
Solution: initialize variable on declaration
b53d4fb63e
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: completion: not possible to limit number of matches
Solution: allow to limit the matches for 'complete' sources by using the
"{flag}^{limit}" notation (Girish Palya)
This change extends the 'complete' option to support limiting the
number of matches returned from individual completion sources.
**Rationale:** In large files, certain sources (such as the current
buffer) can generate an overwhelming number of matches, which may cause
more relevant results from other sources (e.g., LSP or tags) to be
pushed out of view. By specifying per-source match limits, the
completion menu remains balanced and diverse, improving visibility and
relevance of suggestions.
A caret (`^`) followed by a number can be appended to a source flag to
specify the maximum number of matches for that source. For example:
```
:set complete=.^9,w,u,t^5
```
In this configuration:
- The current buffer (`.`) will return up to 9 matches.
- The tag completion (`t`) will return up to 5 matches.
- Other sources (`w`, `u`) are not limited.
This feature is fully backward-compatible and does not affect behavior
when the `^count` suffix is not used.
The caret (`^`) was chosen as the delimiter because it is least likely
to appear in file names.
closes: vim/vim#170870ac1eb3555
Cherry-pick test_options.vim change from patch 9.1.1325.
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: Coverity warns about using uninitialized value
(Coverity, Tony Mechelynck, after v9.1.1301)
Solution: initialize callback pointer to NULL
d2079cff48
Co-authored-by: Christian Brabandt <cb@256bit.org>
Problem: completion: cannot configure completion functions with
'complete'
Solution: add support for setting completion functions using the f and o
flag for 'complete' (Girish Palya)
This change adds two new values to the `'complete'` (`'cpt'`) option:
- `f` – invokes the function specified by the `'completefunc'` option
- `f{func}` – invokes a specific function `{func}` (can be a string or `Funcref`)
These new flags extend keyword completion behavior (e.g., via `<C-N>` /
`<C-P>`) by allowing function-based sources to participate in standard keyword
completion.
**Key behaviors:**
- Multiple `f{func}` values can be specified, and all will be called in order.
- Functions should follow the interface defined in `:help complete-functions`.
- When using `f{func}`, escaping is required for spaces (with `\`) and commas
(with `\\`) in `Funcref` names.
- If a function sets `'refresh'` to `'always'`, it will be re-invoked on every
change to the input text. Otherwise, Vim will attempt to reuse and filter
existing matches as the input changes, which matches the default behavior of
other completion sources.
- Matches are inserted at the keyword boundary for consistency with other completion methods.
- If finding matches is time-consuming, `complete_check()` can be used to
maintain responsiveness.
- Completion matches are gathered in the sequence defined by the `'cpt'`
option, preserving source priority.
This feature increases flexibility of standard completion mechanism and may
reduce the need for external completion plugins for many users.
**Examples:**
Complete matches from [LSP](https://github.com/yegappan/lsp) client. Notice the use of `refresh: always` and `function()`.
```vim
set cpt+=ffunction("g:LspCompletor"\\,\ [5]). # maxitems = 5
def! g:LspCompletor(maxitems: number, findstart: number, base: string): any
if findstart == 1
return g:LspOmniFunc(findstart, base)
endif
return {words: g:LspOmniFunc(findstart, base)->slice(0, maxitems), refresh: 'always'}
enddef
autocmd VimEnter * g:LspOptionsSet({ autoComplete: false, omniComplete: true })
```
Complete matches from `:iabbrev`.
```vim
set cpt+=fAbbrevCompletor
def! g:AbbrevCompletor(findstart: number, base: string): any
if findstart > 0
var prefix = getline('.')->strpart(0, col('.') - 1)->matchstr('\S\+$')
if prefix->empty()
return -2
endif
return col('.') - prefix->len() - 1
endif
var lines = execute('ia', 'silent!')
if lines =~? gettext('No abbreviation found')
return v:none # Suppresses warning message
endif
var items = []
for line in lines->split("\n")
var m = line->matchlist('\v^i\s+\zs(\S+)\s+(.*)$')
if m->len() > 2 && m[1]->stridx(base) == 0
items->add({ word: m[1], info: m[2], dup: 1 })
endif
endfor
return items->empty() ? v:none :
items->sort((v1, v2) => v1.word < v2.word ? -1 : v1.word ==# v2.word ? 0 : 1)
enddef
```
**Auto-completion:**
Vim's standard completion frequently checks for user input while searching for
new matches. It is responsive irrespective of file size. This makes it
well-suited for smooth auto-completion. You can try with above examples:
```vim
set cot=menuone,popup,noselect inf
autocmd TextChangedI * InsComplete()
def InsComplete()
if getcharstr(1) == '' && getline('.')->strpart(0, col('.') - 1) =~ '\k$'
SkipTextChangedIEvent()
feedkeys("\<c-n>", "n")
endif
enddef
inoremap <silent> <c-e> <c-r>=<SID>SkipTextChangedIEvent()<cr><c-e>
def SkipTextChangedIEvent(): string
# Suppress next event caused by <c-e> (or <c-n> when no matches found)
set eventignore+=TextChangedI
timer_start(1, (_) => {
set eventignore-=TextChangedI
})
return ''
enddef
```
closes: vim/vim#17065cbe53191d0
Temporarily remove bufname completion with #if 0 to make merging easier.
Co-authored-by: Girish Palya <girishji@gmail.com>
Co-authored-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: glepnir <glephunter@gmail.com>
Problem: preview-window does not scroll correctly
Solution: init firstline = 0 for a preview window
(Girish Palya)
The 'info' window, which appears during insert-mode completion to display
additional information, was not scrolling properly when using commands like:
win_execute(popup_findinfo(), "normal! \<PageDown>")
This issue made it impossible to navigate through info window contents using
keyboard-based scrolling.
The fix correctly updates the w_firstline value of the popup window, ensuring
proper scrolling behavior. Mouse scrolling was already working as expected and
remains unaffected.
closes: vim/vim#1670312b1eb58ab
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: Buffer setup after moving the message buffer to the "more"
window after ff95d7ff is incomplete.
Solution: Adjust and invoke tab_check_wins() to do the setup instead.
Problem: Closing the "more" window for an entered cmdwin in ff95d7ff9
still requires special casing to properly handle "more" visibility.
Solution: Reposition the "more" window instead; anchoring it to the
cmdwin.
Problem: Unable to change the "relative" of a flag after its target
"win" no longer exists.
Solution: Unset target window if it is not present in config and
reconfigured "relative" no longer expects a target window.
Problem:
Developing/troubleshooting plugins has friction because "restarting"
Nvim requires quitting and manually starting again. #32484
Solution:
- Implement a `:restart` command which emits `restart` UI event.
- Handle the `restart` UI event in the builtin TUI client: stop the
`nvim --embed` server, start a new one, and attach to it.
Complement the documented support for the recognition of all
public types of the "java.lang" package (":help java.vim").
(The original syntax item generator may have, inadvertently,
contributed via suppressing "NullPointerException"s to not
having annotation and interface types qualify in general.)
Also, re-link usage instructions for the alternative syntax
item generator to a rolling "master"'s version.
closes: vim/vim#17419b577ad50d0
Co-authored-by: Aliaksei Budavei <0x000c70@gmail.com>
Problem: When using conhost and pressing the 'x' button
to close it while nvim is open, nvim hangs up
while trying to reset the window icon, causing a big
delay before the terminal actually closes. #34171
Solution: Set the window handle to NULL after receiving SIGHUP
so that nvim will not try resetting the icon.
Problem: Non-visible/focusable windows are assigned a window number,
whereas commands that use this window number skip over them.
Solution: Skip over non-visible/focusable windows when computing
the window number, unless it is made the current window
through the API in which case an identifiable window number
is still useful. This also ensures it matches the window
number of the window entered by `<winnr>wincmd w` since
403fcacf.
Problem: nvim_create_user_command() Lua callbacks were missing the documented nargs field in the options table passed to the callback function.
Solution: Add nargs field derivation from command argument type flags in nlua_do_ucmd(), using the same logic as nvim_parse_cmd().
Problem: Message lines from multiple message events that end up
spilling 'cmdheight' end up spread out over the cmdline
and "more" window.
Messages emitted as feedback to a typed :command (rather than
its sole purpose like :echo/:=) are routed to the more window.
The more window isn't closed when entering the cmdwin, and
doesn't allow `vim.hl.on_yank()`.
Solution: When first opening the "more" window for spilled messages,
move the message buffer to the more window.
Restrict routing of typed commands to echo kinds.
Ignore all events but WinLeave and TextYankPost.
- Match full :mark and :k commands.
- Match 2 and 3 letter :s repeat commands.
- Match :s [count] argument.
closes: vim/vim#17408086b3b5b79
Co-authored-by: Doug Kearns <dougkearns@gmail.com>