Skip to content

Commit e7996f5

Browse files
committed
#1255 completion for doc.enum
1 parent 1a6e210 commit e7996f5

File tree

3 files changed

+146
-4
lines changed

3 files changed

+146
-4
lines changed

script/core/completion/completion.lua

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,80 @@ local function cleanEnums(enums, source)
11211121
return enums
11221122
end
11231123

1124-
local function insertEnum(state, src, enums, isInArray)
1124+
---@param state parser.state
1125+
---@param pos integer
1126+
---@param doc vm.node.object
1127+
---@param enums table[]
1128+
---@return table[]?
1129+
local function insertDocEnum(state, pos, doc, enums)
1130+
local tbl = doc.bindSource
1131+
if not tbl then
1132+
return nil
1133+
end
1134+
local parent = tbl.parent
1135+
local parentName
1136+
if parent._globalNode then
1137+
parentName = parent._globalNode:getName()
1138+
else
1139+
local locals = guide.getVisibleLocals(state.ast, pos)
1140+
for _, loc in pairs(locals) do
1141+
if util.arrayHas(vm.getDefs(loc), tbl) then
1142+
parentName = loc[1]
1143+
break
1144+
end
1145+
end
1146+
end
1147+
local valueEnums = {}
1148+
for _, field in ipairs(tbl) do
1149+
if field.type == 'tablefield'
1150+
or field.type == 'tableindex' then
1151+
if not field.value then
1152+
goto CONTINUE
1153+
end
1154+
local key = guide.getKeyName(field)
1155+
if not key then
1156+
goto CONTINUE
1157+
end
1158+
if field.value.type == 'integer'
1159+
or field.value.type == 'string' then
1160+
if parentName then
1161+
enums[#enums+1] = {
1162+
label = parentName .. '.' .. key,
1163+
kind = define.CompletionItemKind.EnumMember,
1164+
id = stack(function () ---@async
1165+
return {
1166+
detail = buildDetail(field),
1167+
description = buildDesc(field),
1168+
}
1169+
end),
1170+
}
1171+
end
1172+
valueEnums[#valueEnums+1] = {
1173+
label = util.viewLiteral(field.value[1]),
1174+
kind = define.CompletionItemKind.EnumMember,
1175+
id = stack(function () ---@async
1176+
return {
1177+
detail = buildDetail(field),
1178+
description = buildDesc(field),
1179+
}
1180+
end),
1181+
}
1182+
end
1183+
::CONTINUE::
1184+
end
1185+
end
1186+
for _, enum in ipairs(valueEnums) do
1187+
enums[#enums+1] = enum
1188+
end
1189+
return enums
1190+
end
1191+
1192+
---@param state parser.state
1193+
---@param pos integer
1194+
---@param src vm.node.object
1195+
---@param enums table[]
1196+
---@param isInArray boolean?
1197+
local function insertEnum(state, pos, src, enums, isInArray)
11251198
if src.type == 'doc.type.string'
11261199
or src.type == 'doc.type.integer'
11271200
or src.type == 'doc.type.boolean' then
@@ -1139,15 +1212,21 @@ local function insertEnum(state, src, enums, isInArray)
11391212
}
11401213
elseif isInArray and src.type == 'doc.type.array' then
11411214
for i, d in ipairs(vm.getDefs(src.node)) do
1142-
insertEnum(state, d, enums, isInArray)
1215+
insertEnum(state, pos, d, enums, isInArray)
1216+
end
1217+
elseif src.type == 'global' and src.cate == 'type' then
1218+
for _, set in ipairs(src:getSets(state.uri)) do
1219+
if set.type == 'doc.enum' then
1220+
insertDocEnum(state, pos, set, enums)
1221+
end
11431222
end
11441223
end
11451224
end
11461225

11471226
local function checkTypingEnum(state, position, defs, str, results, isInArray)
11481227
local enums = {}
11491228
for _, def in ipairs(defs) do
1150-
insertEnum(state, def, enums, isInArray)
1229+
insertEnum(state, position, def, enums, isInArray)
11511230
end
11521231
cleanEnums(enums, str)
11531232
for _, res in ipairs(enums) do
@@ -1441,7 +1520,7 @@ local function tryCallArg(state, position, results)
14411520

14421521
local enums = {}
14431522
for src in node:eachObject() do
1444-
insertEnum(state, src, enums, arg and arg.type == 'table')
1523+
insertEnum(state, position, src, enums, arg and arg.type == 'table')
14451524
if src.type == 'doc.type.function' then
14461525
---@cast src parser.object
14471526
local insertText = buildInsertDocFunction(src)

script/parser/compile.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3820,6 +3820,7 @@ local function initState(lua, version, options)
38203820
Tokens = tokens(lua)
38213821
Index = 1
38223822
---@class parser.state
3823+
---@field uri uri
38233824
local state = {
38243825
version = version,
38253826
lua = lua,

test/completion/common.lua

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3635,3 +3635,65 @@ local t = {
36353635
textEdit = EXISTS,
36363636
},
36373637
}
3638+
3639+
TEST [[
3640+
---@enum A
3641+
T = {
3642+
x = 1,
3643+
y = 'ss',
3644+
}
3645+
3646+
---@param x A
3647+
local function f(x) end
3648+
3649+
f(<??>)
3650+
]]
3651+
{
3652+
{
3653+
label = 'T.x',
3654+
kind = define.CompletionItemKind.EnumMember,
3655+
},
3656+
{
3657+
label = 'T.y',
3658+
kind = define.CompletionItemKind.EnumMember,
3659+
},
3660+
{
3661+
label = '1',
3662+
kind = define.CompletionItemKind.EnumMember,
3663+
},
3664+
{
3665+
label = '"ss"',
3666+
kind = define.CompletionItemKind.EnumMember,
3667+
},
3668+
}
3669+
3670+
TEST [[
3671+
---@enum A
3672+
local ppp = {
3673+
x = 1,
3674+
y = 'ss',
3675+
}
3676+
3677+
---@param x A
3678+
local function f(x) end
3679+
3680+
f(<??>)
3681+
]]
3682+
{
3683+
{
3684+
label = 'ppp.x',
3685+
kind = define.CompletionItemKind.EnumMember,
3686+
},
3687+
{
3688+
label = 'ppp.y',
3689+
kind = define.CompletionItemKind.EnumMember,
3690+
},
3691+
{
3692+
label = '1',
3693+
kind = define.CompletionItemKind.EnumMember,
3694+
},
3695+
{
3696+
label = '"ss"',
3697+
kind = define.CompletionItemKind.EnumMember,
3698+
},
3699+
}

0 commit comments

Comments
 (0)