local define = require 'proto.define' local config = require 'config' config.set('Lua.completion.callSnippet', 'Both') config.set('Lua.completion.keywordSnippet', 'Both') config.set('Lua.completion.workspaceWord', false) config.set('Lua.completion.showWord', 'Enable') TEST [[ local zabcde za$ ]] { { label = 'zabcde', kind = define.CompletionItemKind.Variable, } } TEST [[ local zabcdefg local zabcde zabcde$ ]] { { label = 'zabcde', kind = define.CompletionItemKind.Variable, }, { label = 'zabcdefg', kind = define.CompletionItemKind.Variable, }, } TEST [[ local zabcdefg za$ local zabcde ]] { { label = 'zabcdefg', kind = define.CompletionItemKind.Variable, }, { label = 'zabcde', kind = define.CompletionItemKind.Text, }, } TEST [[ local zabcde zace$ ]] { { label = 'zabcde', kind = define.CompletionItemKind.Variable, } } TEST [[ ZABC = x local zabc zac$ ]] { { label = 'zabc', kind = define.CompletionItemKind.Variable, }, { label = 'ZABC', kind = define.CompletionItemKind.Field, }, } TEST [[ ass$ ]] { { label = 'assert(v, message)', kind = define.CompletionItemKind.Function, }, { label = 'assert(v, message)', kind = define.CompletionItemKind.Snippet, }, } TEST [[ local assert = 1 ass$ ]] { { label = 'assert', kind = define.CompletionItemKind.Variable, }, } TEST [[ local assert = 1 _G.ass$ ]] { { label = 'assert(v, message)', kind = define.CompletionItemKind.Function, }, { label = 'assert(v, message)', kind = define.CompletionItemKind.Snippet, }, } TEST [[ local function ffff(a, b) end ff$ ]] { { label = 'ffff(a, b)', kind = define.CompletionItemKind.Function, }, { label = 'ffff(a, b)', kind = define.CompletionItemKind.Snippet, } } TEST [[ local zabc = 1 z$ ]] { { label = 'zabc', kind = define.CompletionItemKind.Variable, } } TEST [[ local zabc = 1.0 z$ ]] { { label = 'zabc', kind = define.CompletionItemKind.Variable, } } TEST [[ local t = { abc = 1, } t.ab$ ]] { { label = 'abc', kind = define.CompletionItemKind.Enum, } } TEST [[ local t = { abc = 1, } local n = t.abc t.ab$ ]] { { label = 'abc', kind = define.CompletionItemKind.Enum, } } TEST [[ local mt = {} mt.ggg = 1 function mt:get(a, b) return 1 end mt:g$ ]] { { label = 'get(a, b)', kind = define.CompletionItemKind.Method, }, { label = 'get(a, b)', kind = define.CompletionItemKind.Snippet, }, { label = 'ggg', kind = define.CompletionItemKind.Text, } } TEST [[ loc$ ]] { { label = 'local', kind = define.CompletionItemKind.Keyword, }, { label = 'local function', kind = define.CompletionItemKind.Snippet, }, } IgnoreFunction = true TEST [[ do$ ]] { { label = 'do', kind = define.CompletionItemKind.Keyword, }, { label = 'do .. end', kind = define.CompletionItemKind.Snippet, }, } TEST [[ while true d$ ]] { { label = 'do', kind = define.CompletionItemKind.Keyword, }, { label = 'do .. end', kind = define.CompletionItemKind.Snippet, }, } TEST [[ results$ ]] (nil) TEST [[ result$ local results ]] (EXISTS) TEST [[ local a$ local function f(fff) fff = ast fff = ast fff = ast fff = ast fff = ast fff = ast end ]] { { label = 'ast', kind = define.CompletionItemKind.Variable, } } TEST [[ t.a = {} t.b = {} t.$ ]] { { label = 'a', kind = define.CompletionItemKind.Field, }, { label = 'b', kind = define.CompletionItemKind.Field, }, } TEST [[ t.a = {} t.b = {} t. $ ]] { { label = 'a', kind = define.CompletionItemKind.Field, }, { label = 'b', kind = define.CompletionItemKind.Field, }, } IgnoreFunction = false TEST [[ t.a = {} function t:b() end t:$ ]] { { label = 'b()', kind = define.CompletionItemKind.Method, }, { label = 'b()', kind = define.CompletionItemKind.Snippet, }, } TEST [[ local t = { a = {}, } t.$ xxx() ]] { { label = 'a', kind = define.CompletionItemKind.Field, }, } TEST [[ (''):$ ]] (EXISTS) TEST [[ local zzz return 'aa' .. zz$ ]] { { label = 'zzz', kind = define.CompletionItemKind.Variable, }, } TEST 'local s = "a:$"' (nil) TEST 'debug.$' (EXISTS) IgnoreFunction = true TEST [[ local xxxx = { xxyy = 1, xxzz = 2, } local t = { x$ } ]] { { label = 'xxxx', kind = define.CompletionItemKind.Variable, }, { label = 'xxyy', kind = define.CompletionItemKind.Property, }, { label = 'xxzz', kind = define.CompletionItemKind.Property, }, } TEST [[ print(ff2) local faa local f$ print(fff) ]] { { label = 'function', kind = define.CompletionItemKind.Keyword, }, { label = 'function ()', kind = define.CompletionItemKind.Snippet, }, { label = 'fff', kind = define.CompletionItemKind.Variable, }, { label = 'ff2', kind = define.CompletionItemKind.Text, }, { label = 'faa', kind = define.CompletionItemKind.Text, }, } TEST [[ local function f(ff$) print(fff) end ]] { { label = 'fff', kind = define.CompletionItemKind.Variable, }, } TEST [[ collectgarbage($) ]] (EXISTS) TEST [[ collectgarbage('$') ]] { { label = "'collect'", kind = define.CompletionItemKind.EnumMember, textEdit = { start = 16, finish = 17, newText = "'collect'", }, }, { label = "'stop'", kind = define.CompletionItemKind.EnumMember, textEdit = { start = 16, finish = 17, newText = "'stop'", }, }, { label = "'restart'", kind = define.CompletionItemKind.EnumMember, textEdit = { start = 16, finish = 17, newText = "'restart'", }, }, { label = "'count'", kind = define.CompletionItemKind.EnumMember, textEdit = { start = 16, finish = 17, newText = "'count'", }, }, { label = "'step'", kind = define.CompletionItemKind.EnumMember, textEdit = { start = 16, finish = 17, newText = "'step'", }, }, { label = "'isrunning'", kind = define.CompletionItemKind.EnumMember, textEdit = { start = 16, finish = 17, newText = "'isrunning'", }, }, { label = "'incremental'", kind = define.CompletionItemKind.EnumMember, textEdit = { start = 16, finish = 17, newText = "'incremental'", }, }, { label = "'generational'", kind = define.CompletionItemKind.EnumMember, textEdit = { start = 16, finish = 17, newText = "'generational'", }, }, } TEST [[ io.read($) ]] { { label = '"n"', kind = define.CompletionItemKind.EnumMember, }, { label = '"a"', kind = define.CompletionItemKind.EnumMember, }, { label = '"l"', kind = define.CompletionItemKind.EnumMember, }, { label = '"L"', kind = define.CompletionItemKind.EnumMember, }, } TEST [[ io.open('', $) ]] (EXISTS) TEST [[ local function f(a, $) end ]] (nil) TEST [[ self.results.list[#$] ]] { { label = '#self.results.list+1', kind = define.CompletionItemKind.Snippet, textEdit = { start = 19, finish = 20, newText = '#self.results.list+1] = ', }, }, } TEST [[ self.results.list[#$] local n = 1 ]] { { label = '#self.results.list+1', kind = define.CompletionItemKind.Snippet, textEdit = { start = 19, finish = 20, newText = '#self.results.list+1] = ', }, }, } TEST [[ self.results.list[#$] = 1 ]] { { label = '#self.results.list+1', kind = define.CompletionItemKind.Snippet, textEdit = { start = 19, finish = 20, newText = '#self.results.list+1]', }, }, } TEST [[ self.results.list[#self.re$] ]] { { label = '#self.results.list+1', kind = define.CompletionItemKind.Snippet, textEdit = { start = 19, finish = 27, newText = '#self.results.list+1] = ', }, }, { label = 'results', kind = define.CompletionItemKind.Field, }, } TEST [[ fff[#ff$] ]] { { label = '#fff+1', kind = define.CompletionItemKind.Snippet, textEdit = { start = 5, finish = 8, newText = '#fff+1] = ', }, }, { label = 'fff', kind = define.CompletionItemKind.Text, } } TEST [[ local _ = fff.kkk[#$] ]] { { label = '#fff.kkk', kind = define.CompletionItemKind.Snippet, textEdit = { start = 19, finish = 20, newText = '#fff.kkk]', }, }, } TEST [[ fff.kkk[#$].yy ]] { { label = '#fff.kkk', kind = define.CompletionItemKind.Snippet, textEdit = { start = 9, finish = 10, newText = '#fff.kkk]', }, }, } TEST [[ local t = { a = 1, } t . $ ]] (EXISTS) TEST [[ local t = { a = 1, } t . $ b ]] (EXISTS) TEST [[ local t = { a = 1, } t $ ]] (nil) TEST [[ local t = { a = 1, } t $. ]] (nil) TEST [[ local xxxx xxxx$ ]] { { label = 'xxxx', kind = define.CompletionItemKind.Variable, }, } TEST [[ local xxxx local XXXX xxxx$ ]] { { label = 'XXXX', kind = define.CompletionItemKind.Variable, }, { label = 'xxxx', kind = define.CompletionItemKind.Variable, }, } TEST [[ local t = { xxxxx = 1, } xx$ ]] { { label = 'xxxxx', kind = define.CompletionItemKind.Text, }, } TEST [[ local index tbl[inde$] ]] { { label = 'index', kind = define.CompletionItemKind.Variable, }, } TEST [[ return function () local t = { a = {}, b = {}, } t.$ end ]] { { label = 'a', kind = define.CompletionItemKind.Field, }, { label = 'b', kind = define.CompletionItemKind.Field, }, } TEST [[ local ast = 1 local t = 'as$' local ask = 1 ]] (EXISTS) TEST [[ local add function f(ad$) local _ = add end ]] { { label = 'add', kind = define.CompletionItemKind.Variable, }, } TEST [[ function table.i$ ]] (EXISTS) TEST [[ do xx.$ end ]] (nil) TEST [[ print(io.$) ]] (EXISTS) require 'config'.set('Lua.runtime.version', 'Lua 5.4') --TEST [[ --local $ --]] --{ -- { -- label = '', -- kind = define.CompletionItemKind.Keyword, -- }, -- { -- label = '', -- kind = define.CompletionItemKind.Keyword, -- }, --} -- --TEST [[ --local local x x.a = $ ]] { { label = "'a'", kind = define.CompletionItemKind.EnumMember, }, { label = "'b'", kind = define.CompletionItemKind.EnumMember, }, { label = "'c'", kind = define.CompletionItemKind.EnumMember, }, } TEST [[ ---@type table local x x['a'] = $ ]] { { label = "'a'", kind = define.CompletionItemKind.EnumMember, }, { label = "'b'", kind = define.CompletionItemKind.EnumMember, }, { label = "'c'", kind = define.CompletionItemKind.EnumMember, }, } TEST [[ ---@type table local x = { a = $ } ]] { { label = "'a'", kind = define.CompletionItemKind.EnumMember, }, { label = "'b'", kind = define.CompletionItemKind.EnumMember, }, { label = "'c'", kind = define.CompletionItemKind.EnumMember, }, } TEST [[ ---@type table local x = { ['a'] = $ } ]] { { label = "'a'", kind = define.CompletionItemKind.EnumMember, }, { label = "'b'", kind = define.CompletionItemKind.EnumMember, }, { label = "'c'", kind = define.CompletionItemKind.EnumMember, }, } Cared['insertText'] = true TEST [[ ---@class A.B.C local m function m.f() end m.f$ ]]{ { label = "f()", kind = define.CompletionItemKind.Function, insertText = EXISTS, }, { label = "f()", kind = define.CompletionItemKind.Snippet, insertText = 'f()', }, } Cared['insertText'] = nil TEST [[ if true then$ ]] { { label = 'then', kind = define.CompletionItemKind.Keyword, }, { label = 'then .. end', kind = define.CompletionItemKind.Snippet, } } TEST [[ if true then$ end ]] { { label = 'then', kind = define.CompletionItemKind.Keyword, }, } TEST [[ if true then$ else ]] { { label = 'then', kind = define.CompletionItemKind.Keyword, }, } TEST [[ if true then$ elseif ]] { { label = 'then', kind = define.CompletionItemKind.Keyword, }, } TEST [[ do if true then$ end ]] { { label = 'then', kind = define.CompletionItemKind.Keyword, }, { label = 'then .. end', kind = define.CompletionItemKind.Snippet, } } TEST [[ ---@class C ---@field x number ---@field y number ---@vararg C local function f(x, ...) end f(1, { $ }) ]] { { label = 'x', kind = define.CompletionItemKind.Property, }, { label = 'y', kind = define.CompletionItemKind.Property, } } TEST [[ ---@class C ---@field x number ---@field y number ---@vararg C local function f(x, ...) end f(1, {}, {}, { $ }) ]] { { label = 'x', kind = define.CompletionItemKind.Property, }, { label = 'y', kind = define.CompletionItemKind.Property, } } TEST [[ ---@class C ---@field x number ---@field y number ---@type C local t = { $ } ]] { { label = 'x', kind = define.CompletionItemKind.Property, }, { label = 'y', kind = define.CompletionItemKind.Property, } } TEST [[ ---@class C ---@field x number ---@field y number ---@type C local t = { x$ } ]] { include = true, { label = 'x', kind = define.CompletionItemKind.Property, }, } TEST [[ if $ then ]] (nil) TEST [[ elseif $ then ]] (nil) TEST [[ ---@type iolib local t = { $ ]] (EXISTS) TEST [[ ---@class A ---@field a '"hello"'|'"world"' ---@param t A function api(t) end api({$}) ]] (EXISTS) TEST [[ ---@class A ---@field a '"hello"'|'"world"' ---@param t A function m:api(t) end m:api({$}) ]] (EXISTS) TEST [[ ---@class AAA.BBB ---@type AAA.$ ]] { { label = 'AAA.BBB', kind = define.CompletionItemKind.Class, textEdit = { start = 29, finish = 32, newText = 'AAA.BBB', }, } } Cared['insertText'] = true TEST [[ ---@overload fun(a: any, b: any) local function zzzz(a) end zzzz$ ]] { { label = 'zzzz(a)', kind = define.CompletionItemKind.Function, insertText = 'zzzz', }, { label = 'zzzz(a)', kind = define.CompletionItemKind.Snippet, insertText = 'zzzz(${1:a: any})', }, { label = 'zzzz(a, b)', kind = define.CompletionItemKind.Function, insertText = 'zzzz', }, { label = 'zzzz(a, b)', kind = define.CompletionItemKind.Snippet, insertText = 'zzzz(${1:a: any}, ${2:b: any})', }, } Cared['insertText'] = false TEST [[ --- @diagnostic disable: unused-local --- @class Test2 --- @field world integer local Test2 = {} --- @type Test2 local tdirect --- @type Test2[] local tarray -- Direct inference local b = tdirect -- type . here, shows "world" -- Inferred by index local c = tarray[1].$ -- type . here, no auto completion ]] (EXISTS) TEST [[ local function f() if type() == '$' then end end ]] (EXISTS) config.set('Lua.completion.callSnippet', 'Disable') TEST [[ GGG = 1 GGG = function () end GGG$ ]] { { label = 'GGG', kind = define.CompletionItemKind.Enum, }, { label = 'GGG()', kind = define.CompletionItemKind.Function, }, } TEST [[ ---@class C ---@field GGG number local t = {} t.GGG = function () end t.GGG$ ]] { { label = 'GGG', kind = define.CompletionItemKind.Field, }, { label = 'GGG()', kind = define.CompletionItemKind.Function, }, } TEST [[ ---@param f fun(a: any, b: any):boolean local function f(f) end f(fun$) ]] { { label = 'fun(a: any, b: any):boolean', kind = define.CompletionItemKind.Function, textEdit = { newText = 'function (${1:a}, ${2:b})\n\t$0\nend', start = 68, finish = 70, } }, { label = 'function', kind = define.CompletionItemKind.Keyword, }, { label = 'function ()', kind = define.CompletionItemKind.Snippet, } } TEST [[ ---@type {[1]: number} local t t.$ ]] { { label = '1', kind = define.CompletionItemKind.Field, textEdit = { newText = '[1]', start = 35, finish = 34, }, additionalTextEdits = { { start = 34, finish = 34, newText = '', }, }, } } TEST [[ ---@type {[1]: number} local t t.$ ]] { { label = '1', kind = define.CompletionItemKind.Field, textEdit = { newText = '[1]', start = 35, finish = 34, }, additionalTextEdits = { { start = 34, finish = 34, newText = '', }, }, } } TEST [[ ---@alias enum '"aaa"'|'"bbb"' ---@param x enum ---@return enum local function f(x) end local r = f('$') ]] { { label = "'aaa'", kind = define.CompletionItemKind.EnumMember, textEdit = { newText = "'aaa'", start = 103, finish = 104, }, }, { label = "'bbb'", kind = define.CompletionItemKind.EnumMember, textEdit = { newText = "'bbb'", start = 103, finish = 104, }, }, } TEST [[ ---@type fun(x: "'aaa'"|"'bbb'") local f f('$') ]] { { label = "'aaa'", kind = define.CompletionItemKind.EnumMember, textEdit = { newText = "'aaa'", start = 45, finish = 46, }, }, { label = "'bbb'", kind = define.CompletionItemKind.EnumMember, textEdit = { newText = "'bbb'", start = 45, finish = 46, }, }, } TEST [[ ---@class Class ---@field on fun() local c c:$ ]] { { label = 'on', kind = define.CompletionItemKind.Field, } } TEST [[ ---@class Class ---@field on fun(x: "'aaa'"|"'bbb'") local c c:on($) ]] (EXISTS) TEST [[ ---@class Class ---@field on fun(x: "'aaa'"|"'bbb'") local c c:on('$') ]] (EXISTS) TEST [[ local m = {} function m.f() end m.f() m.$ ]] { [1] = EXISTS, } TEST [[ ---@class class1 class1 = {} function class1:method1() end ---@class class2 : class1 class2 = {} class2:$ ]] { [1] = EXISTS, }