-
-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Improve scheduling of F{func} in Ctrl-N completion #17396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
M src/insexpand.c
M src/insexpand.c
This was referenced May 29, 2025
Member
|
It seems hard to test this properly. So I'll merge it. Thanks. |
zeertzjq
added a commit
to zeertzjq/neovim
that referenced
this pull request
Jun 2, 2025
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#17396
vim/vim@98c29db
Co-authored-by: Girish Palya <girishji@gmail.com>
Contributor
Author
|
Thanks! |
zeertzjq
added a commit
to zeertzjq/neovim
that referenced
this pull request
Jun 2, 2025
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#17396
vim/vim@98c29db
Co-authored-by: Girish Palya <girishji@gmail.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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:
findstart = 1to determine the completion start position.findstart = 0to 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.
Improvement on #17065
To try yegappan LSP client:
If you prefer to use 'native' auto-completion (without plugins), try the following configuration: