summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-12-02 16:59:04 +0800
committerGitHub <noreply@github.com>2022-12-02 16:59:04 +0800
commit98efc5696e8fa512f64dff9508e79143e6aeb200 (patch)
tree6d19bfedaad7e304247d123a871ac9e120181780
parent6999dbb25bf2b7ae306599eceaa0f438ee4f8b8f (diff)
parent2492c1fb71d213de22756949a65e9811af50a92d (diff)
downloadlua-language-server-98efc5696e8fa512f64dff9508e79143e6aeb200.zip
Merge pull request #1711 from sewbacca/feature/auto-require-without-init
Feature/auto require without init
-rw-r--r--script/core/completion/completion.lua126
-rw-r--r--test/crossfile/completion.lua83
2 files changed, 154 insertions, 55 deletions
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua
index e63e8d35..f96d7b99 100644
--- a/script/core/completion/completion.lua
+++ b/script/core/completion/completion.lua
@@ -376,63 +376,79 @@ local function checkModule(state, word, position, results)
goto CONTINUE
end
local path = furi.decode(uri)
- local fileName = path:match '[^/\\]*$'
- local stemName = fileName:gsub('%..+', '')
- if not locals[stemName]
- and not vm.hasGlobalSets(state.uri, 'variable', stemName)
- and not globals[stemName]
- and stemName:match(guide.namePatternFull)
- and matchKey(word, stemName) then
- local targetState = files.getState(uri)
- if not targetState then
- goto CONTINUE
- end
- local targetReturns = targetState.ast.returns
- if not targetReturns then
- goto CONTINUE
- end
- local targetSource = targetReturns[1] and targetReturns[1][1]
- if not targetSource then
- goto CONTINUE
- end
- if targetSource.type ~= 'getlocal'
- and targetSource.type ~= 'table'
- and targetSource.type ~= 'function' then
- goto CONTINUE
- end
- if targetSource.type == 'getlocal'
- and vm.getDeprecated(targetSource.node) then
- goto CONTINUE
- end
- results[#results+1] = {
- label = stemName,
- kind = define.CompletionItemKind.Variable,
- commitCharacters = { '.' },
- command = {
- title = 'autoRequire',
- command = 'lua.autoRequire',
- arguments = {
- {
- uri = guide.getUri(state.ast),
- target = uri,
- name = stemName,
+ local relativePath = workspace.getRelativePath(path)
+ local infos = rpath.getVisiblePath(uri, path)
+ local testedStem = { }
+ for _, sr in ipairs(infos) do
+ local pattern = sr.searcher
+ :gsub("(%p)", "%%%1")
+ :gsub("%%%?", "(.-)")
+
+ local stemName = relativePath
+ :match(pattern)
+ :match("[%a_][%w_]*$")
+
+ if not stemName or testedStem[stemName] then
+ goto INNER_CONTINUE
+ end
+ testedStem[stemName] = true
+
+ if not locals[stemName]
+ and not vm.hasGlobalSets(state.uri, 'variable', stemName)
+ and not globals[stemName]
+ and matchKey(word, stemName) then
+ local targetState = files.getState(uri)
+ if not targetState then
+ goto INNER_CONTINUE
+ end
+ local targetReturns = targetState.ast.returns
+ if not targetReturns then
+ goto INNER_CONTINUE
+ end
+ local targetSource = targetReturns[1] and targetReturns[1][1]
+ if not targetSource then
+ goto INNER_CONTINUE
+ end
+ if targetSource.type ~= 'getlocal'
+ and targetSource.type ~= 'table'
+ and targetSource.type ~= 'function' then
+ goto INNER_CONTINUE
+ end
+ if targetSource.type == 'getlocal'
+ and vm.getDeprecated(targetSource.node) then
+ goto INNER_CONTINUE
+ end
+ results[#results+1] = {
+ label = stemName,
+ kind = define.CompletionItemKind.Variable,
+ commitCharacters = { '.' },
+ command = {
+ title = 'autoRequire',
+ command = 'lua.autoRequire',
+ arguments = {
+ {
+ uri = guide.getUri(state.ast),
+ target = uri,
+ name = stemName,
+ },
},
},
- },
- id = stack(targetSource, function (newSource) ---@async
- local md = markdown()
- md:add('md', lang.script('COMPLETION_IMPORT_FROM', ('[%s](%s)'):format(
- workspace.getRelativePath(uri),
- uri
- )))
- md:add('md', buildDesc(newSource))
- return {
- detail = buildDetail(newSource),
- description = md,
- --additionalTextEdits = buildInsertRequire(state, originUri, stemName),
- }
- end)
- }
+ id = stack(targetSource, function (newSource) ---@async
+ local md = markdown()
+ md:add('md', lang.script('COMPLETION_IMPORT_FROM', ('[%s](%s)'):format(
+ workspace.getRelativePath(uri),
+ uri
+ )))
+ md:add('md', buildDesc(newSource))
+ return {
+ detail = buildDetail(newSource),
+ description = md,
+ --additionalTextEdits = buildInsertRequire(state, originUri, stemName),
+ }
+ end)
+ }
+ end
+ ::INNER_CONTINUE::
end
::CONTINUE::
end
diff --git a/test/crossfile/completion.lua b/test/crossfile/completion.lua
index 24a5f6c9..8504758e 100644
--- a/test/crossfile/completion.lua
+++ b/test/crossfile/completion.lua
@@ -108,6 +108,18 @@ function TEST(data)
assert(eq(expect, result))
end
+local function WITH_CONFIG(cfg, f)
+ local prev = { }
+ for k, v in pairs(cfg) do
+ prev[k] = config.get(nil, k)
+ config.set(nil, k, v)
+ end
+ f()
+ for k, v in pairs(prev) do
+ config.set(nil, k, v)
+ end
+end
+
TEST {
{
path = 'abc.lua',
@@ -951,3 +963,74 @@ TEST {
},
completion = EXISTS
}
+
+-- Find obscured modules
+
+WITH_CONFIG({
+ ["Lua.runtime.pathStrict"] = true,
+ ["Lua.runtime.path"] = {
+ "?/init.lua",
+ "sub/?/init.lua",
+ "obscure_path/?/?/init.lua"
+ },
+}, function()
+ TEST {
+ { path = 'myLib/init.lua', content = 'return {}' },
+ {
+ path = 'main.lua',
+ main = true,
+ content = [[
+ myLib<??>
+ ]],
+ },
+ completion = EXISTS
+ }
+
+ TEST {
+ { path = 'sub/myLib/init.lua', content = 'return {}' },
+ {
+ path = 'main.lua',
+ main = true,
+ content = [[
+ myLib<??>
+ ]],
+ },
+ completion = EXISTS
+ }
+
+ TEST {
+ { path = 'sub/myLib/sublib/init.lua', content = 'return {}' },
+ {
+ path = 'main.lua',
+ main = true,
+ content = [[
+ sublib<??>
+ ]],
+ },
+ completion = EXISTS
+ }
+
+ TEST {
+ { path = 'sublib/init.lua', content = 'return {}' },
+ {
+ path = 'main.lua',
+ main = true,
+ content = [[
+ sublib<??>
+ ]],
+ },
+ completion = EXISTS
+ }
+
+ TEST {
+ { path = 'obscure_path/myLib/obscure/myLib/obscure/init.lua', content = 'return {}' },
+ {
+ path = 'main.lua',
+ main = true,
+ content = [[
+ obscure<??>
+ ]],
+ },
+ completion = EXISTS
+ }
+end)