diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2021-08-18 19:55:04 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2021-08-18 19:55:04 +0800 |
commit | 38d46faae20bbdbc3578452f020276766aed67e0 (patch) | |
tree | 6ff276e89459b4d7098a5d1e50789a82ab2c6449 /script | |
parent | 1d0dc164b84fffdfe281615013278013baf9aae7 (diff) | |
download | lua-language-server-38d46faae20bbdbc3578452f020276766aed67e0.zip |
watching library changes
Diffstat (limited to 'script')
-rw-r--r-- | script/filewatch.lua | 78 | ||||
-rw-r--r-- | script/provider/provider.lua | 63 | ||||
-rw-r--r-- | script/service/service.lua | 4 | ||||
-rw-r--r-- | script/workspace/workspace.lua | 56 |
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 |