diff options
-rw-r--r-- | package.json | 5 | ||||
-rw-r--r-- | package.nls.json | 2 | ||||
-rw-r--r-- | package.nls.zh-cn.json | 2 | ||||
-rw-r--r-- | server/src/async/scanfiles.lua | 9 | ||||
-rw-r--r-- | server/src/files/files.lua | 12 | ||||
-rw-r--r-- | server/src/service.lua | 54 | ||||
-rw-r--r-- | server/src/workspace.lua | 27 | ||||
-rw-r--r-- | server/test/build_package.lua | 4 |
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, }) |