Skip to content

Conversation

@girishji
Copy link
Contributor

@girishji girishji commented Jul 20, 2025

Overview

This PR introduces a new option 'autocomplete' ('ac'), to enable automatic popup menu completion in Insert mode. When enabled, Vim shows a completion menu as you type, without the need to explicitly press i_CTRL-N. The items shown are sourced from the 'complete' option.


Try it

:set ac

You should see a popup menu appear automatically with suggestions. This works seamlessly across:

  • Large files (multi-gigabyte size)
  • Massive codebases (:argadd thousands of .c or .h files)
  • Large dictionaries via the k option
  • Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast, responsive, and useful.

Compatibility: This mode is fully compatible with existing completion methods. You can still invoke any CTRL-X based completion (e.g., CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily suspends autocomplete). To specifically use i_CTRL-N, dismiss the current popup by pressing CTRL-E first.


How it works

To keep completion snappy under all conditions, autocompletion uses a decaying time-sliced algorithm:

  • Starts with an initial timeout (80ms).
  • If a source does not complete within the timeout, it's interrupted and the timeout is halved for the next source.
  • This continues recursively until a minimum timeout (5ms) is reached.
  • All sources are given a chance, but slower ones are de-prioritized quickly.

Most of the time, matches are computed well within the initial window.


Implementation details

  • Completion logic is mostly triggered in edit.c and handled in insexpand.c.

  • Uses existing inc_compl_check_keys() mechanism, so no new polling hooks are needed.

  • The completion system already checks for user input periodically; it now also checks for timer expiry.


Design notes

  • The menu doesn't continuously update after it's shown to prevent visual distraction (due to resizing) and ensure the internal list stays synchronized with the displayed menu.

  • The 'complete' option determines priority—sources listed earlier get more time.

  • The exponential time-decay mechanism prevents indefinite collection, contributing to low CPU usage and a minimal memory footprint.

  • Timeout values are intentionally not configurable—this system is optimized to "just work" out of the box. If autocompletion feels slow, it typically indicates a deeper performance bottleneck (e.g., a slow custom function not using complete_check()) rather than a configuration issue.


Performance

Based on testing, the total roundtrip time for completion is generally under 200ms. For common usage, it often responds in under 50ms on an average laptop, which falls within the "feels instantaneous" category (sub-100ms) for perceived user experience.

Upper Bound (ms) Perceived UX
<100 ms Excellent; instantaneous
<200 ms Good; snappy
>300 ms Noticeable lag
>500 ms Sluggish/Broken

Why this belongs in core:

  • Minimal and focused implementation, tightly integrated with existing Insert-mode completion logic.

  • Zero reliance on autocommands and external scripting.

  • Makes full use of Vim’s highly composable 'complete' infrastructure while avoiding the complexity of plugin-based solutions.

  • Gives users C native autocompletion with excellent responsiveness and no configuration overhead.

  • Adds a key UX functionality in a simple, performant, and Vim-like way.


Thanks to @habamax for LSP testing.

girishji added 2 commits July 20, 2025 20:13
This change introduces the `'autocomplete'` (`'ac'`) boolean option to enable
automatic popup menu completion during insert mode. When enabled, Vim shows a
completion menu as you type, similar to pressing |i\_CTRL-N| manually. The
items are collected from sources defined in the `'complete'` option.

To ensure responsiveness, this feature uses a time-sliced strategy:

* Sources earlier in the `'complete'` list are given more time.
* If a source exceeds its allocated timeout, it is interrupted.
* The next source is then started with a reduced timeout (exponentially decayed).
* A small minimum ensures every source still gets a brief chance to contribute.

The feature is fully compatible with other |i\_CTRL-X| completion modes, which
can temporarily suspend automatic completion when triggered.

See `:help 'autocomplete'` and `:help ins-autocompletion` for more details.

M  runtime/doc/insert.txt
M  runtime/doc/options.txt
M  runtime/doc/quickref.txt
M  runtime/doc/tags
M  runtime/optwin.vim
M  src/edit.c
M  src/insexpand.c
M  src/misc1.c
M  src/option.h
M  src/optiondefs.h
M  src/proto/insexpand.pro
M  src/proto/misc1.pro
M  src/testdir/test_ins_complete.vim
M  src/insexpand.c
@ubaldot
Copy link
Contributor

