summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-08-18 19:55:04 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-08-18 19:55:04 +0800
commit38d46faae20bbdbc3578452f020276766aed67e0 (patch)
tree6ff276e89459b4d7098a5d1e50789a82ab2c6449 /script
parent1d0dc164b84fffdfe281615013278013baf9aae7 (diff)
downloadlua-language-server-38d46faae20bbdbc3578452f020276766aed67e0.zip
watching library changes
Diffstat (limited to 'script')
-rw-r--r--script/filewatch.lua78
-rw-r--r--script/provider/provider.lua63
-rw-r--r--script/service/service.lua4
-rw-r--r--script/workspace/workspace.lua56
4 files changed, 140 insertions, 61 deletions
diff --git a/script/filewatch.lua b/script/filewatch.lua
new file mode 100644
index 00000000..fd3b8686
--- /dev/null
+++ b/script/filewatch.lua
@@ -0,0 +1,78 @@
+local fw = require 'bee.filewatch'
+local fs = require 'bee.filesystem'
+local await = require 'await'
+
+local MODIFY = 1 << 0
+local RENAME = 1 << 1
+
+---@class filewatch
+local m = {}
+
+m._eventList = {}
+
+function m.watch(path)
+ local id = fw.add(path)
+ return function ()
+ fw.remove(id)
+ end
+end
+
+function m.event(callback)
+ m._eventList[#m._eventList+1] = callback
+end
+
+function m._callEvent(changes)
+ for _, callback in ipairs(m._eventList) do
+ await.call(function ()
+ callback(changes)
+ end)
+ end
+end
+
+function m.update()
+ local collect
+ while true do
+ local ev, path = fw.select()
+ if not ev then
+ break
+ end
+ if not collect then
+ collect = {}
+ end
+ if ev == 'modify' then
+ collect[path] = (collect[path] or 0) | MODIFY
+ elseif ev == 'rename' then
+ collect[path] = (collect[path] or 0) | RENAME
+ end
+ end
+
+ if not collect or not next(collect) then
+ return
+ end
+
+ local changes = {}
+ for path, flag in pairs(collect) do
+ if flag & RENAME ~= 0 then
+ if fs.exists(fs.path(path)) then
+ changes[#changes+1] = {
+ type = 'create',
+ path = path,
+ }
+ else
+ changes[#changes+1] = {
+ type = 'delete',
+ path = path,
+ }
+ end
+ elseif flag & MODIFY ~= 0 then
+ changes[#changes+1] = {
+ type = 'change',
+ path = path,
+ }
+ end
+ end
+
+ m._callEvent(changes)
+end
+
+return m
diff --git a/script/provider/provider.lua b/script/provider/provider.lua
index 477a342c..c416e748 100644
--- a/script/provider/provider.lua
+++ b/script/provider/provider.lua
@@ -35,17 +35,6 @@ local function updateConfig()
log.debug('loaded config dump:', util.dump(new))
end
-local function isValidLuaUri(uri)
- if not files.isLua(uri) then
- return false
- end
- if workspace.isIgnored(uri)
- and not files.isLibrary(uri) then
- return false
- end
- return true
-end
-
proto.on('initialize', function (params)
client.init(params)
config.init()
@@ -64,12 +53,6 @@ proto.on('initialized', function (params)
updateConfig()
local registrations = {}
- if client.getAbility 'workspace.didChangeWatchedFiles.dynamicRegistration'
- and workspace.path then
- -- 监视文件变化
- client.watchFiles(workspace.path)
- end
-
if client.getAbility 'workspace.didChangeConfiguration.dynamicRegistration' then
-- 监视配置变化
registrations[#registrations+1] = {
@@ -105,50 +88,10 @@ proto.on('workspace/didChangeConfiguration', function ()
updateConfig()
end)
-proto.on('workspace/didChangeWatchedFiles', function (params)
- workspace.awaitReady()
- for _, change in ipairs(params.changes) do
- local uri = change.uri
- if not workspace.isWorkspaceUri(uri)
- and not files.isLibrary(uri) then
- goto CONTINUE
- end
- if change.type == define.FileChangeType.Created then
- log.debug('FileChangeType.Created', uri)
- workspace.awaitLoadFile(uri)
- elseif change.type == define.FileChangeType.Deleted then
- log.debug('FileChangeType.Deleted', uri)
- files.remove(uri)
- local childs = files.getChildFiles(uri)
- for _, curi in ipairs(childs) do
- log.debug('FileChangeType.Deleted.Child', curi)
- files.remove(curi)
- end
- elseif change.type == define.FileChangeType.Changed then
- if isValidLuaUri(uri) then
- -- 如果文件处于关闭状态,则立即更新;否则等待didChange协议来更新
- if not files.isOpen(uri) then
- files.setText(uri, pub.awaitTask('loadFile', uri), false)
- end
- else
- local path = furi.decode(uri)
- local filename = fs.path(path):filename():string()
- -- 排除类文件发生更改需要重新扫描
- if filename == '.gitignore'
- or filename == '.gitmodules' then
- workspace.reload()
- break
- end
- end
- end
- ::CONTINUE::
- end
-end)
-
proto.on('workspace/didCreateFiles', function (params)
log.debug('workspace/didCreateFiles', util.dump(params))
for _, file in ipairs(params.files) do
- if isValidLuaUri(file.uri) then
+ if workspace.isValidLuaUri(file.uri) then
files.setText(file.uri, pub.awaitTask('loadFile', file.uri), false)
end
end
@@ -172,7 +115,7 @@ proto.on('workspace/didRenameFiles', function (params)
local text = files.getOriginText(file.oldUri)
if text then
files.remove(file.oldUri)
- if isValidLuaUri(file.newUri) then
+ if workspace.isValidLuaUri(file.newUri) then
files.setText(file.newUri, text, false)
end
end
@@ -185,7 +128,7 @@ proto.on('workspace/didRenameFiles', function (params)
local nuri = file.newUri .. tail
log.debug('workspace/didRenameFiles#child', ouri, nuri)
files.remove(uri)
- if isValidLuaUri(nuri) then
+ if workspace.isValidLuaUri(nuri) then
files.setText(nuri, text, false)
end
end
diff --git a/script/service/service.lua b/script/service/service.lua
index ed83a27a..973b5745 100644
--- a/script/service/service.lua
+++ b/script/service/service.lua
@@ -10,6 +10,7 @@ local files = require 'files'
local lang = require 'language'
local ws = require 'workspace'
local time = require 'bee.time'
+local fw = require 'filewatch'
local m = {}
m.type = 'service'
@@ -174,6 +175,9 @@ function m.pulse()
timer.loop(0.1, function ()
m.reportStatus()
end)
+ timer.loop(1, function ()
+ fw.update()
+ end)
end
function m.reportStatus()
diff --git a/script/workspace/workspace.lua b/script/workspace/workspace.lua
index ebd1b842..f7b2e97b 100644
--- a/script/workspace/workspace.lua
+++ b/script/workspace/workspace.lua
@@ -14,6 +14,7 @@ local define = require "proto.define"
local client = require 'client'
local plugin = require 'plugin'
local util = require 'utility'
+local fw = require 'filewatch'
local m = {}
m.type = 'workspace'
@@ -41,6 +42,8 @@ function m.initPath(uri)
client.logMessage('Log', 'Log path: ' .. furi.encode(logPath:string()))
log.info('Log path: ', logPath)
log.init(ROOT, logPath)
+
+ fw.watch(m.path)
end
local globInteferFace = {
@@ -183,6 +186,17 @@ function m.isIgnored(uri)
return ignore(path)
end
+function m.isValidLuaUri(uri)
+ if not files.isLua(uri) then
+ return false
+ end
+ if m.isIgnored(uri)
+ and not files.isLibrary(uri) then
+ return false
+ end
+ return true
+end
+
local function loadFileFactory(root, progressData, isLibrary)
return function (path)
local uri = furi.encode(path)
@@ -325,7 +339,7 @@ function m.awaitPreload()
local libraryLoader = loadFileFactory(library.path, progressData, true)
log.info('Scan library at:', library.path)
library.matcher:scan(library.path, libraryLoader)
- m.watchers[#m.watchers+1] = client.watchFiles(library.path)
+ m.watchers[#m.watchers+1] = fw.watch(library.path)
end
local isLoadingFiles = false
@@ -596,4 +610,44 @@ config.watch(function (key, value, oldValue)
end
end)
+fw.event(function (changes)
+ m.awaitReady()
+ for _, change in ipairs(changes) do
+ local path = change.path
+ local uri = furi.encode(path)
+ if not m.isWorkspaceUri(uri)
+ and not files.isLibrary(uri) then
+ goto CONTINUE
+ end
+ if change.type == 'create' then
+ log.debug('FileChangeType.Created', uri)
+ m.awaitLoadFile(uri)
+ elseif change.type == 'delete' then
+ log.debug('FileChangeType.Deleted', uri)
+ files.remove(uri)
+ local childs = files.getChildFiles(uri)
+ for _, curi in ipairs(childs) do
+ log.debug('FileChangeType.Deleted.Child', curi)
+ files.remove(curi)
+ end
+ elseif change.type == 'change' then
+ if m.isValidLuaUri(uri) then
+ -- 如果文件处于关闭状态,则立即更新;否则等待didChange协议来更新
+ if not files.isOpen(uri) then
+ files.setText(uri, pub.awaitTask('loadFile', uri), false)
+ end
+ else
+ local filename = fs.path(path):filename():string()
+ -- 排除类文件发生更改需要重新扫描
+ if filename == '.gitignore'
+ or filename == '.gitmodules' then
+ m.reload()
+ break
+ end
+ end
+ end
+ ::CONTINUE::
+ end
+end)
+
return m