summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-06-24 16:58:49 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-06-24 16:58:49 +0800
commit0e3c22455e4398541471351291522b200417e31c (patch)
treebe27dee3e173adecaeaf04be307d1e4558f8a887
parentcc97259ed0d37d964e16bc37c0be3e9e982e719f (diff)
downloadlua-language-server-0e3c22455e4398541471351291522b200417e31c.zip
实现library
-rw-r--r--package.json5
-rw-r--r--package.nls.json2
-rw-r--r--package.nls.zh-cn.json2
-rw-r--r--server/src/async/scanfiles.lua9
-rw-r--r--server/src/files/files.lua12
-rw-r--r--server/src/service.lua54
-rw-r--r--server/src/workspace.lua27
-rw-r--r--server/test/build_package.lua4
8 files changed, 95 insertions, 20 deletions
diff --git a/package.json b/package.json
index bd9ac8aa..66bdf5e3 100644
--- a/package.json
+++ b/package.json
@@ -248,6 +248,11 @@
"scope": "resource",
"type": "boolean"
},
+ "Lua.workspace.library": {
+ "markdownDescription": "%config.workspace.library%",
+ "scope": "resource",
+ "type": "object"
+ },
"Lua.workspace.maxPreload": {
"default": 300,
"markdownDescription": "%config.workspace.maxPreload%",
diff --git a/package.nls.json b/package.nls.json
index 2fc65bcf..81fe0500 100644
--- a/package.nls.json
+++ b/package.nls.json
@@ -6,7 +6,7 @@
"config.runtime.version": "Lua runtime version.",
"config.workspace.ignoreDir": "Ignored directories (Use `.gitignore` grammar).\n```json\n\"Lua.workspace.ignoreDir\" : [\n \"temp/*.*\",\n \"!temp/*.lua\"\n]\n```\n",
"config.workspace.ignoreSubmodules": "Ignore submodules.",
- "config.workspace.library": "加载的外部函数库。\n下面这个例子表示加载`C:/lua`中的所有文件,以及加载`../lib`中的`.txt`与`.lua`文件,但不加载`../lib/temp`中的`.txt`文件。加载的文件最终会受文件关联的影响,因此需要设置`.txt`文件关联`lua`后`*.txt`才有意义。\n```json\n\"Lua.workspace.library\": {\n \"C:/lua\": true,\n \"../lib\": [\n \"*.txt\",\n \"*.lua\",\n \"!/temp/**/*.txt\"\n ]\n}\n```\n",
+ "config.workspace.library": "加载的外部函数库。\n下面这个例子表示加载`C:/lua`中的所有文件,以及加载`../lib`中的`.txt`与`.lua`文件,但不加载`../lib/temp`中的`.txt`文件。\n```json\n\"Lua.workspace.library\": {\n \"C:/lua\": true,\n \"../lib\": [\n \"*.txt\",\n \"*.lua\",\n \"!/temp/**/*.txt\"\n ]\n}\n```\n",
"config.workspace.maxPreload": "Max preloaded files.",
"config.workspace.preloadFileSize": "Skip files larger than this value (KB) when preloading.",
"config.workspace.useGitIgnore": "Ignore files list in `.gitignore` ."
diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json
index 9d45d90e..5f276bc5 100644
--- a/package.nls.zh-cn.json
+++ b/package.nls.zh-cn.json
@@ -6,7 +6,7 @@
"config.runtime.version": "Lua运行版本。",
"config.workspace.ignoreDir": "忽略的目录(使用 `.gitignore` 语法)。\n```json\n\"Lua.workspace.ignoreDir\" : [\n \"temp/*.*\",\n \"!temp/*.lua\"\n]\n```\n",
"config.workspace.ignoreSubmodules": "忽略子模块。",
- "config.workspace.library": "加载的外部函数库。\n下面这个例子表示加载`C:/lua`中的所有文件,以及加载`../lib`中的`.txt`与`.lua`文件,但不加载`../lib/temp`中的`.txt`文件。加载的文件最终会受文件关联的影响,因此需要设置`.txt`文件关联`lua`后`*.txt`才有意义。\n```json\n\"Lua.workspace.library\": {\n \"C:/lua\": true,\n \"../lib\": [\n \"*.txt\",\n \"*.lua\",\n \"!/temp/**/*.txt\"\n ]\n}\n```\n",
+ "config.workspace.library": "加载外部函数库。\n该功能可以加载外部的Lua文件,用于函数定义、自动完成等功能。注意,语言服务不会监视外部文件的变化,如果修改了外部文件需要重启。\n下面这个例子表示加载`C:/lua`中的所有文件,以及加载`../lib`中的`.txt`与`.lua`文件,但不加载`../lib/temp`中的`.txt`文件。\n```json\n\"Lua.workspace.library\": {\n \"C:/lua\": true,\n \"../lib\": [\n \"*.txt\",\n \"*.lua\",\n \"!/temp/**/*.txt\"\n ]\n}\n```\n",
"config.workspace.maxPreload": "最大预加载文件数。",
"config.workspace.preloadFileSize": "预加载时跳过大小大于该值(KB)的文件。",
"config.workspace.useGitIgnore": "忽略 `.gitignore` 中列举的文件。"
diff --git a/server/src/async/scanfiles.lua b/server/src/async/scanfiles.lua
index 090e866f..7a08a86f 100644
--- a/server/src/async/scanfiles.lua
+++ b/server/src/async/scanfiles.lua
@@ -8,7 +8,14 @@ local function scan(mode, root, pattern, options)
OUT:push('log', 'Scanning:', root:string())
OUT:push('log', 'Scan pattern:', table.dump(pattern))
OUT:push('log', 'Scan options:', table.dump(options))
- local session = glob.gitignore(pattern, options)
+ local session
+ if mode == 'workspace' then
+ session = glob.gitignore(pattern, options)
+ elseif mode == 'library' then
+ session = glob.glob(pattern, options)
+ else
+ return
+ end
session:setInterface('type', function (path)
local fullpath = root / path
if not fs.exists(fullpath) then
diff --git a/server/src/files/files.lua b/server/src/files/files.lua
index 4d420739..e271e501 100644
--- a/server/src/files/files.lua
+++ b/server/src/files/files.lua
@@ -50,6 +50,17 @@ function mt:isOpen(uri)
end
---@param uri uri
+function mt:setLibrary(uri)
+ self._library[uri] = true
+end
+
+---@param uri uri
+---@return uri
+function mt:isLibrary(uri)
+ return self._library[uri] == true
+end
+
+---@param uri uri
function mt:isDead(uri)
local f = self._files[uri]
if not f then
@@ -89,6 +100,7 @@ return function ()
local self = setmetatable({
_files = {},
_open = {},
+ _library = {},
}, mt)
return self
end
diff --git a/server/src/service.lua b/server/src/service.lua
index d2232086..3dfcb5a5 100644
--- a/server/src/service.lua
+++ b/server/src/service.lua
@@ -211,6 +211,9 @@ end
---@param uri uri
function mt:close(uri)
self._files:close(uri)
+ if self._files:isLibrary(uri) then
+ return
+ end
if not self:isLua(uri) or self:isIgnored(uri) then
self:removeText(uri)
end
@@ -224,24 +227,16 @@ end
---@param uri uri
---@param path path
----@param buf string
----@param compiled table
-function mt:readText(uri, path, buf, compiled)
- if self._files:get(uri) then
- return
- end
- if not self:isLua(uri) or self:isIgnored(uri) then
- return
- end
- local text = buf or io.load(path)
+---@param text string
+function mt:checkReadFile(uri, path, text)
if not text then
log.debug('No file: ', path)
- return
+ return false
end
local size = #text / 1000.0
if size > config.config.workspace.preloadFileSize then
log.info(('Skip large file, size: %.3f KB: %s'):format(size, uri))
- return
+ return false
end
if self:getCachedFileCount() >= config.config.workspace.maxPreload then
if not self._hasShowHitMaxPreload then
@@ -251,6 +246,24 @@ function mt:readText(uri, path, buf, compiled)
message = lang.script('MWS_MAX_PRELOAD', config.config.workspace.maxPreload),
})
end
+ return false
+ end
+ return true
+end
+
+---@param uri uri
+---@param path path
+---@param buf string
+---@param compiled table
+function mt:readText(uri, path, buf, compiled)
+ if self._files:get(uri) then
+ return
+ end
+ if not self:isLua(uri) or self:isIgnored(uri) then
+ return
+ end
+ local text = buf or io.load(path)
+ if not self:checkReadFile(uri, path, text) then
return
end
self._files:save(uri, text, 0)
@@ -258,6 +271,19 @@ function mt:readText(uri, path, buf, compiled)
end
---@param uri uri
+---@param path path
+---@param buf string
+---@param compiled table
+function mt:readLibrary(uri, path, buf, compiled)
+ if not self:checkReadFile(uri, path, buf) then
+ return
+ end
+ self._files:save(uri, buf, 0)
+ self._files:setLibrary(uri)
+ self:needCompile(uri, compiled)
+end
+
+---@param uri uri
function mt:removeText(uri)
self._files:remove(uri)
self:compileVM(uri)
@@ -515,7 +541,9 @@ function mt:doDiagnostics(uri)
if not file
or file:isRemoved()
or not file:getVM()
- or file:getVM():isRemoved() then
+ or file:getVM():isRemoved()
+ or self._files:isLibrary(uri)
+ then
self._needDiagnostics[uri] = nil
self:clearDiagnostics(uri)
return
diff --git a/server/src/workspace.lua b/server/src/workspace.lua
index 0933509c..8865a1fb 100644
--- a/server/src/workspace.lua
+++ b/server/src/workspace.lua
@@ -59,7 +59,11 @@ function mt:listenLoadFile()
local name = getFileName(path)
local uri = uric.encode(path)
self.files[name] = uri
- self.lsp:readText(uri, path, buf, self._currentScanCompiled)
+ if mode == 'workspace' then
+ self.lsp:readText(uri, path, buf, self._currentScanCompiled)
+ elseif mode == 'library' then
+ self.lsp:readLibrary(uri, path, buf, self._currentScanCompiled)
+ end
end)
end
@@ -103,6 +107,20 @@ function mt:buildScanPattern()
return pattern
end
+---@param options table
+function mt:buildLibraryRequests(options)
+ local requests = {}
+ for path, pattern in pairs(config.config.workspace.library) do
+ requests[#requests+1] = {
+ mode = 'library',
+ root = fs.absolute(fs.path(path)):string(),
+ pattern = pattern == true and '*' or pattern,
+ options = options,
+ }
+ end
+ return table.unpack(requests)
+end
+
function mt:scanFiles()
if self._scanRequest then
log.info('Break scan.')
@@ -126,7 +144,8 @@ function mt:scanFiles()
root = self.root:string(),
pattern = pattern,
options = options,
- }
+ },
+ self:buildLibraryRequests(options),
}, function (mode, ...)
if mode == 'ok' then
log.info('Scan finish, got', count, 'files.')
@@ -143,6 +162,10 @@ function mt:scanFiles()
end
self._loadFileRequest:push(path:string(), 'workspace')
count = count + 1
+ elseif mode == 'library' then
+ local path = fs.path(...)
+ self._loadFileRequest:push(path:string(), 'library')
+ count = count + 1
elseif mode == 'stop' then
log.info('Scan stoped.')
return false
diff --git a/server/test/build_package.lua b/server/test/build_package.lua
index 44375e6f..2c0dc5d0 100644
--- a/server/test/build_package.lua
+++ b/server/test/build_package.lua
@@ -215,7 +215,7 @@ io.save(ROOT:parent_path() / 'package.nls.json', json.encode {
["config.workspace.preloadFileSize"] = "Skip files larger than this value (KB) when preloading.",
["config.workspace.library"] = [[
加载的外部函数库。
-下面这个例子表示加载`C:/lua`中的所有文件,以及加载`../lib`中的`.txt`与`.lua`文件,但不加载`../lib/temp`中的`.txt`文件。加载的文件最终会受文件关联的影响,因此需要设置`.txt`文件关联`lua`后`*.txt`才有意义。
+下面这个例子表示加载`C:/lua`中的所有文件,以及加载`../lib`中的`.txt`与`.lua`文件,但不加载`../lib/temp`中的`.txt`文件。
]] .. example.library,
})
@@ -233,6 +233,6 @@ io.save(ROOT:parent_path() / 'package.nls.zh-cn.json', json.encode {
["config.workspace.library"] = [[
加载外部函数库。
该功能可以加载外部的Lua文件,用于函数定义、自动完成等功能。注意,语言服务不会监视外部文件的变化,如果修改了外部文件需要重启。
-下面这个例子表示加载`C:/lua`中的所有文件,以及加载`../lib`中的`.txt`与`.lua`文件,但不加载`../lib/temp`中的`.txt`文件。加载的文件最终会受文件关联的影响,因此需要设置`.txt`文件关联`lua`后`*.txt`才有意义。
+下面这个例子表示加载`C:/lua`中的所有文件,以及加载`../lib`中的`.txt`与`.lua`文件,但不加载`../lib/temp`中的`.txt`文件。
]] .. example.library,
})