Skip to content

Commit fa2bcbd

Browse files
habamaxchrisbra
authored andcommitted
runtime(vim): add simple vimscript complete function
closes: #17871 Signed-off-by: Maxim Kim <habamax@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent 2559990 commit fa2bcbd

2 files changed

Lines changed: 90 additions & 1 deletion

File tree

runtime/autoload/vimcomplete.vim

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
vim9script
2+
3+
# Vim completion script
4+
# Language: Vimscript
5+
# Maintainer: Maxim Kim <habamax@gmail.com>
6+
# Last Change: 2025-07-28
7+
#
8+
# Usage:
9+
# setlocal omnifunc=vimcomplete#Complete
10+
#
11+
# Simple complete function for the Vimscript
12+
13+
var trigger: string = ""
14+
var prefix: string = ""
15+
16+
17+
def GetTrigger(line: string): list<any>
18+
var result = ""
19+
var result_len = 0
20+
21+
if line =~ '->\k*$'
22+
result = 'function'
23+
elseif line =~ '\v%(^|\s+)\&\k*$'
24+
result = 'option'
25+
elseif line =~ '[\[(]\s*$'
26+
result = 'expression'
27+
elseif line =~ '[lvgsb]:\k*$'
28+
result = 'var'
29+
result_len = 2
30+
else
31+
result = getcompletiontype(line) ?? 'cmdline'
32+
endif
33+
return [result, result_len]
34+
enddef
35+
36+
export def Complete(findstart: number, base: string): any
37+
if findstart > 0
38+
var line = getline('.')->strpart(0, col('.') - 1)
39+
var keyword = line->matchstr('\k\+$')
40+
var stx = synstack(line('.'), col('.') - 1)->map('synIDattr(v:val, "name")')->join()
41+
if stx =~? 'Comment' || (stx =~ 'String' && stx !~ 'vimStringInterpolationExpr')
42+
return -2
43+
endif
44+
var trigger_len: number = 0
45+
[trigger, trigger_len] = GetTrigger(line)
46+
if keyword->empty() && trigger->empty()
47+
return -2
48+
endif
49+
prefix = line
50+
return line->len() - keyword->len() - trigger_len
51+
endif
52+
53+
var items = []
54+
if trigger == 'function'
55+
items = getcompletion(base, 'function')
56+
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Function', dup: 0}))
57+
elseif trigger == 'option'
58+
items = getcompletion(base, 'option')
59+
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Option', dup: 0}))
60+
elseif trigger == 'var'
61+
items = getcompletion(base, 'var')
62+
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Variable', dup: 0}))
63+
elseif trigger == 'expression'
64+
items = getcompletion(base, 'expression')
65+
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Expression', dup: 0}))
66+
elseif trigger == 'command'
67+
var commands = getcompletion(base, 'command')
68+
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Command', dup: 0}))
69+
var functions = getcompletion(base, 'function')
70+
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Function', dup: 0}))
71+
items = commands + functions
72+
else
73+
items = getcompletion(prefix, 'cmdline')
74+
->mapnew((_, v) => ({word: v->matchstr('\k\+'), kind: 'v', dup: 0}))
75+
76+
if empty(items) && !empty(base)
77+
items = getcompletion(base, 'expression')
78+
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Expression', dup: 0}))
79+
endif
80+
endif
81+
82+
return items->empty() ? v:none : items
83+
enddef

runtime/ftplugin/vim.vim

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
" @lacygoill
99
" Last Change: 2025 Mar 05
1010
" 2025 Aug 06 by Vim Project (add gf maps #17881)
11+
" 2025 Aug 08 by Vim Project (add vimscript complete function #17871)
1112

1213
" Only do this when not done yet for this buffer
1314
if exists("b:did_ftplugin")
@@ -22,7 +23,7 @@ set cpo&vim
2223

2324
if !exists('*VimFtpluginUndo')
2425
func VimFtpluginUndo()
25-
setl fo< isk< com< tw< commentstring< include< define< keywordprg<
26+
setl fo< isk< com< tw< commentstring< include< define< keywordprg< omnifunc<
2627
sil! delc -buffer VimKeywordPrg
2728
if exists('b:did_add_maps')
2829
silent! nunmap <buffer> [[
@@ -121,6 +122,11 @@ setlocal include=\\v^\\s*import\\s*(autoload)?
121122
" set 'define' to recognize export commands
122123
setlocal define=\\v^\\s*export\\s*(def\|const\|var\|final)
123124

125+
if has("vim9script")
126+
" set omnifunc completion
127+
setlocal omnifunc=vimcomplete#Complete
128+
endif
129+
124130
" Format comments to be up to 78 characters long
125131
if &tw == 0
126132
setlocal tw=78

0 commit comments

Comments
 (0)