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 <habamax@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
6e1c84cc4d
commit
3add0d5e75
@ -3,7 +3,7 @@ vim9script noclear
|
|||||||
# Vim completion script
|
# Vim completion script
|
||||||
# Language: C
|
# Language: C
|
||||||
# Maintainer: The Vim Project <https://github.com/vim/vim>
|
# Maintainer: The Vim Project <https://github.com/vim/vim>
|
||||||
# Last Change: 2024 Jun 06
|
# Last Change: 2025 Jul 23
|
||||||
# Rewritten in Vim9 script by github user lacygoill
|
# Rewritten in Vim9 script by github user lacygoill
|
||||||
# Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
# Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||||
|
|
||||||
@ -82,6 +82,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
|
|||||||
var s: number = 0
|
var s: number = 0
|
||||||
var arrays: number = 0
|
var arrays: number = 0
|
||||||
while 1
|
while 1
|
||||||
|
if complete_check()
|
||||||
|
return v:none
|
||||||
|
endif
|
||||||
var e: number = base->charidx(match(base, '\.\|->\|\[', s))
|
var e: number = base->charidx(match(base, '\.\|->\|\[', s))
|
||||||
if e < 0
|
if e < 0
|
||||||
if s == 0 || base[s - 1] != ']'
|
if s == 0 || base[s - 1] != ']'
|
||||||
@ -104,6 +107,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
|
|||||||
s = e
|
s = e
|
||||||
++e
|
++e
|
||||||
while e < strcharlen(base)
|
while e < strcharlen(base)
|
||||||
|
if complete_check()
|
||||||
|
return v:none
|
||||||
|
endif
|
||||||
if base[e] == ']'
|
if base[e] == ']'
|
||||||
if n == 0
|
if n == 0
|
||||||
break
|
break
|
||||||
@ -121,6 +127,10 @@ export def Complete(findstart: bool, abase: string): any # {{{1
|
|||||||
endif
|
endif
|
||||||
endwhile
|
endwhile
|
||||||
|
|
||||||
|
if complete_check()
|
||||||
|
return v:none
|
||||||
|
endif
|
||||||
|
|
||||||
# Find the variable items[0].
|
# Find the variable items[0].
|
||||||
# 1. in current function (like with "gd")
|
# 1. in current function (like with "gd")
|
||||||
# 2. in tags file(s) (like with ":tag")
|
# 2. in tags file(s) (like with ":tag")
|
||||||
@ -135,6 +145,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
|
|||||||
# Handle multiple declarations on the same line.
|
# Handle multiple declarations on the same line.
|
||||||
var col2: number = col - 1
|
var col2: number = col - 1
|
||||||
while line[col2] != ';'
|
while line[col2] != ';'
|
||||||
|
if complete_check()
|
||||||
|
return v:none
|
||||||
|
endif
|
||||||
--col2
|
--col2
|
||||||
endwhile
|
endwhile
|
||||||
line = line[col2 + 1 :]
|
line = line[col2 + 1 :]
|
||||||
@ -145,6 +158,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
|
|||||||
# declaration.
|
# declaration.
|
||||||
var col2: number = col - 1
|
var col2: number = col - 1
|
||||||
while line[col2] != ','
|
while line[col2] != ','
|
||||||
|
if complete_check()
|
||||||
|
return v:none
|
||||||
|
endif
|
||||||
--col2
|
--col2
|
||||||
endwhile
|
endwhile
|
||||||
if line[col2 + 1 : col - 1] =~ ' *[^ ][^ ]* *[^ ]'
|
if line[col2 + 1 : col - 1] =~ ' *[^ ][^ ]* *[^ ]'
|
||||||
@ -184,6 +200,10 @@ export def Complete(findstart: bool, abase: string): any # {{{1
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if complete_check()
|
||||||
|
return v:none
|
||||||
|
endif
|
||||||
|
|
||||||
if len(items) == 1 || len(items) == arrays + 1
|
if len(items) == 1 || len(items) == arrays + 1
|
||||||
# Only one part, no "." or "->": complete from tags file.
|
# Only one part, no "." or "->": complete from tags file.
|
||||||
var tags: list<dict<any>>
|
var tags: list<dict<any>>
|
||||||
@ -206,6 +226,10 @@ export def Complete(findstart: bool, abase: string): any # {{{1
|
|||||||
res = res->extend(tags->map((_, v: dict<any>) => Tag2item(v)))
|
res = res->extend(tags->map((_, v: dict<any>) => Tag2item(v)))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if complete_check()
|
||||||
|
return v:none
|
||||||
|
endif
|
||||||
|
|
||||||
if len(res) == 0
|
if len(res) == 0
|
||||||
# Find the variable in the tags file(s)
|
# Find the variable in the tags file(s)
|
||||||
var diclist: list<dict<any>> = taglist('^' .. items[0] .. '$')
|
var diclist: list<dict<any>> = taglist('^' .. items[0] .. '$')
|
||||||
@ -215,6 +239,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
|
|||||||
|
|
||||||
res = []
|
res = []
|
||||||
for i: number in len(diclist)->range()
|
for i: number in len(diclist)->range()
|
||||||
|
if complete_check()
|
||||||
|
return []
|
||||||
|
endif
|
||||||
# New ctags has the "typeref" field. Patched version has "typename".
|
# New ctags has the "typeref" field. Patched version has "typename".
|
||||||
if diclist[i]->has_key('typename')
|
if diclist[i]->has_key('typename')
|
||||||
res = res->extend(diclist[i]['typename']->StructMembers(items[1 :], true))
|
res = res->extend(diclist[i]['typename']->StructMembers(items[1 :], true))
|
||||||
@ -234,6 +261,10 @@ export def Complete(findstart: bool, abase: string): any # {{{1
|
|||||||
endfor
|
endfor
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if complete_check()
|
||||||
|
return v:none
|
||||||
|
endif
|
||||||
|
|
||||||
if len(res) == 0 && items[0]->searchdecl(true) == 0
|
if len(res) == 0 && items[0]->searchdecl(true) == 0
|
||||||
# Found, now figure out the type.
|
# Found, now figure out the type.
|
||||||
# TODO: join previous line if it makes sense
|
# TODO: join previous line if it makes sense
|
||||||
@ -246,6 +277,9 @@ export def Complete(findstart: bool, abase: string): any # {{{1
|
|||||||
var last: number = len(items) - 1
|
var last: number = len(items) - 1
|
||||||
var brackets: string = ''
|
var brackets: string = ''
|
||||||
while last >= 0
|
while last >= 0
|
||||||
|
if complete_check()
|
||||||
|
return v:none
|
||||||
|
endif
|
||||||
if items[last][0] != '['
|
if items[last][0] != '['
|
||||||
break
|
break
|
||||||
endif
|
endif
|
||||||
@ -311,6 +345,9 @@ def Dict2info(dict: dict<any>): string # {{{1
|
|||||||
# Use all the items in dictionary for the "info" entry.
|
# Use all the items in dictionary for the "info" entry.
|
||||||
var info: string = ''
|
var info: string = ''
|
||||||
for k: string in dict->keys()->sort()
|
for k: string in dict->keys()->sort()
|
||||||
|
if complete_check()
|
||||||
|
return ""
|
||||||
|
endif
|
||||||
info ..= k .. repeat(' ', 10 - strlen(k))
|
info ..= k .. repeat(' ', 10 - strlen(k))
|
||||||
if k == 'cmd'
|
if k == 'cmd'
|
||||||
info ..= dict['cmd']
|
info ..= dict['cmd']
|
||||||
@ -346,6 +383,9 @@ def ParseTagline(line: string): dict<any> # {{{1
|
|||||||
endwhile
|
endwhile
|
||||||
endif
|
endif
|
||||||
for i: number in range(n + 1, len(l) - 1)
|
for i: number in range(n + 1, len(l) - 1)
|
||||||
|
if complete_check()
|
||||||
|
return {}
|
||||||
|
endif
|
||||||
if l[i] == 'file:'
|
if l[i] == 'file:'
|
||||||
d['static'] = 1
|
d['static'] = 1
|
||||||
elseif l[i] !~ ':'
|
elseif l[i] !~ ':'
|
||||||
@ -441,6 +481,9 @@ def Nextitem( # {{{1
|
|||||||
# Try to recognize the type of the variable. This is rough guessing...
|
# Try to recognize the type of the variable. This is rough guessing...
|
||||||
var res: list<dict<string>>
|
var res: list<dict<string>>
|
||||||
for tidx: number in len(tokens)->range()
|
for tidx: number in len(tokens)->range()
|
||||||
|
if complete_check()
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
# Skip tokens starting with a non-ID character.
|
# Skip tokens starting with a non-ID character.
|
||||||
if tokens[tidx] !~ '^\h'
|
if tokens[tidx] !~ '^\h'
|
||||||
@ -467,6 +510,9 @@ def Nextitem( # {{{1
|
|||||||
# Use the tags file to find out if this is a typedef.
|
# Use the tags file to find out if this is a typedef.
|
||||||
var diclist: list<dict<any>> = taglist('^' .. tokens[tidx] .. '$')
|
var diclist: list<dict<any>> = taglist('^' .. tokens[tidx] .. '$')
|
||||||
for tagidx: number in len(diclist)->range()
|
for tagidx: number in len(diclist)->range()
|
||||||
|
if complete_check()
|
||||||
|
return []
|
||||||
|
endif
|
||||||
var item: dict<any> = diclist[tagidx]
|
var item: dict<any> = diclist[tagidx]
|
||||||
|
|
||||||
# New ctags has the "typeref" field. Patched version has "typename".
|
# New ctags has the "typeref" field. Patched version has "typename".
|
||||||
@ -559,6 +605,9 @@ def StructMembers( # {{{1
|
|||||||
endif
|
endif
|
||||||
if !cached
|
if !cached
|
||||||
while 1
|
while 1
|
||||||
|
if complete_check()
|
||||||
|
return []
|
||||||
|
endif
|
||||||
execute 'silent! keepjumps noautocmd '
|
execute 'silent! keepjumps noautocmd '
|
||||||
.. n .. 'vimgrep ' .. '/\t' .. typename .. '\(\t\|$\)/j '
|
.. n .. 'vimgrep ' .. '/\t' .. typename .. '\(\t\|$\)/j '
|
||||||
.. fnames
|
.. fnames
|
||||||
@ -581,6 +630,9 @@ def StructMembers( # {{{1
|
|||||||
var idx: number = 0
|
var idx: number = 0
|
||||||
var target: string
|
var target: string
|
||||||
while 1
|
while 1
|
||||||
|
if complete_check()
|
||||||
|
return []
|
||||||
|
endif
|
||||||
if idx >= len(items)
|
if idx >= len(items)
|
||||||
target = '' # No further items, matching all members
|
target = '' # No further items, matching all members
|
||||||
break
|
break
|
||||||
@ -619,6 +671,9 @@ def StructMembers( # {{{1
|
|||||||
# Skip over next [...] items
|
# Skip over next [...] items
|
||||||
++idx
|
++idx
|
||||||
while 1
|
while 1
|
||||||
|
if complete_check()
|
||||||
|
return []
|
||||||
|
endif
|
||||||
if idx >= len(items)
|
if idx >= len(items)
|
||||||
return matches # No further items, return the result.
|
return matches # No further items, return the result.
|
||||||
endif
|
endif
|
||||||
@ -646,6 +701,9 @@ def SearchMembers( # {{{1
|
|||||||
# When "all" is true find all, otherwise just return 1 if there is any member.
|
# When "all" is true find all, otherwise just return 1 if there is any member.
|
||||||
var res: list<dict<string>>
|
var res: list<dict<string>>
|
||||||
for i: number in len(matches)->range()
|
for i: number in len(matches)->range()
|
||||||
|
if complete_check()
|
||||||
|
return []
|
||||||
|
endif
|
||||||
var typename: string = ''
|
var typename: string = ''
|
||||||
var line: string
|
var line: string
|
||||||
if matches[i]->has_key('dict')
|
if matches[i]->has_key('dict')
|
||||||
|
|||||||
Reference in New Issue
Block a user