ubaldot commented Jul 20, 2025

On top of my head, I am wondering if the same effect can be obtained with some insert-mapping.... 🤔

I was thinking something like the following (draft of the idea):

vim9script

def SmartComplete(c: string): string
  if pumvisible()
    return c
  else
    return c .. "\<C-n>"
  endif
enddef

for c in range(char2nr('a'), char2nr('z'))
  execute printf("inoremap <expr> %s SmartComplete('%s')", nr2char(c), nr2char(c))
endfor

@gcanat
Copy link
Contributor

gcanat commented Jul 20, 2025

Seems to work well, thanks.
I just feel like 80ms is a bit short for some slower lsp like python ones (jedi-language-server for example).
Maybe this value should be configurable ?

@habamax
Copy link
Contributor

habamax commented Jul 20, 2025

Amazing! Thanks!

While trying it I figured out in case of pylsp and omnifunc from yegappan/lsp it doesn't complete module's functions as well as sometimes built-in functions:

https://asciinema.org/a/tQZ5XVEtItFNrh613QXnrOfrE

PS and looks like there is no obvious way to control when it would be triggered, e.g. \k\. in python.

PS,
we need collaboration with @yegappan (yegappan/lsp) to make possible an even more seamless integration with lsp completion.

@girishji
Copy link
Contributor Author

girishji commented Jul 21, 2025

Amazing! Thanks!

While trying it I figured out in case of pylsp and omnifunc from yegappan/lsp it doesn't complete module's functions as well as sometimes built-in functions:

https://asciinema.org/a/tQZ5XVEtItFNrh613QXnrOfrE

Can you pl. explain what is happening? You removed LSP omnifunc in the first case. Are you using Vim's python omnifunc? I think it is very slow, and I doubt it uses complete_check(). Also, can you use the LSP omnifunc without the wrapper?

PS and looks like there is no obvious way to control when it would be triggered, e.g. \k\. in python.

LSP controls when it triggers through its own 'triggerchars' that the server sets at the client. User need not do anything.

M  src/testdir/test_ins_complete.vim
@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

LSP controls when it triggers through its own 'triggerchars' that the server sets at the client. User need not do anything.

Case 1: omnicompletion with pylsp

https://asciinema.org/a/bxdipzHwbLi2VgfTA0THjFGlT

if you just type, then

  1. print couldn't be completed from lsp unless you backspace and type again
  2. module functions os. doesn't complete when you type it but works with i_CTRL-N once you close existing pmenu issuing said i_CTRL-N

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

Case 2: using F{func}

generally doesn't work at all: https://asciinema.org/a/s1lOr4FTRwbl70pnMEW3tTGTe

The same function, using previous method (autocommands and feedkeys()) works just fine for completing modules os. but it sometimes fail to complete simple print:

https://asciinema.org/a/s1lOr4FTRwbl70pnMEW3tTGTe

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

It very well might be me doing LspCompletor func in the wrong way too.

@gcanat
Copy link
Contributor

gcanat commented Jul 21, 2025

@habamax try to set #define COMPL_INITIAL_TIMEOUT_MS 300

@brianhuster
Copy link
Contributor

Does this new option require users to set 'completeopt' to have noselect or noinsert?

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

@habamax try to set #define COMPL_INITIAL_TIMEOUT_MS 300

Yep, it works with 300. So the lsp should be really fast to meet 80ms requirements. Or vim should be multithreaded, I guess.

UPD
It works for me with 150 too.

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

Does this new option require users to set 'completeopt' to have noselect or noinsert?

Huh, good question. I have just tried with default completeopt and set ac -- works fine.

verbose set completeopt?

# completeopt=menu,preview

@Shane-XB-Qian

This comment was marked as off-topic.

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

We can get similar effect with quite a few lines of vimscript, as author showed in his other Pull Requests.

Here set autocomplete is a huge win for an average vim user or any user who would like to use autocomplete, especially on remote hosts (in some distant future).

@Shane-XB-Qian

This comment was marked as off-topic.

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

Lsp (pylsp and yegappan/lsp here) is just an example of a slow completion source that current implementation is not able to handle. It is not a blocker as I can still use the "more vimscript lines solution" to handle this.

