diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-07-07 21:13:58 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-07-07 21:13:58 +0800 |
commit | 4c71c56f925246618cce854ab9773311a7812055 (patch) | |
tree | 45721d5321668cf5b749caab322a84b414e587fb /script | |
parent | d50a75aac341d6b87caadb3eb9b863cb8ebe2751 (diff) | |
download | lua-language-server-4c71c56f925246618cce854ab9773311a7812055.zip |
support change workspace folders
TODO: has memory leak after remove folders
Diffstat (limited to 'script')
-rw-r--r-- | script/library.lua | 9 | ||||
-rw-r--r-- | script/plugin.lua | 13 | ||||
-rw-r--r-- | script/provider/provider.lua | 24 | ||||
-rw-r--r-- | script/workspace/scope.lua | 22 | ||||
-rw-r--r-- | script/workspace/workspace.lua | 26 |
5 files changed, 81 insertions, 13 deletions
diff --git a/script/library.lua b/script/library.lua index ded12a27..9457b74b 100644 --- a/script/library.lua +++ b/script/library.lua @@ -542,11 +542,10 @@ files.watch(function (ev, uri) end end) -function m.init() - initBuiltIn(nil) - for _, scp in ipairs(ws.folders) do - initBuiltIn(scp.uri) +ws.watch(function (ev, uri) + if ev == 'startReload' then + initBuiltIn(uri) end -end +end) return m diff --git a/script/plugin.lua b/script/plugin.lua index 145abe74..bdd02ea8 100644 --- a/script/plugin.lua +++ b/script/plugin.lua @@ -4,6 +4,7 @@ local client = require 'client' local lang = require 'language' local await = require 'await' local scope = require 'workspace.scope' +local ws = require 'workspace' ---@class plugin local m = {} @@ -69,10 +70,10 @@ local function checkTrustLoad(scp) return true end ----@param scp scope -function m.init(scp) +---@param uri uri +local function initPlugin(uri) await.call(function () ---@async - local ws = require 'workspace' + local scp = scope.getScope(uri) local interface = {} scp:set('pluginInterface', interface) @@ -108,4 +109,10 @@ function m.init(scp) end) end +ws.watch(function (ev, uri) + if ev == 'startReload' then + initPlugin(uri) + end +end) + return m diff --git a/script/provider/provider.lua b/script/provider/provider.lua index f10fb66e..dbeb9804 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -149,7 +149,6 @@ m.register 'initialized'{ }) end client.setReady() - library.init() workspace.init() return true end @@ -234,6 +233,29 @@ m.register 'workspace/didRenameFiles' { end } +m.register 'workspace/didChangeWorkspaceFolders' { + capability = { + workspace = { + workspaceFolders = { + supported = true, + changeNotifications = true, + }, + }, + }, + ---@async + function (params) + log.debug('workspace/didChangeWorkspaceFolders', inspect(params)) + for _, folder in ipairs(params.event.added) do + workspace.create(folder.uri) + updateConfig() + workspace.reload(scope.getScope(folder.uri)) + end + for _, folder in ipairs(params.event.removed) do + workspace.remove(folder.uri) + end + end +} + m.register 'textDocument/didOpen' { function (params) local doc = params.textDocument diff --git a/script/workspace/scope.lua b/script/workspace/scope.lua index a81d638c..4649d354 100644 --- a/script/workspace/scope.lua +++ b/script/workspace/scope.lua @@ -11,6 +11,7 @@ local m = {} ---@field _links table<uri, boolean> ---@field _data table<string, any> ---@field _gc gc +---@field _removed? true local mt = {} mt.__index = mt @@ -117,9 +118,30 @@ end function mt:flushGC() self._gc:remove() + if self._removed then + return + end self._gc = gc() end +function mt:remove() + if self._removed then + return + end + self._removed = true + for i, scp in ipairs(m.folders) do + if scp == self then + table.remove(m.folders, i) + break + end + end + self:flushGC() +end + +function mt:isRemoved() + return self._removed == true +end + ---@param scopeType scope.type ---@return scope local function createScope(scopeType) diff --git a/script/workspace/workspace.lua b/script/workspace/workspace.lua index 74e16096..6a6c59c7 100644 --- a/script/workspace/workspace.lua +++ b/script/workspace/workspace.lua @@ -7,7 +7,6 @@ local glob = require 'glob' local platform = require 'bee.platform' local await = require 'await' local client = require 'client' -local plugin = require 'plugin' local util = require 'utility' local fw = require 'filewatch' local scope = require 'workspace.scope' @@ -52,12 +51,26 @@ function m.create(uri) client.showMessage('Error', lang.script('WORKSPACE_NOT_ALLOWED', furi.decode(uri))) return end - local path = m.normalize(furi.decode(uri)) - fw.watch(path) local scp = scope.createFolder(uri) m.folders[#m.folders+1] = scp end +function m.remove(uri) + log.info('Workspace remove: ', uri) + for i, scp in ipairs(m.folders) do + if scp.uri == uri then + scp:remove() + table.remove(m.folders, i) + scp:set('ready', false) + scp:set('nativeMatcher', nil) + scp:set('libraryMatcher', nil) + scp:removeAllLinks() + m.flushFiles(scp) + return + end + end +end + function m.reset() ---@type scope[] m.folders = {} @@ -279,6 +292,10 @@ function m.awaitPreload(scp) scp:flushGC() + if scp:isRemoved() then + return + end + local ld <close> = loading.create(scp) scp:set('loading', ld) @@ -301,6 +318,7 @@ function m.awaitPreload(scp) client.showMessage('Warning', lang.script('WORKSPACE_SCAN_TOO_MUCH', count, furi.decode(scp.uri))) end end) + scp:gc(fw.watch(m.normalize(furi.decode(scp.uri)))) end for _, libMatcher in ipairs(librarys) do @@ -465,7 +483,7 @@ function m.awaitReload(scp) scp:set('libraryMatcher', nil) scp:removeAllLinks() m.flushFiles(scp) - plugin.init(scp) + m.onWatch('startReload', scp.uri) m.awaitPreload(scp) scp:set('ready', true) local waiting = scp:get('waitingReady') |