0
0
mirror of https://github.com/vim/vim.git synced 2025-08-26 20:03:41 -04:00

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>
This commit is contained in:
Maxim Kim 2025-08-08 13:42:49 +02:00 committed by Christian Brabandt
parent 25599902ca
commit fa2bcbdebc
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
2 changed files with 90 additions and 1 deletions

View File

@ -0,0 +1,83 @@
vim9script
# Vim completion script
# Language: Vimscript
# Maintainer: Maxim Kim <habamax@gmail.com>
# Last Change: 2025-07-28
#
# Usage:
# setlocal omnifunc=vimcomplete#Complete
#
# Simple complete function for the Vimscript
var trigger: string = ""
var prefix: string = ""
def GetTrigger(line: string): list<any>
var result = ""
var result_len = 0
if line =~ '->\k*$'
result = 'function'
elseif line =~ '\v%(^|\s+)\&\k*$'
result = 'option'
elseif line =~ '[\[(]\s*$'
result = 'expression'
elseif line =~ '[lvgsb]:\k*$'
result = 'var'
result_len = 2
else
result = getcompletiontype(line) ?? 'cmdline'
endif
return [result, result_len]
enddef
export def Complete(findstart: number, base: string): any
if findstart > 0
var line = getline('.')->strpart(0, col('.') - 1)
var keyword = line->matchstr('\k\+$')
var stx = synstack(line('.'), col('.') - 1)->map('synIDattr(v:val, "name")')->join()
if stx =~? 'Comment' || (stx =~ 'String' && stx !~ 'vimStringInterpolationExpr')
return -2
endif
var trigger_len: number = 0
[trigger, trigger_len] = GetTrigger(line)
if keyword->empty() && trigger->empty()
return -2
endif
prefix = line
return line->len() - keyword->len() - trigger_len
endif
var items = []
if trigger == 'function'
items = getcompletion(base, 'function')
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Function', dup: 0}))
elseif trigger == 'option'
items = getcompletion(base, 'option')
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Option', dup: 0}))
elseif trigger == 'var'
items = getcompletion(base, 'var')
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Variable', dup: 0}))
elseif trigger == 'expression'
items = getcompletion(base, 'expression')
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Expression', dup: 0}))
elseif trigger == 'command'
var commands = getcompletion(base, 'command')
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Command', dup: 0}))
var functions = getcompletion(base, 'function')
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Function', dup: 0}))
items = commands + functions
else
items = getcompletion(prefix, 'cmdline')
->mapnew((_, v) => ({word: v->matchstr('\k\+'), kind: 'v', dup: 0}))
if empty(items) && !empty(base)
items = getcompletion(base, 'expression')
->mapnew((_, v) => ({word: v, kind: 'v', menu: 'Expression', dup: 0}))
endif
endif
return items->empty() ? v:none : items
enddef

View File

@ -8,6 +8,7 @@
" @lacygoill
" Last Change: 2025 Mar 05
" 2025 Aug 06 by Vim Project (add gf maps #17881)
" 2025 Aug 08 by Vim Project (add vimscript complete function #17871)
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
@ -22,7 +23,7 @@ set cpo&vim
if !exists('*VimFtpluginUndo')
func VimFtpluginUndo()
setl fo< isk< com< tw< commentstring< include< define< keywordprg<
setl fo< isk< com< tw< commentstring< include< define< keywordprg< omnifunc<
sil! delc -buffer VimKeywordPrg
if exists('b:did_add_maps')
silent! nunmap <buffer> [[
@ -121,6 +122,11 @@ setlocal include=\\v^\\s*import\\s*(autoload)?
" set 'define' to recognize export commands
setlocal define=\\v^\\s*export\\s*(def\|const\|var\|final)
if has("vim9script")
" set omnifunc completion
setlocal omnifunc=vimcomplete#Complete
endif
" Format comments to be up to 78 characters long
if &tw == 0
setlocal tw=78