@girishji
Copy link
Contributor Author

girishji commented Jul 21, 2025

Lsp (pylsp and yegappan/lsp here) is just an example of a slow completion source that current implementation is not able to handle. It is not a blocker as I can still use the "more vimscript lines solution" to handle this.

Can you measure how long the round trip for pylsp is (:h reltime())?

Internet says:
⚡ Fast LSPs like pyright or tsserver often respond in <50ms for basic features.
🐢 Heavier servers like clangd, rust-analyzer may take 100–500ms+ for completion.

I guess building AST is time consuming. Maybe an exception needs to be made for omnifunc with higher time slice, but total period should still be capped.

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

Can you measure how long the round trip for pylsp is (:h reltime())?

not sure how to do it to be honest, using omnifunc directly?

inoremap <C-j> <cmd>echow reltime()<CR><C-x><C-o><cmd>echow reltime()<CR>

os.<c-j>

echoes:

[2066, 222869909]
[2066, 321178024]

second time

[2481, 471892238]
[2481, 623487374]

Third time

[2489, 7535825]
[2489, 109516412]

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

I guess building AST is time consuming. Maybe an exception needs to be made for omnifunc with higher time slice, but total period should still be capped.

I think this could be tackled in other (subsequent) PRs?

@Shane-XB-Qian

This comment was marked as off-topic.

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

perhaps you misunderstood, i meant to remote hosts, light weight vim was more useful, and normally there were not compl source installed, unless those remote hosts was fully controlled by you; tho i knew you should be just brought it (remote hosts) as an argument example. anyway, unless there were acceleration code added to help this 'option' functionality, otherwise i maybe suggest not to add such combination option.

Indeed I don't understand what are you talking about. What hosts? Why it relates to completion sources (which are just vim functions).

@Shane-XB-Qian

This comment was marked as off-topic.

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

have you really use lsp? what you get compl items if you didnot installed e.g you mentioned pylsp. or you config F func into cpt, which was a lsp, how it be functional if it was a remote host which not controlled by you? clear?

Oh, I see, you are about vim on remote hosts and lsp. No, I don't use lsp there and don't plan to. But it would be nice to have autocomplete on remote hosts, eventually, with regular vim sources - keywords and friends. Sorry for misreading your message.

@girishji
Copy link
Contributor Author

girishji commented Jul 21, 2025

@habamax , can you try this with feedkeys() script:

set cpt+=FLspCompletor
def! g:LspCompletor(findstart: number, base: string): any
  if findstart > 0
    return g:LspOmniFunc(findstart, base)
  endif
  var starttime = reltime()
  var result = g:LspOmniFunc(findstart, base)
  echom (starttime->reltime()->reltimefloat() * 1000)
  return result
enddef

From pylsp I am seeing 7-10ms, but first time ~80ms (some setup happens here). From clangd similar numbers.

Edit: Can you also test it on a large project, with many buffers open?

@gcanat
Copy link
Contributor

gcanat commented Jul 21, 2025

@habamax , can you pl. try this with feedkeys() script:

set cpt+=FLspCompletor
def! g:LspCompletor(findstart: number, base: string): any
  if findstart > 0
    return g:LspOmniFunc(findstart, base)
  endif
  var starttime = reltime()
  var result = g:LspOmniFunc(findstart, base)
  echom (starttime->reltime()->reltimefloat() * 1000)
  return result
enddef

From pylsp I am seeing 7-10ms, but first time ~80ms (some setup happens here). From clangd similar numbers.

Edit: Can you also test it on a large project, with many buffers open?

With the default COMPL_INITIAL_TIMEOUT_MS of 80ms, if the LspCompletor takes longer to reply it will be skipped/ignored and hence no response time will be displayed.
If you increased the timeout to 300ms you will see that these python language servers (pylsp, jedi...) sometimes take longer to respond, not just the first time but, from what I gather, anytime a module is accessed for the first time.
You can try for yourself by importing a bunch of external libs, say numpy, scipy, sklearn and trying to complete some class or methods from those.

@girishji
Copy link
Contributor Author

girishji commented Jul 21, 2025

