summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/client.lua42
-rw-r--r--script/config/config.lua160
-rw-r--r--script/config/loader.lua18
-rw-r--r--script/core/collector.lua29
-rw-r--r--script/core/completion/completion.lua32
-rw-r--r--script/core/completion/postfix.lua2
-rw-r--r--script/core/diagnostics/circle-doc-class.lua2
-rw-r--r--script/core/diagnostics/deprecated.lua6
-rw-r--r--script/core/diagnostics/duplicate-doc-class.lua2
-rw-r--r--script/core/diagnostics/init.lua6
-rw-r--r--script/core/diagnostics/lowercase-global.lua2
-rw-r--r--script/core/diagnostics/type-check.lua16
-rw-r--r--script/core/diagnostics/undefined-doc-class.lua2
-rw-r--r--script/core/diagnostics/undefined-global.lua4
-rw-r--r--script/core/hint.lua8
-rw-r--r--script/core/hover/description.lua6
-rw-r--r--script/core/hover/label.lua2
-rw-r--r--script/core/hover/table.lua2
-rw-r--r--script/core/infer.lua4
-rw-r--r--script/core/noder.lua8
-rw-r--r--script/core/searcher.lua12
-rw-r--r--script/core/semantic-tokens.lua2
-rw-r--r--script/files.lua72
-rw-r--r--script/library.lua18
-rw-r--r--script/plugin.lua14
-rw-r--r--script/progress.lua4
-rw-r--r--script/provider/completion.lua4
-rw-r--r--script/provider/diagnostic.lua16
-rw-r--r--script/provider/provider.lua127
-rw-r--r--script/provider/semantic-tokens.lua2
-rw-r--r--script/service/service.lua2
-rw-r--r--script/service/telemetry.lua6
-rw-r--r--script/vm/getDocs.lua8
-rw-r--r--script/vm/getGlobals.lua6
-rw-r--r--script/workspace/loading.lua162
-rw-r--r--script/workspace/require-path.lua6
-rw-r--r--script/workspace/scope.lua123
-rw-r--r--script/workspace/workspace.lua452
-rw-r--r--test.lua3
-rw-r--r--test/completion/common.lua12
-rw-r--r--test/completion/continue.lua6
-rw-r--r--test/crossfile/allreferences.lua5
-rw-r--r--test/crossfile/completion.lua24
-rw-r--r--test/crossfile/definition.lua16
-rw-r--r--test/crossfile/diagnostic.lua4
-rw-r--r--test/definition/bug.lua4
-rw-r--r--test/diagnostics/init.lua20
-rw-r--r--test/full/example.lua2
-rw-r--r--test/full/init.lua4
-rw-r--r--test/full/projects.lua4
-rw-r--r--test/hover/init.lua12
-rw-r--r--test/references/all.lua4
-rw-r--r--test/references/common.lua16
-rw-r--r--test/rename/init.lua4
-rw-r--r--test/type_inference/init.lua16
55 files changed, 920 insertions, 625 deletions
diff --git a/script/client.lua b/script/client.lua
index c7e12fbf..a0935df6 100644
--- a/script/client.lua
+++ b/script/client.lua
@@ -6,6 +6,7 @@ local define = require 'proto.define'
local config = require 'config'
local converter = require 'proto.converter'
local json = require 'json-beautify'
+local await = require 'await'
local m = {}
@@ -108,10 +109,8 @@ end
---@param type message.type
---@param message string
---@param titles string[]
----@return string action
----@return integer index
----@async
-function m.awaitRequestMessage(type, message, titles)
+---@param callback fun(action: string, index: integer)
+function m.requestMessage(type, message, titles, callback)
proto.notify('window/logMessage', {
type = define.MessageType[type] or 3,
message = message,
@@ -124,15 +123,29 @@ function m.awaitRequestMessage(type, message, titles)
}
map[title] = i
end
- local item = proto.awaitRequest('window/showMessageRequest', {
+ proto.request('window/showMessageRequest', {
type = define.MessageType[type] or 3,
message = message,
actions = actions,
- })
- if not item then
- return nil
- end
- return item.title, map[item.title]
+ }, function (item)
+ if item then
+ callback(item.title, map[item.title])
+ else
+ callback(nil, nil)
+ end
+ end)
+end
+
+---@param type message.type
+---@param message string
+---@param titles string[]
+---@return string action
+---@return integer index
+---@async
+function m.awaitRequestMessage(type, message, titles)
+ return await.wait(function (waker)
+ m.requestMessage(type, message, titles, waker)
+ end)
end
---@param type message.type
@@ -190,7 +203,7 @@ end
---@param changes config.change[]
local function applyConfig(cfg, changes)
for _, change in ipairs(changes) do
- cfg[change.key] = config.getRaw(change.key)
+ cfg[change.key] = config.getRaw(change.uri, change.key)
end
end
@@ -274,22 +287,21 @@ function m.setConfig(changes, onlyMemory)
local finalChanges = {}
for _, change in ipairs(changes) do
if change.action == 'add' then
- local suc = config.add(change.key, change.value)
+ local suc = config.add(change.uri, change.key, change.value)
if suc then
finalChanges[#finalChanges+1] = change
end
elseif change.action == 'set' then
- local suc = config.set(change.key, change.value)
+ local suc = config.set(change.uri, change.key, change.value)
if suc then
finalChanges[#finalChanges+1] = change
end
elseif change.action == 'prop' then
- local suc = config.prop(change.key, change.prop, change.value)
+ local suc = config.prop(change.uri, change.key, change.prop, change.value)
if suc then
finalChanges[#finalChanges+1] = change
end
end
- change.uri = m.info.rootUri
end
if onlyMemory then
return
diff --git a/script/config/config.lua b/script/config/config.lua
index 0f74828d..ed93078f 100644
--- a/script/config/config.lua
+++ b/script/config/config.lua
@@ -1,6 +1,7 @@
local util = require 'utility'
local define = require 'proto.define'
local timer = require 'timer'
+local scope = require 'workspace.scope'
---@alias config.source '"client"'|'"path"'|'"local"'
@@ -214,42 +215,80 @@ local Template = {
['editor.acceptSuggestionOnEnter'] = Type.String >> 'on',
}
-local config = {}
-local rawConfig = {}
-
---@class config.api
local m = {}
m.watchList = {}
-local function update(key, value, raw)
- local oldValue = config[key]
- config[key] = value
- rawConfig[key] = raw
- m.event(key, value, oldValue)
+m.NULL = {}
+
+---@param scp scope
+---@param key string
+---@param nowValue any
+---@param rawValue any
+local function update(scp, key, nowValue, rawValue)
+ local now = scp:get 'config.now'
+ local raw = scp:get 'config.raw'
+
+ now[key] = nowValue
+ raw[key] = rawValue
end
-function m.set(key, value)
+---@param uri uri
+---@param key? string
+---@return scope
+local function getScope(uri, key)
+ local raw = scope.override:get 'config.raw'
+ if raw then
+ if not key or raw[key] ~= nil then
+ return scope.override
+ end
+ end
+ if uri then
+ ---@type scope
+ local scp = scope.getFolder(uri) or scope.getLinkedScope(uri)
+ if scp then
+ if not key or scp:get 'config.raw' [key] ~= nil then
+ return scp
+ end
+ end
+ end
+ return scope.fallback
+end
+
+---@param scp scope
+---@param key string
+---@param value any
+function m.setByScope(scp, key, value)
local unit = Template[key]
if not unit then
return false
end
- if util.equal(rawConfig[key], value) then
+ local raw = scp:get 'config.raw'
+ if util.equal(raw[key], value) then
return false
end
if unit:checker(value) then
- update(key, unit:loader(value), value)
+ update(scp, key, unit:loader(value), value)
else
- update(key, unit.default, unit.default)
+ update(scp, key, unit.default, unit.default)
end
return true
end
-function m.add(key, value)
+---@param uri uri
+---@param key string
+---@param value any
+function m.set(uri, key, value)
+ local scp = getScope(uri)
+ return m.setByScope(scp, key, value)
+end
+
+function m.add(uri, key, value)
local unit = Template[key]
if not unit then
return false
end
- local list = rawConfig[key]
+ local list = m.getRaw(uri, key)
if type(list) ~= 'table' then
return false
end
@@ -261,18 +300,15 @@ function m.add(key, value)
copyed[i] = v
end
copyed[#copyed+1] = value
- if unit:checker(copyed) then
- update(key, unit:loader(copyed), copyed)
- end
- return true
+ return m.set(uri, key, copyed)
end
-function m.prop(key, prop, value)
+function m.prop(uri, key, prop, value)
local unit = Template[key]
if not unit then
return false
end
- local map = rawConfig[key]
+ local map = m.getRaw(uri, key)
if type(map) ~= 'table' then
return false
end
@@ -284,43 +320,48 @@ function m.prop(key, prop, value)
copyed[k] = v
end
copyed[prop] = value
- if unit:checker(copyed) then
- update(key, unit:loader(copyed), copyed)
- end
- return true
+ return m.set(uri, key, copyed)
end
-function m.get(key)
- return config[key]
-end
-
-function m.getRaw(key)
- return rawConfig[key]
+---@param uri uri
+---@param key string
+---@return any
+function m.get(uri, key)
+ local scp = getScope(uri, key)
+ local value = scp:get 'config.now' [key]
+ if value == nil then
+ value = Template[key].default
+ end
+ if value == m.NULL then
+ value = nil
+ end
+ return value
end
-function m.dump()
- local dump = {}
-
- local function expand(parent, key, value)
- local left, right = key:match '([^%.]+)%.(.+)'
- if left then
- if not parent[left] then
- parent[left] = {}
- end
- expand(parent[left], right, value)
- else
- parent[key] = value
- end
+---@param uri uri
+---@param key string
+---@return any
+function m.getRaw(uri, key)
+ local scp = getScope(uri, key)
+ local value = scp:get 'config.raw' [key]
+ if value == nil then
+ value = Template[key].default
end
-
- for key, value in pairs(config) do
- expand(dump, key, value)
+ if value == m.NULL then
+ value = nil
end
-
- return dump
+ return value
end
-function m.update(new, null)
+---@param scp scope
+---@param new table
+---@param null any
+function m.update(scp, new, null)
+ local oldConfig = scp:get 'config.now'
+
+ scp:set('config.now', {})
+ scp:set('config.raw', {})
+
local function expand(t, left)
for key, value in pairs(t) do
local fullKey = key
@@ -328,12 +369,12 @@ function m.update(new, null)
fullKey = left .. '.' .. key
end
if value == null then
- value = nil
+ value = m.NULL
end
if Template[fullKey] then
- m.set(fullKey, value)
+ m.setByScope(scp, fullKey, value)
elseif Template['Lua.' .. fullKey] then
- m.set('Lua.' .. fullKey, value)
+ m.setByScope(scp, 'Lua.' .. fullKey, value)
elseif type(value) == 'table' then
expand(value, fullKey)
end
@@ -341,6 +382,11 @@ function m.update(new, null)
end
expand(new)
+
+ -- compare then fire event
+ if oldConfig then
+
+ end
end
---@param callback fun(key: string, value: any, oldValue: any)
@@ -368,14 +414,6 @@ function m.event(key, value, oldValue)
}
end
-function m.init()
- if m.inited then
- return
- end
- m.inited = true
- for key, unit in pairs(Template) do
- m.set(key, unit.default)
- end
-end
+m.update(scope.fallback, {})
return m
diff --git a/script/config/loader.lua b/script/config/loader.lua
index daa370cd..58ddec27 100644
--- a/script/config/loader.lua
+++ b/script/config/loader.lua
@@ -16,8 +16,8 @@ end
local m = {}
-function m.loadRCConfig(filename)
- local path = workspace.getAbsolutePath(filename)
+function m.loadRCConfig(uri, filename)
+ local path = workspace.getAbsolutePath(uri, filename)
if not path then
m.lastRCConfig = nil
return nil
@@ -75,27 +75,29 @@ function m.loadLocalConfig(filename)
end
---@async
-function m.loadClientConfig()
+---@param uri? uri
+---@return table
+function m.loadClientConfig(uri)
local configs = proto.awaitRequest('workspace/configuration', {
items = {
{
- scopeUri = workspace.uri,
+ scopeUri = uri,
section = 'Lua',
},
{
- scopeUri = workspace.uri,
+ scopeUri = uri,
section = 'files.associations',
},
{
- scopeUri = workspace.uri,
+ scopeUri = uri,
section = 'files.exclude',
},
{
- scopeUri = workspace.uri,
+ scopeUri = uri,
section = 'editor.semanticHighlighting.enabled',
},
{
- scopeUri = workspace.uri,
+ scopeUri = uri,
section = 'editor.acceptSuggestionOnEnter',
},
},
diff --git a/script/core/collector.lua b/script/core/collector.lua
index 3293c9fe..947f4059 100644
--- a/script/core/collector.lua
+++ b/script/core/collector.lua
@@ -1,3 +1,5 @@
+local scope = require 'workspace.scope'
+
local collect = {}
local subscribed = {}
@@ -58,17 +60,34 @@ end
local DUMMY_FUNCTION = function () end
--- 迭代某个名字的订阅
+---@param uri uri
---@param name string
-function m.each(name)
+function m.each(uri, name)
local nameCollect = collect[name]
if not nameCollect then
return DUMMY_FUNCTION
end
- local uri, value
- return function ()
- uri, value = next(nameCollect, uri)
- return value, uri
+ ---@type scope
+ local scp = scope.getFolder(uri)
+ or scope.getLinkedScope(uri)
+ if not scp then
+ return DUMMY_FUNCTION
+ end
+
+ local curi, value
+ local function getNext()
+ curi, value = next(nameCollect, curi)
+ if not curi then
+ return nil, nil
+ end
+ if not scp:isChildUri(curi)
+ and not scp:isLinkedUri(curi) then
+ return getNext()
+ end
+
+ return value, curi
end
+ return getNext
end
return m
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua
index ba2b0efc..dc005b52 100644
--- a/script/core/completion/completion.lua
+++ b/script/core/completion/completion.lua
@@ -180,7 +180,7 @@ local function buildDetail(source)
end
local function getSnip(source)
- local context = config.get 'Lua.completion.displayContext'
+ local context = config.get(nil, 'Lua.completion.displayContext')
if context <= 0 then
return nil
end
@@ -222,7 +222,7 @@ local function buildDesc(source)
end
local function buildFunction(results, source, value, oop, data)
- local snipType = config.get 'Lua.completion.callSnippet'
+ local snipType = config.get(nil, 'Lua.completion.callSnippet')
if snipType == 'Disable' or snipType == 'Both' then
results[#results+1] = data
end
@@ -324,7 +324,7 @@ local function checkLocal(state, word, position, results)
end
local function checkModule(state, word, position, results)
- if not config.get 'Lua.completion.autoRequire' then
+ if not config.get(nil, 'Lua.completion.autoRequire') then
return
end
local locals = guide.getVisibleLocals(state.ast, position)
@@ -337,7 +337,7 @@ local function checkModule(state, word, position, results)
local stemName = fileName:gsub('%..+', '')
if not locals[stemName]
and not vm.hasGlobalSets(stemName)
- and not config.get 'Lua.diagnostics.globals'[stemName]
+ and not config.get(nil, 'Lua.diagnostics.globals')[stemName]
and stemName:match '^[%a_][%w_]*$'
and matchKey(word, stemName) then
local targetState = files.getState(uri)
@@ -448,8 +448,8 @@ local function checkFieldFromFieldToIndex(state, name, src, parent, word, startP
}
end
else
- if config.get 'Lua.runtime.version' == 'lua 5.1'
- or config.get 'Lua.runtime.version' == 'luaJIT' then
+ if config.get(nil, 'Lua.runtime.version') == 'lua 5.1'
+ or config.get(nil, 'Lua.runtime.version') == 'luaJIT' then
textEdit.newText = '_G' .. textEdit.newText
else
textEdit.newText = '_ENV' .. textEdit.newText
@@ -536,7 +536,7 @@ local function checkFieldOfRefs(refs, state, word, startPos, position, parent, o
goto CONTINUE
end
local funcLabel
- if config.get 'Lua.completion.showParams' then
+ if config.get(nil, 'Lua.completion.showParams') then
local value = searcher.getObjectValue(src) or src
if value.type == 'function'
or value.type == 'doc.type.function' then
@@ -584,14 +584,14 @@ end
---@async
local function checkGlobal(state, word, startPos, position, parent, oop, results)
local locals = guide.getVisibleLocals(state.ast, position)
- local globals = vm.getGlobalSets '*'
+ local globals = vm.getGlobalSets(state.uri, '*')
checkFieldOfRefs(globals, state, word, startPos, position, parent, oop, results, locals, 'global')
end
---@async
local function checkField(state, word, start, position, parent, oop, results)
if parent.tag == '_ENV' or parent.special == '_G' then
- local globals = vm.getGlobalSets '*'
+ local globals = vm.getGlobalSets(state.uri, '*')
checkFieldOfRefs(globals, state, word, start, position, parent, oop, results)
else
local refs = vm.getRefs(parent, '*')
@@ -630,7 +630,7 @@ end
local function checkCommon(state, word, position, results)
local myUri = state.uri
- local showWord = config.get 'Lua.completion.showWord'
+ local showWord = config.get(nil, 'Lua.completion.showWord')
if showWord == 'Disable' then
return
end
@@ -645,7 +645,7 @@ local function checkCommon(state, word, position, results)
for _, data in ipairs(keyWordMap) do
used[data[1]] = true
end
- if config.get 'Lua.completion.workspaceWord' and #word >= 2 then
+ if config.get(nil, 'Lua.completion.workspaceWord') and #word >= 2 then
results.complete = true
local myHead = word:sub(1, 2)
for uri in files.eachFile() do
@@ -720,7 +720,7 @@ end
local function checkKeyWord(state, start, position, word, hasSpace, afterLocal, results)
local text = state.lua
- local snipType = config.get 'Lua.completion.keywordSnippet'
+ local snipType = config.get(nil, 'Lua.completion.keywordSnippet')
local symbol = lookBackward.findSymbol(text, guide.positionToOffset(state, start))
local isExp = symbol == '(' or symbol == ',' or symbol == '='
local info = {
@@ -1630,7 +1630,7 @@ local function tryluaDocBySource(state, position, source, results)
if source.type == 'doc.extends.name' then
if source.parent.type == 'doc.class' then
local used = {}
- for _, doc in ipairs(vm.getDocDefines '*') do
+ for _, doc in ipairs(vm.getDocDefines(state.uri, '*')) do
if doc.type == 'doc.class.name'
and doc.parent ~= source.parent
and not used[doc[1]]
@@ -1651,7 +1651,7 @@ local function tryluaDocBySource(state, position, source, results)
return true
elseif source.type == 'doc.type.name' then
local used = {}
- for _, doc in ipairs(vm.getDocDefines '*') do
+ for _, doc in ipairs(vm.getDocDefines(state.uri, '*')) do
if (doc.type == 'doc.class.name' or doc.type == 'doc.alias.name')
and doc.parent ~= source.parent
and not used[doc[1]]
@@ -1729,7 +1729,7 @@ end
local function tryluaDocByErr(state, position, err, docState, results)
if err.type == 'LUADOC_MISS_CLASS_EXTENDS_NAME' then
- for _, doc in ipairs(vm.getDocDefines '*') do
+ for _, doc in ipairs(vm.getDocDefines(state.uri, '*')) do
if doc.type == 'doc.class.name'
and doc.parent ~= docState then
results[#results+1] = {
@@ -1739,7 +1739,7 @@ local function tryluaDocByErr(state, position, err, docState, results)
end
end
elseif err.type == 'LUADOC_MISS_TYPE_NAME' then
- for _, doc in ipairs(vm.getDocDefines '*') do
+ for _, doc in ipairs(vm.getDocDefines(state.uri, '*')) do
if (doc.type == 'doc.class.name' or doc.type == 'doc.alias.name') then
results[#results+1] = {
label = doc[1],
diff --git a/script/core/completion/postfix.lua b/script/core/completion/postfix.lua
index 0395e2a5..b2b777e7 100644
--- a/script/core/completion/postfix.lua
+++ b/script/core/completion/postfix.lua
@@ -278,7 +278,7 @@ return function (state, position, results)
offset = newOffset - 1
end
local symbol = text:sub(offset, offset)
- if symbol == config.get 'Lua.completion.postfix' then
+ if symbol == config.get(nil, 'Lua.completion.postfix') then
local wordPosition = guide.offsetToPosition(state, offset - 1)
checkPostFix(state, word or '', wordPosition, position, symbol, results)
return symbol ~= '.' and symbol ~= ':'
diff --git a/script/core/diagnostics/circle-doc-class.lua b/script/core/diagnostics/circle-doc-class.lua
index ae6d4d3b..61dc46b4 100644
--- a/script/core/diagnostics/circle-doc-class.lua
+++ b/script/core/diagnostics/circle-doc-class.lua
@@ -40,7 +40,7 @@ return function (uri, callback)
end
if not mark[newName] then
mark[newName] = true
- local docs = vm.getDocDefines(newName)
+ local docs = vm.getDocDefines(uri, newName)
for _, otherDoc in ipairs(docs) do
if otherDoc.type == 'doc.class.name' then
list[#list+1] = otherDoc.parent
diff --git a/script/core/diagnostics/deprecated.lua b/script/core/diagnostics/deprecated.lua
index e9a1fef7..5fe36c42 100644
--- a/script/core/diagnostics/deprecated.lua
+++ b/script/core/diagnostics/deprecated.lua
@@ -23,10 +23,10 @@ return function (uri, callback)
if not key then
return
end
- if config.get 'Lua.diagnostics.globals'[key] then
+ if config.get(nil, 'Lua.diagnostics.globals')[key] then
return
end
- if config.get 'Lua.runtime.special'[key] then
+ if config.get(nil, 'Lua.runtime.special')[key] then
return
end
end
@@ -83,7 +83,7 @@ return function (uri, callback)
end
table.sort(versions)
if #versions > 0 then
- message = ('%s(%s)'):format(message, lang.script('DIAG_DEFINED_VERSION', table.concat(versions, '/'), config.get 'Lua.runtime.version'))
+ message = ('%s(%s)'):format(message, lang.script('DIAG_DEFINED_VERSION', table.concat(versions, '/'), config.get(nil, 'Lua.runtime.version')))
end
end
cache[id] = {
diff --git a/script/core/diagnostics/duplicate-doc-class.lua b/script/core/diagnostics/duplicate-doc-class.lua
index 97e2089a..5114a54f 100644
--- a/script/core/diagnostics/duplicate-doc-class.lua
+++ b/script/core/diagnostics/duplicate-doc-class.lua
@@ -19,7 +19,7 @@ return function (uri, callback)
if doc.type == 'doc.alias' then
local name = guide.getKeyName(doc)
if not cache[name] then
- local docs = vm.getDocDefines(name)
+ local docs = vm.getDocDefines(uri, name)
cache[name] = {}
for _, otherDoc in ipairs(docs) do
if otherDoc.type == 'doc.class.name'
diff --git a/script/core/diagnostics/init.lua b/script/core/diagnostics/init.lua
index 4950900b..2a21302b 100644
--- a/script/core/diagnostics/init.lua
+++ b/script/core/diagnostics/init.lua
@@ -20,13 +20,13 @@ table.sort(diagList, function (a, b)
end)
local function check(uri, name, results)
- if config.get 'Lua.diagnostics.disable'[name] then
+ if config.get(nil, 'Lua.diagnostics.disable')[name] then
return
end
- local level = config.get 'Lua.diagnostics.severity'[name]
+ local level = config.get(nil, 'Lua.diagnostics.severity')[name]
or define.DiagnosticDefaultSeverity[name]
- local neededFileStatus = config.get 'Lua.diagnostics.neededFileStatus'[name]
+ local neededFileStatus = config.get(nil, 'Lua.diagnostics.neededFileStatus')[name]
or define.DiagnosticDefaultNeededFileStatus[name]
if neededFileStatus == 'None' then
diff --git a/script/core/diagnostics/lowercase-global.lua b/script/core/diagnostics/lowercase-global.lua
index 299ac110..bd301c7f 100644
--- a/script/core/diagnostics/lowercase-global.lua
+++ b/script/core/diagnostics/lowercase-global.lua
@@ -24,7 +24,7 @@ return function (uri, callback)
end
local definedGlobal = {}
- for name in pairs(config.get 'Lua.diagnostics.globals') do
+ for name in pairs(config.get(nil, 'Lua.diagnostics.globals')) do
definedGlobal[name] = true
end
diff --git a/script/core/diagnostics/type-check.lua b/script/core/diagnostics/type-check.lua
index 8728b169..5f37312e 100644
--- a/script/core/diagnostics/type-check.lua
+++ b/script/core/diagnostics/type-check.lua
@@ -36,11 +36,11 @@ local function isTable(name)
return false
end
-local function isUserDefineClass(name)
+local function isUserDefineClass(uri, name)
if vm.isBuiltinType(name) then
return false
else
- local defs = vm.getDocDefines(name)
+ local defs = vm.getDocDefines(uri, name)
for _, v in ipairs(defs) do
if v.type == 'doc.class.name' then
return true
@@ -116,10 +116,10 @@ end
-- end
-- end
-local function addFatherClass(infers)
+local function addFatherClass(uri, infers)
for k in pairs(infers) do
if type(k) == 'string' then
- local docDefs = vm.getDocDefines(k)
+ local docDefs = vm.getDocDefines(uri, k)
for _, doc in ipairs(docDefs) do
if doc.parent
and doc.parent.type == 'doc.class'
@@ -264,7 +264,7 @@ local function getInfoFromDefs(defs)
return paramsTypes
end
-local function getArgsInfo(callArgs)
+local function getArgsInfo(uri, callArgs)
local callArgsType = {}
for _, arg in ipairs(callArgs) do
-- local defs = vm.getDefs(arg)
@@ -276,7 +276,7 @@ local function getArgsInfo(callArgs)
end
local hasAny = infers['any']
---处理继承
- addFatherClass(infers)
+ addFatherClass(uri, infers)
if not hasAny then
infers['any'] = nil
infers['unknown'] = nil
@@ -285,7 +285,7 @@ local function getArgsInfo(callArgs)
if not infers['table'] then
for k in pairs(infers) do
if not vm.isBuiltinType(k)
- and isUserDefineClass(k) then
+ and isUserDefineClass(uri, k) then
infers['table'] = true
break
end
@@ -424,7 +424,7 @@ return function (uri, callback)
end
await.delay()
local callArgs = source.args
- local suc, callArgsType = getArgsInfo(callArgs)
+ local suc, callArgsType = getArgsInfo(uri, callArgs)
if not suc then
return
end
diff --git a/script/core/diagnostics/undefined-doc-class.lua b/script/core/diagnostics/undefined-doc-class.lua
index e7133ab9..5f3902a2 100644
--- a/script/core/diagnostics/undefined-doc-class.lua
+++ b/script/core/diagnostics/undefined-doc-class.lua
@@ -25,7 +25,7 @@ return function (uri, callback)
end
for _, ext in ipairs(doc.extends) do
local name = ext[1]
- local docs = vm.getDocDefines(name)
+ local docs = vm.getDocDefines(uri, name)
if cache[name] == nil then
cache[name] = false
for _, otherDoc in ipairs(docs) do
diff --git a/script/core/diagnostics/undefined-global.lua b/script/core/diagnostics/undefined-global.lua
index 48c8a226..41a50d99 100644
--- a/script/core/diagnostics/undefined-global.lua
+++ b/script/core/diagnostics/undefined-global.lua
@@ -27,10 +27,10 @@ return function (uri, callback)
if not key then
return
end
- if config.get 'Lua.diagnostics.globals'[key] then
+ if config.get(nil, 'Lua.diagnostics.globals')[key] then
return
end
- if config.get 'Lua.runtime.special'[key] then
+ if config.get(nil, 'Lua.runtime.special')[key] then
return
end
local node = src.node
diff --git a/script/core/hint.lua b/script/core/hint.lua
index 42390443..b3aec88e 100644
--- a/script/core/hint.lua
+++ b/script/core/hint.lua
@@ -32,11 +32,11 @@ local function typeHint(uri, results, start, finish)
return
end
if source.parent.type == 'funcargs' then
- if not config.get 'Lua.hint.paramType' then
+ if not config.get(nil, 'Lua.hint.paramType') then
return
end
else
- if not config.get 'Lua.hint.setType' then
+ if not config.get(nil, 'Lua.hint.setType') then
return
end
end
@@ -99,7 +99,7 @@ end
---@async
local function paramName(uri, results, start, finish)
- local paramConfig = config.get 'Lua.hint.paramName'
+ local paramConfig = config.get(nil, 'Lua.hint.paramName')
if not paramConfig or paramConfig == 'None' then
return
end
@@ -162,7 +162,7 @@ end
---@async
local function awaitHint(uri, results, start, finish)
- local awaitConfig = config.get 'Lua.hint.await'
+ local awaitConfig = config.get(nil, 'Lua.hint.await')
if not awaitConfig then
return
end
diff --git a/script/core/hover/description.lua b/script/core/hover/description.lua
index 725ea7a5..51027aed 100644
--- a/script/core/hover/description.lua
+++ b/script/core/hover/description.lua
@@ -11,7 +11,7 @@ local guide = require 'parser.guide'
local noder = require 'core.noder'
local function collectRequire(mode, literal)
- local rootPath = ws.path or ''
+ local rootPath = ws.rootPath or ''
local result, searchers
if mode == 'require' then
result, searchers = ws.findUrisByRequirePath(literal)
@@ -64,11 +64,11 @@ end
local function asStringView(source, literal)
-- 内部包含转义符?
local rawLen = source.finish - source.start - 2 * #source[2] + 1
- if config.get 'Lua.hover.viewString'
+ if config.get(nil, 'Lua.hover.viewString')
and (source[2] == '"' or source[2] == "'")
and rawLen > #literal then
local view = literal
- local max = config.get 'Lua.hover.viewStringMax'
+ local max = config.get(nil, 'Lua.hover.viewStringMax')
if #view > max then
view = view:sub(1, max) .. '...'
end
diff --git a/script/core/hover/label.lua b/script/core/hover/label.lua
index 0bb4fe89..f797d520 100644
--- a/script/core/hover/label.lua
+++ b/script/core/hover/label.lua
@@ -167,7 +167,7 @@ local function formatNumber(n)
end
local function asNumber(source)
- if not config.get 'Lua.hover.viewNumber' then
+ if not config.get(nil, 'Lua.hover.viewNumber') then
return nil
end
local num = source[1]
diff --git a/script/core/hover/table.lua b/script/core/hover/table.lua
index 285d5c02..3785d479 100644
--- a/script/core/hover/table.lua
+++ b/script/core/hover/table.lua
@@ -136,7 +136,7 @@ end
---@async
return function (source)
- local maxFields = config.get 'Lua.hover.previewFields'
+ local maxFields = config.get(nil, 'Lua.hover.previewFields')
if maxFields <= 0 then
return 'table'
end
diff --git a/script/core/infer.lua b/script/core/infer.lua
index 39cb8c5e..9166168b 100644
--- a/script/core/infer.lua
+++ b/script/core/infer.lua
@@ -232,7 +232,7 @@ local function bindClassOrType(source)
end
local function cleanInfers(infers)
- local version = config.get 'Lua.runtime.version'
+ local version = config.get(nil, 'Lua.runtime.version')
local enableInteger = version == 'Lua 5.3' or version == 'Lua 5.4'
infers['unknown'] = nil
if infers['number'] then
@@ -297,7 +297,7 @@ function m.viewInfers(infers)
return sa < sb
end
end)
- local limit = config.get 'Lua.hover.enumsLimit'
+ local limit = config.get(nil, 'Lua.hover.enumsLimit')
if limit < 0 then
limit = 0
end
diff --git a/script/core/noder.lua b/script/core/noder.lua
index dc846cf3..373644de 100644
--- a/script/core/noder.lua
+++ b/script/core/noder.lua
@@ -497,7 +497,7 @@ local function getNodeKey(source)
if methodNode then
return getNodeKey(methodNode)
end
- if config.get 'Lua.IntelliSense.traceFieldInject' then
+ if config.get(nil, 'Lua.IntelliSense.traceFieldInject') then
local localValueID = getLocalValueID(source)
if localValueID then
return localValueID
@@ -822,7 +822,7 @@ local function bindValue(noders, source, id)
local bindDocs = source.bindDocs
if source.type == 'getlocal'
or source.type == 'setlocal' then
- if not config.get 'Lua.IntelliSense.traceLocalSet' then
+ if not config.get(nil, 'Lua.IntelliSense.traceLocalSet') then
return
end
bindDocs = source.node.bindDocs
@@ -837,7 +837,7 @@ local function bindValue(noders, source, id)
end
-- x = y : x -> y
pushForward(noders, id, valueID, INFO_REJECT_SET)
- if not config.get 'Lua.IntelliSense.traceBeSetted'
+ if not config.get(nil, 'Lua.IntelliSense.traceBeSetted')
and source.type ~= 'local' then
return
end
@@ -1329,7 +1329,7 @@ compileNodeMap = util.switch()
, index
)
pushForward(noders, returnID, getID(rtnObj))
- if config.get 'Lua.IntelliSense.traceReturn' then
+ if config.get(nil, 'Lua.IntelliSense.traceReturn') then
pushBackward(noders, getID(rtnObj), returnID, INFO_DEEP_AND_DONT_CROSS)
end
end
diff --git a/script/core/searcher.lua b/script/core/searcher.lua
index 9c0f0faa..1f4091b3 100644
--- a/script/core/searcher.lua
+++ b/script/core/searcher.lua
@@ -820,7 +820,7 @@ function m.searchRefsByID(status, suri, expect, mode)
or mode == 'alldef'
or field
or hasCall(field) then
- for _, guri in ceach('def:' .. id) do
+ for _, guri in ceach(uri, 'def:' .. id) do
if uri == guri then
goto CONTINUE
end
@@ -829,14 +829,14 @@ function m.searchRefsByID(status, suri, expect, mode)
end
elseif mode == 'field'
or mode == 'allfield' then
- for _, guri in ceach('def:' .. id) do
+ for _, guri in ceach(uri, 'def:' .. id) do
if uri == guri then
goto CONTINUE
end
searchID(guri, id, field, uri)
::CONTINUE::
end
- for _, guri in ceach('field:' .. id) do
+ for _, guri in ceach(uri, 'field:' .. id) do
if uri == guri then
goto CONTINUE
end
@@ -844,7 +844,7 @@ function m.searchRefsByID(status, suri, expect, mode)
::CONTINUE::
end
else
- for _, guri in ceach(id) do
+ for _, guri in ceach(uri, id) do
if crossed[guri] then
goto CONTINUE
end
@@ -872,7 +872,7 @@ function m.searchRefsByID(status, suri, expect, mode)
or ignoredIDs[id]
or id == 'dn:string'
or hasCall(field) then
- for _, guri in ceach('def:' .. id) do
+ for _, guri in ceach(uri, 'def:' .. id) do
if uri == guri then
goto CONTINUE
end
@@ -880,7 +880,7 @@ function m.searchRefsByID(status, suri, expect, mode)
::CONTINUE::
end
else
- for _, guri in ceach(id) do
+ for _, guri in ceach(uri, id) do
if crossed[guri] then
goto CONTINUE
end
diff --git a/script/core/semantic-tokens.lua b/script/core/semantic-tokens.lua
index 8389cbb4..291819f2 100644
--- a/script/core/semantic-tokens.lua
+++ b/script/core/semantic-tokens.lua
@@ -9,7 +9,7 @@ local converter = require 'proto.converter'
local infer = require 'core.infer'
local config = require 'config'
-local isEnhanced = config.get 'Lua.color.mode' == 'SemanticEnhanced'
+local isEnhanced = config.get(nil, 'Lua.color.mode') == 'SemanticEnhanced'
local Care = {}
Care['getglobal'] = function (source, results)
diff --git a/script/files.lua b/script/files.lua
index 074a262e..765ac88a 100644
--- a/script/files.lua
+++ b/script/files.lua
@@ -64,6 +64,7 @@ function m.open(uri)
cache = {},
}
m.onWatch('open', uri)
+ m.addRef(uri)
end
--- 关闭文件
@@ -75,6 +76,7 @@ function m.close(uri)
file.trusted = false
end
m.onWatch('close', uri)
+ m.delRef(uri)
end
--- 是否打开
@@ -93,8 +95,11 @@ function m.getOpenedCache(uri)
end
--- 标记为库文件
-function m.setLibraryPath(uri, libraryPath)
- m.libraryMap[uri] = libraryPath
+---@param scp scope
+---@param uri uri
+---@param libraryUri uri
+function m.setLibraryUri(scp, uri, libraryUri)
+ scp:get 'libraryMap' [uri] = libraryUri
end
--- 是否是库文件
@@ -107,8 +112,9 @@ function m.getLibraryPath(uri)
return m.libraryMap[uri]
end
-function m.flushAllLibrary()
- m.libraryMap = {}
+---@param scp scope
+function m.flushAllLibrary(scp)
+ scp:set('libraryMap', {})
end
--- 是否存在
@@ -174,7 +180,7 @@ function m.setText(uri, text, isTrust, version)
return
end
if not isTrust then
- local encoding = config.get 'Lua.runtime.fileEncoding'
+ local encoding = config.get(nil, 'Lua.runtime.fileEncoding')
text = encoder.decode(encoding, text)
end
file.version = version
@@ -344,6 +350,25 @@ function m.getChildFiles(uri)
return results
end
+function m.addRef(uri)
+ local file = m.fileMap[uri]
+ if not file then
+ return
+ end
+ file._ref = (file._ref or 0) + 1
+end
+
+function m.delRef(uri)
+ local file = m.fileMap[uri]
+ if not file then
+ return
+ end
+ file._ref = (file._ref or 0) - 1
+ if file._ref <= 0 then
+ m.remove(uri)
+ end
+end
+
--- 移除文件
---@param uri uri
function m.remove(uri)
@@ -355,7 +380,6 @@ function m.remove(uri)
m.fileMap[uri] = nil
m.astMap[uri] = nil
m._pairsCache = nil
- m.flushFileCache(uri)
m.fileCount = m.fileCount - 1
m.globalVersion = m.globalVersion + 1
@@ -452,7 +476,7 @@ function m.compileState(uri, text)
local client = require 'client'
if not m.isOpen(uri)
and not m.isLibrary(uri)
- and #text >= config.get 'Lua.workspace.preloadFileSize' * 1000 then
+ and #text >= config.get(nil, 'Lua.workspace.preloadFileSize') * 1000 then
if not m.notifyCache['preloadFileSize'] then
m.notifyCache['preloadFileSize'] = {}
m.notifyCache['skipLargeFileCount'] = 0
@@ -462,7 +486,7 @@ function m.compileState(uri, text)
m.notifyCache['skipLargeFileCount'] = m.notifyCache['skipLargeFileCount'] + 1
local message = lang.script('WORKSPACE_SKIP_LARGE_FILE'
, ws.getRelativePath(uri)
- , config.get 'Lua.workspace.preloadFileSize'
+ , config.get(nil, 'Lua.workspace.preloadFileSize')
, #text / 1000
)
if m.notifyCache['skipLargeFileCount'] <= 1 then
@@ -478,11 +502,11 @@ function m.compileState(uri, text)
local clock = os.clock()
local state, err = parser.compile(text
, 'Lua'
- , config.get 'Lua.runtime.version'
+ , config.get(nil, 'Lua.runtime.version')
, {
- special = config.get 'Lua.runtime.special',
- unicodeName = config.get 'Lua.runtime.unicodeName',
- nonstandardSymbol = config.get 'Lua.runtime.nonstandardSymbol',
+ special = config.get(nil, 'Lua.runtime.special'),
+ unicodeName = config.get(nil, 'Lua.runtime.unicodeName'),
+ nonstandardSymbol = config.get(nil, 'Lua.runtime.nonstandardSymbol'),
}
)
local passed = os.clock() - clock
@@ -634,12 +658,12 @@ end
--- 获取文件关联
function m.getAssoc()
- if m.assocVersion == config.get 'version' then
+ if m.assocVersion == config.get(nil, 'version') then
return m.assocMatcher
end
- m.assocVersion = config.get 'version'
+ m.assocVersion = config.get(nil, 'version')
local patt = {}
- for k, v in pairs(config.get 'files.associations') do
+ for k, v in pairs(config.get(nil, 'files.associations')) do
if v == 'lua' then
patt[#patt+1] = k
end
@@ -752,24 +776,6 @@ function m.onWatch(ev, uri)
end
end
-function m.flushCache()
- for uri, file in pairs(m.fileMap) do
- file.cacheActiveTime = math.huge
- m.astMap[uri] = nil
- file.cache = {}
- end
-end
-
-function m.flushFileCache(uri)
- local file = m.fileMap[uri]
- if not file then
- return
- end
- file.cacheActiveTime = math.huge
- m.astMap[uri] = nil
- file.cache = {}
-end
-
function m.init()
--TODO 可以清空文件缓存,之后看要不要启用吧
--timer.loop(10, function ()
diff --git a/script/library.lua b/script/library.lua
index 81242a91..ef62ceab 100644
--- a/script/library.lua
+++ b/script/library.lua
@@ -15,7 +15,7 @@ local encoder = require 'encoder'
local m = {}
local function getDocFormater()
- local version = config.get 'Lua.runtime.version'
+ local version = config.get(nil, 'Lua.runtime.version')
if client.isVSCode() then
if version == 'Lua 5.1' then
return 'HOVER_NATIVE_DOCUMENT_LUA51'
@@ -99,11 +99,11 @@ local function compileSingleMetaDoc(script, metaLang, status)
middleBuf[#middleBuf+1] = ('PUSH [===[%s]===]'):format(script:sub(last))
local middleScript = table.concat(middleBuf, '\n')
local version, jit
- if config.get 'Lua.runtime.version' == 'LuaJIT' then
+ if config.get(nil, 'Lua.runtime.version') == 'LuaJIT' then
version = 5.1
jit = true
else
- version = tonumber(config.get 'Lua.runtime.version':sub(-3))
+ version = tonumber(config.get(nil, 'Lua.runtime.version'):sub(-3))
jit = false
end
@@ -202,9 +202,9 @@ local function initBuiltIn()
return
end
local langID = lang.id
- local version = config.get 'Lua.runtime.version'
- local encoding = config.get 'Lua.runtime.fileEncoding'
- local metaPath = fs.path(METAPATH) / config.get 'Lua.runtime.meta':gsub('%$%{(.-)%}', {
+ local version = config.get(nil, 'Lua.runtime.version')
+ local encoding = config.get(nil, 'Lua.runtime.fileEncoding')
+ local metaPath = fs.path(METAPATH) / config.get(nil, 'Lua.runtime.meta'):gsub('%$%{(.-)%}', {
version = version,
language = langID,
encoding = encoding,
@@ -227,7 +227,7 @@ local function initBuiltIn()
local out = fsu.dummyFS()
local templateDir = ROOT / 'meta' / 'template'
for libName, status in pairs(define.BuiltIn) do
- status = config.get 'Lua.runtime.builtin'[libName] or status
+ status = config.get(nil, 'Lua.runtime.builtin')[libName] or status
if status == 'disable' then
goto CONTINUE
end
@@ -308,7 +308,7 @@ end
local function load3rdConfig()
local configs = {}
load3rdConfigInDir(innerThirdDir, configs, true)
- local thirdDirs = config.get 'Lua.workspace.userThirdParty'
+ local thirdDirs = config.get(nil, 'Lua.workspace.userThirdParty')
for _, thirdDir in ipairs(thirdDirs) do
load3rdConfigInDir(fs.path(thirdDir), configs)
end
@@ -450,7 +450,7 @@ local function check3rd(uri)
if hasAsked then
return
end
- if not config.get 'Lua.workspace.checkThirdParty' then
+ if not config.get(nil, 'Lua.workspace.checkThirdParty') then
return
end
if thirdConfigs == nil then
diff --git a/script/plugin.lua b/script/plugin.lua
index f56dc9f9..0914c0c0 100644
--- a/script/plugin.lua
+++ b/script/plugin.lua
@@ -43,13 +43,6 @@ function m.isReady()
return m.interface ~= nil
end
-local function resetFiles()
- local files = require 'files'
- for uri in files.eachFile() do
- files.resetText(uri)
- end
-end
-
---@async
local function checkTrustLoad()
local filePath = LOGPATH .. '/trusted'
@@ -75,7 +68,8 @@ local function checkTrustLoad()
return true
end
-function m.init()
+---@param scp scope
+function m.init(scp)
if m.hasInited then
return
end
@@ -84,7 +78,7 @@ function m.init()
local ws = require 'workspace'
m.interface = {}
- local pluginPath = ws.getAbsolutePath(config.get 'Lua.runtime.plugin')
+ local pluginPath = ws.getAbsolutePath(scp.uri, config.get(scp.uri, 'Lua.runtime.plugin'))
log.info('plugin path:', pluginPath)
if not pluginPath then
return
@@ -110,7 +104,7 @@ function m.init()
return
end
- resetFiles()
+ ws.resetFiles(scp)
end)
end
diff --git a/script/progress.lua b/script/progress.lua
index 8ae5e9e0..d1595cf8 100644
--- a/script/progress.lua
+++ b/script/progress.lua
@@ -83,7 +83,7 @@ function mt:_update()
and self._clock + self._delay <= os.clock() then
self._updated = os.clock()
self._dirty = false
- if not config.get 'Lua.window.progressBar' then
+ if not config.get(nil, 'Lua.window.progressBar') then
return
end
proto.request('window/workDoneProgress/create', {
@@ -106,7 +106,7 @@ function mt:_update()
if not self._showed then
return
end
- if not config.get 'Lua.window.progressBar' then
+ if not config.get(nil, 'Lua.window.progressBar') then
self:remove()
return
end
diff --git a/script/provider/completion.lua b/script/provider/completion.lua
index ec31858a..8e529e95 100644
--- a/script/provider/completion.lua
+++ b/script/provider/completion.lua
@@ -13,7 +13,7 @@ local function allWords()
list[#list+1] = c
mark[c] = true
end
- local postfix = config.get 'Lua.completion.postfix'
+ local postfix = config.get(nil, 'Lua.completion.postfix')
if postfix ~= '' and not mark[postfix] then
list[#list+1] = postfix
mark[postfix] = true
@@ -76,7 +76,7 @@ config.watch(function (key, value)
end
end
if key == 'Lua.completion.postfix' then
- if config.get 'Lua.completion.enable' then
+ if config.get(nil, 'Lua.completion.enable') then
disable()
enable()
end
diff --git a/script/provider/diagnostic.lua b/script/provider/diagnostic.lua
index e90d8afb..a6724a29 100644
--- a/script/provider/diagnostic.lua
+++ b/script/provider/diagnostic.lua
@@ -29,7 +29,7 @@ local function buildSyntaxError(uri, err)
local message = lang.script('PARSER_'..err.type, err.info)
if err.version then
- local version = err.info and err.info.version or config.get 'Lua.runtime.version'
+ local version = err.info and err.info.version or config.get(nil, 'Lua.runtime.version')
message = message .. ('(%s)'):format(lang.script('DIAG_NEED_VERSION'
, concat(err.version, '/')
, version
@@ -159,7 +159,7 @@ function m.syntaxErrors(uri, ast)
pcall(function ()
for _, err in ipairs(ast.errs) do
- if not config.get 'Lua.diagnostics.disable'[err.type:lower():gsub('_', '-')] then
+ if not config.get(nil, 'Lua.diagnostics.disable')[err.type:lower():gsub('_', '-')] then
results[#results+1] = buildSyntaxError(uri, err)
end
end
@@ -189,11 +189,11 @@ end
---@async
function m.doDiagnostic(uri)
- if not config.get 'Lua.diagnostics.enable' then
+ if not config.get(nil, 'Lua.diagnostics.enable') then
return
end
if files.isLibrary(uri) then
- local status = config.get 'Lua.diagnostics.libraryFiles'
+ local status = config.get(nil, 'Lua.diagnostics.libraryFiles')
if status == 'Disable' then
return
elseif status == 'Opened' then
@@ -203,7 +203,7 @@ function m.doDiagnostic(uri)
end
end
if ws.isIgnored(uri) then
- local status = config.get 'Lua.diagnostics.ignoredFiles'
+ local status = config.get(nil, 'Lua.diagnostics.ignoredFiles')
if status == 'Disable' then
return
elseif status == 'Opened' then
@@ -332,14 +332,14 @@ local function askForDisable()
end
function m.diagnosticsAll(force)
- if not force and not config.get 'Lua.diagnostics.enable' then
+ if not force and not config.get(nil, 'Lua.diagnostics.enable') then
m.clearAll()
return
end
if not m._start then
return
end
- local delay = config.get 'Lua.diagnostics.workspaceDelay' / 1000
+ local delay = config.get(nil, 'Lua.diagnostics.workspaceDelay') / 1000
if not force and delay < 0 then
return
end
@@ -392,7 +392,7 @@ function m.checkWorkspaceDiag()
if not await.hasID 'diagnosticsAll' then
return
end
- local speedRate = config.get 'Lua.diagnostics.workspaceRate'
+ local speedRate = config.get(nil, 'Lua.diagnostics.workspaceRate')
if speedRate <= 0 or speedRate >= 100 then
return
end
diff --git a/script/provider/provider.lua b/script/provider/provider.lua
index addfe320..11501b9c 100644
--- a/script/provider/provider.lua
+++ b/script/provider/provider.lua
@@ -16,30 +16,41 @@ local cfgLoader = require 'config.loader'
local converter = require 'proto.converter'
local filewatch = require 'filewatch'
local json = require 'json'
+local scope = require 'workspace.scope'
---@async
local function updateConfig()
- local clientConfig = cfgLoader.loadClientConfig()
- if clientConfig then
- log.debug('load config from client')
- config.update(clientConfig, json.null)
+ local specified = cfgLoader.loadLocalConfig(CONFIGPATH)
+ if specified then
+ log.debug('Load config from specified', CONFIGPATH)
+ log.debug(util.dump(specified))
+ -- watch directory
+ filewatch.watch(workspace.getAbsolutePath(CONFIGPATH):gsub('[^/\\]+$', ''))
+ config.update(scope.override, specified, json.null)
end
- local rc = cfgLoader.loadRCConfig('.luarc.json')
- if rc then
- log.debug('load config from luarc')
- config.update(rc, json.null)
- end
+ for _, folder in ipairs(scope.folders) do
+ local uri = folder.uri
- local cfg = cfgLoader.loadLocalConfig(CONFIGPATH)
- if cfg then
- log.debug('load config from local', CONFIGPATH)
- -- watch directory
- filewatch.watch(workspace.getAbsolutePath(CONFIGPATH):gsub('[^/\\]+$', ''))
- config.update(cfg, json.null)
+ local clientConfig = cfgLoader.loadClientConfig(uri)
+ if clientConfig then
+ log.debug('Load config from client', uri)
+ log.debug(util.dump(clientConfig))
+ config.update(folder, clientConfig, json.null)
+ end
+
+ local rc = cfgLoader.loadRCConfig(uri, '.luarc.json')
+ if rc then
+ log.debug('Load config from luarc.json', uri)
+ log.debug(util.dump(rc))
+ config.update(folder, rc, json.null)
+ end
end
- log.debug('loaded config dump:', util.dump(config.dump()))
+ local global = cfgLoader.loadClientConfig()
+ log.debug('Load config from client', 'fallback')
+ log.debug(util.dump(global))
+ config.update(scope.fallback, global, json.null)
end
---@class provider
@@ -69,8 +80,19 @@ end)
m.register 'initialize' {
function (params)
client.init(params)
- config.init()
- workspace.initPath(params.rootUri)
+
+ if params.rootUri then
+ workspace.initRoot(params.rootUri)
+ end
+
+ if params.workspaceFolders then
+ for _, folder in ipairs(params.workspaceFolders) do
+ workspace.create(folder.uri)
+ end
+ elseif params.rootUri then
+ workspace.create(params.rootUri)
+ end
+
return {
capabilities = cap.getIniter(),
serverInfo = {
@@ -189,9 +211,9 @@ m.register 'workspace/didRenameFiles' {
m.register 'textDocument/didOpen' {
---@async
function (params)
- workspace.awaitReady()
local doc = params.textDocument
local uri = files.getRealUri(doc.uri)
+ workspace.awaitReady(uri)
local text = doc.text
files.setText(uri, text, true, doc.version)
files.open(uri)
@@ -213,10 +235,10 @@ m.register 'textDocument/didClose' {
m.register 'textDocument/didChange' {
---@async
function (params)
- workspace.awaitReady()
local doc = params.textDocument
local changes = params.contentChanges
local uri = files.getRealUri(doc.uri)
+ workspace.awaitReady(uri)
--log.debug('changes', util.dump(changes))
local text = files.getOriginText(uri) or ''
local rows = files.getCachedRows(uri)
@@ -265,13 +287,13 @@ m.register 'textDocument/definition' {
abortByFileUpdate = true,
---@async
function (params)
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_DEFINITION, 0.5)
- local core = require 'core.definition'
local uri = files.getRealUri(params.textDocument.uri)
+ workspace.awaitReady(uri)
if not files.exists(uri) then
return nil
end
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_DEFINITION, 0.5)
+ local core = require 'core.definition'
local pos = converter.unpackPosition(uri, params.position)
local result = core(uri, pos)
if not result then
@@ -304,13 +326,13 @@ m.register 'textDocument/typeDefinition' {
abortByFileUpdate = true,
---@async
function (params)
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_TYPE_DEFINITION, 0.5)
- local core = require 'core.type-definition'
local uri = files.getRealUri(params.textDocument.uri)
+ workspace.awaitReady(uri)
if not files.exists(uri) then
return nil
end
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_TYPE_DEFINITION, 0.5)
+ local core = require 'core.type-definition'
local pos = converter.unpackPosition(uri, params.position)
local result = core(uri, pos)
if not result then
@@ -343,13 +365,13 @@ m.register 'textDocument/references' {
abortByFileUpdate = true,
---@async
function (params)
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_REFERENCE, 0.5)
- local core = require 'core.reference'
local uri = files.getRealUri(params.textDocument.uri)
+ workspace.awaitReady(uri)
if not files.exists(uri) then
return nil
end
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_REFERENCE, 0.5)
+ local core = require 'core.reference'
local pos = converter.unpackPosition(uri, params.position)
local result = core(uri, pos)
if not result then
@@ -394,13 +416,13 @@ m.register 'textDocument/rename' {
abortByFileUpdate = true,
---@async
function (params)
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_RENAME, 0.5)
- local core = require 'core.rename'
local uri = files.getRealUri(params.textDocument.uri)
+ workspace.awaitReady(uri)
if not files.exists(uri) then
return nil
end
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_RENAME, 0.5)
+ local core = require 'core.rename'
local pos = converter.unpackPosition(uri, params.position)
local result = core.rename(uri, pos, params.newName)
if not result then
@@ -468,7 +490,7 @@ m.register 'textDocument/completion' {
return nil
end
local triggerCharacter = params.context and params.context.triggerCharacter
- if config.get 'editor.acceptSuggestionOnEnter' ~= 'off' then
+ if config.get(nil, 'editor.acceptSuggestionOnEnter') ~= 'off' then
if triggerCharacter == '\n'
or triggerCharacter == '{'
or triggerCharacter == ',' then
@@ -597,15 +619,15 @@ m.register 'textDocument/signatureHelp' {
abortByFileUpdate = true,
---@async
function (params)
- if not config.get 'Lua.signatureHelp.enable' then
+ local uri = files.getRealUri(params.textDocument.uri)
+ if not config.get(uri, 'Lua.signatureHelp.enable') then
return nil
end
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SIGNATURE, 0.5)
- local uri = files.getRealUri(params.textDocument.uri)
+ workspace.awaitReady(uri)
if not files.exists(uri) then
return nil
end
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SIGNATURE, 0.5)
local pos = converter.unpackPosition(uri, params.position)
local core = require 'core.signature'
local results = core(uri, pos)
@@ -643,11 +665,11 @@ m.register 'textDocument/documentSymbol' {
abortByFileUpdate = true,
---@async
function (params)
- workspace.awaitReady()
- local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SYMBOL, 0.5)
- local core = require 'core.document-symbol'
local uri = files.getRealUri(params.textDocument.uri)
+ workspace.awaitReady(uri)
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SYMBOL, 0.5)
+ local core = require 'core.document-symbol'
local symbols = core(uri)
if not symbols then
return nil
@@ -746,7 +768,6 @@ m.register 'workspace/symbol' {
abortByFileUpdate = true,
---@async
function (params)
- workspace.awaitReady()
local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_WS_SYMBOL, 0.5)
local core = require 'core.workspace-symbol'
@@ -780,7 +801,7 @@ m.register 'textDocument/semanticTokens/full' {
---@async
function (params)
local uri = files.getRealUri(params.textDocument.uri)
- workspace.awaitReady()
+ workspace.awaitReady(uri)
local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SEMANTIC_FULL, 0.5)
local core = require 'core.semantic-tokens'
local results = core(uri, 0, math.huge)
@@ -795,7 +816,7 @@ m.register 'textDocument/semanticTokens/range' {
---@async
function (params)
local uri = files.getRealUri(params.textDocument.uri)
- workspace.awaitReady()
+ workspace.awaitReady(uri)
local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SEMANTIC_RANGE, 0.5)
local core = require 'core.semantic-tokens'
local cache = files.getOpenedCache(uri)
@@ -888,10 +909,10 @@ m.register 'textDocument/onTypeFormatting' {
abortByFileUpdate = true,
---@async
function (params)
- workspace.awaitReady()
+ local uri = files.getRealUri(params.textDocument.uri)
+ workspace.awaitReady(uri)
local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_TYPE_FORMATTING, 0.5)
local ch = params.ch
- local uri = files.getRealUri(params.textDocument.uri)
if not files.exists(uri) then
return nil
end
@@ -925,12 +946,12 @@ m.register '$/cancelRequest' {
m.register '$/requestHint' {
---@async
function (params)
- local core = require 'core.hint'
- if not config.get 'Lua.hint.enable' then
+ local uri = files.getRealUri(params.textDocument.uri)
+ if not config.get(uri, 'Lua.hint.enable') then
return
end
- workspace.awaitReady()
- local uri = files.getRealUri(params.textDocument.uri)
+ workspace.awaitReady(uri)
+ local core = require 'core.hint'
local start, finish = converter.unpackRange(uri, params.range)
local results = core(uri, start, finish)
local hintResults = {}
@@ -949,13 +970,13 @@ m.register '$/requestHint' {
do
---@async
local function updateHint(uri)
- if not config.get 'Lua.hint.enable' then
+ if not config.get(uri, 'Lua.hint.enable') then
return
end
local id = 'updateHint' .. uri
await.close(id)
await.setID(id)
- workspace.awaitReady()
+ workspace.awaitReady(uri)
local visibles = files.getVisibles(uri)
if not visibles then
return
@@ -963,7 +984,7 @@ do
await.close(id)
await.setID(id)
await.delay()
- workspace.awaitReady()
+ workspace.awaitReady(uri)
local edits = {}
local hint = require 'core.hint'
local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_HINT, 0.5)
@@ -996,7 +1017,7 @@ do
end
local function refreshStatusBar()
- local value = config.get 'Lua.window.statusBar'
+ local value = config.get(nil, 'Lua.window.statusBar')
if value then
proto.notify('$/status/show')
else
diff --git a/script/provider/semantic-tokens.lua b/script/provider/semantic-tokens.lua
index 68db9b7f..759a9885 100644
--- a/script/provider/semantic-tokens.lua
+++ b/script/provider/semantic-tokens.lua
@@ -47,7 +47,7 @@ local function enable()
},
}
})
- if config.get 'editor.semanticHighlighting.enabled' == 'configuredByTheme' and not dontShowAgain then
+ if config.get(nil, 'editor.semanticHighlighting.enabled') == 'configuredByTheme' and not dontShowAgain then
proto.request('window/showMessageRequest', {
type = define.MessageType.Info,
message = lang.script.WINDOW_CHECK_SEMANTIC,
diff --git a/script/service/service.lua b/script/service/service.lua
index 973b5745..a961d03c 100644
--- a/script/service/service.lua
+++ b/script/service/service.lua
@@ -190,7 +190,7 @@ function m.reportStatus()
info.text = '😺Lua'
end
info.tooltip = lang.script('WINDOW_LUA_STATUS', {
- ws = ws.path or '',
+ ws = ws.rootPath or '',
ast = files.astCount,
max = files.fileCount,
mem = collectgarbage('count') / 1000,
diff --git a/script/service/telemetry.lua b/script/service/telemetry.lua
index dac72f3f..8f24b7d1 100644
--- a/script/service/telemetry.lua
+++ b/script/service/telemetry.lua
@@ -74,7 +74,7 @@ end
timer.wait(5, function ()
timer.loop(300, function ()
- if not config.get 'Lua.telemetry.enable' then
+ if not config.get(nil, 'Lua.telemetry.enable') then
return
end
local suc, link = pcall(net.connect, 'tcp', 'moe-moe.love', 11577)
@@ -93,7 +93,7 @@ timer.wait(5, function ()
end
end)()
timer.loop(1, function ()
- if not config.get 'Lua.telemetry.enable' then
+ if not config.get(nil, 'Lua.telemetry.enable') then
return
end
net.update()
@@ -103,7 +103,7 @@ end)
local m = {}
function m.updateConfig()
- if config.get 'Lua.telemetry.enable' ~= nil then
+ if config.get(nil, 'Lua.telemetry.enable') ~= nil then
return
end
if m.hasShowedMessage then
diff --git a/script/vm/getDocs.lua b/script/vm/getDocs.lua
index 3a0765bf..f179c684 100644
--- a/script/vm/getDocs.lua
+++ b/script/vm/getDocs.lua
@@ -10,14 +10,14 @@ local noder = require 'core.noder'
---获取class与alias
---@param name? string
---@return parser.guide.object[]
-function vm.getDocDefines(name)
+function vm.getDocDefines(uri, name)
local cache = vm.getCache 'getDocDefines'
if cache[name] then
return cache[name]
end
local results = {}
if name == '*' then
- for noders in collector.each('def:dn:') do
+ for noders in collector.each(uri, 'def:dn:') do
for id in noder.eachID(noders) do
if id:sub(1, 3) == 'dn:'
and not id:find(noder.SPLIT_CHAR) then
@@ -31,7 +31,7 @@ function vm.getDocDefines(name)
end
else
local id = 'dn:' .. name
- for noders in collector.each('def:' .. id) do
+ for noders in collector.each(uri, 'def:' .. id) do
for source in noder.eachSource(noders, id) do
if source.type == 'doc.class.name'
or source.type == 'doc.alias.name' then
@@ -153,7 +153,7 @@ local function isDeprecated(value)
return true
elseif doc.type == 'doc.version' then
local valids = vm.getValidVersions(doc)
- if not valids[config.get 'Lua.runtime.version'] then
+ if not valids[config.get(nil, 'Lua.runtime.version')] then
value._deprecated = true
return true
end
diff --git a/script/vm/getGlobals.lua b/script/vm/getGlobals.lua
index 92fd1c8e..f6646559 100644
--- a/script/vm/getGlobals.lua
+++ b/script/vm/getGlobals.lua
@@ -14,7 +14,7 @@ function vm.hasGlobalSets(name)
return collector.has(id)
end
-function vm.getGlobalSets(name)
+function vm.getGlobalSets(uri, name)
local cache = vm.getCache 'getGlobalSets'
if cache[name] then
return cache[name]
@@ -22,7 +22,7 @@ function vm.getGlobalSets(name)
local results = {}
cache[name] = results
if name == '*' then
- for noders in collector.each('def:g:') do
+ for noders in collector.each(uri, 'def:g:') do
for id in noder.eachID(noders) do
if id:sub(1, 2) == 'g:'
and not id:find(noder.SPLIT_CHAR) then
@@ -41,7 +41,7 @@ function vm.getGlobalSets(name)
else
id = ('g:%s'):format(noder.STRING_CHAR, name)
end
- for noders in collector.each('def:' .. id) do
+ for noders in collector.each(uri, 'def:' .. id) do
for source in noder.eachSource(noders, id) do
if guide.isSet(source) then
results[#results+1] = source
diff --git a/script/workspace/loading.lua b/script/workspace/loading.lua
new file mode 100644
index 00000000..c3e8c00c
--- /dev/null
+++ b/script/workspace/loading.lua
@@ -0,0 +1,162 @@
+local progress = require 'progress'
+local lang = require 'language'
+local await = require 'await'
+local files = require 'files'
+local config = require 'config.config'
+local client = require 'client'
+local pub = require 'pub.pub'
+
+---@class workspace.loading
+---@field scp scope
+---@field _bar progress
+---@field _stash function[]
+---@field _refs uri[]
+local mt = {}
+mt.__index = mt
+
+mt._loadLock = false
+mt.read = 0
+mt.max = 0
+mt.preload = 0
+
+function mt:update()
+ self._bar:setMessage(('%d/%d'):format(self.read, self.max))
+ self._bar:setPercentage(self.read / self.max * 100.0)
+end
+
+---@param uri uri
+function mt:checkMaxPreload(uri)
+ local max = config.get(uri, 'Lua.workspace.maxPreload')
+ if self.preload <= max then
+ return true
+ end
+ if self.scp:get 'hasHintedMaxPreload' then
+ return false
+ end
+ self.scp:set('hasHintedMaxPreload', true)
+ client.requestMessage('Info'
+ , lang.script('MWS_MAX_PRELOAD', max)
+ , {
+ lang.script
+ }
+ , function (_, index)
+ if index == 1 then
+ client.setConfig {
+ {
+ key = 'Lua.workspace.maxPreload',
+ uri = self.scp.uri,
+ action = 'set',
+ value = max + math.max(1000, max),
+ }
+ }
+ end
+ end
+ )
+ return false
+end
+
+---@param uri uri
+---@param libraryUri boolean
+---@async
+function mt:scanFile(uri, libraryUri)
+ if files.isLua(uri) then
+ if not libraryUri then
+ self.preload = self.preload + 1
+ if not self:checkMaxPreload(uri) then
+ return
+ end
+ end
+ self.max = self.max + 1
+ self:update()
+ pub.task('loadFile', uri, function (content)
+ self._stash[#self._stash+1] = function ()
+ self.read = self.read + 1
+ self:update()
+ if not content then
+ return
+ end
+ log.info(('Preload file at: %s , size = %.3f KB'):format(uri, #content / 1024.0))
+ table.insert(self.scp:get 'cachedUris', uri)
+ files.setText(uri, content, false)
+ files.addRef(uri)
+ if libraryUri then
+ log.info('++++As library of:', libraryUri)
+ files.setLibraryUri(self.scp, uri, libraryUri)
+ end
+ end
+ end)
+ elseif files.isDll(uri) then
+ self.max = self.max + 1
+ self:update()
+ pub.task('loadFile', uri, function (content)
+ self._stash[#self._stash+1] = function ()
+ self.read = self.read + 1
+ self:update()
+ if not content then
+ return
+ end
+ log.info(('Preload dll at: %s , size = %.3f KB'):format(uri, #content / 1024.0))
+ table.insert(self.scp:get 'cachedUris', uri)
+ files.saveDll(uri, content)
+ files.addRef(uri)
+ if libraryUri then
+ log.info('++++As library of:', libraryUri)
+ end
+ end
+ end)
+ await.delay()
+ end
+end
+
+function mt:loadStashed()
+ self:update()
+ if self._loadLock then
+ return
+ end
+ self._loadLock = true
+ ---@async
+ await.call(function ()
+ while true do
+ local loader = table.remove(self._stash)
+ if not loader then
+ break
+ end
+ loader()
+ await.delay()
+ end
+ self._loadLock = false
+ end)
+end
+
+---@async
+function mt:loadAll()
+ while self.read < self.max do
+ log.info(('Loaded %d/%d files'):format(self.read, self.max))
+ self:loadStashed()
+ await.sleep(0.1)
+ end
+end
+
+function mt:remove()
+ self._bar:remove()
+end
+
+function mt:__close()
+ self:remove()
+end
+
+---@class workspace.loading.manager
+local m = {}
+
+---@return workspace.loading
+function m.create(scp)
+ local loading = setmetatable({
+ scp = scp,
+ _bar = progress.create(lang.script('WORKSPACE_LOADING', scp.uri)),
+ _stash = {},
+ }, mt)
+ scp:set('cachedUris', {})
+ return loading
+end
+
+return m
diff --git a/script/workspace/require-path.lua b/script/workspace/require-path.lua
index e2149bac..e6bb6c78 100644
--- a/script/workspace/require-path.lua
+++ b/script/workspace/require-path.lua
@@ -9,7 +9,7 @@ m.cache = {}
--- `aaa/bbb/ccc.lua` 与 `?.lua` 将返回 `aaa.bbb.cccc`
local function getOnePath(path, searcher)
- local separator = config.get 'Lua.completion.requireSeparator'
+ local separator = config.get(nil, 'Lua.completion.requireSeparator')
local stemPath = path
: gsub('%.[^%.]+$', '')
: gsub('[/\\%.]+', separator)
@@ -28,8 +28,8 @@ local function getOnePath(path, searcher)
end
function m.getVisiblePath(path)
- local searchers = config.get 'Lua.runtime.path'
- local strict = config.get 'Lua.runtime.pathStrict'
+ local searchers = config.get(nil, 'Lua.runtime.path')
+ local strict = config.get(nil, 'Lua.runtime.pathStrict')
path = path:gsub('^[/\\]+', '')
local uri = furi.encode(path)
local libraryPath = files.getLibraryPath(uri)
diff --git a/script/workspace/scope.lua b/script/workspace/scope.lua
new file mode 100644
index 00000000..6abf30d5
--- /dev/null
+++ b/script/workspace/scope.lua
@@ -0,0 +1,123 @@
+---@alias scope.type '"override"'|'"folder"'|'"fallback"'
+
+---@class scope
+---@field type scope.type
+---@field uri? uri
+---@field _links table<uri, boolean>
+---@field _data table<string, any>
+local mt = {}
+mt.__index = mt
+
+---@param uri uri
+function mt:addLink(uri)
+ self._links[uri] = true
+end
+
+---@param uri uri
+function mt:removeLink(uri)
+ self._links[uri] = nil
+end
+
+function mt:removeAllLinks()
+ self._links = {}
+end
+
+---@param uri uri
+---@return boolean
+function mt:isChildUri(uri)
+ return uri:sub(1, #self.uri) == self.uri
+end
+
+---@param uri uri
+---@return boolean
+function mt:isLinkedUri(uri)
+ for linkUri in pairs(self._links) do
+ if uri:sub(1, #linkUri) == linkUri then
+ return true
+ end
+ end
+ return false
+end
+
+---@param k string
+---@param v any
+function mt:set(k, v)
+ self._data[k] = v
+ return v
+end
+
+---@param k string
+---@return any
+function mt:get(k)
+ return self._data[k]
+end
+
+---@param scopeType scope.type
+---@return scope
+local function createScope(scopeType)
+ local scope = setmetatable({
+ type = scopeType,
+ _links = {},
+ _data = {},
+ }, mt)
+
+ return scope
+end
+
+---@class scope.manager
+local m = {}
+
+---@type scope[]
+m.folders = {}
+m.override = createScope 'override'
+m.fallback = createScope 'fallback'
+
+---@param uri uri
+---@return scope
+function m.createFolder(uri)
+ local scope = createScope 'folder'
+ scope.uri = uri
+
+ local inserted = false
+ for i, otherScope in ipairs(m.folders) do
+ if #uri > #otherScope.uri then
+ table.insert(m.folders, i, scope)
+ inserted = true
+ break
+ end
+ end
+ if not inserted then
+ table.insert(m.folders, scope)
+ end
+
+ return scope
+end
+
+---@param uri uri
+---@return scope
+function m.getFolder(uri)
+ for _, scope in ipairs(m.folders) do
+ if not uri or scope:isChildUri(uri) then
+ return scope
+ end
+ end
+ return nil
+end
+
+---@param uri uri
+---@return scope
+function m.getLinkedScope(uri)
+ if m.override and m.override:isLinkedUri(uri) then
+ return m.override
+ end
+ for _, scope in ipairs(m.folders) do
+ if scope:isLinkedUri(uri) then
+ return scope
+ end
+ end
+ if m.fallback:isLinkedUri(uri) then
+ return m.fallback
+ end
+end
+
+return m
diff --git a/script/workspace/workspace.lua b/script/workspace/workspace.lua
index ea2c4737..12971ae5 100644
--- a/script/workspace/workspace.lua
+++ b/script/workspace/workspace.lua
@@ -6,44 +6,34 @@ local config = require 'config'
local glob = require 'glob'
local platform = require 'bee.platform'
local await = require 'await'
-local proto = require 'proto.proto'
-local lang = require 'language'
local library = require 'library'
-local progress = require 'progress'
-local define = require "proto.define"
local client = require 'client'
local plugin = require 'plugin'
local util = require 'utility'
local fw = require 'filewatch'
+local scope = require 'workspace.scope'
+local loading = require 'workspace.loading'
+---@class workspace
local m = {}
m.type = 'workspace'
-m.nativeVersion = -1
-m.libraryVersion = -1
-m.nativeMatcher = nil
-m.fileLoaded = 0
-m.fileFound = 0
-m.waitingReady = {}
-m.requireCache = {}
-m.cache = {}
-m.watchers = {}
-m.matchOption = {}
---- 初始化工作区
-function m.initPath(uri)
- log.info('Workspace inited: ', uri)
- if not uri then
- return
- end
- m.uri = uri
- m.path = m.normalize(furi.decode(uri))
- plugin.workspace = m.path
+function m.initRoot(uri)
+ m.rootUri = uri
+ log.info('Workspace init root: ', uri)
+
local logPath = fs.path(LOGPATH) / (uri:gsub('[/:]+', '_') .. '.log')
client.logMessage('Log', 'Log path: ' .. furi.encode(logPath:string()))
log.info('Log path: ', logPath)
log.init(ROOT, logPath)
+end
- fw.watch(m.path)
+--- 初始化工作区
+function m.create(uri)
+ log.info('Workspace create: ', uri)
+ local path = m.normalize(furi.decode(uri))
+ fw.watch(path)
+ scope.createFolder(uri)
end
local globInteferFace = {
@@ -75,25 +65,23 @@ local globInteferFace = {
--- 创建排除文件匹配器
---@async
-function m.getNativeMatcher()
- if not m.path then
- return nil
- end
- if m.nativeMatcher then
- return m.nativeMatcher
+---@param scp scope
+function m.getNativeMatcher(scp)
+ if scp:get 'nativeMatcher' then
+ return scp:get 'nativeMatcher'
end
local pattern = {}
- -- config.get 'files.exclude'
- for path, ignore in pairs(config.get 'files.exclude') do
+ -- config.get(nil, 'files.exclude'
+ for path, ignore in pairs(config.get(scp.uri, 'files.exclude')) do
if ignore then
log.info('Ignore by exclude:', path)
pattern[#pattern+1] = path
end
end
- -- config.get 'workspace.useGitIgnore'
- if config.get 'Lua.workspace.useGitIgnore' then
- local buf = pub.awaitTask('loadFile', furi.encode(m.path .. '/.gitignore'))
+ -- config.get(nil, 'workspace.useGitIgnore'
+ if config.get(scp.uri, 'Lua.workspace.useGitIgnore') then
+ local buf = pub.awaitTask('loadFile', m.rootUri .. '/.gitignore')
if buf then
for line in buf:gmatch '[^\r\n]+' do
if line:sub(1, 1) ~= '#' then
@@ -102,7 +90,7 @@ function m.getNativeMatcher()
end
end
end
- buf = pub.awaitTask('loadFile', furi.encode(m.path .. '/.git/info/exclude'))
+ buf = pub.awaitTask('loadFile', m.rootUri .. '/.git/info/exclude')
if buf then
for line in buf:gmatch '[^\r\n]+' do
if line:sub(1, 1) ~= '#' then
@@ -112,9 +100,9 @@ function m.getNativeMatcher()
end
end
end
- -- config.get 'workspace.ignoreSubmodules'
- if config.get 'Lua.workspace.ignoreSubmodules' then
- local buf = pub.awaitTask('loadFile', furi.encode(m.path .. '/.gitmodules'))
+ -- config.get(nil, 'workspace.ignoreSubmodules'
+ if config.get(scp.uri, 'Lua.workspace.ignoreSubmodules') then
+ local buf = pub.awaitTask('loadFile', m.rootUri .. '/.gitmodules')
if buf then
for path in buf:gmatch('path = ([^\r\n]+)') do
log.info('Ignore by .gitmodules:', path)
@@ -122,66 +110,75 @@ function m.getNativeMatcher()
end
end
end
- -- config.get 'workspace.library'
- for path in pairs(config.get 'Lua.workspace.library') do
+ -- config.get(nil, 'workspace.library'
+ for path in pairs(config.get(scp.uri, 'Lua.workspace.library')) do
path = m.getAbsolutePath(path)
if path then
log.info('Ignore by library:', path)
pattern[#pattern+1] = path
end
end
- -- config.get 'workspace.ignoreDir'
- for _, path in ipairs(config.get 'Lua.workspace.ignoreDir') do
+ -- config.get(nil, 'workspace.ignoreDir'
+ for _, path in ipairs(config.get(scp.uri, 'Lua.workspace.ignoreDir')) do
log.info('Ignore directory:', path)
pattern[#pattern+1] = path
end
- m.nativeMatcher = glob.gitignore(pattern, m.matchOption, globInteferFace)
- m.nativeMatcher:setOption('root', m.path)
+ local matcher = glob.gitignore(pattern, {
+ root = furi.decode(scp.uri),
+ ignoreCase = platform.OS == 'Windows',
+ }, globInteferFace)
- m.nativeVersion = config.get 'version'
- return m.nativeMatcher
+ scp:set('nativeMatcher', matcher)
+ return matcher
end
--- 创建代码库筛选器
-function m.getLibraryMatchers()
- if m.libraryMatchers then
- return m.libraryMatchers
+---@param scp scope
+function m.getLibraryMatchers(scp)
+ if scp:get 'nativeMatcher' then
+ return scp:get 'nativeMatcher'
end
local librarys = {}
- for path in pairs(config.get 'Lua.workspace.library') do
+ for path in pairs(config.get(scp.uri, 'Lua.workspace.library')) do
path = m.getAbsolutePath(path)
if path then
librarys[m.normalize(path)] = true
end
end
+ -- TODO
if library.metaPath then
librarys[m.normalize(library.metaPath)] = true
end
- m.libraryMatchers = {}
+
+ local matchers = {}
for path in pairs(librarys) do
if fs.exists(fs.path(path)) then
local nPath = fs.absolute(fs.path(path)):string()
- local matcher = glob.gitignore(true, m.matchOption, globInteferFace)
- matcher:setOption('root', path)
- log.debug('getLibraryMatchers', path, nPath)
- m.libraryMatchers[#m.libraryMatchers+1] = {
- path = nPath,
+ local matcher = glob.gitignore(true, {
+ root = path,
+ ignoreCase = platform.OS == 'Windows',
+ }, globInteferFace)
+ matchers[#matchers+1] = {
+ uri = furi.encode(nPath),
matcher = matcher
}
end
end
- m.libraryVersion = config.get 'version'
- return m.libraryMatchers
+ scp:set('nativeMatcher', matchers)
+
+ return matchers
end
--- 文件是否被忽略
---@async
+---@param uri uri
function m.isIgnored(uri)
- local path = m.getRelativePath(uri)
- local ignore = m.getNativeMatcher()
+ local scp = m.getScope(uri)
+ local path = m.getRelativePath(uri)
+ local ignore = m.getNativeMatcher(scp)
if not ignore then
return false
end
@@ -200,187 +197,63 @@ function m.isValidLuaUri(uri)
return true
end
-local function loadFileFactory(root, progressData, isLibrary)
- return function (path) ---@async
- local uri = furi.encode(path)
- if files.isLua(uri) then
- if not isLibrary and progressData.preload >= config.get 'Lua.workspace.maxPreload' then
- if not m.hasHitMaxPreload then
- m.hasHitMaxPreload = true
- proto.request('window/showMessageRequest', {
- type = define.MessageType.Info,
- message = lang.script('MWS_MAX_PRELOAD', config.get 'Lua.workspace.maxPreload'),
- actions = {
- {
- title = lang.script.WINDOW_INCREASE_UPPER_LIMIT,
- },
- {
- title = lang.script.WINDOW_CLOSE,
- }
- }
- }, function (item)
- if not item then
- return
- end
- if item.title == lang.script.WINDOW_INCREASE_UPPER_LIMIT then
- client.setConfig {
- {
- key = 'Lua.workspace.maxPreload',
- action = 'set',
- value = config.get 'Lua.workspace.maxPreload'
- + math.max(1000, config.get 'Lua.workspace.maxPreload'),
- }
- }
- end
- end)
- end
- return
- end
- if not isLibrary then
- progressData.preload = progressData.preload + 1
- end
- progressData.max = progressData.max + 1
- progressData:update()
- pub.task('loadFile', uri, function (text)
- local loader = function ()
- if text then
- log.info(('Preload file at: %s , size = %.3f KB'):format(uri, #text / 1024.0))
- if isLibrary then
- log.info('++++As library of:', root)
- files.setLibraryPath(uri, root)
- end
- files.setText(uri, text, false)
- else
- files.remove(uri)
- end
- progressData.read = progressData.read + 1
- progressData:update()
- end
- if progressData.loaders then
- progressData.loaders[#progressData.loaders+1] = loader
- else
- loader()
- end
- end)
- end
- if files.isDll(uri) then
- progressData.max = progressData.max + 1
- progressData:update()
- pub.task('loadFile', uri, function (content)
- if content then
- log.info(('Preload file at: %s , size = %.3f KB'):format(uri, #content / 1024.0))
- if isLibrary then
- log.info('++++As library of:', root)
- end
- files.saveDll(uri, content)
- end
- progressData.read = progressData.read + 1
- progressData:update()
- end)
- end
- await.delay()
- end
-end
-
---@async
function m.awaitLoadFile(uri)
- local progressBar <close> = progress.create(lang.script.WORKSPACE_LOADING)
- local progressData = {
- max = 0,
- read = 0,
- preload = 0,
- update = function (self)
- progressBar:setMessage(('%d/%d'):format(self.read, self.max))
- progressBar:setPercentage(self.read / self.max * 100)
- end
- }
- local nativeLoader = loadFileFactory(m.path, progressData)
- local native = m.getNativeMatcher()
- if native then
- log.info('Scan files at:', m.path)
- native:scan(furi.decode(uri), nativeLoader)
- end
+ local scp = m.getScope(uri)
+ local ld <close> = loading.create(scp)
+ local native = m.getNativeMatcher(scp)
+ log.info('Scan files at:', uri)
+ ---@async
+ native:scan(furi.decode(uri), function (path)
+ ld:scanFile(furi.encode(path))
+ end)
+ ld:loadAll()
end
--- 预读工作区内所有文件
---@async
-function m.awaitPreload()
- local diagnostic = require 'provider.diagnostic'
+---@param scp scope
+function m.awaitPreload(scp)
await.close 'preload'
await.setID 'preload'
await.sleep(0.1)
- diagnostic.pause()
- m.libraryMatchers = nil
- m.nativeMatcher = nil
- m.fileLoaded = 0
- m.fileFound = 0
- m.cache = {}
- for i, watchers in ipairs(m.watchers) do
- watchers()
- m.watchers[i] = nil
- end
- local progressBar <close> = progress.create(lang.script.WORKSPACE_LOADING)
- local progressData = {
- max = 0,
- read = 0,
- preload = 0,
- loaders = {},
- update = function (self)
- progressBar:setMessage(('%d/%d'):format(self.read, self.max))
- progressBar:setPercentage(self.read / self.max * 100)
- m.fileLoaded = self.read
- m.fileFound = self.max
- end
- }
- log.info('Preload start.')
- local nativeLoader = loadFileFactory(m.path, progressData)
- local native = m.getNativeMatcher()
- local librarys = m.getLibraryMatchers()
- if native then
- log.info('Scan files at:', m.path)
- native:scan(m.path, nativeLoader)
- end
- for _, library in ipairs(librarys) do
- 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] = fw.watch(library.path)
- end
-
- local isLoadingFiles = false
- local function loadSomeFiles()
- if isLoadingFiles then
- return
+
+ local watchers = scp:get 'watchers'
+ if watchers then
+ for _, dispose in ipairs(watchers) do
+ dispose()
end
- await.call(function () ---@async
- isLoadingFiles = true
- while true do
- local loader = table.remove(progressData.loaders)
- if not loader then
- break
- end
- loader()
- await.delay()
- end
- isLoadingFiles = false
+ end
+ watchers = {}
+ scp:set('watchers', watchers)
+
+ local ld <close> = loading.create(scp)
+
+ log.info('Preload start:', scp.uri)
+
+ local native = m.getNativeMatcher(scp)
+ local librarys = m.getLibraryMatchers(scp)
+
+ do
+ log.info('Scan files at:', m.rootUri)
+ ---@async
+ native:scan(furi.decode(scp.uri), function (path)
+ ld:scanFile(furi.encode(path))
end)
end
- log.info(('Found %d files.'):format(progressData.max))
- while true do
- loadSomeFiles()
- log.info(('Loaded %d/%d files'):format(progressData.read, progressData.max))
- progressData:update()
- if progressData.read >= progressData.max then
- break
- end
- await.sleep(0.1)
+ for _, libMatcher in ipairs(librarys) do
+ log.info('Scan library at:', libMatcher.uri)
+ ---@async
+ libMatcher.matcher:scan(furi.decode(libMatcher.uri), function (path)
+ ld:scanFile(furi.encode(path), libMatcher.uri)
+ end)
+ watchers[#watchers+1] = fw.watch(furi.decode(libMatcher.uri))
end
- progressBar:remove()
+ log.info(('Found %d files.'):format(ld.max))
+ ld:loadAll()
log.info('Preload finish.')
-
- diagnostic.start()
end
--- 查找符合指定file path的所有uri
@@ -396,7 +269,7 @@ function m.findUrisByFilePath(path)
return resultCache[path].results, resultCache[path].posts
end
tracy.ZoneBeginN('findUrisByFilePath #1')
- local strict = config.get 'Lua.runtime.pathStrict'
+ local strict = config.get(nil, 'Lua.runtime.pathStrict')
local results = {}
local posts = {}
for uri in files.eachFile() do
@@ -455,7 +328,7 @@ function m.findUrisByRequirePath(path)
local input = path:gsub('%.', '/')
:gsub('%%', '%%%%')
- for _, luapath in ipairs(config.get 'Lua.runtime.path') do
+ for _, luapath in ipairs(config.get(nil, 'Lua.runtime.path')) do
local part = m.normalize(luapath:gsub('%?', input))
local uris, posts = m.findUrisByFilePath(part)
for _, uri in ipairs(uris) do
@@ -499,16 +372,22 @@ function m.normalize(path)
end
---@return string
-function m.getAbsolutePath(path)
+function m.getAbsolutePath(folderUriOrPath, 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
+ if not folderUriOrPath then
return nil
end
- path = m.normalize(m.path .. '/' .. path)
+ local folderPath
+ if folderUriOrPath:sub(1, 5) == 'file:' then
+ folderPath = furi.decode(folderUriOrPath)
+ else
+ folderPath = folderUriOrPath
+ end
+ path = m.normalize(folderPath .. '/' .. path)
end
return path
end
@@ -516,17 +395,20 @@ end
---@param uriOrPath uri|string
---@return string
function m.getRelativePath(uriOrPath)
- local path
+ local path, uri
if uriOrPath:sub(1, 5) == 'file:' then
path = furi.decode(uriOrPath)
+ uri = uriOrPath
else
path = uriOrPath
+ uri = furi.encode(uriOrPath)
end
- if not m.path then
+ local scp = m.getScope(uri)
+ if not scp.uri then
local relative = m.normalize(path)
return relative:gsub('^[/\\]+', '')
end
- local _, pos = m.normalize(path):find(m.path, 1, true)
+ local _, pos = m.normalize(path):find(furi.decode(scp.uri), 1, true)
if pos then
return m.normalize(path:sub(pos + 1)):gsub('^[/\\]+', '')
else
@@ -534,14 +416,6 @@ function m.getRelativePath(uriOrPath)
end
end
-function m.isWorkspaceUri(uri)
- if not m.uri then
- return false
- end
- local ruri = m.uri
- return uri:sub(1, #ruri) == ruri
-end
-
--- 获取工作区等级的缓存
function m.getCache(name)
if not m.cache[name] then
@@ -554,14 +428,18 @@ function m.flushCache()
m.cache = {}
end
-function m.reload()
+---@param scp scope
+function m.reload(scp)
if not m.inited then
return
end
if TEST then
return
end
- await.call(m.awaitReload)
+ ---@async
+ await.call(function ()
+ m.awaitReload(scp)
+ end)
end
function m.init()
@@ -569,39 +447,80 @@ function m.init()
return
end
m.inited = true
- m.reload()
+ if m.rootUri then
+ for _, folder in ipairs(scope.folders) do
+ m.reload(folder)
+ end
+ else
+ m.reload(scope.fallback)
+ end
+end
+
+---@param scp scope
+function m.removeFiles(scp)
+ local cachedUris = scp:get 'cachedUris'
+ if not cachedUris then
+ return
+ end
+ scp:set('cachedUris', nil)
+ for _, uri in ipairs(cachedUris) do
+ files.delRef(uri)
+ end
+end
+
+---@param scp scope
+function m.resetFiles(scp)
+ local cachedUris = scp:get 'cachedUris'
+ if not cachedUris then
+ return
+ end
+ for _, uri in ipairs(cachedUris) do
+ files.resetText(uri)
+ end
end
---@async
-function m.awaitReload()
- m.ready = false
- m.hasHitMaxPreload = false
- files.flushAllLibrary()
- files.removeAllClosed()
- files.flushCache()
- plugin.init()
- m.awaitPreload()
- m.ready = true
- local waiting = m.waitingReady
- m.waitingReady = {}
- for _, waker in ipairs(waiting) do
- waker()
+---@param scp scope
+function m.awaitReload(scp)
+ m.removeFiles(scp)
+ plugin.init(scp)
+ m.awaitPreload(scp)
+ scp:set('ready', true)
+ local waiting = scp:get('waitingReady')
+ if waiting then
+ scp:set('waitingReady', nil)
+ for _, waker in ipairs(waiting) do
+ waker()
+ end
end
end
+---@param uri uri
+---@return scope
+function m.getScope(uri)
+ return scope.getFolder(uri)
+ or scope.getLinkedScope(uri)
+ or scope.fallback
+end
+
---等待工作目录加载完成
---@async
-function m.awaitReady()
- if m.isReady() then
+function m.awaitReady(uri)
+ if m.isReady(uri) then
return
end
+ local scp = m.getScope(uri)
+ local waitingReady = scp:get('waitingReady')
+ or scp:set('waitingReady', {})
await.wait(function (waker)
- m.waitingReady[#m.waitingReady+1] = waker
+ waitingReady[#waitingReady+1] = waker
end)
end
-function m.isReady()
- return m.ready == true
+---@param uri uri
+function m.isReady(uri)
+ local scp = m.getScope(uri)
+ return scp:get('ready') == true
end
function m.getLoadProcess()
@@ -627,12 +546,13 @@ config.watch(function (key, value, oldValue)
end)
fw.event(function (changes) ---@async
+ -- TODO
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
+ local scp = m.getScope(uri)
+ if scp.type == 'fallback' then
goto CONTINUE
end
if change.type == 'create' then
@@ -657,7 +577,7 @@ fw.event(function (changes) ---@async
-- 排除类文件发生更改需要重新扫描
if filename == '.gitignore'
or filename == '.gitmodules' then
- m.reload()
+ m.reload(scp)
break
end
end
diff --git a/test.lua b/test.lua
index 21d10c5d..8bf17e8b 100644
--- a/test.lua
+++ b/test.lua
@@ -41,7 +41,7 @@ local function loadDocMetas()
for _, path in ipairs(library.metaPaths) do
local uri = furi.encode(path)
files.setText(uri, fsu.loadFile(path))
- files.setLibraryPath(uri, library.metaPath)
+ files.addRef(uri)
end
end
@@ -82,7 +82,6 @@ end
local function main()
require 'utility'.enableCloseFunction()
- require 'config'.init()
require 'core.searcher'.debugMode = true
require 'language' 'zh-cn'
require 'library'.init()
diff --git a/test/completion/common.lua b/test/completion/common.lua
index 3a3d1d46..94b55514 100644
--- a/test/completion/common.lua
+++ b/test/completion/common.lua
@@ -1,10 +1,10 @@
local define = require 'proto.define'
local config = require 'config'
-config.set('Lua.completion.callSnippet', 'Both')
-config.set('Lua.completion.keywordSnippet', 'Both')
-config.set('Lua.completion.workspaceWord', false)
-config.set('Lua.completion.showWord', 'Enable')
+config.set(nil, 'Lua.completion.callSnippet', 'Both')
+config.set(nil, 'Lua.completion.keywordSnippet', 'Both')
+config.set(nil, 'Lua.completion.workspaceWord', false)
+config.set(nil, 'Lua.completion.showWord', 'Enable')
TEST [[
local zabcde
@@ -805,7 +805,7 @@ print(io.<??>)
]]
(EXISTS)
-require 'config'.set('Lua.runtime.version', 'Lua 5.4')
+require 'config'.set(nil, 'Lua.runtime.version', 'Lua 5.4')
--TEST [[
--local <??>
--]]
@@ -2402,7 +2402,7 @@ end
]]
(EXISTS)
-config.set('Lua.completion.callSnippet', 'Disable')
+config.set(nil, 'Lua.completion.callSnippet', 'Disable')
TEST [[
GGG = 1
diff --git a/test/completion/continue.lua b/test/completion/continue.lua
index 63f970e9..83eaf270 100644
--- a/test/completion/continue.lua
+++ b/test/completion/continue.lua
@@ -1,9 +1,9 @@
local define = require 'proto.define'
local config = require 'config'
-config.set('Lua.completion.callSnippet', 'Disable')
-config.set('Lua.completion.keywordSnippet', 'Disable')
-config.set('Lua.completion.workspaceWord', false)
+config.set(nil, 'Lua.completion.callSnippet', 'Disable')
+config.set(nil, 'Lua.completion.keywordSnippet', 'Disable')
+config.set(nil, 'Lua.completion.workspaceWord', false)
ContinueTyping = true
diff --git a/test/crossfile/allreferences.lua b/test/crossfile/allreferences.lua
index 6c7febeb..2753d785 100644
--- a/test/crossfile/allreferences.lua
+++ b/test/crossfile/allreferences.lua
@@ -68,7 +68,7 @@ TEST {
},
}
-config.set('Lua.IntelliSense.traceBeSetted', true)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', true)
TEST {
{
path = 'a.lua',
@@ -215,5 +215,4 @@ TEST {
]]
},
}
-config.set('Lua.IntelliSense.traceBeSetted', false)
-
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', false)
diff --git a/test/crossfile/completion.lua b/test/crossfile/completion.lua
index 50ebad45..c608ccab 100644
--- a/test/crossfile/completion.lua
+++ b/test/crossfile/completion.lua
@@ -307,8 +307,8 @@ TEST {
}
}
-local originSeparator = config.get 'Lua.completion.requireSeparator'
-config.set('Lua.completion.requireSeparator', '/')
+local originSeparator = config.get(nil, 'Lua.completion.requireSeparator')
+config.set(nil, 'Lua.completion.requireSeparator', '/')
TEST {
{
path = 'abc.lua',
@@ -331,7 +331,7 @@ TEST {
},
}
}
-config.set('Lua.completion.requireSeparator', originSeparator)
+config.set(nil, 'Lua.completion.requireSeparator', originSeparator)
TEST {
{
@@ -390,8 +390,8 @@ TEST {
}
-local originRuntimePath = config.get 'Lua.runtime.path'
-config.set('Lua.runtime.path', {
+local originRuntimePath = config.get(nil, 'Lua.runtime.path')
+config.set(nil, 'Lua.runtime.path', {
'?/1.lua',
})
@@ -419,10 +419,10 @@ TEST {
}
}
-config.set('Lua.runtime.path', originRuntimePath)
+config.set(nil, 'Lua.runtime.path', originRuntimePath)
-local originRuntimePath = config.get 'Lua.runtime.path'
-config.set('Lua.runtime.path', {
+local originRuntimePath = config.get(nil, 'Lua.runtime.path')
+config.set(nil, 'Lua.runtime.path', {
'D:/?/1.lua',
})
@@ -445,7 +445,7 @@ TEST {
}
}
-config.set('Lua.runtime.path', originRuntimePath)
+config.set(nil, 'Lua.runtime.path', originRuntimePath)
TEST {
{
@@ -627,7 +627,7 @@ TEST {
}
}
-config.set('Lua.runtime.pathStrict', true)
+config.set(nil, 'Lua.runtime.pathStrict', true)
TEST {
{ path = 'f/a.lua' },
@@ -672,7 +672,7 @@ TEST {
}
}
-config.set('Lua.runtime.pathStrict', false)
+config.set(nil, 'Lua.runtime.pathStrict', false)
TEST {
{
@@ -960,7 +960,7 @@ TEST {
completion = EXISTS
}
-config.prop('Lua.runtime.special', 'import', 'require')
+config.prop(nil, 'Lua.runtime.special', 'import', 'require')
TEST {
{ path = 'abcde.lua', content = '' },
{
diff --git a/test/crossfile/definition.lua b/test/crossfile/definition.lua
index 058f5d18..8f4dd7e8 100644
--- a/test/crossfile/definition.lua
+++ b/test/crossfile/definition.lua
@@ -117,7 +117,7 @@ TEST {
},
}
-config.set('Lua.runtime.pathStrict', true)
+config.set(nil, 'Lua.runtime.pathStrict', true)
TEST {
{
path = 'aaa/bbb.lua',
@@ -140,7 +140,7 @@ TEST {
},
}
-config.set('Lua.runtime.pathStrict', false)
+config.set(nil, 'Lua.runtime.pathStrict', false)
TEST {
{
@@ -740,8 +740,8 @@ TEST {
}
platform.OS = originOS
-local originRuntimePath = config.get 'Lua.runtime.path'
-config.set('Lua.runtime.path', {
+local originRuntimePath = config.get(nil, 'Lua.runtime.path')
+config.set(nil, 'Lua.runtime.path', {
'?/1.lua',
})
TEST {
@@ -760,7 +760,7 @@ TEST {
},
}
-config.set('Lua.runtime.path', {
+config.set(nil, 'Lua.runtime.path', {
'D:/?/1.lua',
})
TEST {
@@ -778,7 +778,7 @@ TEST {
]],
},
}
-config.set('Lua.runtime.path', originRuntimePath)
+config.set(nil, 'Lua.runtime.path', originRuntimePath)
TEST {
{
@@ -795,7 +795,7 @@ TEST {
},
}
-config.set('Lua.IntelliSense.traceFieldInject', true)
+config.set(nil, 'Lua.IntelliSense.traceFieldInject', true)
TEST {
{
path = 'a.lua',
@@ -816,7 +816,7 @@ print(b.<?test?>)
]]
}
}
-config.set('Lua.IntelliSense.traceFieldInject', false)
+config.set(nil, 'Lua.IntelliSense.traceFieldInject', false)
TEST {
{
diff --git a/test/crossfile/diagnostic.lua b/test/crossfile/diagnostic.lua
index c2d043f4..9bdce197 100644
--- a/test/crossfile/diagnostic.lua
+++ b/test/crossfile/diagnostic.lua
@@ -5,8 +5,8 @@ local config = require 'config'
local platform = require 'bee.platform'
local catch = require 'catch'
-config.get 'Lua.diagnostics.neededFileStatus'['deprecated'] = 'Any'
-config.get 'Lua.diagnostics.neededFileStatus'['type-check'] = 'Any'
+config.get(nil, 'Lua.diagnostics.neededFileStatus')['deprecated'] = 'Any'
+config.get(nil, 'Lua.diagnostics.neededFileStatus')['type-check'] = 'Any'
rawset(_G, 'TEST', true)
diff --git a/test/definition/bug.lua b/test/definition/bug.lua
index a7780803..4a755170 100644
--- a/test/definition/bug.lua
+++ b/test/definition/bug.lua
@@ -172,7 +172,7 @@ string.xx:<?format?>()
--v.<?bar1?>
--]]
-config.set('Lua.IntelliSense.traceLocalSet', true)
+config.set(nil, 'Lua.IntelliSense.traceLocalSet', true)
TEST [[
local A, B
@@ -232,7 +232,7 @@ end
local <!b!> = B:get()
print(<?b?>)
]]
-config.set('Lua.IntelliSense.traceLocalSet', false)
+config.set(nil, 'Lua.IntelliSense.traceLocalSet', false)
TEST [[
g[a.b.c] = 1
diff --git a/test/diagnostics/init.lua b/test/diagnostics/init.lua
index 1bbd83b9..f95c0bad 100644
--- a/test/diagnostics/init.lua
+++ b/test/diagnostics/init.lua
@@ -4,9 +4,9 @@ local config = require 'config'
local util = require 'utility'
local catch = require 'catch'
-config.get 'Lua.diagnostics.neededFileStatus'['deprecated'] = 'Any'
-config.get 'Lua.diagnostics.neededFileStatus'['type-check'] = 'Any'
-config.get 'Lua.diagnostics.neededFileStatus'['await-in-sync'] = 'Any'
+config.get(nil, 'Lua.diagnostics.neededFileStatus')['deprecated'] = 'Any'
+config.get(nil, 'Lua.diagnostics.neededFileStatus')['type-check'] = 'Any'
+config.get(nil, 'Lua.diagnostics.neededFileStatus')['await-in-sync'] = 'Any'
rawset(_G, 'TEST', true)
@@ -177,7 +177,7 @@ local _ENV = { print = print }
print(1)
]]
-config.get 'Lua.diagnostics.disable'['undefined-env-child'] = true
+config.get(nil, 'Lua.diagnostics.disable')['undefined-env-child'] = true
TEST [[
_ENV = nil
<!GLOBAL!> = 1 --> _ENV.GLOBAL = 1
@@ -203,7 +203,7 @@ GLOBAL = 1
_ENV = nil
]]
-config.get 'Lua.diagnostics.disable'['undefined-env-child'] = nil
+config.get(nil, 'Lua.diagnostics.disable')['undefined-env-child'] = nil
TEST [[
<!print()
('string')!>:sub(1, 1)
@@ -315,17 +315,17 @@ return [[
]]
]=]
-config.get 'Lua.diagnostics.disable'['close-non-object'] = true
+config.get(nil, 'Lua.diagnostics.disable')['close-non-object'] = true
TEST [[
local _ <close> = function () end
]]
-config.get 'Lua.diagnostics.disable'['close-non-object'] = nil
+config.get(nil, 'Lua.diagnostics.disable')['close-non-object'] = nil
TEST [[
local _ <close> = <!1!>
]]
-config.get 'Lua.diagnostics.disable'['unused-local'] = true
+config.get(nil, 'Lua.diagnostics.disable')['unused-local'] = true
TEST [[
local f = <!function () end!>
]]
@@ -338,7 +338,7 @@ TEST [[
local <!function f() end!>
]]
-config.get 'Lua.diagnostics.disable'['unused-local'] = nil
+config.get(nil, 'Lua.diagnostics.disable')['unused-local'] = nil
TEST [[
local mt, x
function mt:m()
@@ -1427,7 +1427,7 @@ end
X = f()
]]
-config.get 'Lua.diagnostics.neededFileStatus'['not-yieldable'] = 'Any'
+config.get(nil, 'Lua.diagnostics.neededFileStatus')['not-yieldable'] = 'Any'
TEST [[
local function f(cb)
return cb
diff --git a/test/full/example.lua b/test/full/example.lua
index 0505f1a5..c0ce23ee 100644
--- a/test/full/example.lua
+++ b/test/full/example.lua
@@ -10,7 +10,7 @@ local noder = require 'core.noder'
-- 临时
---@diagnostic disable: await-in-sync
local function testIfExit(path)
- config.set('Lua.workspace.preloadFileSize', 1000000000)
+ config.set(nil, 'Lua.workspace.preloadFileSize', 1000000000)
local buf = util.loadFile(path:string())
if buf then
local state
diff --git a/test/full/init.lua b/test/full/init.lua
index 9584db6f..e83a7d6d 100644
--- a/test/full/init.lua
+++ b/test/full/init.lua
@@ -12,9 +12,9 @@ function TEST(script)
end
local function startCollectDiagTimes()
- for name in pairs(config.get 'Lua.diagnostics.neededFileStatus') do
+ for name in pairs(config.get(nil, 'Lua.diagnostics.neededFileStatus')) do
if name ~= 'no-implicit-any' then
- --config.get 'Lua.diagnostics.neededFileStatus'[name] = 'Any'
+ --config.get(nil, 'Lua.diagnostics.neededFileStatus')[name] = 'Any'
end
end
DIAGTIMES = {}
diff --git a/test/full/projects.lua b/test/full/projects.lua
index a095f316..7beaa026 100644
--- a/test/full/projects.lua
+++ b/test/full/projects.lua
@@ -6,8 +6,8 @@ local config = require 'config'
local ws = require 'workspace'
local fs = require 'bee.filesystem'
-config.set('Lua.workspace.preloadFileSize', 1000000)
-config.set('Lua.diagnostics.neededFileStatus', {
+config.set(nil, 'Lua.workspace.preloadFileSize', 1000000)
+config.set(nil, 'Lua.diagnostics.neededFileStatus', {
['await-in-sync'] = 'Any',
['not-yieldable'] = 'Any',
})
diff --git a/test/hover/init.lua b/test/hover/init.lua
index 15bf60d4..35274384 100644
--- a/test/hover/init.lua
+++ b/test/hover/init.lua
@@ -838,7 +838,7 @@ local t: {
}
]]
-config.set('Lua.IntelliSense.traceLocalSet', true)
+config.set(nil, 'Lua.IntelliSense.traceLocalSet', true)
TEST [[
local x
x = 1
@@ -849,7 +849,7 @@ print(<?x?>)
[[
local x: number = 1
]]
-config.set('Lua.IntelliSense.traceLocalSet', false)
+config.set(nil, 'Lua.IntelliSense.traceLocalSet', false)
TEST [[
local <?x?> <close> = 1
@@ -1730,7 +1730,7 @@ t.<?x?>()
field t.x: any
]]
-config.set('Lua.IntelliSense.traceLocalSet', true)
+config.set(nil, 'Lua.IntelliSense.traceLocalSet', true)
TEST [[
---@class A
local a
@@ -1743,7 +1743,7 @@ print(b.<?x?>)
[[
field A.x: any
]]
-config.set('Lua.IntelliSense.traceLocalSet', false)
+config.set(nil, 'Lua.IntelliSense.traceLocalSet', false)
TEST [[
---@class A
@@ -1793,11 +1793,11 @@ local <?f?>
local f: async fun()
]]
-config.set('Lua.runtime.nonstandardSymbol', { '//' })
+config.set(nil, 'Lua.runtime.nonstandardSymbol', { '//' })
TEST [[
local <?x?> = 1 // 2
]]
[[
local x: integer = 1
]]
-config.set('runtime.nonstandardSymbol', {})
+config.set(nil, 'runtime.nonstandardSymbol', {})
diff --git a/test/references/all.lua b/test/references/all.lua
index cbe8ebb5..4ba63579 100644
--- a/test/references/all.lua
+++ b/test/references/all.lua
@@ -78,7 +78,7 @@ end
local _, <!f2!> = f()
]]
-config.set('Lua.IntelliSense.traceReturn', true)
+config.set(nil, 'Lua.IntelliSense.traceReturn', true)
TEST [[
local <?x?>
local function f()
@@ -96,7 +96,7 @@ local function f()
end
local <!y!> = f()()
]]
-config.set('Lua.IntelliSense.traceReturn', false)
+config.set(nil, 'Lua.IntelliSense.traceReturn', false)
TEST [[
---@class A
diff --git a/test/references/common.lua b/test/references/common.lua
index 20ddd353..b46aa81f 100644
--- a/test/references/common.lua
+++ b/test/references/common.lua
@@ -96,7 +96,7 @@ t.x = 1
t[a.b.<?x?>] = 1
]]
-config.set('Lua.IntelliSense.traceBeSetted', true)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', true)
TEST [[
local t
local <!f!> = t.<?f?>
@@ -107,7 +107,7 @@ return {
<!f!> = <!f!>,
}
]]
-config.set('Lua.IntelliSense.traceBeSetted', false)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', false)
TEST [[
self = {
@@ -142,7 +142,7 @@ a.<!b!>.c = 1
print(a.<?b?>.c)
]]
-config.set('Lua.IntelliSense.traceBeSetted', true)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', true)
TEST [[
local <?f?>
local t = {
@@ -150,14 +150,14 @@ local t = {
}
print(t.<!a!>)
]]
-config.set('Lua.IntelliSense.traceBeSetted', false)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', false)
TEST [[
local <!f!>
local <!t!> = <?f?>
]]
-config.set('Lua.IntelliSense.traceBeSetted', true)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', true)
TEST [[
local <!f!>
a.<!t!> = <?f?>
@@ -166,19 +166,19 @@ a.<!t!> = <?f?>
TEST [[
<!t!>.<!f!> = <?t?>
]]
-config.set('Lua.IntelliSense.traceBeSetted', false)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', false)
TEST [[
local <!f!>
local <?t?> = <!f!>
]]
-config.set('Lua.IntelliSense.traceBeSetted', true)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', true)
TEST [[
local <!t!>
<!t!>.<!f!> = <?t?>
]]
-config.set('Lua.IntelliSense.traceBeSetted', false)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', false)
TEST [[
_G.<?xxx?> = 1
diff --git a/test/rename/init.lua b/test/rename/init.lua
index 774c86d2..29e6f1a6 100644
--- a/test/rename/init.lua
+++ b/test/rename/init.lua
@@ -90,7 +90,7 @@ local function f(b)
end
]]
-config.set('Lua.IntelliSense.traceBeSetted', true)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', true)
TEST ('a', '!!!') [[
t = {
a = 0
@@ -118,7 +118,7 @@ t = {
t["!!!"] = 1
a = t["!!!"]
]]
-config.set('Lua.IntelliSense.traceBeSetted', false)
+config.set(nil, 'Lua.IntelliSense.traceBeSetted', false)
TEST ('a', '"') [[
print(t[ "a" ])
diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua
index 24c151b1..d62bc607 100644
--- a/test/type_inference/init.lua
+++ b/test/type_inference/init.lua
@@ -57,7 +57,7 @@ local var = '111'
t.<?x?> = var
]]
-config.set('Lua.IntelliSense.traceLocalSet', true)
+config.set(nil, 'Lua.IntelliSense.traceLocalSet', true)
TEST 'string' [[
local <?var?>
var = '111'
@@ -68,7 +68,7 @@ local var
var = '111'
print(<?var?>)
]]
-config.set('Lua.IntelliSense.traceLocalSet', false)
+config.set(nil, 'Lua.IntelliSense.traceLocalSet', false)
TEST 'function' [[
function <?xx?>()
@@ -80,13 +80,13 @@ local function <?xx?>()
end
]]
-config.set('Lua.IntelliSense.traceLocalSet', true)
+config.set(nil, 'Lua.IntelliSense.traceLocalSet', true)
TEST 'function' [[
local xx
<?xx?> = function ()
end
]]
-config.set('Lua.IntelliSense.traceLocalSet', false)
+config.set(nil, 'Lua.IntelliSense.traceLocalSet', false)
TEST 'table' [[
local <?t?> = {}
@@ -748,25 +748,25 @@ TEST 'function' [[
string.gsub():gsub():<?gsub?>()
]]
-config.set('Lua.hover.enumsLimit', 5)
+config.set(nil, 'Lua.hover.enumsLimit', 5)
TEST 'a|b|c|d|e...(+5)' [[
---@type 'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'
local <?t?>
]]
-config.set('Lua.hover.enumsLimit', 1)
+config.set(nil, 'Lua.hover.enumsLimit', 1)
TEST 'a...(+9)' [[
---@type 'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'
local <?t?>
]]
-config.set('Lua.hover.enumsLimit', 0)
+config.set(nil, 'Lua.hover.enumsLimit', 0)
TEST '...(+10)' [[
---@type 'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'
local <?t?>
]]
-config.set('Lua.hover.enumsLimit', 5)
+config.set(nil, 'Lua.hover.enumsLimit', 5)
TEST 'string|fun():string' [[
---@type string | fun(): string