summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meta/3rd/example/config.lua18
-rw-r--r--script/await.lua15
-rw-r--r--script/client.lua32
-rw-r--r--script/core/type-formatting.lua3
-rw-r--r--script/files.lua6
-rw-r--r--script/library.lua78
-rw-r--r--script/plugin.lua41
-rw-r--r--script/provider/provider.lua7
-rw-r--r--script/workspace/workspace.lua20
9 files changed, 166 insertions, 54 deletions
diff --git a/meta/3rd/example/config.lua b/meta/3rd/example/config.lua
index 17b6ab06..7bf8e04a 100644
--- a/meta/3rd/example/config.lua
+++ b/meta/3rd/example/config.lua
@@ -5,20 +5,20 @@ files = {'thisIsAnExampleFile%.ifItExistsInWorkSpace%.thenTryLoadThisLibrary'}
-- lsit of settings to be changed
configs = {
{
- name = 'Lua.runtime.version',
- type = 'set',
- value = 'LuaJIT',
+ key = 'Lua.runtime.version',
+ action = 'set',
+ value = 'LuaJIT',
},
{
- name = 'Lua.diagnostics.globals',
- type = 'add',
- value = 'global1',
+ key = 'Lua.diagnostics.globals',
+ action = 'add',
+ value = 'global1',
}
}
for _, name in ipairs {'global2', 'global3', 'global4'} do
configs[#configs+1] = {
- name = 'Lua.diagnostics.globals',
- type = 'add',
- value = name,
+ key = 'Lua.diagnostics.globals',
+ action = 'add',
+ value = name,
}
end
diff --git a/script/await.lua b/script/await.lua
index 6815bc1a..81b44679 100644
--- a/script/await.lua
+++ b/script/await.lua
@@ -10,6 +10,7 @@ m.idMap = {}
m.delayQueue = {}
m.delayQueueIndex = 1
m.watchList = {}
+m.needClose = {}
m._enable = true
--- 设置错误处理器
@@ -161,6 +162,15 @@ function m.delay()
return coroutine.yield()
end
+--- stop then close
+function m.stop()
+ if not coroutine.isyieldable() then
+ return
+ end
+ m.needClose[#m.needClose+1] = coroutine.running()
+ coroutine.yield()
+end
+
local function warnStepTime(passed, waker)
if passed < 1 then
log.warn(('Await step takes [%.3f] sec.'):format(passed))
@@ -180,6 +190,11 @@ end
--- 步进
function m.step()
+ for i = #m.needClose, 1, -1 do
+ coroutine.close(m.needClose[i])
+ m.needClose[i] = nil
+ end
+
local resume = m.delayQueue[m.delayQueueIndex]
if resume then
m.delayQueue[m.delayQueueIndex] = false
diff --git a/script/client.lua b/script/client.lua
index 14973a64..31093fe7 100644
--- a/script/client.lua
+++ b/script/client.lua
@@ -47,8 +47,10 @@ local function packMessage(...)
return table.concat(strs, '\t')
end
+---@alias message.type '"Error"'|'"Warning"'|'"Info"'|'"Log"'
+
---show message to client
----@param type '"Error"'|'"Warning"'|'"Info"'|'"Log"'
+---@param type message.type
function m.showMessage(type, ...)
local message = packMessage(...)
proto.notify('window/showMessage', {
@@ -61,7 +63,33 @@ function m.showMessage(type, ...)
})
end
----@param type '"Error"'|'"Warning"'|'"Info"'|'"Log"'
+---@param type message.type
+---@param message string
+---@param titles string[]
+---@return string action
+function m.awaitRequestMessage(type, message, titles)
+ proto.notify('window/logMessage', {
+ type = define.MessageType[type] or 3,
+ message = message,
+ })
+ local actions = {}
+ for i, title in ipairs(titles) do
+ actions[i] = {
+ title = title,
+ }
+ end
+ local item = proto.awaitRequest('window/showMessageRequest', {
+ type = type,
+ message = message,
+ actions = actions,
+ })
+ if not item then
+ return nil
+ end
+ return item.title
+end
+
+---@param type message.type
function m.logMessage(type, ...)
local message = packMessage(...)
proto.notify('window/logMessage', {
diff --git a/script/core/type-formatting.lua b/script/core/type-formatting.lua
index b01a1999..a225d9d7 100644
--- a/script/core/type-formatting.lua
+++ b/script/core/type-formatting.lua
@@ -15,6 +15,9 @@ end
local function findForward(text, offset, ...)
local pos = text:match('^[ \t]*()', offset)
+ if not pos then
+ return nil
+ end
for _, symbol in ipairs { ... } do
if text:sub(pos, pos + #symbol - 1) == symbol then
return pos, symbol
diff --git a/script/files.lua b/script/files.lua
index c42ed624..1d20a3be 100644
--- a/script/files.lua
+++ b/script/files.lua
@@ -205,7 +205,13 @@ function m.setText(uri, text, isTrust, instance)
end
end)
end
+end
+function m.resetText(uri)
+ local file = m.fileMap[uri]
+ local originText = file.originText
+ file.originText = nil
+ m.setText(uri, originText, file.trusted)
end
function m.setRawText(uri, text)
diff --git a/script/library.lua b/script/library.lua
index 628b3bbe..d4be539e 100644
--- a/script/library.lua
+++ b/script/library.lua
@@ -7,6 +7,7 @@ local lloader = require 'locale-loader'
local fsu = require 'fs-utility'
local define = require "proto.define"
local files = require 'files'
+local await = require 'await'
local m = {}
@@ -246,9 +247,9 @@ local function loadSingle3rdConfig(libraryDir)
cfg.name = libraryDir:filename():string()
- local pluginPath = libraryDir / 'plugin.lua'
- if fs.exists(pluginPath) then
- cfg.plugin = pluginPath:string()
+ local pluginPath = ('${3rd}/%s/plugin.lua'):format('cfg.name')
+ if fs.exists(fs.path(pluginPath)) then
+ cfg.plugin = pluginPath
end
for k, v in pairs(env) do
@@ -273,20 +274,81 @@ local function load3rdConfig()
return configs
end
-local function check3rdByWords(configs)
-
+local function apply3rd(cfg)
+ local changes = {}
+ for _, change in ipairs(cfg.configs) do
+ changes[#changes+1] = change
+ end
+
+ if cfg.plugin then
+ changes[#changes+1] = {
+ key = 'Lua.workspace.library',
+ action = 'set',
+ value = cfg.plugin,
+ }
+ end
+end
+
+local hasAsked
+local function askFor3rd(cfg)
+ hasAsked = true
+ -- TODO: translate
+ local yes = lang.script['启用']
+ local no = lang.script.WINDOW_DONT_SHOW_AGAIN
+ local result = client.awaitRequestMessage('Info'
+ , lang.script('是否需要将你的工作环境配置为 `{}` ?(这会修改你的工作区设置)', cfg.name)
+ , {yes, no}
+ )
+ if not result then
+ return nil
+ end
+ client.setConfig {
+ {
+ key = 'Lua.workspace.checkThirdParty',
+ action = 'set',
+ value = false,
+ },
+ }
+ if result == yes then
+ apply3rd(cfg)
+ end
+end
+
+local function check3rdByWords(text, configs)
+ await.call(function ()
+ for _, cfg in ipairs(configs) do
+ if cfg.words then
+ for _, word in ipairs(cfg.words) do
+ await.delay()
+ if text:match(word) then
+ askFor3rd()
+ return
+ end
+ end
+ end
+ end
+ end)
end
local thirdConfigs
+local hasCheckedUri = {}
local function check3rd(uri)
+ if hasAsked then
+ return
+ end
+ if not config.get 'Lua.workspace.checkThirdParty' then
+ return
+ end
if thirdConfigs == nil then
thirdConfigs = load3rdConfig() or false
end
if not thirdConfigs then
return
end
- if files.isLua(uri) then
- local text = files.getUri(uri)
+ if not hasCheckedUri[uri]
+ and files.isLua(uri) then
+ hasCheckedUri[uri] = true
+ local text = files.getText(uri)
check3rdByWords(text, thirdConfigs)
end
end
@@ -299,7 +361,7 @@ end)
files.watch(function (ev, uri)
if ev == 'update' then
- check3rd(uri)
+ check3rd(files.asKey(uri))
end
end)
diff --git a/script/plugin.lua b/script/plugin.lua
index af86cea5..15c7c311 100644
--- a/script/plugin.lua
+++ b/script/plugin.lua
@@ -1,11 +1,8 @@
local config = require 'config'
-local fs = require 'bee.filesystem'
-local fsu = require 'fs-utility'
-local await = require "await"
+local util = require 'utility'
---@class plugin
local m = {}
-m.waitingReady = {}
function m.dispatch(event, ...)
if not m.interface then
@@ -28,49 +25,35 @@ function m.isReady()
return m.interface ~= nil
end
-function m.awaitReady()
- if m.isReady() then
- return
+local function resetFiles()
+ local files = require 'files'
+ for uri in files.eachFile() do
+ files.resetText(uri)
end
- await.wait(function (waker)
- m.waitingReady[#m.waitingReady+1] = waker
- end)
end
function m.init()
local ws = require 'workspace'
m.interface = {}
- local _ <close> = function ()
- local waiting = m.waitingReady
- m.waitingReady = {}
- for _, waker in ipairs(waiting) do
- waker()
- end
- end
-
- if not config.get 'Lua.runtime.plugin' or config.get 'Lua.runtime.plugin' == '' then
+ local pluginPath = ws.getAbsolutePath(config.get 'Lua.runtime.plugin')
+ log.info('plugin path:', pluginPath)
+ if not pluginPath then
return
end
-
- local pluginPath = fs.path(config.get 'Lua.runtime.plugin')
- if pluginPath:is_relative() then
- if not ws.path then
- return
- end
- pluginPath = fs.path(ws.path) / pluginPath
- end
- local pluginLua = fsu.loadFile(pluginPath)
+ local pluginLua = util.loadFile(pluginPath)
if not pluginLua then
return
end
local env = setmetatable(m.interface, { __index = _ENV })
- local f, err = load(pluginLua, '@'..pluginPath:string(), "t", env)
+ local f, err = load(pluginLua, '@'..pluginPath, "t", env)
if not f then
log.error(err)
return
end
xpcall(f, log.error, f)
+
+ resetFiles()
end
return m
diff --git a/script/provider/provider.lua b/script/provider/provider.lua
index c3a1113a..ae389b70 100644
--- a/script/provider/provider.lua
+++ b/script/provider/provider.lua
@@ -40,7 +40,7 @@ end
proto.on('initialize', function (params)
client.init(params)
- workspace.init(params.rootUri)
+ workspace.initPath(params.rootUri)
return {
capabilities = cap.getIniter(),
serverInfo = {
@@ -130,7 +130,6 @@ proto.on('workspace/didChangeWatchedFiles', function (params)
if files.isLua(uri)
and not files.isOpen(uri)
and (not workspace.isIgnored(uri) or files.isLibrary(uri)) then
- plugin.awaitReady()
files.setText(uri, pub.awaitTask('loadFile', uri), false)
else
local path = furi.decode(uri)
@@ -149,7 +148,6 @@ end)
proto.on('workspace/didCreateFiles', function (params)
log.debug('workspace/didCreateFiles', util.dump(params))
- plugin.awaitReady()
for _, file in ipairs(params.files) do
if files.isLua(file.uri) then
files.setText(file.uri, pub.awaitTask('loadFile', file.uri), false)
@@ -171,7 +169,6 @@ end)
proto.on('workspace/didRenameFiles', function (params)
log.debug('workspace/didRenameFiles', util.dump(params))
- plugin.awaitReady()
for _, file in ipairs(params.files) do
local text = files.getOriginText(file.oldUri)
if text then
@@ -199,7 +196,6 @@ proto.on('textDocument/didOpen', function (params)
local text = doc.text
log.debug('didOpen', uri)
files.open(uri)
- plugin.awaitReady()
if not files.isOpen(uri) then
return
end
@@ -220,7 +216,6 @@ proto.on('textDocument/didChange', function (params)
local doc = params.textDocument
local changes = params.contentChanges
local uri = doc.uri
- plugin.awaitReady()
if not files.isLua(uri) and not files.isOpen(uri) then
return
end
diff --git a/script/workspace/workspace.lua b/script/workspace/workspace.lua
index 36fc7771..72d7e4bb 100644
--- a/script/workspace/workspace.lua
+++ b/script/workspace/workspace.lua
@@ -440,6 +440,11 @@ function m.findUrisByRequirePath(path)
end
function m.normalize(path)
+ path = path:gsub('$$${(.-)$}', function (key)
+ if key == '3rd' then
+ return (ROOT / 'meta' / '3rd'):string()
+ end
+ end)
if platform.OS == 'Windows' then
path = path:gsub('[/\\]+', '\\')
:gsub('[/\\]+$', '')
@@ -450,6 +455,21 @@ function m.normalize(path)
return path
end
+---@return string
+function m.getAbsolutePath(path)
+ if not path or path == '' then
+ return nil
+ end
+ path = m.normalize(path)
+ if fs.path(path):is_relative() then
+ if not m.path then
+ return nil
+ end
+ path = m.normalize(m.path .. '/' .. path)
+ end
+ return path
+end
+
function m.getRelativePath(uri)
local path = furi.decode(uri)
if not m.path then