summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2020-09-13 19:23:09 +0800
committer最萌小汐 <sumneko@hotmail.com>2020-09-13 19:23:09 +0800
commitb22099c12e001bf81a6d1cf47655e6e815d04391 (patch)
tree79be562401816f70c831003ab6f7216b4c21350e
parent2dacca7b19ba0162975c7f2da2dd5e9381b4a73c (diff)
downloadlua-language-server-b22099c12e001bf81a6d1cf47655e6e815d04391.zip
支持自动完成 dofile
-rw-r--r--script-beta/core/completion.lua24
-rw-r--r--script-beta/core/definition.lua4
-rw-r--r--script-beta/core/hover/description.lua4
-rw-r--r--script-beta/vm/getLinks.lua2
-rw-r--r--script-beta/vm/guideInterface.lua4
-rw-r--r--script-beta/workspace/workspace.lua43
-rw-r--r--test-beta/crossfile/completion.lua21
7 files changed, 72 insertions, 30 deletions
diff --git a/script-beta/core/completion.lua b/script-beta/core/completion.lua
index ec4b0fe6..2e32f515 100644
--- a/script-beta/core/completion.lua
+++ b/script-beta/core/completion.lua
@@ -512,7 +512,29 @@ local function checkUri(ast, text, offset, results)
end
elseif lib.name == 'dofile'
or lib.name == 'loadfile' then
- return workspace.findUrisByFilePath(literal, false)
+ for uri in files.eachFile() do
+ uri = files.getOriginUri(uri)
+ if files.eq(myUri, uri) then
+ goto CONTINUE
+ end
+ local path = workspace.getRelativePath(uri)
+ if matchKey(literal, path) then
+ if not collect[path] then
+ collect[path] = {
+ textEdit = {
+ start = source.start + #source[2],
+ finish = source.finish - #source[2],
+ }
+ }
+ end
+ -- TODO 翻译
+ collect[path][#collect[path]+1] = ([=[[%s](%s)]=]):format(
+ path,
+ uri
+ )
+ end
+ ::CONTINUE::
+ end
end
end)
for label, infos in util.sortPairs(collect) do
diff --git a/script-beta/core/definition.lua b/script-beta/core/definition.lua
index 8e76bfab..8c308aaf 100644
--- a/script-beta/core/definition.lua
+++ b/script-beta/core/definition.lua
@@ -64,10 +64,10 @@ local function checkRequire(source, offset)
return nil
end
if lib.name == 'require' then
- return workspace.findUrisByRequirePath(literal, true)
+ return workspace.findUrisByRequirePath(literal)
elseif lib.name == 'dofile'
or lib.name == 'loadfile' then
- return workspace.findUrisByFilePath(literal, true)
+ return workspace.findUrisByFilePath(literal)
end
return nil
end
diff --git a/script-beta/core/hover/description.lua b/script-beta/core/hover/description.lua
index 277ea9c8..9a0bd83a 100644
--- a/script-beta/core/hover/description.lua
+++ b/script-beta/core/hover/description.lua
@@ -19,10 +19,10 @@ local function asString(source)
return
end
if lib.name == 'require' then
- result = ws.findUrisByRequirePath(literal, true)
+ result = ws.findUrisByRequirePath(literal)
elseif lib.name == 'dofile'
or lib.name == 'loadfile' then
- result = ws.findUrisByFilePath(literal, true)
+ result = ws.findUrisByFilePath(literal)
end
if result and #result > 0 then
for i, uri in ipairs(result) do
diff --git a/script-beta/vm/getLinks.lua b/script-beta/vm/getLinks.lua
index cc1ed190..0bb1c6ff 100644
--- a/script-beta/vm/getLinks.lua
+++ b/script-beta/vm/getLinks.lua
@@ -18,7 +18,7 @@ local function getFileLinks(uri)
if not args[1] or args[1].type ~= 'string' then
return
end
- local uris = ws.findUrisByRequirePath(args[1][1], true)
+ local uris = ws.findUrisByRequirePath(args[1][1])
for _, u in ipairs(uris) do
u = files.asKey(u)
if not links[u] then
diff --git a/script-beta/vm/guideInterface.lua b/script-beta/vm/guideInterface.lua
index c8658b42..c85194d8 100644
--- a/script-beta/vm/guideInterface.lua
+++ b/script-beta/vm/guideInterface.lua
@@ -27,7 +27,7 @@ function m.require(args, index)
end
local results = {}
local myUri = guide.getUri(args[1])
- local uris = ws.findUrisByRequirePath(reqName, true)
+ local uris = ws.findUrisByRequirePath(reqName)
for _, uri in ipairs(uris) do
if not files.eq(myUri, uri) then
local ast = files.getAst(uri)
@@ -50,7 +50,7 @@ function m.dofile(args, index)
end
local results = {}
local myUri = guide.getUri(args[1])
- local uris = ws.findUrisByFilePath(reqName, true)
+ local uris = ws.findUrisByFilePath(reqName)
for _, uri in ipairs(uris) do
if not files.eq(myUri, uri) then
local ast = files.getAst(uri)
diff --git a/script-beta/workspace/workspace.lua b/script-beta/workspace/workspace.lua
index f92d8308..f837fe91 100644
--- a/script-beta/workspace/workspace.lua
+++ b/script-beta/workspace/workspace.lua
@@ -22,7 +22,7 @@ m.requireCache = {}
function m.init(name, uri)
m.name = name
m.uri = uri
- m.path = furi.decode(uri)
+ m.path = m.normalize(furi.decode(uri))
log.info('Workspace inited: ', uri)
local logPath = ROOT / 'log' / (uri:gsub('[/:]+', '_') .. '.log')
log.info('Log path: ', logPath)
@@ -145,26 +145,16 @@ end
--- 查找符合指定file path的所有uri
---@param path string
----@param whole boolean
-function m.findUrisByFilePath(path, whole)
+function m.findUrisByFilePath(path)
local results = {}
for uri in files.eachFile() do
local pathLen = #path
local uriLen = #uri
- if whole then
- local seg = uri:sub(uriLen - pathLen, uriLen - pathLen)
- if seg == '/' or seg == '\\' or seg == '' then
- local see = uri:sub(uriLen - pathLen + 1, uriLen)
- if files.eq(see, path) then
- results[#results+1] = uri
- end
- end
- else
- for i = uriLen, uriLen - pathLen + 1, -1 do
- local see = uri:sub(i - pathLen + 1, i)
- if files.eq(see, path) then
- results[#results+1] = uri
- end
+ local seg = uri:sub(uriLen - pathLen, uriLen - pathLen)
+ if seg == '/' or seg == '\\' or seg == '' then
+ local see = uri:sub(uriLen - pathLen + 1, uriLen)
+ if files.eq(see, path) then
+ results[#results+1] = uri
end
end
end
@@ -174,14 +164,14 @@ end
--- 查找符合指定require path的所有uri
---@param path string
---@param whole boolean
-function m.findUrisByRequirePath(path, whole)
+function m.findUrisByRequirePath(path)
local results = {}
local mark = {}
local input = path:gsub('%.', '/')
:gsub('%%', '%%%%')
for _, luapath in ipairs(config.config.runtime.path) do
local part = luapath:gsub('%?', input)
- local uris = m.findUrisByFilePath(part, whole)
+ local uris = m.findUrisByFilePath(part)
for _, uri in ipairs(uris) do
if not mark[uri] then
mark[uri] = true
@@ -192,13 +182,22 @@ function m.findUrisByRequirePath(path, whole)
return results
end
+function m.normalize(path)
+ if platform.OS == 'Windows' then
+ path = path:gsub('[/\\]+', '\\')
+ else
+ path = path:gsub('[/\\]+', '/')
+ end
+ return path:gsub('^[/\\]+', '')
+end
+
function m.getRelativePath(uri)
local path = furi.decode(uri)
- local _, pos = path:lower():find(m.path:lower(), 1, true)
+ local _, pos = m.normalize(path):lower():find(m.path:lower(), 1, true)
if pos then
- return path:sub(pos + 1):gsub('^[/\\]+', '')
+ return m.normalize(path:sub(pos + 1))
else
- return path:gsub('^[/\\]+', '')
+ return m.normalize(path)
end
end
diff --git a/test-beta/crossfile/completion.lua b/test-beta/crossfile/completion.lua
index 6801abb7..0e344a5b 100644
--- a/test-beta/crossfile/completion.lua
+++ b/test-beta/crossfile/completion.lua
@@ -521,3 +521,24 @@ TEST {
},
}
}
+
+TEST {
+ {
+ path = [[abc/init.lua]],
+ content = ''
+ },
+ {
+ path = 'main.lua',
+ content = [[
+ dofile 'ab$'
+ ]],
+ main = true,
+ },
+ completion = {
+ {
+ label = [[abc\init.lua]],
+ kind = CompletionItemKind.Reference,
+ textEdit = EXISTS,
+ },
+ }
+}