diff options
-rw-r--r-- | script/client.lua | 8 | ||||
-rw-r--r-- | script/core/code-action.lua | 22 | ||||
-rw-r--r-- | script/core/command/jsonToLua.lua | 4 | ||||
-rw-r--r-- | script/core/command/removeSpace.lua | 2 | ||||
-rw-r--r-- | script/core/command/solve.lua | 4 | ||||
-rw-r--r-- | script/core/diagnostics/codestyle-check.lua | 9 | ||||
-rw-r--r-- | script/core/diagnostics/spell-check.lua | 9 | ||||
-rw-r--r-- | script/core/rangeformatting.lua | 10 | ||||
-rw-r--r-- | script/core/semantic-tokens.lua | 10 | ||||
-rw-r--r-- | script/core/type-formatting.lua | 10 | ||||
-rw-r--r-- | script/core/view/psi-select.lua | 2 | ||||
-rw-r--r-- | script/core/view/psi-view.lua | 4 | ||||
-rw-r--r-- | script/files.lua | 43 | ||||
-rw-r--r-- | script/parser/compile.lua | 1 | ||||
-rw-r--r-- | script/proto/converter.lua | 113 | ||||
-rw-r--r-- | script/provider/diagnostic.lua | 29 | ||||
-rw-r--r-- | script/provider/provider.lua | 269 |
17 files changed, 340 insertions, 209 deletions
diff --git a/script/client.lua b/script/client.lua index 7432e60b..1e4689a8 100644 --- a/script/client.lua +++ b/script/client.lua @@ -382,10 +382,14 @@ end ---@param uri uri ---@param edits textEditor[] function m.editText(uri, edits) - local files = require 'files' + local files = require 'files' + local state = files.getState(uri) + if not state then + return + end local textEdits = {} for i, edit in ipairs(edits) do - textEdits[i] = converter.textEdit(converter.packRange(uri, edit.start, edit.finish), edit.text) + textEdits[i] = converter.textEdit(converter.packRange(state, edit.start, edit.finish), edit.text) end proto.request('workspace/applyEdit', { edit = { diff --git a/script/core/code-action.lua b/script/core/code-action.lua index 1e19d466..4f15b335 100644 --- a/script/core/code-action.lua +++ b/script/core/code-action.lua @@ -135,7 +135,7 @@ local function solveUndefinedGlobal(uri, diag, results) if not state then return end - local start = converter.unpackRange(uri, diag.range) + local start = converter.unpackRange(state, diag.range) guide.eachSourceContain(state.ast, start, function (source) if source.type ~= 'getglobal' then return @@ -157,7 +157,7 @@ local function solveLowercaseGlobal(uri, diag, results) if not state then return end - local start = converter.unpackRange(uri, diag.range) + local start = converter.unpackRange(state, diag.range) guide.eachSourceContain(state.ast, start, function (source) if source.type ~= 'setglobal' then return @@ -175,7 +175,7 @@ local function findSyntax(uri, diag) end for _, err in ipairs(state.errs) do if err.type:lower():gsub('_', '-') == diag.code then - local range = converter.packRange(uri, err.start, err.finish) + local range = converter.packRange(state, err.start, err.finish) if util.equal(range, diag.range) then return err end @@ -276,7 +276,11 @@ local function solveSyntax(uri, diag, results) end local function solveNewlineCall(uri, diag, results) - local start = converter.unpackRange(uri, diag.range) + local state = files.getState(uri) + if not state then + return + end + local start = converter.unpackRange(state, diag.range) results[#results+1] = { title = lang.script.ACTION_ADD_SEMICOLON, kind = 'quickfix', @@ -333,7 +337,7 @@ local function solveAwaitInSync(uri, diag, results) if not state then return end - local start, finish = converter.unpackRange(uri, diag.range) + local start, finish = converter.unpackRange(state, diag.range) local parentFunction guide.eachSourceType(state.ast, 'function', function (source) if source.start > finish @@ -369,6 +373,10 @@ local function solveAwaitInSync(uri, diag, results) end local function solveSpell(uri, diag, results) + local state = files.getState(uri) + if not state then + return + end local spell = require 'provider.spell' local word = diag.data if word == nil then @@ -401,8 +409,8 @@ local function solveSpell(uri, diag, results) changes = { [uri] = { { - start = converter.unpackPosition(uri, diag.range.start), - finish = converter.unpackPosition(uri, diag.range["end"]), + start = converter.unpackPosition(state, diag.range.start), + finish = converter.unpackPosition(state, diag.range["end"]), newText = suggest } } diff --git a/script/core/command/jsonToLua.lua b/script/core/command/jsonToLua.lua index 8d9e8ba1..da1aeb4b 100644 --- a/script/core/command/jsonToLua.lua +++ b/script/core/command/jsonToLua.lua @@ -11,7 +11,7 @@ local guide = require 'parser.guide' return function (data) local state = files.getState(data.uri) local text = files.getText(data.uri) - if not text then + if not text or not state then return end local start = guide.positionToOffset(state, data.start) @@ -43,7 +43,7 @@ return function (data) changes = { [data.uri] = { { - range = converter.packRange(data.uri, data.start, data.finish), + range = converter.packRange(state, data.start, data.finish), newText = luaStr, } } diff --git a/script/core/command/removeSpace.lua b/script/core/command/removeSpace.lua index 992a0705..87d11fff 100644 --- a/script/core/command/removeSpace.lua +++ b/script/core/command/removeSpace.lua @@ -38,7 +38,7 @@ return function (data) end local firstPos = guide.offsetToPosition(state, firstOffset) - 1 textEdit[#textEdit+1] = { - range = converter.packRange(uri, firstPos, lastPos), + range = converter.packRange(state, firstPos, lastPos), newText = '', } diff --git a/script/core/command/solve.lua b/script/core/command/solve.lua index 98ceaa58..ca1458aa 100644 --- a/script/core/command/solve.lua +++ b/script/core/command/solve.lua @@ -36,7 +36,7 @@ return function (data) return end - local start, finish = converter.unpackRange(uri, data.range) + local start, finish = converter.unpackRange(state, data.range) local result = guide.eachSourceContain(state.ast, start, function (source) if source.start ~= start @@ -86,7 +86,7 @@ return function (data) changes = { [uri] = { { - range = converter.packRange(uri, result.start, result.finish), + range = converter.packRange(state, result.start, result.finish), newText = ('(%s)'):format(text:sub( guide.positionToOffset(state, result.start + 1), guide.positionToOffset(state, result.finish) diff --git a/script/core/diagnostics/codestyle-check.lua b/script/core/diagnostics/codestyle-check.lua index 6448979d..6d22597b 100644 --- a/script/core/diagnostics/codestyle-check.lua +++ b/script/core/diagnostics/codestyle-check.lua @@ -6,10 +6,11 @@ local pformatting = require 'provider.formatting' ---@async return function(uri, callback) - local text = files.getOriginText(uri) - if not text then + local state = files.getState(uri) + if not state then return end + local text = state.originText local suc, codeFormat = pcall(require, 'code_format') if not suc then @@ -31,8 +32,8 @@ return function(uri, callback) if diagnosticInfos then for _, diagnosticInfo in ipairs(diagnosticInfos) do callback { - start = converter.unpackPosition(uri, diagnosticInfo.range.start), - finish = converter.unpackPosition(uri, diagnosticInfo.range["end"]), + start = converter.unpackPosition(state, diagnosticInfo.range.start), + finish = converter.unpackPosition(state, diagnosticInfo.range["end"]), message = diagnosticInfo.message } end diff --git a/script/core/diagnostics/spell-check.lua b/script/core/diagnostics/spell-check.lua index 7369a235..a4cb87be 100644 --- a/script/core/diagnostics/spell-check.lua +++ b/script/core/diagnostics/spell-check.lua @@ -6,10 +6,11 @@ local spell = require 'provider.spell' ---@async return function(uri, callback) - local text = files.getOriginText(uri) - if not text then + local state = files.getState(uri) + if not state then return end + local text = state.originText local status, diagnosticInfos = spell.spellCheck(uri, text) @@ -24,8 +25,8 @@ return function(uri, callback) if diagnosticInfos then for _, diagnosticInfo in ipairs(diagnosticInfos) do callback { - start = converter.unpackPosition(uri, diagnosticInfo.range.start), - finish = converter.unpackPosition(uri, diagnosticInfo.range["end"]), + start = converter.unpackPosition(state, diagnosticInfo.range.start), + finish = converter.unpackPosition(state, diagnosticInfo.range["end"]), message = diagnosticInfo.message, data = diagnosticInfo.data } diff --git a/script/core/rangeformatting.lua b/script/core/rangeformatting.lua index 04a61bd9..7c3953e6 100644 --- a/script/core/rangeformatting.lua +++ b/script/core/rangeformatting.lua @@ -3,11 +3,15 @@ local log = require("log") local converter = require("proto.converter") return function(uri, range, options) + local state = files.getState(uri) + if not state then + return + end local suc, codeFormat = pcall(require, "code_format") if not suc then return end - local text = files.getOriginText(uri) + local text = state.originText local status, formattedText, startLine, endLine = codeFormat.range_format( uri, text, range.start.line, range["end"].line, options) @@ -21,8 +25,8 @@ return function(uri, range, options) return { { - start = converter.unpackPosition(uri, { line = startLine, character = 0 }), - finish = converter.unpackPosition(uri, { line = endLine + 1, character = 0 }), + start = converter.unpackPosition(state, { line = startLine, character = 0 }), + finish = converter.unpackPosition(state, { line = endLine + 1, character = 0 }), text = formattedText, } } diff --git a/script/core/semantic-tokens.lua b/script/core/semantic-tokens.lua index bc9bf8af..610b3061 100644 --- a/script/core/semantic-tokens.lua +++ b/script/core/semantic-tokens.lua @@ -699,13 +699,15 @@ local Care = util.switch() } end) -local function buildTokens(uri, results) +---@param state table +---@param results table +local function buildTokens(state, results) local tokens = {} local lastLine = 0 local lastStartChar = 0 for i, source in ipairs(results) do - local startPos = converter.packPosition(uri, source.start) - local finishPos = converter.packPosition(uri, source.finish) + local startPos = converter.packPosition(state, source.start) + local finishPos = converter.packPosition(state, source.finish) local line = startPos.line local startChar = startPos.character local deltaLine = line - lastLine @@ -881,7 +883,7 @@ return function (uri, start, finish) results = solveMultilineAndOverlapping(state, results) - local tokens = buildTokens(uri, results) + local tokens = buildTokens(state, results) return tokens end diff --git a/script/core/type-formatting.lua b/script/core/type-formatting.lua index 94edc71b..419cb56b 100644 --- a/script/core/type-formatting.lua +++ b/script/core/type-formatting.lua @@ -199,22 +199,22 @@ local function typeFormat(results, uri, position, ch, options) return end local converter = require("proto.converter") - local pos = converter.packPosition(uri, position) + local pos = converter.packPosition(state, position) local typeFormatOptions = config.get(uri, 'Lua.typeFormat.config') local success, result = codeFormat.type_format(uri, text, pos.line, pos.character, options, typeFormatOptions) if success then local range = result.range results[#results+1] = { text = result.newText, - start = converter.unpackPosition(uri, { line = range.start.line, character = range.start.character }), - finish = converter.unpackPosition(uri, { line = range["end"].line, character = range["end"].character }), + start = converter.unpackPosition(state, { line = range.start.line, character = range.start.character }), + finish = converter.unpackPosition(state, { line = range["end"].line, character = range["end"].character }), } end end return function (uri, position, ch, options) - local ast = files.getState(uri) - if not ast then + local state = files.getState(uri) + if not state then return nil end diff --git a/script/core/view/psi-select.lua b/script/core/view/psi-select.lua index b6733aa5..40642039 100644 --- a/script/core/view/psi-select.lua +++ b/script/core/view/psi-select.lua @@ -8,6 +8,6 @@ return function(uri, position) return end - local pos = converter.unpackPosition(uri, position) + local pos = converter.unpackPosition(state, position) return { data = guide.positionToOffset(state, pos) } end diff --git a/script/core/view/psi-view.lua b/script/core/view/psi-view.lua index 86ed1403..640d1c4c 100644 --- a/script/core/view/psi-view.lua +++ b/script/core/view/psi-view.lua @@ -27,8 +27,8 @@ local function toPsiNode(astNode, state) local startOffset = guide.positionToOffset(state, astNode.start) local finishOffset = guide.positionToOffset(state, astNode.finish) - local startPosition = converter.packPosition(state.uri, astNode.start) - local finishPosition = converter.packPosition(state.uri, astNode.finish) + local startPosition = converter.packPosition(state, astNode.start) + local finishPosition = converter.packPosition(state, astNode.finish) return { name = string.format("%s@[%d:%d .. %d:%d]", astNode.type, diff --git a/script/files.lua b/script/files.lua index 545c6735..d7a7b16b 100644 --- a/script/files.lua +++ b/script/files.lua @@ -593,9 +593,14 @@ function m.compileState(uri, text) end end +---@class parser.state +---@field _diffInfo? table[] +---@field originLines? integer[] +---@field originText string + --- 获取文件语法树 ---@param uri uri ----@return table? state +---@return parser.state? state function m.getState(uri) local file = m.fileMap[uri] if not file then @@ -606,6 +611,9 @@ function m.getState(uri) state = m.compileState(uri, file.text) m.astMap[uri] = state file.state = state + state._diffInfo = file._diffInfo + state.originLines = file.originLines + state.originText = file.originText --await.delay() end file.cacheActiveTime = timer.clock() @@ -637,43 +645,32 @@ local function isNameChar(text) end --- 将应用差异前的offset转换为应用差异后的offset ----@param uri uri +---@param state parser.state ---@param offset integer ---@return integer start ---@return integer finish -function m.diffedOffset(uri, offset) - local file = m.getFile(uri) - if not file then +function m.diffedOffset(state, offset) + if not state._diffInfo then return offset, offset end - if not file._diffInfo then - return offset, offset - end - return smerger.getOffset(file._diffInfo, offset) + return smerger.getOffset(state._diffInfo, offset) end --- 将应用差异后的offset转换为应用差异前的offset ----@param uri uri +---@param state parser.state ---@param offset integer ---@return integer start ---@return integer finish -function m.diffedOffsetBack(uri, offset) - local file = m.getFile(uri) - if not file then +function m.diffedOffsetBack(state, offset) + if not state._diffInfo then return offset, offset end - if not file._diffInfo then - return offset, offset - end - return smerger.getOffsetBack(file._diffInfo, offset) + return smerger.getOffsetBack(state._diffInfo, offset) end -function m.hasDiffed(uri) - local file = m.getFile(uri) - if not file then - return false - end - return file._diffInfo ~= nil +---@param state parser.state +function m.hasDiffed(state) + return state._diffInfo ~= nil end --- 获取文件的自定义缓存信息(在文件内容更新后自动失效) diff --git a/script/parser/compile.lua b/script/parser/compile.lua index 45678976..12d80f7e 100644 --- a/script/parser/compile.lua +++ b/script/parser/compile.lua @@ -3818,6 +3818,7 @@ local function initState(lua, version, options) Index = 1 ---@class parser.state ---@field uri uri + ---@field lines integer[] local state = { version = version, lua = lua, diff --git a/script/proto/converter.lua b/script/proto/converter.lua index 56b45c1f..d761042c 100644 --- a/script/proto/converter.lua +++ b/script/proto/converter.lua @@ -8,11 +8,23 @@ local m = {} ---@alias position {line: integer, character: integer} -local function rawPackPosition(uri, pos) +---@param row integer +---@param col integer +---@return position +function m.position(row, col) + return { + line = row, + character = col, + } +end + +---@param state parser.state +---@param pos integer +---@return position +local function rawPackPosition(state, pos) local row, col = guide.rowColOf(pos) if col > 0 then - local state = files.getState(uri) - local text = files.getText(uri) + local text = state.lua if state and text then local lineOffset = state.lines[row] if lineOffset then @@ -32,17 +44,18 @@ local function rawPackPosition(uri, pos) } end -local function diffedPackPosition(uri, pos) - local state = files.getState(uri) +---@param state parser.state +---@param pos integer +---@return position +local function diffedPackPosition(state, pos) local offset = guide.positionToOffset(state, pos) - local originOffset = files.diffedOffsetBack(uri, offset) - local originLines = files.getOriginLines(uri) - local originPos = guide.offsetToPositionByLines(originLines, originOffset) + local originOffset = files.diffedOffsetBack(state, offset) + local originPos = guide.offsetToPositionByLines(state.originLines, originOffset) local row, col = guide.rowColOf(originPos) if col > 0 then - local text = files.getOriginText(uri) + local text = state.originText if text then - local lineOffset = originLines[row] + local lineOffset = state.originLines[row] local finalOffset = math.min(lineOffset + col - 1, #text + 1) col = encoder.len(offsetEncoding, text, lineOffset, finalOffset) end @@ -53,22 +66,24 @@ local function diffedPackPosition(uri, pos) } end ----@param uri uri +---@param state parser.state ---@param pos integer ---@return position -function m.packPosition(uri, pos) - if files.hasDiffed(uri) then - return diffedPackPosition(uri, pos) +function m.packPosition(state, pos) + if files.hasDiffed(state) then + return diffedPackPosition(state, pos) else - return rawPackPosition(uri, pos) + return rawPackPosition(state, pos) end end -local function rawUnpackPosition(uri, position) +---@param state parser.state +---@param position position +---@return integer +local function rawUnpackPosition(state, position) local row, col = position.line, position.character if col > 0 then - local state = files.getState(uri) - local text = files.getText(uri) + local text = state.lua if state and text then local lineOffset = state.lines[row] local textOffset = encoder.offset(offsetEncoding, text, col + 1, lineOffset) @@ -81,61 +96,69 @@ local function rawUnpackPosition(uri, position) return pos end -local function diffedUnpackPosition(uri, position) - local row, col = position.line, position.character - local originLines = files.getOriginLines(uri) +---@param state parser.state +---@param position position +---@return integer +local function diffedUnpackPosition(state, position) + local row, col = position.line, position.character if col > 0 then - local text = files.getOriginText(uri) - if text then - local lineOffset = originLines[row] - if lineOffset then - local textOffset = encoder.offset(offsetEncoding, text, col + 1, lineOffset) - if textOffset and lineOffset then - col = textOffset - lineOffset - end + local lineOffset = state.originLines[row] + if lineOffset then + local textOffset = encoder.offset(offsetEncoding, state.originText, col + 1, lineOffset) + if textOffset and lineOffset then + col = textOffset - lineOffset end end end - local state = files.getState(uri) local originPos = guide.positionOf(row, col) - local originOffset = guide.positionToOffsetByLines(originLines, originPos) - local offset = files.diffedOffset(uri, originOffset) + local originOffset = guide.positionToOffsetByLines(state.originLines, originPos) + local offset = files.diffedOffset(state, originOffset) local pos = guide.offsetToPosition(state, offset) return pos end ----@param uri uri +---@param state parser.state ---@param position position ---@return integer -function m.unpackPosition(uri, position) - if files.hasDiffed(uri) then - return diffedUnpackPosition(uri, position) +function m.unpackPosition(state, position) + if files.hasDiffed(state) then + return diffedUnpackPosition(state, position) else - return rawUnpackPosition(uri, position) + return rawUnpackPosition(state, position) end end ---@alias range {start: position, end: position} ----@param uri uri +---@param state parser.state ---@param start integer ---@param finish integer ---@return range -function m.packRange(uri, start, finish) +function m.packRange(state, start, finish) local range = { - start = m.packPosition(uri, start), - ['end'] = m.packPosition(uri, finish), + start = m.packPosition(state, start), + ['end'] = m.packPosition(state, finish), } return range end ----@param uri uri +---@param start position +---@param finish position +---@return range +function m.range(start, finish) + return { + start = start, + ['end'] = finish, + } +end + +---@param state parser.state ---@param range range ---@return integer start ---@return integer finish -function m.unpackRange(uri, range) - local start = m.unpackPosition(uri, range.start) - local finish = m.unpackPosition(uri, range['end']) +function m.unpackRange(state, range) + local start = m.unpackPosition(state, range.start) + local finish = m.unpackPosition(state, range['end']) return start, finish end diff --git a/script/provider/diagnostic.lua b/script/provider/diagnostic.lua index 58179514..149e409f 100644 --- a/script/provider/diagnostic.lua +++ b/script/provider/diagnostic.lua @@ -32,8 +32,9 @@ local function concat(t, sep) end local function buildSyntaxError(uri, err) - local text = files.getText(uri) - if not text then + local state = files.getState(uri) + local text = files.getText(uri) + if not text or not state then return end local message = lang.script('PARSER_' .. err.type, err.info) @@ -58,16 +59,19 @@ local function buildSyntaxError(uri, err) rmessage = text:sub(rel.start, rel.finish) end local relUri = rel.uri or uri - relatedInformation[#relatedInformation+1] = { - message = rmessage, - location = converter.location(relUri, converter.packRange(relUri, rel.start, rel.finish)), - } + local relState = files.getState(relUri) + if relState then + relatedInformation[#relatedInformation+1] = { + message = rmessage, + location = converter.location(relUri, converter.packRange(relState, rel.start, rel.finish)), + } + end end end return { code = err.type:lower():gsub('_', '-'), - range = converter.packRange(uri, err.start, err.finish), + range = converter.packRange(state, err.start, err.finish), severity = define.DiagnosticSeverity[err.level], source = lang.script.DIAG_SYNTAX_CHECK, message = message, @@ -78,7 +82,8 @@ local function buildSyntaxError(uri, err) end local function buildDiagnostic(uri, diag) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return end @@ -90,16 +95,20 @@ local function buildDiagnostic(uri, diag) if not rtext then goto CONTINUE end + local relState = files.getState(rel.uri) + if not relState then + goto CONTINUE + end relatedInformation[#relatedInformation+1] = { message = rel.message or rtext:sub(rel.start, rel.finish), - location = converter.location(rel.uri, converter.packRange(rel.uri, rel.start, rel.finish)) + location = converter.location(rel.uri, converter.packRange(relState, rel.start, rel.finish)) } ::CONTINUE:: end end return { - range = converter.packRange(uri, diag.start, diag.finish), + range = converter.packRange(state, diag.start, diag.finish), source = lang.script.DIAG_DIAGNOSTICS, severity = diag.level, message = diag.message, diff --git a/script/provider/provider.lua b/script/provider/provider.lua index 517ef54e..fb16c2c6 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -335,10 +335,11 @@ m.register 'textDocument/hover' { end local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_HOVER, 0.5) local core = require 'core.hover' - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local hover, source = core.byUri(uri, pos) if not hover or not source then return nil @@ -348,7 +349,7 @@ m.register 'textDocument/hover' { value = tostring(hover), kind = 'markdown', }, - range = converter.packRange(uri, source.start, source.finish), + range = converter.packRange(state, source.start, source.finish), } end } @@ -362,29 +363,42 @@ m.register 'textDocument/definition' { function (params) local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then + local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_DEFINITION, 0.5) + local state = files.getState(uri) + if not state then return nil end - local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_DEFINITION, 0.5) local core = require 'core.definition' - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core(uri, pos) if not result then return nil end local response = {} for i, info in ipairs(result) do + ---@type uri local targetUri = info.uri if targetUri then - if client.getAbility 'textDocument.definition.linkSupport' then - response[i] = converter.locationLink(targetUri - , converter.packRange(targetUri, info.target.start, info.target.finish) - , converter.packRange(targetUri, info.target.start, info.target.finish) - , converter.packRange(uri, info.source.start, info.source.finish) - ) + local targetState = files.getState(targetUri) + if targetState then + if client.getAbility 'textDocument.definition.linkSupport' then + response[i] = converter.locationLink(targetUri + , converter.packRange(targetState, info.target.start, info.target.finish) + , converter.packRange(targetState, info.target.start, info.target.finish) + , converter.packRange(state, info.source.start, info.source.finish) + ) + else + response[i] = converter.location(targetUri + , converter.packRange(targetState, info.target.start, info.target.finish) + ) + end else - response[i] = converter.location(targetUri - , converter.packRange(targetUri, info.target.start, info.target.finish) + response[i] = converter.location( + targetUri, + converter.range( + converter.position(guide.rowColOf(info.target.start)), + converter.position(guide.rowColOf(info.target.finish)) + ) ) end end @@ -402,30 +416,35 @@ m.register 'textDocument/typeDefinition' { function (params) local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then - return nil - end local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_TYPE_DEFINITION, 0.5) + local state = files.getState(uri) + if not state then + return + end local core = require 'core.type-definition' - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core(uri, pos) if not result then return nil end local response = {} for i, info in ipairs(result) do + ---@type uri local targetUri = info.uri if targetUri then - if client.getAbility 'textDocument.typeDefinition.linkSupport' then - response[i] = converter.locationLink(targetUri - , converter.packRange(targetUri, info.target.start, info.target.finish) - , converter.packRange(targetUri, info.target.start, info.target.finish) - , converter.packRange(uri, info.source.start, info.source.finish) - ) - else - response[i] = converter.location(targetUri - , converter.packRange(targetUri, info.target.start, info.target.finish) - ) + local targetState = files.getState(targetUri) + if targetState then + if client.getAbility 'textDocument.typeDefinition.linkSupport' then + response[i] = converter.locationLink(targetUri + , converter.packRange(targetState, info.target.start, info.target.finish) + , converter.packRange(targetState, info.target.start, info.target.finish) + , converter.packRange(state, info.source.start, info.source.finish) + ) + else + response[i] = converter.location(targetUri + , converter.packRange(targetState, info.target.start, info.target.finish) + ) + end end end end @@ -442,22 +461,27 @@ m.register 'textDocument/references' { function (params) local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then + local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_REFERENCE, 0.5) + local state = files.getState(uri) + if not state then return nil end - local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_REFERENCE, 0.5) local core = require 'core.reference' - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core(uri, pos) if not result then return nil end local response = {} for i, info in ipairs(result) do + ---@type uri local targetUri = info.uri - response[i] = converter.location(targetUri - , converter.packRange(targetUri, info.target.start, info.target.finish) - ) + local targetState = files.getState(targetUri) + if targetState then + response[#response+1] = converter.location(targetUri + , converter.packRange(targetState, info.target.start, info.target.finish) + ) + end end return response end @@ -472,10 +496,11 @@ m.register 'textDocument/documentHighlight' { local core = require 'core.highlight' local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core(uri, pos) if not result then return nil @@ -483,7 +508,7 @@ m.register 'textDocument/documentHighlight' { local response = {} for _, info in ipairs(result) do response[#response+1] = { - range = converter.packRange(uri, info.start, info.finish), + range = converter.packRange(state, info.start, info.finish), kind = info.kind, } end @@ -502,12 +527,13 @@ m.register 'textDocument/rename' { function (params) local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then + local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_RENAME, 0.5) + local state = files.getState(uri) + if not state then return nil end - local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_RENAME, 0.5) local core = require 'core.rename' - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core.rename(uri, pos, params.newName) if not result then return nil @@ -516,12 +542,16 @@ m.register 'textDocument/rename' { changes = {}, } for _, info in ipairs(result) do - local ruri = info.uri - if not workspaceEdit.changes[ruri] then - workspaceEdit.changes[ruri] = {} + ---@type uri + local ruri = info.uri + local rstate = files.getState(ruri) + if rstate then + if not workspaceEdit.changes[ruri] then + workspaceEdit.changes[ruri] = {} + end + local textEdit = converter.textEdit(converter.packRange(rstate, info.start, info.finish), info.text) + workspaceEdit.changes[ruri][#workspaceEdit.changes[ruri]+1] = textEdit end - local textEdit = converter.textEdit(converter.packRange(ruri, info.start, info.finish), info.text) - workspaceEdit.changes[ruri][#workspaceEdit.changes[ruri]+1] = textEdit end return workspaceEdit end @@ -532,16 +562,17 @@ m.register 'textDocument/prepareRename' { function (params) local core = require 'core.rename' local uri = files.getRealUri(params.textDocument.uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core.prepareRename(uri, pos) if not result then return nil end return { - range = converter.packRange(uri, result.start, result.finish), + range = converter.packRange(state, result.start, result.finish), placeholder = result.text, } end @@ -571,8 +602,9 @@ m.register 'textDocument/completion' { local core = require 'core.completion' --log.debug('textDocument/completion') --log.debug('completion:', params.context and params.context.triggerKind, params.context and params.context.triggerCharacter) - if not files.exists(uri) then - return nil + local state = files.getState(uri) + if not state then + return end local triggerCharacter = params.context and params.context.triggerCharacter if config.get(uri, 'editor.acceptSuggestionOnEnter') ~= 'off' then @@ -584,7 +616,7 @@ m.register 'textDocument/completion' { end --await.setPriority(1000) local clock = os.clock() - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local result = core.completion(uri, pos, triggerCharacter) local passed = os.clock() - clock if passed > 0.1 then @@ -611,7 +643,7 @@ m.register 'textDocument/completion' { command = res.command, textEdit = res.textEdit and { range = converter.packRange( - uri, + state, res.textEdit.start, res.textEdit.finish ), @@ -622,7 +654,7 @@ m.register 'textDocument/completion' { for j, edit in ipairs(res.additionalTextEdits) do t[j] = { range = converter.packRange( - uri, + state, edit.start, edit.finish ), @@ -676,6 +708,10 @@ m.register 'completionItem/resolve' { local id = item.data.id local uri = item.data.uri --await.setPriority(1000) + local state = files.getState(uri) + if not state then + return nil + end local resolved = core.resolve(id) if not resolved then return nil @@ -690,7 +726,7 @@ m.register 'completionItem/resolve' { for j, edit in ipairs(resolved.additionalTextEdits) do t[j] = { range = converter.packRange( - uri, + state, edit.start, edit.finish ), @@ -717,11 +753,12 @@ m.register 'textDocument/signatureHelp' { return nil end workspace.awaitReady(uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_SIGNATURE, 0.5) - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local core = require 'core.signature' local results = core(uri, pos) if not results then @@ -764,7 +801,10 @@ m.register 'textDocument/documentSymbol' { local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_SYMBOL, 0.5) - + local state = files.getState(uri) + if not state then + return nil + end local core = require 'core.document-symbol' local symbols = core(uri) if not symbols then @@ -775,12 +815,12 @@ m.register 'textDocument/documentSymbol' { local function convert(symbol) await.delay() symbol.range = converter.packRange( - uri, + state, symbol.range[1], symbol.range[2] ) symbol.selectionRange = converter.packRange( - uri, + state, symbol.selectionRange[1], symbol.selectionRange[2] ) @@ -821,11 +861,13 @@ m.register 'textDocument/codeAction' { local uri = files.getRealUri(params.textDocument.uri) local range = params.range local diagnostics = params.context.diagnostics - if not files.exists(uri) then + + local state = files.getState(uri) + if not state then return nil end - local start, finish = converter.unpackRange(uri, range) + local start, finish = converter.unpackRange(state, range) local results = core(uri, start, finish, diagnostics) if not results or #results == 0 then @@ -834,11 +876,15 @@ m.register 'textDocument/codeAction' { for _, res in ipairs(results) do if res.edit then + ---@param turi uri for turi, changes in pairs(res.edit.changes) do - for _, change in ipairs(changes) do - change.range = converter.packRange(turi, change.start, change.finish) - change.start = nil - change.finish = nil + local tstate = files.getState(turi) + if tstate then + for _, change in ipairs(changes) do + change.range = converter.packRange(tstate, change.start, change.finish) + change.start = nil + change.finish = nil + end end end end @@ -898,22 +944,31 @@ m.register 'workspace/symbol' { end local function convert(symbol) - symbol.location = converter.location( - symbol.uri, - converter.packRange( + local state = files.getState(symbol.uri) + if not state then + return nil + end + return { + name = symbol.name, + kind = symbol.kind, + location = converter.location( symbol.uri, - symbol.range[1], - symbol.range[2] + converter.packRange( + state, + symbol.range[1], + symbol.range[2] + ) ) - ) - symbol.uri = nil + } end + local results = {} + for _, symbol in ipairs(symbols) do - convert(symbol) + results[#results+1] = convert(symbol) end - return symbols + return results end } @@ -978,8 +1033,12 @@ m.register 'textDocument/semanticTokens/range' { workspace.awaitReady(uri) local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_SEMANTIC_RANGE, 0.5) await.sleep(0.0) + local state = files.getState(uri) + if not state then + return nil + end local core = require 'core.semantic-tokens' - local start, finish = converter.unpackRange(uri, params.range) + local start, finish = converter.unpackRange(state, params.range) local results = core(uri, start, finish) return { data = results @@ -999,6 +1058,10 @@ m.register 'textDocument/foldingRange' { if not files.exists(uri) then return nil end + local state = files.getState(uri) + if not state then + return nil + end local regions = core(uri) if not regions then return nil @@ -1006,8 +1069,8 @@ m.register 'textDocument/foldingRange' { local results = {} for _, region in ipairs(regions) do - local startLine = converter.packPosition(uri, region.start).line - local endLine = converter.packPosition(uri, region.finish).line + local startLine = converter.packPosition(state, region.start).line + local endLine = converter.packPosition(state, region.finish).line if not region.hideLastLine then endLine = endLine - 1 end @@ -1033,7 +1096,8 @@ m.register 'textDocument/documentColor' { local color = require 'core.color' local uri = files.getRealUri(params.textDocument.uri) workspace.awaitReady(uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end local colors = color.colors(uri) @@ -1043,7 +1107,7 @@ m.register 'textDocument/documentColor' { local results = {} for _, colorValue in ipairs(colors) do results[#results+1] = { - range = converter.packRange(uri, colorValue.start, colorValue.finish), + range = converter.packRange(state, colorValue.start, colorValue.finish), color = colorValue.color } end @@ -1103,7 +1167,8 @@ m.register 'textDocument/formatting' { function(params) local uri = files.getRealUri(params.textDocument.uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end @@ -1123,7 +1188,7 @@ m.register 'textDocument/formatting' { local results = {} for i, edit in ipairs(edits) do results[i] = { - range = converter.packRange(uri, edit.start, edit.finish), + range = converter.packRange(state, edit.start, edit.finish), newText = edit.text, } end @@ -1140,7 +1205,8 @@ m.register 'textDocument/rangeFormatting' { function(params) local uri = files.getRealUri(params.textDocument.uri) - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end @@ -1160,7 +1226,7 @@ m.register 'textDocument/rangeFormatting' { local results = {} for i, edit in ipairs(edits) do results[i] = { - range = converter.packRange(uri, edit.start, edit.finish), + range = converter.packRange(state, edit.start, edit.finish), newText = edit.text, } end @@ -1183,11 +1249,12 @@ m.register 'textDocument/onTypeFormatting' { workspace.awaitReady(uri) local _ <close> = progress.create(uri, lang.script.WINDOW_PROCESSING_TYPE_FORMATTING, 0.5) local ch = params.ch - if not files.exists(uri) then + local state = files.getState(uri) + if not state then return nil end local core = require 'core.type-formatting' - local pos = converter.unpackPosition(uri, params.position) + local pos = converter.unpackPosition(state, params.position) local edits = core(uri, pos, ch, params.options) if not edits or #edits == 0 then return nil @@ -1199,7 +1266,7 @@ m.register 'textDocument/onTypeFormatting' { local results = {} for i, edit in ipairs(edits) do results[i] = { - range = converter.packRange(uri, edit.start, edit.finish), + range = converter.packRange(state, edit.start, edit.finish), newText = edit.text:gsub('\t', tab), } end @@ -1221,14 +1288,18 @@ m.register '$/requestHint' { return end workspace.awaitReady(uri) + local state = files.getState(uri) + if not state then + return + end local core = require 'core.hint' - local start, finish = converter.unpackRange(uri, params.range) + local start, finish = converter.unpackRange(state, params.range) local results = core(uri, start, finish) local hintResults = {} for i, res in ipairs(results) do hintResults[i] = { text = res.text, - pos = converter.packPosition(uri, res.offset), + pos = converter.packPosition(state, res.offset), kind = res.kind, } end @@ -1246,34 +1317,44 @@ m.register 'textDocument/inlayHint' { function (params) local uri = files.getRealUri(params.textDocument.uri) if not config.get(uri, 'Lua.hint.enable') then - return + return nil end workspace.awaitReady(uri) local core = require 'core.hint' - local start, finish = converter.unpackRange(uri, params.range) + local state = files.getState(uri) + if not state then + return nil + end + local start, finish = converter.unpackRange(state, params.range) local results = core(uri, start, finish) local hintResults = {} for i, res in ipairs(results) do - hintResults[i] = { + local luri = guide.getUri(res.source) + local lstate = files.getState(luri) + if not lstate then + goto CONTINUE + end + hintResults[#hintResults+1] = { label = { { value = res.text, tooltip = res.tooltip, location = res.source and converter.location( - guide.getUri(res.source), + luri, converter.packRange( - guide.getUri(res.source), + lstate, res.source.start, res.source.finish ) ), }, }, - position = converter.packPosition(uri, res.offset), + position = converter.packPosition(lstate, res.offset), kind = res.kind, paddingLeft = true, paddingRight = true, } + ::CONTINUE:: end return hintResults end |