summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-07-07 21:13:58 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-07-07 21:13:58 +0800
commit4c71c56f925246618cce854ab9773311a7812055 (patch)
tree45721d5321668cf5b749caab322a84b414e587fb /script
parentd50a75aac341d6b87caadb3eb9b863cb8ebe2751 (diff)
downloadlua-language-server-4c71c56f925246618cce854ab9773311a7812055.zip
support change workspace folders
TODO: has memory leak after remove folders
Diffstat (limited to 'script')
-rw-r--r--script/library.lua9
-rw-r--r--script/plugin.lua13
-rw-r--r--script/provider/provider.lua24
-rw-r--r--script/workspace/scope.lua22
-rw-r--r--script/workspace/workspace.lua26
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')