Skip to content

Commit 3add0d5

Browse files
habamaxchrisbra
authored andcommitted
runtime(ccomplete): use complete_check() in ccomplete plugin
Add complete_check() to ccomplete completion script to avoid UI hangs and keep Vim responsive as ccomplete can be slow on huge files. closes: #17826 Signed-off-by: Maxim Kim <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent 6e1c84c commit 3add0d5

1 file changed

Lines changed: 59 additions & 1 deletion

File tree

runtime/autoload/ccomplete.vim

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ vim9script noclear
33
# Vim completion script
44
# Language: C
55
# Maintainer: The Vim Project <https://github.com/vim/vim>
6-
# Last Change: 2024 Jun 06
6+
# Last Change: 2025 Jul 23
77
# Rewritten in Vim9 script by github user lacygoill
88
# Former Maintainer: Bram Moolenaar <[email protected]>
99

@@ -82,6 +82,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
8282
var s: number = 0
8383
var arrays: number = 0
8484
while 1
85+
if complete_check()
86+
return v:none
87+
endif
8588
var e: number = base->charidx(match(base, '\.\|->\|\[', s))
8689
if e < 0
8790
if s == 0 || base[s - 1] != ']'
@@ -104,6 +107,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
104107
s = e
105108
++e
106109
while e < strcharlen(base)
110+
if complete_check()
111+
return v:none
112+
endif
107113
if base[e] == ']'
108114
if n == 0
109115
break
@@ -121,6 +127,10 @@ export def Complete(findstart: bool, abase: string): any # {{{1
121127
endif
122128
endwhile
123129

130+
if complete_check()
131+
return v:none
132+
endif
133+
124134
# Find the variable items[0].
125135
# 1. in current function (like with "gd")
126136
# 2. in tags file(s) (like with ":tag")
@@ -135,6 +145,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
135145
# Handle multiple declarations on the same line.
136146
var col2: number = col - 1
137147
while line[col2] != ';'
148+
if complete_check()
149+
return v:none
150+
endif
138151
--col2
139152
endwhile
140153
line = line[col2 + 1 :]
@@ -145,6 +158,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
145158
# declaration.
146159
var col2: number = col - 1
147160
while line[col2] != ','
161+
if complete_check()
162+
return v:none
163+
endif
148164
--col2
149165
endwhile
150166
if line[col2 + 1 : col - 1] =~ ' *[^ ][^ ]* *[^ ]'
@@ -184,6 +200,10 @@ export def Complete(findstart: bool, abase: string): any # {{{1
184200
endif
185201
endif
186202

203+
if complete_check()
204+
return v:none
205+
endif
206+
187207
if len(items) == 1 || len(items) == arrays + 1
188208
# Only one part, no "." or "->": complete from tags file.
189209
var tags: list<dict<any>>
@@ -206,6 +226,10 @@ export def Complete(findstart: bool, abase: string): any # {{{1
206226
res = res->extend(tags->map((_, v: dict<any>) => Tag2item(v)))
207227
endif
208228

229+
if complete_check()
230+
return v:none
231+
endif
232+
209233
if len(res) == 0
210234
# Find the variable in the tags file(s)
211235
var diclist: list<dict<any>> = taglist('^' .. items[0] .. '$')
@@ -215,6 +239,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
215239

216240
res = []
217241
for i: number in len(diclist)->range()
242+
if complete_check()
243+
return []
244+
endif
218245
# New ctags has the "typeref" field. Patched version has "typename".
219246
if diclist[i]->has_key('typename')
220247
res = res->extend(diclist[i]['typename']->StructMembers(items[1 :], true))
@@ -234,6 +261,10 @@ export def Complete(findstart: bool, abase: string): any # {{{1
234261
endfor
235262
endif
236263

264+
if complete_check()
265+
return v:none
266+
endif
267+
237268
if len(res) == 0 && items[0]->searchdecl(true) == 0
238269
# Found, now figure out the type.
239270
# TODO: join previous line if it makes sense
@@ -246,6 +277,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
246277
var last: number = len(items) - 1
247278
var brackets: string = ''
248279
while last >= 0
280+
if complete_check()
281+
return v:none
282+
endif
249283
if items[last][0] != '['
250284
break
251285
endif
@@ -311,6 +345,9 @@ def Dict2info(dict: dict<any>): string # {{{1
311345
# Use all the items in dictionary for the "info" entry.
312346
var info: string = ''
313347
for k: string in dict->keys()->sort()
348+
if complete_check()
349+
return ""
350+
endif
314351
info ..= k .. repeat(' ', 10 - strlen(k))
315352
if k == 'cmd'
316353
info ..= dict['cmd']
@@ -346,6 +383,9 @@ def ParseTagline(line: string): dict<any> # {{{1
346383
endwhile
347384
endif
348385
for i: number in range(n + 1, len(l) - 1)
386+
if complete_check()
387+
return {}
388+
endif
349389
if l[i] == 'file:'
350390
d['static'] = 1
351391
elseif l[i] !~ ':'
@@ -441,6 +481,9 @@ def Nextitem( # {{{1
441481
# Try to recognize the type of the variable. This is rough guessing...
442482
var res: list<dict<string>>
443483
for tidx: number in len(tokens)->range()
484+
if complete_check()
485+
return []
486+
endif
444487

445488
# Skip tokens starting with a non-ID character.
446489
if tokens[tidx] !~ '^\h'
@@ -467,6 +510,9 @@ def Nextitem( # {{{1
467510
# Use the tags file to find out if this is a typedef.
468511
var diclist: list<dict<any>> = taglist('^' .. tokens[tidx] .. '$')
469512
for tagidx: number in len(diclist)->range()
513+
if complete_check()
514+
return []
515+
endif
470516
var item: dict<any> = diclist[tagidx]
471517

472518
# New ctags has the "typeref" field. Patched version has "typename".
@@ -559,6 +605,9 @@ def StructMembers( # {{{1
559605
endif
560606
if !cached
561607
while 1
608+
if complete_check()
609+
return []
610+
endif
562611
execute 'silent! keepjumps noautocmd '
563612
.. n .. 'vimgrep ' .. '/\t' .. typename .. '\(\t\|$\)/j '
564613
.. fnames
@@ -581,6 +630,9 @@ def StructMembers( # {{{1
581630
var idx: number = 0
582631
var target: string
583632
while 1
633+
if complete_check()
634+
return []
635+
endif
584636
if idx >= len(items)
585637
target = '' # No further items, matching all members
586638
break
@@ -619,6 +671,9 @@ def StructMembers( # {{{1
619671
# Skip over next [...] items
620672
++idx
621673
while 1
674+
if complete_check()
675+
return []
676+
endif
622677
if idx >= len(items)
623678
return matches # No further items, return the result.
624679
endif
@@ -646,6 +701,9 @@ def SearchMembers( # {{{1
646701
# When "all" is true find all, otherwise just return 1 if there is any member.
647702
var res: list<dict<string>>
648703
for i: number in len(matches)->range()
704+
if complete_check()
705+
return []
706+
endif
649707
var typename: string = ''
650708
var line: string
651709
if matches[i]->has_key('dict')

0 commit comments

Comments
 (0)