vim9script class Item const len: number const val: string endclass def GetLongestSuffix(hay: string, ndl: string): string var s = ndl var l = len(ndl) while stridx(hay, s) == -1 s = strpart(s, 1) l = l - 1 if l == 0 return "" endif endwhile return s enddef # echo GetLongestSuffix("hello world", "world")->assert_equal("world") # echo GetLongestSuffix("hello world", "foo world")->assert_equal("o world") # echo GetLongestSuffix("hello world foo bar blah", "foo world")->assert_equal("o world") # echo v:errors def GetMatch(base: string, line: string): Item const s = GetLongestSuffix(line, base) const idx = stridx(line, s) const slen = strlen(s) const m = strpart(line, idx + slen) return Item.new(slen, base .. m) enddef def GetMatches(base: string): list 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 GetMatches(getline('.'))->complete(1) set completefunc=LineSuffixCompl