59 lines
1.5 KiB
VimL
59 lines
1.5 KiB
VimL
vim9script
|
|
|
|
class Item
|
|
const len: number
|
|
const val: string
|
|
endclass
|
|
|
|
def GetLongestSuffix(hay: string, ndl: string): tuple<string, number>
|
|
var s = ndl
|
|
var l = len(ndl)
|
|
while true
|
|
const idx = stridx(hay, s)
|
|
if idx != -1
|
|
return (s, idx)
|
|
endif
|
|
l = l - 1
|
|
if l == 0
|
|
break
|
|
endif
|
|
s = strpart(s, 1)
|
|
endwhile
|
|
return ("", 0)
|
|
enddef
|
|
# echo GetLongestSuffix("hello world", "world")->assert_equal(("world", 6))
|
|
# echo GetLongestSuffix("hello world", "foo world")->assert_equal(("o world", 4))
|
|
# echo GetLongestSuffix("hello world foo bar blah", "foo world")->assert_equal(("o world", 4))
|
|
# echo v:errors
|
|
|
|
def GetMatch(base: string, line: string): Item
|
|
const [s, idx] = GetLongestSuffix(line, base)
|
|
const slen = strlen(s)
|
|
const m = strpart(line, idx + slen)
|
|
return Item.new(slen, base .. m)
|
|
enddef
|
|
|
|
def GetMatches(base: string): list<string>
|
|
return getbufinfo()
|
|
->filter( (_, bf) => bf.listed )
|
|
->map( (_, buf) => getbufline(buf["bufnr"], 1, "$"))
|
|
->flattennew()
|
|
->sort()
|
|
->uniq()
|
|
->map( (_, v) => GetMatch(base, v) )
|
|
->filter( (_, m) => m.len > 2 )
|
|
->sort( (x, y) => y.len - x.len )
|
|
->map( (_, m) => m.val )
|
|
enddef
|
|
|
|
def LineSuffixCompl(findstart: bool, base: string): any
|
|
if findstart
|
|
return 0
|
|
endif
|
|
return GetMatches(base)
|
|
enddef
|
|
|
|
inoremap <C-X><C-L> <ScriptCmd>GetMatches(getline('.'))->complete(1)<CR>
|
|
|
|
set completefunc=LineSuffixCompl
|