diff options
Diffstat (limited to 'script-beta')
-rw-r--r-- | script-beta/core/completion.lua | 51 | ||||
-rw-r--r-- | script-beta/core/matchkey.lua | 30 | ||||
-rw-r--r-- | script-beta/parser/guide.lua | 33 |
3 files changed, 114 insertions, 0 deletions
diff --git a/script-beta/core/completion.lua b/script-beta/core/completion.lua index e69de29b..d3a7a022 100644 --- a/script-beta/core/completion.lua +++ b/script-beta/core/completion.lua @@ -0,0 +1,51 @@ +local ckind = require 'define.CompletionItemKind' +local files = require 'files' +local guide = require 'parser.guide' +local matchKey = require 'core.matchKey' + +local function findWord(text, offset) + for i = offset, 1, -1 do + if not text:sub(i, i):match '[%w_]' then + if i == offset then + return nil + end + return text:sub(i+1, offset) + end + end + return nil +end + +local function checkLocal(ast, word, offset, results) + guide.getVisibleLocalNames(ast.ast, offset, function (name) + if matchKey(word, name) then + results[#results+1] = { + label = name, + kind = ckind.Variable, + } + end + end) +end + +local function tryWord(ast, text, offset, results) + local word = findWord(text, offset) + if not word then + return nil + end + checkLocal(ast, word, offset, results) +end + +return function (uri, offset) + local ast = files.getAst(uri) + if not ast then + return nil + end + local text = files.getText(uri) + local results = {} + + tryWord(ast, text, offset, results) + + if #results == 0 then + return nil + end + return results +end diff --git a/script-beta/core/matchkey.lua b/script-beta/core/matchkey.lua new file mode 100644 index 00000000..b46250cb --- /dev/null +++ b/script-beta/core/matchkey.lua @@ -0,0 +1,30 @@ +return function (me, other) + if me == other then + return true + end + if me == '' then + return true + end + if #me > #other then + return false + end + local lMe = me:lower() + local lOther = other:lower() + if lMe == lOther:sub(1, #lMe) then + return true + end + local chars = {} + for i = 1, #lOther do + local c = lOther:sub(i, i) + chars[c] = (chars[c] or 0) + 1 + end + for i = 1, #lMe do + local c = lMe:sub(i, i) + if chars[c] and chars[c] > 0 then + chars[c] = chars[c] - 1 + else + return false + end + end + return true +end diff --git a/script-beta/parser/guide.lua b/script-beta/parser/guide.lua index 2e26a3da..4ccfd23d 100644 --- a/script-beta/parser/guide.lua +++ b/script-beta/parser/guide.lua @@ -235,6 +235,39 @@ function m.getLocal(block, name, pos) error('guide.getLocal overstack') end +--- 获取指定区块中所有的可见局部变量名称 +function m.getVisibleLocalNames(block, pos, callback) + block = m.getBlock(block) + local used = {} + for _ = 1, 1000 do + if not block then + return nil + end + local locals = block.locals + local res + if not locals then + goto CONTINUE + end + for i = 1, #locals do + local loc = locals[i] + if loc.effect > pos then + break + end + local name = loc[1] + if not used[name] then + used[name] = true + callback(name) + end + end + if res then + return res, res + end + ::CONTINUE:: + block = m.getParentBlock(block) + end + error('guide.getLocal overstack') +end + --- 获取指定区块中可见的标签 ---@param block table ---@param name string {comment = '标签名'} |