diff options
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 @@ -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 |