fix(exrc): lua exrc files know their location
Problem:
'exrc' files are inherently bound to their location / workspace and
therefore require to "know" their location on the filesystem. However,
currently using `debug.getinfo(1, 'S')` returns `"<nvim>"`.
Solution:
Include the filepath as chunkname in `loadstring()` and `nlua_exec()`.
- 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:
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 buffer is not cleared for a new message (since c973c7ae),
resulting in an incorrect spill indicator. When the cmdline
buffer is cleared, "msg_row" is not invalidated, resulting in
an error. The extui module is untested.
Return value of `vim.ui_attach()->callback` is undocumented.
Solution: Clear the cmdline buffer for the first message in an event
loop iteration. Ensure msg_row passed as end_row does not
exceed buffer length.
Add `messages_spec2.lua` to test the extui module, keeping in
mind that test coverage will greatly increase if this UI is made
the default. As such, only tests for specific extui functionality
unlikely to be covered by tests leveraging the current message grid.
Document the return value of `vim.ui_attach()->callback`, it seems
to make sense, and is also used to suppress remote UI events in
`messages_spec2.lua`.
Before this commit, I had trouble finding information about configuring
the insert mode completion. In particular, it was not clear that the
'wildopt' config that I already had in my vimrc does not apply here.
Also, `insert.txt` barely mentioned 'completeopt' except when
describing popups (I was more interested in bash-like behavior
where the unique prefix of all completions is completed first).
I'm hoping these edits will make the relevant docs easier to find.
closes: vim/vim#17515053aee01f7
Co-authored-by: Ilya Grigoriev <ilyagr@users.noreply.github.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: 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: 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: 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: It is difficult to ignore all but some events.
Solution: Add support for a "-" prefix syntax in '(win)eventignore' that
subtracts an event from the ignored set if present
(Luuk van Baal).
8cc6d8b187
Problem: missing info about register completion in complete_info()
(after v9.1.1408)
Solution: update documentation and mention that register is used as
source, add a test (glepnir)
closes: vim/vim#1738949864aecd0
Co-authored-by: glepnir <glephunter@gmail.com>
Problem: not easily possible to complete from register content
Solution: add register-completion submode using i_CTRL-X_CTRL-R
(glepnir)
closes: vim/vim#173540546068aae
Problem: Unable to emit a message with arbitrary kind.
Solution: Add a "kind" opts field to nvim_echo().
Use it to set the "list_cmd" kind for vim.show_pos().
Problem: "99 searchcount ought to be enough for anyone."
Solution: Increase `SEARCH_STAT_DEF_MAX_COUNT` to 999, which I'm sure
will suffice for the next twenty years.
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
Problem:
No way for a user to limit 'exrc' search in parent directories (compare
editorconfig.root).
Solution:
A configuration file can unset 'exrc', disabling the search for its
parent directories.
Problem: The 'grepformat' option is global option, but it would be
useful to have it buffer-local, similar to 'errorformat' and
other quickfix related options (Dani Dickstein)
Solution: Add the necessary code to support global-local 'grepformat',
allowing different buffers to parse different grep output
formats (glepnir)
fixes: vim/vim#17316closes: vim/vim#173157b9eb6389d
Co-authored-by: glepnir <glephunter@gmail.com>
feat(exrc): search exrc in parent directories
Problem:
`.nvim.lua` is only loaded from current directory, which is not flexible
when working from a subfolder of the project.
Solution:
Also search parent directories for configuration file.
Problem: Currently, 'smartcase' is respected when completing keywords
using <C-N>, <C-P>, <C-X><C-N>, and <C-X><C-P>. However, when
a user continues typing and the completion menu is filtered
using cached matches, 'smartcase' is not applied. This leads
to poor-quality or irrelevant completion suggestions, as shown
in the example below.
Solution: When filtering cached completion items after typing additional
characters, apply case-sensitive comparison if 'smartcase' is
enabled and the typed pattern includes uppercase characters.
This ensures consistent and expected completion behavior.
(Girish Palya)
closes: vim/vim#17271dc314053e1
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem:
`any[]` means nothing, and the return value is not the same as what's
documented in the comment (eg, Lua returns `{ "row", { { "leaf", 1000 },
{ "leaf", 1001 } } }`, not `{ "row", { "leaf", 1000, "leaf", 1001 } }`)
Solution:
Create two classes (vim.fn.winlayout.leaf and vim.fn.winlayout.branch)
and one alias that links the two together.
Also: Due to LuaLS limitations, there is an empty class,
vim.fn.winlayout.empty
Signed-Off-By: VoxelPrismatic <voxelprismatic@pm.me>
Problem: UIs implementing ext_cmdline/message must also implement
ext_popupmenu in order to get cmdline completion with
wildoptions+=pum.
Solution: Allow marking a window as the ext_cmdline window through
nvim_open_win(), including prompt offset. Anchor the cmdline-
completion popupmenu to this window.
clarify complete_match() documentation to better explain its backward
search behavior, argument handling, and return value format and add an
example of isexpand
closes: https://github.com/vim/vim/pull/17212ffc89e47d0
* feat(shada): don't store jumplist if '0 in 'shada'
* fix(shada): don't store search and sub patterns if /0 in 'shada'
* fix(shada): don't store empty replacement string
* fix(shada): don't add '0' mark if f0 in 'shada'
Problem: Cannot define completion triggers and act upon it
Solution: add the new option 'isexpand' and add the complete_match()
function to return the completion matches according to the
'isexpand' setting (glepnir)
Currently, completion trigger position is determined solely by the
'iskeyword' pattern (\k\+$), which causes issues when users need
different completion behaviors - such as triggering after '/' for
comments or '.' for methods. Modifying 'iskeyword' to include these
characters has undesirable side effects on other Vim functionality that
relies on keyword definitions.
Introduce a new buffer-local option 'isexpand' that allows specifying
different completion triggers and add the complete_match() function that
finds the appropriate start column for completion based on these
triggers, scanning backwards from cursor position.
This separation of concerns allows customized completion behavior
without affecting iskeyword-dependent features. The option's
buffer-local nature enables per-filetype completion triggers.
closes: vim/vim#16716bcd5995b40
Co-authored-by: glepnir <glephunter@gmail.com>