With the default COMPL_INITIAL_TIMEOUT_MS of 80ms, if the LspCompletor takes longer to reply it will be skipped/ignored and hence no response time will be displayed. If you increased the timeout to 300ms you will see that these python language servers (pylsp, jedi...) sometimes take longer to respond, not just the first time but, from what I gather, anytime a module is accessed for the first time. You can try for yourself by importing a bunch of external libs, say numpy, scipy, sklearn and trying to complete some class or methods from those.

Thanks for the feedback. I'll have to do some measurement on these LSPs. Also, I suggested using feedkeys() script.If the response time is truly unpredictable and delays occur only occasionally, it may be better to exempt 'omnifunc' from the time-slice limitation.

@habamax
Copy link
Contributor

habamax commented Jul 21, 2025

From pylsp I am seeing 7-10ms, but first time ~80ms (some setup happens here).

it is quite inconsistent here:

88.899835
126.587573
138.093986
17.989421
65.282824
107.238257
32.559945
25.277073
46.265534
15.840048
117.769392
169.590932
0.11221
863.264294
13.746489
18.361648
19.753915

I wonder if it is possible and/or feasible to re-run F{func} after first bail out, when user did a short 200ms pause? Like if do somemodule. and pause for a bit it could still gather candidates?

@habamax
Copy link
Contributor

habamax commented Jul 24, 2025

Is it ready to merge?

@girishji
Copy link
Contributor Author

Is it ready to merge?

From my side, yes.

@habamax
Copy link
Contributor

habamax commented Jul 25, 2025

@chrisbra do you want us to test more?

@chrisbra
Copy link
Member

Are those timing issues resolved?

@habamax
Copy link
Contributor

habamax commented Jul 25, 2025

Are those timing issues resolved?

Yes, it works pretty good. There still might be slowdowns if o would be added to complete in the user config for the filetypes that have very slow implementation of omnicomplete (old ones predating complete_check() function), but it could be tackled one at a time when there is complain about it.

My issue with slow lsp responses was resolved.

@chrisbra
Copy link
Member

Thanks, I include it. I have two suggestion however:

  • Can we make it so that CTRL-V key does not trigger autocompletion?
  • It's not clear to me, what keys trigger autocompletion. Every key in insertmode? Can we update the documentation for this?

@chrisbra chrisbra closed this in af9a7a0 Jul 25, 2025
@girishji
Copy link
Contributor Author

Thanks!

@girishji girishji deleted the auto2 branch July 25, 2025 20:32
@habamax
Copy link
Contributor

habamax commented Jul 27, 2025

Can we make it so that CTRL-V key does not trigger autocompletion?

It doesn't trigger autocompletion as far as I can see.

aerkkila pushed a commit to aerkkila/vim that referenced this pull request Jul 28, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim#17812

Signed-off-by: Girish Palya <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
@girishji
Copy link
Contributor Author

girishji commented Jul 28, 2025

  • It's not clear to me, what keys trigger autocompletion. Every key in insertmode? Can we update the documentation for this?

Just like CTRL-N, keywords trigger autocompletion. Additionally, if F{func}/omnifunc is included in complete and chooses to trigger for non-keywords, it will do so.

zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Aug 3, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim/vim#17812

vim/vim@af9a7a0

Co-authored-by: Girish Palya <[email protected]>
zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Aug 3, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim/vim#17812

vim/vim@af9a7a0

Co-authored-by: Girish Palya <[email protected]>
zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Aug 3, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim/vim#17812

vim/vim@af9a7a0

Co-authored-by: Girish Palya <[email protected]>
zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Aug 3, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim/vim#17812

vim/vim@af9a7a0

Co-authored-by: Girish Palya <[email protected]>
zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Aug 3, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim/vim#17812

vim/vim@af9a7a0

Co-authored-by: Girish Palya <[email protected]>
zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Aug 3, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim/vim#17812

vim/vim@af9a7a0

Co-authored-by: Girish Palya <[email protected]>
zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Aug 3, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim/vim#17812

vim/vim@af9a7a0

Co-authored-by: Girish Palya <[email protected]>
zeertzjq added a commit to neovim/neovim that referenced this pull request Aug 3, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim/vim#17812

vim/vim@af9a7a0

Co-authored-by: Girish Palya <[email protected]>
vimpostor added a commit to vimpostor/dotfiles that referenced this pull request Aug 10, 2025
This is annoying, especially once we want to switch to vim's newly
improved native autocompletion [0][1] in conjunction with lsp.

