commit e23794b090e0b3b7f1b26460f317726fd2ebac8d
parent f7af0cff359fb5547e2590ab888a772b9c259c54
Author: zeertzjq <zeertzjq@outlook.com>
Date: Sun, 3 Aug 2025 11:49:13 +0800
vim-patch:3add0d5: runtime(ccomplete): use complete_check() in ccomplete plugin (#35142)
Add complete_check() to ccomplete completion script to avoid UI hangs
and keep Vim responsive as ccomplete can be slow on huge files.
closes: vim/vim#17826
https://github.com/vim/vim/commit/3add0d5e75f82e34c3740ef697620cd330507ae5
vim-patch:44309b9: runtime(ccomplete): return partial results on complete_check()
closes: vim/vim#17838
https://github.com/vim/vim/commit/44309b9d08ba657d8c2ee5ed614c14b0fa0cfefc
Co-authored-by: Maxim Kim <habamax@gmail.com>
Diffstat:
1 file changed, 43 insertions(+), 0 deletions(-)
diff --git a/runtime/autoload/ccomplete.vim b/runtime/autoload/ccomplete.vim
@@ -114,6 +114,11 @@ func ccomplete#Complete(findstart, base)
endif
endwhile
+ if complete_check()
+ " return v:none
+ return []
+ endif
+
" Find the variable items[0].
" 1. in current function (like with "gd")
" 2. in tags file(s) (like with ":tag")
@@ -128,6 +133,9 @@ func ccomplete#Complete(findstart, base)
" Handle multiple declarations on the same line.
let col2 = col - 1
while line[col2] != ';'
+ if complete_check()
+ return res
+ endif
let col2 -= 1
endwhile
let line = strpart(line, col2 + 1)
@@ -138,6 +146,9 @@ func ccomplete#Complete(findstart, base)
" declaration.
let col2 = col - 1
while line[col2] != ','
+ if complete_check()
+ return res
+ endif
let col2 -= 1
endwhile
if strpart(line, col2 + 1, col - col2 - 1) =~ ' *[^ ][^ ]* *[^ ]'
@@ -203,6 +214,9 @@ func ccomplete#Complete(findstart, base)
let res = []
for i in range(len(diclist))
+ if complete_check()
+ return res
+ endif
" New ctags has the "typeref" field. Patched version has "typename".
if has_key(diclist[i], 'typename')
call extend(res, s:StructMembers(diclist[i]['typename'], items[1:], 1))
@@ -234,6 +248,9 @@ func ccomplete#Complete(findstart, base)
let last = len(items) - 1
let brackets = ''
while last >= 0
+ if complete_check()
+ return res
+ endif
if items[last][0] != '['
break
endif
@@ -295,6 +312,9 @@ endfunc
func s:Dict2info(dict)
let info = ''
for k in sort(keys(a:dict))
+ if complete_check()
+ return info
+ endif
let info .= k . repeat(' ', 10 - len(k))
if k == 'cmd'
let info .= substitute(matchstr(a:dict['cmd'], '/^\s*\zs.*\ze$/'), '\\\(.\)', '\1', 'g')
@@ -323,6 +343,9 @@ func s:ParseTagline(line)
endwhile
endif
for i in range(n + 1, len(l) - 1)
+ if complete_check()
+ return d
+ endif
if l[i] == 'file:'
let d['static'] = 1
elseif l[i] !~ ':'
@@ -409,6 +432,9 @@ func s:Nextitem(lead, items, depth, all)
" Try to recognize the type of the variable. This is rough guessing...
let res = []
for tidx in range(len(tokens))
+ if complete_check()
+ return res
+ endif
" Skip tokens starting with a non-ID character.
if tokens[tidx] !~ '^\h'
@@ -431,6 +457,11 @@ func s:Nextitem(lead, items, depth, all)
" Use the tags file to find out if this is a typedef.
let diclist = taglist('^' . tokens[tidx] . '$')
for tagidx in range(len(diclist))
+
+ if complete_check()
+ return res
+ endif
+
let item = diclist[tagidx]
" New ctags has the "typeref" field. Patched version has "typename".
@@ -514,6 +545,9 @@ func s:StructMembers(typename, items, all)
endif
if !cached
while 1
+ if complete_check()
+ return []
+ endif
exe 'silent! keepj noautocmd ' . n . 'vimgrep /\t' . typename . '\(\t\|$\)/j ' . fnames
let qflist = getqflist()
@@ -533,6 +567,9 @@ func s:StructMembers(typename, items, all)
" Skip over [...] items
let idx = 0
while 1
+ if complete_check()
+ return []
+ endif
if idx >= len(a:items)
let target = '' " No further items, matching all members
break
@@ -570,6 +607,9 @@ func s:StructMembers(typename, items, all)
" Skip over next [...] items
let idx += 1
while 1
+ if complete_check()
+ return matches
+ endif
if idx >= len(a:items)
return matches " No further items, return the result.
endif
@@ -594,6 +634,9 @@ endfunc
func s:SearchMembers(matches, items, all)
let res = []
for i in range(len(a:matches))
+ if complete_check()
+ return res
+ endif
let typename = ''
if has_key(a:matches[i], 'dict')
if has_key(a:matches[i].dict, 'typename')