[0] vim/vim#17812
[1] girishji/vimcomplete#101
aerkkila pushed a commit to aerkkila/vim that referenced this pull request Aug 12, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim#17812

Signed-off-by: Girish Palya <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
yochem pushed a commit to yochem/neovim that referenced this pull request Aug 23, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim/vim#17812

vim/vim@af9a7a0

Co-authored-by: Girish Palya <[email protected]>
dundargoc pushed a commit to dundargoc/neovim that referenced this pull request Sep 27, 2025
Problem:  cannot perform autocompletion
Solution: Add the 'autocomplete' option value
          (Girish Palya)

This change introduces the 'autocomplete' ('ac') boolean option to
enable automatic popup menu completion during insert mode. When enabled,
Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N|
manually. The items are collected from sources defined in the
'complete' option.

To ensure responsiveness, this feature uses a time-sliced strategy:

- Sources earlier in the 'complete' list are given more time.
- If a source exceeds its allocated timeout, it is interrupted.
- The next source is then started with a reduced timeout (exponentially
  decayed).
- A small minimum ensures every source still gets a brief chance to
  contribute.

The feature is fully compatible with other |i_CTRL-X| completion modes,
which can temporarily suspend automatic completion when triggered.

See :help 'autocomplete' and :help ins-autocompletion for more details.

To try it out, use :set ac

You should see a popup menu appear automatically with suggestions. This
works seamlessly across:

- Large files (multi-gigabyte size)
- Massive codebases (:argadd thousands of .c or .h files)
- Large dictionaries via the `k` option
- Slow or blocking LSP servers or user-defined 'completefunc'

Despite potential slowness in sources, the menu remains fast,
responsive, and useful.

Compatibility: This mode is fully compatible with existing completion
methods. You can still invoke any CTRL-X based completion (e.g.,
CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily
suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the
current popup by pressing CTRL-E first.

---

How it works

To keep completion snappy under all conditions, autocompletion uses a
decaying time-sliced algorithm:

- Starts with an initial timeout (80ms).
- If a source does not complete within the timeout, it's interrupted and
  the timeout is halved for the next source.
- This continues recursively until a minimum timeout (5ms) is reached.
- All sources are given a chance, but slower ones are de-prioritized
  quickly.

Most of the time, matches are computed well within the initial window.

---

Implementation details

- Completion logic is mostly triggered in `edit.c` and handled in
  insexpand.c.

- Uses existing inc_compl_check_keys() mechanism, so no new polling
  hooks are needed.

- The completion system already checks for user input periodically; it
  now also checks for timer expiry.

---

Design notes

- The menu doesn't continuously update after it's shown to prevent
  visual distraction (due to resizing) and ensure the internal list
  stays synchronized with the displayed menu.

- The 'complete' option determines priority—sources listed earlier get
  more time.

- The exponential time-decay mechanism prevents indefinite collection,
  contributing to low CPU usage and a minimal memory footprint.

- Timeout values are intentionally not configurable—this system is
  optimized to "just work" out of the box. If autocompletion feels slow,
  it typically indicates a deeper performance bottleneck (e.g., a slow
  custom function not using `complete_check()`) rather than a
  configuration issue.

---

Performance

Based on testing, the total roundtrip time for completion is generally
under 200ms. For common usage, it often responds in under 50ms on an
average laptop, which falls within the "feels instantaneous" category
(sub-100ms) for perceived user experience.

| Upper Bound (ms) | Perceived UX
|----------------- |-------------
| <100 ms          | Excellent; instantaneous
| <200 ms          | Good; snappy
| >300 ms          | Noticeable lag
| >500 ms          | Sluggish/Broken

---

Why this belongs in core:

- Minimal and focused implementation, tightly integrated with existing
  Insert-mode completion logic.
- Zero reliance on autocommands and external scripting.
- Makes full use of Vim’s highly composable 'complete' infrastructure
  while avoiding the complexity of plugin-based solutions.
- Gives users C native autocompletion with excellent responsiveness and
  no configuration overhead.
- Adds a key UX functionality in a simple, performant, and Vim-like way.

closes: vim/vim#17812

vim/vim@af9a7a0

Co-authored-by: Girish Palya <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants