From 3ce73bee997a385b5f31cd7e7474eb3e23cbbd64 Mon Sep 17 00:00:00 2001 From: NeOzay Date: Mon, 22 Jul 2024 22:47:20 +0200 Subject: improve diagnosis (missing-fields). --- script/core/diagnostics/missing-fields.lua | 91 ++++++++++++++++++------------ 1 file changed, 54 insertions(+), 37 deletions(-) (limited to 'script') diff --git a/script/core/diagnostics/missing-fields.lua b/script/core/diagnostics/missing-fields.lua index 210920fd..e6b48ffd 100644 --- a/script/core/diagnostics/missing-fields.lua +++ b/script/core/diagnostics/missing-fields.lua @@ -16,69 +16,86 @@ return function (uri, callback) await.delay() local defs = vm.getDefs(src) + local sortedDefs = {} for _, def in ipairs(defs) do - if def.type == 'doc.class' and def.bindSource then - if guide.isInRange(def.bindSource, src.start) then + if def.type == 'doc.class' then + if def.bindSource and guide.isInRange(def.bindSource, src.start) then return end + if not sortedDefs[def.class[1]] then + sortedDefs[def.class[1]] = {} + end + local samedefs = sortedDefs[def.class[1]] + samedefs[#samedefs+1] = def end if def.type == 'doc.type.array' or def.type == 'doc.type.table' then return end end - local warnings = {} - for _, def in ipairs(defs) do - if def.type == 'doc.class' then - if not def.fields then - return - end + + local Allwarnings = {} + for _, samedefs in pairs(sortedDefs) do + local warnings = {} + for _, def in ipairs(samedefs) do + if def.type == 'doc.class' then + if not def.fields then + goto continue + end - local requiresKeys = {} - for _, field in ipairs(def.fields) do - if not field.optional - and not vm.compileNode(field):isNullable() then + local requiresKeys = {} + for _, field in ipairs(def.fields) do + if not field.optional + and not vm.compileNode(field):isNullable() then + local key = vm.getKeyName(field) + if key and not requiresKeys[key] then + requiresKeys[key] = true + requiresKeys[#requiresKeys+1] = key + end + end + end + + if #requiresKeys == 0 then + goto continue + end + local myKeys = {} + for _, field in ipairs(src) do local key = vm.getKeyName(field) - if key and not requiresKeys[key] then - requiresKeys[key] = true - requiresKeys[#requiresKeys+1] = key + if key then + myKeys[key] = true end end - end - if #requiresKeys == 0 then - return - end - local myKeys = {} - for _, field in ipairs(src) do - local key = vm.getKeyName(field) - if key then - myKeys[key] = true + local missedKeys = {} + for _, key in ipairs(requiresKeys) do + if not myKeys[key] then + missedKeys[#missedKeys+1] = ('`%s`'):format(key) + end end - end - local missedKeys = {} - for _, key in ipairs(requiresKeys) do - if not myKeys[key] then - missedKeys[#missedKeys+1] = ('`%s`'):format(key) + if #missedKeys == 0 then + goto continue end - end - if #missedKeys == 0 then - return + warnings[#warnings+1] = lang.script('DIAG_MISSING_FIELDS', def.class[1], table.concat(missedKeys, ', ')) + end + ::continue:: + end + if #warnings == 0 then + return + else + for i = 1, #warnings do + Allwarnings[#Allwarnings+1] = warnings[i] end - - warnings[#warnings+1] = lang.script('DIAG_MISSING_FIELDS', def.class[1], table.concat(missedKeys, ', ')) end end - - if #warnings == 0 then + if #Allwarnings == 0 then return end callback { start = src.start, finish = src.finish, - message = table.concat(warnings, '\n') + message = table.concat(Allwarnings, '\n') } end) end -- cgit v1.2.3 From 0b8102e3774b74db5557a494567fb0a9c5da9013 Mon Sep 17 00:00:00 2001 From: NeOzay Date: Tue, 23 Jul 2024 17:14:37 +0200 Subject: improve missing-fields diagnostic logic --- script/core/diagnostics/missing-fields.lua | 75 ++++++++++++------------------ 1 file changed, 29 insertions(+), 46 deletions(-) (limited to 'script') diff --git a/script/core/diagnostics/missing-fields.lua b/script/core/diagnostics/missing-fields.lua index e6b48ffd..746f7b00 100644 --- a/script/core/diagnostics/missing-fields.lua +++ b/script/core/diagnostics/missing-fields.lua @@ -22,10 +22,11 @@ return function (uri, callback) if def.bindSource and guide.isInRange(def.bindSource, src.start) then return end - if not sortedDefs[def.class[1]] then - sortedDefs[def.class[1]] = {} + local className = def.class[1] + if not sortedDefs[className] then + sortedDefs[className] = {} end - local samedefs = sortedDefs[def.class[1]] + local samedefs = sortedDefs[className] samedefs[#samedefs+1] = def end if def.type == 'doc.type.array' @@ -33,69 +34,51 @@ return function (uri, callback) return end end - - local Allwarnings = {} + + local warnings = {} for _, samedefs in pairs(sortedDefs) do - local warnings = {} + local missedKeys = {} + local className for _, def in ipairs(samedefs) do - if def.type == 'doc.class' then - if not def.fields then - goto continue - end + className = def.class[1] + if not def.fields or #def.fields == 0 then + goto continue + end - local requiresKeys = {} - for _, field in ipairs(def.fields) do - if not field.optional - and not vm.compileNode(field):isNullable() then - local key = vm.getKeyName(field) - if key and not requiresKeys[key] then - requiresKeys[key] = true - requiresKeys[#requiresKeys+1] = key - end - end + local myKeys = {} + for _, field in ipairs(src) do + local key = vm.getKeyName(field) + if key then + myKeys[key] = true end + end - if #requiresKeys == 0 then - goto continue - end - local myKeys = {} - for _, field in ipairs(src) do + for _, field in ipairs(def.fields) do + if not field.optional + and not vm.compileNode(field):isNullable() then local key = vm.getKeyName(field) - if key then - myKeys[key] = true - end - end - - local missedKeys = {} - for _, key in ipairs(requiresKeys) do - if not myKeys[key] then + if key and not myKeys[key] then missedKeys[#missedKeys+1] = ('`%s`'):format(key) end end - - if #missedKeys == 0 then - goto continue - end - - warnings[#warnings+1] = lang.script('DIAG_MISSING_FIELDS', def.class[1], table.concat(missedKeys, ', ')) - end + end ::continue:: end - if #warnings == 0 then + + if #missedKeys == 0 then return else - for i = 1, #warnings do - Allwarnings[#Allwarnings+1] = warnings[i] - end + warnings[#warnings+1] = lang.script('DIAG_MISSING_FIELDS', className, table.concat(missedKeys, ', ')) end end - if #Allwarnings == 0 then + + if #warnings == 0 then return end callback { start = src.start, finish = src.finish, - message = table.concat(Allwarnings, '\n') + message = table.concat(warnings, '\n') } end) end -- cgit v1.2.3 From 7582afd72f6d111f81b9c48caf43bafa80a1887a Mon Sep 17 00:00:00 2001 From: NeOzay Date: Tue, 23 Jul 2024 17:55:39 +0200 Subject: update changelog --- script/core/diagnostics/missing-fields.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'script') diff --git a/script/core/diagnostics/missing-fields.lua b/script/core/diagnostics/missing-fields.lua index 746f7b00..b901461a 100644 --- a/script/core/diagnostics/missing-fields.lua +++ b/script/core/diagnostics/missing-fields.lua @@ -67,9 +67,9 @@ return function (uri, callback) if #missedKeys == 0 then return - else - warnings[#warnings+1] = lang.script('DIAG_MISSING_FIELDS', className, table.concat(missedKeys, ', ')) end + + warnings[#warnings+1] = lang.script('DIAG_MISSING_FIELDS', className, table.concat(missedKeys, ', ')) end if #warnings == 0 then -- cgit v1.2.3 From c08410458924a9f3c604e662cfce80f0f86d5b78 Mon Sep 17 00:00:00 2001 From: NeOzay Date: Wed, 24 Jul 2024 18:01:44 +0200 Subject: also detects missing index fields --- script/core/diagnostics/missing-fields.lua | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'script') diff --git a/script/core/diagnostics/missing-fields.lua b/script/core/diagnostics/missing-fields.lua index b901461a..18b561ee 100644 --- a/script/core/diagnostics/missing-fields.lua +++ b/script/core/diagnostics/missing-fields.lua @@ -15,6 +15,7 @@ return function (uri, callback) guide.eachSourceType(state.ast, 'table', function (src) await.delay() + vm.removeNode(src) -- the node is not updated correctly, reason still unknown local defs = vm.getDefs(src) local sortedDefs = {} for _, def in ipairs(defs) do @@ -47,7 +48,7 @@ return function (uri, callback) local myKeys = {} for _, field in ipairs(src) do - local key = vm.getKeyName(field) + local key = vm.getKeyName(field) or field.tindex if key then myKeys[key] = true end @@ -57,8 +58,20 @@ return function (uri, callback) if not field.optional and not vm.compileNode(field):isNullable() then local key = vm.getKeyName(field) + if not key then + local fieldnode = vm.compileNode(field.field)[1] + if fieldnode and fieldnode.type == 'doc.type.integer' then + ---@cast fieldnode parser.object + key = vm.getKeyName(fieldnode) + end + end + if key and not myKeys[key] then - missedKeys[#missedKeys+1] = ('`%s`'):format(key) + if type(key) == "number" then + missedKeys[#missedKeys+1] = ('`[%s]`'):format(key) + else + missedKeys[#missedKeys+1] = ('`%s`'):format(key) + end end end end -- cgit v1.2.3 From 9035afd4b4fb548c2d88c0a4e3ec566cb0c2cc11 Mon Sep 17 00:00:00 2001 From: NeOzay <69015205+NeOzay@users.noreply.github.com> Date: Sun, 28 Jul 2024 18:20:49 +0200 Subject: Update script/core/diagnostics/missing-fields.lua Co-authored-by: Tom Lau --- script/core/diagnostics/missing-fields.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'script') diff --git a/script/core/diagnostics/missing-fields.lua b/script/core/diagnostics/missing-fields.lua index 18b561ee..d332b091 100644 --- a/script/core/diagnostics/missing-fields.lua +++ b/script/core/diagnostics/missing-fields.lua @@ -37,11 +37,9 @@ return function (uri, callback) end local warnings = {} - for _, samedefs in pairs(sortedDefs) do + for className, samedefs in pairs(sortedDefs) do local missedKeys = {} - local className for _, def in ipairs(samedefs) do - className = def.class[1] if not def.fields or #def.fields == 0 then goto continue end -- cgit v1.2.3 From df9db56b148f8ab242d35f7d4e2b91cd2ba02668 Mon Sep 17 00:00:00 2001 From: NeOzay Date: Sun, 28 Jul 2024 18:30:02 +0200 Subject: compute table keys once --- script/core/diagnostics/missing-fields.lua | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'script') diff --git a/script/core/diagnostics/missing-fields.lua b/script/core/diagnostics/missing-fields.lua index d332b091..5ce650ec 100644 --- a/script/core/diagnostics/missing-fields.lua +++ b/script/core/diagnostics/missing-fields.lua @@ -35,7 +35,8 @@ return function (uri, callback) return end end - + + local myKeys local warnings = {} for className, samedefs in pairs(sortedDefs) do local missedKeys = {} @@ -43,12 +44,14 @@ return function (uri, callback) if not def.fields or #def.fields == 0 then goto continue end - - local myKeys = {} - for _, field in ipairs(src) do - local key = vm.getKeyName(field) or field.tindex - if key then - myKeys[key] = true + + if not myKeys then + myKeys = {} + for _, field in ipairs(src) do + local key = vm.getKeyName(field) or field.tindex + if key then + myKeys[key] = true + end end end -- cgit v1.2.3 From e760b69c8104d0bf6ef17f6f033265908557743d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Tue, 30 Jul 2024 17:22:02 +0800 Subject: =?UTF-8?q?=E6=8B=86=E5=88=86=E6=88=90=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/core/diagnostics/unused-function.lua | 6 +++++- script/library.lua | 2 +- script/plugin.lua | 2 +- script/provider/provider.lua | 6 +++++- 4 files changed, 12 insertions(+), 4 deletions(-) (limited to 'script') diff --git a/script/core/diagnostics/unused-function.lua b/script/core/diagnostics/unused-function.lua index a873375f..1145036d 100644 --- a/script/core/diagnostics/unused-function.lua +++ b/script/core/diagnostics/unused-function.lua @@ -5,6 +5,7 @@ local define = require 'proto.define' local lang = require 'language' local await = require 'await' local client = require 'client' +local util = require 'utility' local function isToBeClosed(source) if not source.attrs then @@ -105,8 +106,11 @@ return function (uri, callback) turnBlack(source, black, white, links) end + local tagSupports = client.getAbility('textDocument.completion.completionItem.tagSupport.valueSet') + local supportUnnecessary = tagSupports and util.arrayHas(tagSupports, define.DiagnosticTag.Unnecessary) + for source in pairs(white) do - if client.isVSCode() then + if supportUnnecessary then callback { start = source.start, finish = source.finish, diff --git a/script/library.lua b/script/library.lua index cfc7e328..49e39470 100644 --- a/script/library.lua +++ b/script/library.lua @@ -22,7 +22,7 @@ m.metaPaths = {} local function getDocFormater(uri) local version = config.get(uri, 'Lua.runtime.version') - if client.isVSCode() then + if client.getOption('viewDocument') then if version == 'Lua 5.1' then return 'HOVER_NATIVE_DOCUMENT_LUA51' elseif version == 'Lua 5.2' then diff --git a/script/plugin.lua b/script/plugin.lua index b8ecfb6a..ec55875e 100644 --- a/script/plugin.lua +++ b/script/plugin.lua @@ -195,7 +195,7 @@ local function initPlugin(uri) m.showError(scp, err) return end - if not client.isVSCode() and not checkTrustLoad(scp) then + if not client.getOption('trustByClient') and not checkTrustLoad(scp) then return end local suc, err = xpcall(f, log.error, f, uri, myArgs) diff --git a/script/provider/provider.lua b/script/provider/provider.lua index 2e2fb5eb..3c9782c1 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -292,6 +292,7 @@ m.register 'textDocument/didClose' { m.register 'textDocument/didChange' { ---@async function (params) + local fixIndent = require 'core.fix-indent' local doc = params.textDocument local changes = params.contentChanges local uri = files.getRealUri(doc.uri) @@ -299,6 +300,7 @@ m.register 'textDocument/didChange' { if not text then text = util.loadFile(furi.decode(uri)) files.setText(uri, text, false) + fixIndent(uri, changes) return end local rows = files.getCachedRows(uri) @@ -307,6 +309,8 @@ m.register 'textDocument/didChange' { file.version = doc.version end) files.setCachedRows(uri, rows) + + fixIndent(uri, changes) end } @@ -1059,7 +1063,7 @@ end client.event(function (ev) if ev == 'init' then - if not client.isVSCode() then + if not client.getOption('useSemanticByRange') then m.register 'textDocument/semanticTokens/full' { capability = { semanticTokensProvider = { -- cgit v1.2.3 From aae2c7888bad227b6df897b97c01f123744175de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Tue, 30 Jul 2024 17:46:00 +0800 Subject: =?UTF-8?q?=E8=BF=87=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/lclient.lua | 28 +++++++++++++++++++++++++++- script/vm/def.lua | 2 +- 2 files changed, 28 insertions(+), 2 deletions(-) (limited to 'script') diff --git a/script/lclient.lua b/script/lclient.lua index 13b431b0..96a6c16f 100644 --- a/script/lclient.lua +++ b/script/lclient.lua @@ -5,6 +5,8 @@ local await = require 'await' local timer = require 'timer' local pub = require 'pub' local json = require 'json' +local client = require 'client' +local define = require 'proto.define' require 'provider' @@ -61,9 +63,33 @@ function mt:_localLoadFile() end) end +local defaultClientOptions = { + initializationOptions = { + changeConfiguration = true, + viewDocument = true, + trustByClient = true, + useSemanticByRange = true, + }, + capabilities = { + textDocument = { + completion = { + completionItem = { + tagSupport = { + valueSet = { + define.DiagnosticTag.Unnecessary, + define.DiagnosticTag.Deprecated, + }, + }, + }, + }, + }, + }, +} + ---@async function mt:initialize(params) - self:awaitRequest('initialize', params or {}) + local initParams = util.tableMerge(params or {}, defaultClientOptions) + self:awaitRequest('initialize', initParams) self:notify('initialized') end diff --git a/script/vm/def.lua b/script/vm/def.lua index 669d39c2..ffd2de7a 100644 --- a/script/vm/def.lua +++ b/script/vm/def.lua @@ -93,7 +93,7 @@ function vm.getDefs(source) return results end -local HAS_DEF_ERR = {} -- the error object for comparing +local HAS_DEF_ERR = {''} -- the error object for comparing local function checkHasDef(checkFunc, source, pushResult) local _, err = pcall(checkFunc, source, pushResult) return err == HAS_DEF_ERR -- cgit v1.2.3 From 4133ed413c78b749dd77ccbab70981fd5fb3a537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Wed, 31 Jul 2024 18:48:50 +0800 Subject: You can now click on "References" in CodeLen to display the reference list --- script/core/code-lens.lua | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'script') diff --git a/script/core/code-lens.lua b/script/core/code-lens.lua index bc39ec86..bebfeedf 100644 --- a/script/core/code-lens.lua +++ b/script/core/code-lens.lua @@ -4,6 +4,7 @@ local await = require 'await' local conv = require 'proto.converter' local getRef = require 'core.reference' local lang = require 'language' +local client = require 'client' ---@class parser.state ---@field package _codeLens? codeLens @@ -88,12 +89,35 @@ end function mt:resolveReference(source) local refs = getRef(self.uri, source.finish, false) local count = refs and #refs or 0 - local command = conv.command( - lang.script('COMMAND_REFERENCE_COUNT', count), - '', - {} - ) - return command + if client.getOption('codeLensViewReferences') then + local locations = {} + for _, ref in ipairs(refs or {}) do + local state = files.getState(ref.uri) + if state then + locations[#locations+1] = conv.location( + ref.uri, + conv.packRange(state, ref.target.start, ref.target.finish) + ) + end + end + local command = conv.command( + lang.script('COMMAND_REFERENCE_COUNT', count), + 'lua.showReferences', + { + self.uri, + conv.packPosition(self.state, source.start), + locations, + } + ) + return command + else + local command = conv.command( + lang.script('COMMAND_REFERENCE_COUNT', count), + '', + {} + ) + return command + end end ---@async -- cgit v1.2.3 From fcf295284b2bb71c6ed4e08ded11e8a4b8dd758f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Wed, 31 Jul 2024 18:53:58 +0800 Subject: =?UTF-8?q?=E5=85=88=E6=8A=8A=E8=BF=99=E4=B8=AA=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BA=86=EF=BC=8C=E8=BF=87=E4=B8=80=E4=B8=8B?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/core/fix-indent.lua | 170 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 script/core/fix-indent.lua (limited to 'script') diff --git a/script/core/fix-indent.lua b/script/core/fix-indent.lua new file mode 100644 index 00000000..9389072d --- /dev/null +++ b/script/core/fix-indent.lua @@ -0,0 +1,170 @@ +local files = require 'files' +local guide = require 'parser.guide' +local lookBackward = require 'core.look-backward' +local proto = require 'proto.proto' + +---@param state parser.state +local function insertIndentation(state, position, edits) + local text = state.originText or state.lua + local lines = state.originLines or state.lines + local row = guide.rowColOf(position) + if not lines or not text then + return + end + local offset = lines[row] + local indent = text:match('^%s*', offset) + for _, edit in ipairs(edits) do + edit.text = edit.text:gsub('\n', '\n' .. indent) + end +end + +---@param state parser.state +local function findForward(state, position, ...) + local lines = state.originLines or state.lines + local offset = guide.positionToOffsetByLines(lines, position) + local firstOffset = state.originText:match('^[ \t]*()', offset + 1) + if not firstOffset then + return nil + end + for _, symbol in ipairs { ... } do + if state.originText:sub(firstOffset, firstOffset + #symbol - 1) == symbol then + return guide.offsetToPositionByLines(lines, firstOffset - 1), symbol + end + end + return nil +end + +---@param state parser.state +local function findBackward(state, position, ...) + local text = state.originText or state.lua + local lines = state.originLines or state.lines + if not text or not lines then + return nil + end + local offset = guide.positionToOffsetByLines(lines, position) + local lastOffset = lookBackward.findAnyOffset(text, offset) + if not lastOffset then + return nil + end + for _, symbol in ipairs { ... } do + if text:sub(lastOffset - #symbol + 1, lastOffset) == symbol then + return guide.offsetToPositionByLines(lines, lastOffset) + end + end + return nil +end + +---@param state parser.state +---@param change table +---@param result any[] +local function checkSplitOneLine(state, change, result) + if change.text ~= '\r\n' + and change.text ~= '\n' then + return + end + + local lines = state.originLines or state.lines + local position = lines[change.range.start.line + 1] + + local fPosition, fSymbol = findForward(state, position, 'end', '}') + if not fPosition or not fSymbol then + return + end + local bPosition = findBackward(state, position, 'then', 'do', ')', '{') + if not bPosition then + return + end + local edits = {} + edits[#edits+1] = { + start = bPosition, + finish = position, + text = '\n\t', + } + edits[#edits+1] = { + start = position, + finish = fPosition + 1, + text = '', + } + edits[#edits+1] = { + start = fPosition + 1, + finish = fPosition + 1, + text = '\n' .. fSymbol:sub(1, 1) + } + insertIndentation(state, bPosition, edits) + for _, edit in ipairs(edits) do + result[#result+1] = edit + end +end + +---@param state parser.state +local function applyEdits(state, edits) + if #edits == 0 then + return + end + + local lines = state.originLines or state.lines + + local results = {} + for i, edit in ipairs(edits) do + local startPos = guide.offsetToPositionByLines(lines, edit.start) + local endPos = guide.offsetToPositionByLines(lines, edit.finish) + local startRow, startCol = guide.rowColOf(startPos) + local endRow, endCol = guide.rowColOf(endPos) + results[i] = { + range = { + start = { + line = startRow, + character = startCol, + }, + ['end'] = { + line = endRow, + character = endCol, + } + }, + newText = edit.text, + } + end + + proto.request('workspace/applyEdit', { + label = 'Fix Indent', + edit = { + changes = { + [state.uri] = { + { + range = { + start = { + line = 1, + character = 0, + }, + ['end'] = { + line = 1, + character = 0, + } + }, + newText = '\t', + }, + } + } + }, + }) + proto.notify('$/command', { + command = 'cursorMove', + }) +end + +return function (uri, changes) + do return end + local state = files.compileState(uri) + if not state then + return + end + + local edits = {} + for _, change in ipairs(changes) do + if change.range then + checkSplitOneLine(state, change, edits) + end + end + + applyEdits(state, edits) +end -- cgit v1.2.3 From a72aa21a2f1bdaccabc757b0c8ecef17959785fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Thu, 1 Aug 2024 16:11:44 +0800 Subject: =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99=E7=A9=BA=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/core/fix-indent.lua | 138 +++++++--------------------- script/core/type-formatting.lua | 195 +--------------------------------------- 2 files changed, 36 insertions(+), 297 deletions(-) (limited to 'script') diff --git a/script/core/fix-indent.lua b/script/core/fix-indent.lua index 9389072d..2d1dc318 100644 --- a/script/core/fix-indent.lua +++ b/script/core/fix-indent.lua @@ -4,95 +4,44 @@ local lookBackward = require 'core.look-backward' local proto = require 'proto.proto' ---@param state parser.state -local function insertIndentation(state, position, edits) - local text = state.originText or state.lua - local lines = state.originLines or state.lines - local row = guide.rowColOf(position) - if not lines or not text then +---@param change table +---@param edits table[] +local function removeSpacesAfterEnter(state, change, edits) + if not change.text:match '^\r?\n[\t ]+\r?\n' then return end - local offset = lines[row] - local indent = text:match('^%s*', offset) - for _, edit in ipairs(edits) do - edit.text = edit.text:gsub('\n', '\n' .. indent) - end -end - ----@param state parser.state -local function findForward(state, position, ...) local lines = state.originLines or state.lines - local offset = guide.positionToOffsetByLines(lines, position) - local firstOffset = state.originText:match('^[ \t]*()', offset + 1) - if not firstOffset then - return nil - end - for _, symbol in ipairs { ... } do - if state.originText:sub(firstOffset, firstOffset + #symbol - 1) == symbol then - return guide.offsetToPositionByLines(lines, firstOffset - 1), symbol - end - end - return nil -end + local text = state.originText or state.lua + ---@cast text -? ----@param state parser.state -local function findBackward(state, position, ...) - local text = state.originText or state.lua - local lines = state.originLines or state.lines - if not text or not lines then - return nil - end - local offset = guide.positionToOffsetByLines(lines, position) - local lastOffset = lookBackward.findAnyOffset(text, offset) - if not lastOffset then - return nil - end - for _, symbol in ipairs { ... } do - if text:sub(lastOffset - #symbol + 1, lastOffset) == symbol then - return guide.offsetToPositionByLines(lines, lastOffset) + -- 清除前置空格 + local startPos = guide.positionOf(change.range.start.line, change.range.start.character) + local startOffset = guide.positionToOffsetByLines(lines, startPos) + local leftOffset + for offset = startOffset, lines[change.range.start.line], -1 do + leftOffset = offset + local char = text:sub(offset, offset) + if char ~= ' ' and char ~= '\t' then + break end end - return nil -end - ----@param state parser.state ----@param change table ----@param result any[] -local function checkSplitOneLine(state, change, result) - if change.text ~= '\r\n' - and change.text ~= '\n' then - return + if leftOffset and leftOffset < startOffset then + edits[#edits+1] = { + start = leftOffset, + finish = startOffset, + text = '', + } end - local lines = state.originLines or state.lines - local position = lines[change.range.start.line + 1] - - local fPosition, fSymbol = findForward(state, position, 'end', '}') - if not fPosition or not fSymbol then - return - end - local bPosition = findBackward(state, position, 'then', 'do', ')', '{') - if not bPosition then - return - end - local edits = {} - edits[#edits+1] = { - start = bPosition, - finish = position, - text = '\n\t', - } - edits[#edits+1] = { - start = position, - finish = fPosition + 1, - text = '', - } - edits[#edits+1] = { - start = fPosition + 1, - finish = fPosition + 1, - text = '\n' .. fSymbol:sub(1, 1) - } - insertIndentation(state, bPosition, edits) - for _, edit in ipairs(edits) do - result[#result+1] = edit + -- 清除后置空格 + local endOffset = startOffset + #change.text + local _, rightOffset = text:find('^[\t ]+', endOffset + 1) + if rightOffset then + edits[#edits+1] = { + start = endOffset, + finish = rightOffset, + text = '', + } end end @@ -129,41 +78,22 @@ local function applyEdits(state, edits) label = 'Fix Indent', edit = { changes = { - [state.uri] = { - { - range = { - start = { - line = 1, - character = 0, - }, - ['end'] = { - line = 1, - character = 0, - } - }, - newText = '\t', - }, - } + [state.uri] = results } }, }) - proto.notify('$/command', { - command = 'cursorMove', - }) end return function (uri, changes) - do return end local state = files.compileState(uri) if not state then return end local edits = {} - for _, change in ipairs(changes) do - if change.range then - checkSplitOneLine(state, change, edits) - end + local firstChange = changes[1] + if firstChange.range then + removeSpacesAfterEnter(state, firstChange, edits) end applyEdits(state, edits) diff --git a/script/core/type-formatting.lua b/script/core/type-formatting.lua index 419cb56b..f6080650 100644 --- a/script/core/type-formatting.lua +++ b/script/core/type-formatting.lua @@ -4,187 +4,6 @@ local guide = require 'parser.guide' local config = require 'config' local util = require 'utility' - -local function insertIndentation(uri, position, edits) - local text = files.getText(uri) - local state = files.getState(uri) - local row = guide.rowColOf(position) - if not state or not text then - return - end - local offset = state.lines[row] - local indent = text:match('^%s*', offset) - for _, edit in ipairs(edits) do - edit.text = edit.text:gsub('\n', '\n' .. indent) - end -end - -local function findForward(uri, position, ...) - local text = files.getText(uri) - local state = files.getState(uri) - if not state or not text then - return nil - end - local offset = guide.positionToOffset(state, position) - local firstOffset = text:match('^[ \t]*()', offset + 1) - if not firstOffset then - return nil - end - for _, symbol in ipairs { ... } do - if text:sub(firstOffset, firstOffset + #symbol - 1) == symbol then - return guide.offsetToPosition(state, firstOffset - 1), symbol - end - end - return nil -end - -local function findBackward(uri, position, ...) - local text = files.getText(uri) - local state = files.getState(uri) - if not state or not text then - return nil - end - local offset = guide.positionToOffset(state, position) - local lastOffset = lookBackward.findAnyOffset(text, offset) - for _, symbol in ipairs { ... } do - if text:sub(lastOffset - #symbol + 1, lastOffset) == symbol then - return guide.offsetToPosition(state, lastOffset) - end - end - return nil -end - -local function checkSplitOneLine(results, uri, position, ch) - if ch ~= '\n' then - return - end - - local fPosition, fSymbol = findForward(uri, position, 'end', '}') - if not fPosition or not fSymbol then - return - end - local bPosition = findBackward(uri, position, 'then', 'do', ')', '{') - if not bPosition then - return - end - local edits = {} - edits[#edits+1] = { - start = bPosition, - finish = position, - text = '\n\t', - } - edits[#edits+1] = { - start = position, - finish = fPosition + 1, - text = '', - } - edits[#edits+1] = { - start = fPosition + 1, - finish = fPosition + 1, - text = '\n' .. fSymbol:sub(1, 1) - } - insertIndentation(uri, bPosition, edits) - for _, edit in ipairs(edits) do - results[#results+1] = edit - end -end - -local function getIndent(state, row) - local offset = state.lines[row] - local indent = state.lua:match('^[\t ]*', offset) - return indent -end - -local function isInBlock(state, position) - local block = guide.eachSourceContain(state.ast, position, function(source) - if source.type == 'ifblock' - or source.type == 'elseifblock' then - if source.keyword[4] and source.keyword[4] <= position then - return true - end - end - if source.type == 'else' then - if source.keyword[2] and source.keyword[2] <= position then - return true - end - end - if source.type == 'while' then - if source.keyword[4] and source.keyword[4] <= position then - return true - end - end - if source.type == 'repeat' then - if source.keyword[2] and source.keyword[2] <= position then - return true - end - end - if source.type == 'loop' then - if source.keyword[4] and source.keyword[4] <= position then - return true - end - end - if source.type == 'in' then - if source.keyword[6] and source.keyword[6] <= position then - return true - end - end - if source.type == 'do' then - if source.keyword[2] and source.keyword[2] <= position then - return true - end - end - if source.type == 'function' then - if source.args and source.args.finish <= position then - return true - end - if not source.keyword[3] or source.keyword[3] >= position then - return true - end - end - if source.type == 'table' then - if source.start + 1 == position then - return true - end - end - end) - return block ~= nil -end - -local function checkWrongIndentation(results, uri, position, ch) - if ch ~= '\n' then - return - end - local state = files.getState(uri) - if not state then - return - end - local row = guide.rowColOf(position) - if row <= 0 then - return - end - local myIndent = getIndent(state, row) - local lastIndent = getIndent(state, row - 1) - if #myIndent <= #lastIndent then - return - end - if not util.stringStartWith(myIndent, lastIndent) then - return - end - local lastOffset = lookBackward.findAnyOffset(state.lua, guide.positionToOffset(state, position) - 1) - if not lastOffset then - return - end - local lastPosition = guide.offsetToPosition(state, lastOffset) - if isInBlock(state, lastPosition) then - return - end - results[#results+1] = { - start = position - #myIndent + #lastIndent, - finish = position, - text = '', - } -end - local function typeFormat(results, uri, position, ch, options) if ch ~= '\n' then return @@ -218,22 +37,12 @@ return function (uri, position, ch, options) return nil end - local results = {} - -- split `function () $ end` - checkSplitOneLine(results, uri, position, ch) - if #results > 0 then - return results - end - - checkWrongIndentation(results, uri, position, ch) - if #results > 0 then - return results - end - if TEST then return nil end + local results = {} + typeFormat(results, uri, position, ch, options) if #results > 0 then return results -- cgit v1.2.3 From d0a712ddab9e0ecb9569870d2a26a6ce95d3e305 Mon Sep 17 00:00:00 2001 From: Tyler Miller Date: Sun, 28 Jul 2024 17:49:10 -0700 Subject: fix: incorrect `CompletionItemKind` for postfix snippets --- script/core/completion/postfix.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'script') diff --git a/script/core/completion/postfix.lua b/script/core/completion/postfix.lua index b5f33315..46c24b8e 100644 --- a/script/core/completion/postfix.lua +++ b/script/core/completion/postfix.lua @@ -353,7 +353,7 @@ local function checkPostFix(state, word, wordPosition, position, symbol, results end):gsub('%$%{?%d+%}?', '') results[#results+1] = { label = action.key, - kind = define.CompletionItemKind.Event, + kind = define.CompletionItemKind.Snippet, description = markdown() : add('lua', descText) : string(), -- cgit v1.2.3 From d87be6dff95dfe00244e109c69aadb8a3c102928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Thu, 1 Aug 2024 17:52:53 +0800 Subject: fix wrong indent --- script/core/fix-indent.lua | 123 +++++++++++++++++++++++++++++++++++++++++---- script/parser/guide.lua | 2 + 2 files changed, 116 insertions(+), 9 deletions(-) (limited to 'script') diff --git a/script/core/fix-indent.lua b/script/core/fix-indent.lua index 2d1dc318..f9564dd8 100644 --- a/script/core/fix-indent.lua +++ b/script/core/fix-indent.lua @@ -1,19 +1,20 @@ local files = require 'files' local guide = require 'parser.guide' -local lookBackward = require 'core.look-backward' local proto = require 'proto.proto' +local lookBackward = require 'core.look-backward' +local util = require 'utility' ---@param state parser.state ---@param change table ----@param edits table[] -local function removeSpacesAfterEnter(state, change, edits) - if not change.text:match '^\r?\n[\t ]+\r?\n' then - return +local function removeSpacesAfterEnter(state, change) + if not change.text:match '^\r?\n[\t ]+\r?\n$' then + return false end local lines = state.originLines or state.lines local text = state.originText or state.lua ---@cast text -? + local edits = {} -- 清除前置空格 local startPos = guide.positionOf(change.range.start.line, change.range.start.character) local startOffset = guide.positionToOffsetByLines(lines, startPos) @@ -25,6 +26,7 @@ local function removeSpacesAfterEnter(state, change, edits) break end end + if leftOffset and leftOffset < startOffset then edits[#edits+1] = { start = leftOffset, @@ -43,6 +45,108 @@ local function removeSpacesAfterEnter(state, change, edits) text = '', } end + + if #edits == 0 then + return nil + end + + return edits +end + +local function getIndent(state, row) + local offset = state.lines[row] + local indent = state.lua:match('^[\t ]*', offset) + return indent +end + +local function isInBlock(state, position) + local block = guide.eachSourceContain(state.ast, position, function(source) + if source.type == 'ifblock' + or source.type == 'elseifblock' then + if source.keyword[4] and source.keyword[4] <= position then + return true + end + end + if source.type == 'else' then + if source.keyword[2] and source.keyword[2] <= position then + return true + end + end + if source.type == 'while' then + if source.keyword[4] and source.keyword[4] <= position then + return true + end + end + if source.type == 'repeat' then + if source.keyword[2] and source.keyword[2] <= position then + return true + end + end + if source.type == 'loop' then + if source.keyword[4] and source.keyword[4] <= position then + return true + end + end + if source.type == 'in' then + if source.keyword[6] and source.keyword[6] <= position then + return true + end + end + if source.type == 'do' then + if source.keyword[2] and source.keyword[2] <= position then + return true + end + end + if source.type == 'function' then + if source.args and source.args.finish <= position then + return true + end + if not source.keyword[3] or source.keyword[3] >= position then + return true + end + end + if source.type == 'table' then + if source.start + 1 == position then + return true + end + end + end) + return block ~= nil +end + +local function fixWrongIdent(state, change) + if not change.text:match '^\r?\n[\t ]+$' then + return false + end + local position = guide.positionOf(change.range.start.line, change.range.start.character) + local row = guide.rowColOf(position) + local myIndent = getIndent(state, row + 1) + local lastIndent = getIndent(state, row) + if #myIndent <= #lastIndent then + return + end + if not util.stringStartWith(myIndent, lastIndent) then + return + end + local lastOffset = lookBackward.findAnyOffset(state.lua, guide.positionToOffset(state, position)) + if not lastOffset then + return + end + local lastPosition = guide.offsetToPosition(state, lastOffset) + if isInBlock(state, lastPosition) then + return + end + + local endOffset = guide.positionToOffset(state, position) + #change.text + + local edits = {} + edits[#edits+1] = { + start = endOffset - #myIndent + #lastIndent, + finish = endOffset, + text = '', + } + + return edits end ---@param state parser.state @@ -90,11 +194,12 @@ return function (uri, changes) return end - local edits = {} local firstChange = changes[1] if firstChange.range then - removeSpacesAfterEnter(state, firstChange, edits) + local edits = removeSpacesAfterEnter(state, firstChange) + or fixWrongIdent(state, firstChange) + if edits then + applyEdits(state, edits) + end end - - applyEdits(state, edits) end diff --git a/script/parser/guide.lua b/script/parser/guide.lua index e42f2acd..768d7dec 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -105,6 +105,8 @@ local blockTypes = { ['main'] = true, } +m.blockTypes = blockTypes + local topBlockTypes = { ['while'] = true, ['function'] = true, -- cgit v1.2.3 From 8ecec087ee48501252699b2759b00056db6ef298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Fri, 2 Aug 2024 16:33:06 +0800 Subject: fix runtime error fix #2776 --- script/vm/compiler.lua | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'script') diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index f3655123..54390450 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -578,7 +578,17 @@ local function matchCall(source) if call.args then -- clear node caches of args to allow recomputation with the type narrowed call for _, arg in ipairs(call.args) do - vm.removeNode(arg) + vm.setNode(arg, vm.createNode(), true) + end + for n in newNode:eachObject() do + if n.type == 'function' + or n.type == 'doc.type.function' then + for i, arg in ipairs(call.args) do + if n.args[i] then + vm.setNode(arg, vm.compileNode(n.args[i])) + end + end + end end end end -- cgit v1.2.3 From bc303ac5063352663b995a0a16d7d082a5561f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Fri, 2 Aug 2024 16:49:49 +0800 Subject: Disable indentation fixing for Non-VSCode fix 2778 --- script/core/fix-indent.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'script') diff --git a/script/core/fix-indent.lua b/script/core/fix-indent.lua index f9564dd8..8513c4a8 100644 --- a/script/core/fix-indent.lua +++ b/script/core/fix-indent.lua @@ -3,6 +3,7 @@ local guide = require 'parser.guide' local proto = require 'proto.proto' local lookBackward = require 'core.look-backward' local util = require 'utility' +local client = require 'client' ---@param state parser.state ---@param change table @@ -114,7 +115,7 @@ local function isInBlock(state, position) return block ~= nil end -local function fixWrongIdent(state, change) +local function fixWrongIndent(state, change) if not change.text:match '^\r?\n[\t ]+$' then return false end @@ -189,6 +190,9 @@ local function applyEdits(state, edits) end return function (uri, changes) + if not client.getOption('fixIndents') then + return + end local state = files.compileState(uri) if not state then return @@ -197,7 +201,7 @@ return function (uri, changes) local firstChange = changes[1] if firstChange.range then local edits = removeSpacesAfterEnter(state, firstChange) - or fixWrongIdent(state, firstChange) + or fixWrongIndent(state, firstChange) if edits then applyEdits(state, edits) end -- cgit v1.2.3 From 16a7c65b0284d4b8ae40b2d1c75d898c08771b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Tue, 6 Aug 2024 19:06:42 +0800 Subject: fix wront indentation in some case #2786 --- script/core/fix-indent.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'script') diff --git a/script/core/fix-indent.lua b/script/core/fix-indent.lua index 8513c4a8..c0aaeee1 100644 --- a/script/core/fix-indent.lua +++ b/script/core/fix-indent.lua @@ -138,7 +138,8 @@ local function fixWrongIndent(state, change) return end - local endOffset = guide.positionToOffset(state, position) + #change.text + local endPosition = guide.positionOf(change.range.start.line + 1, #myIndent) + local endOffset = guide.positionToOffset(state, endPosition) local edits = {} edits[#edits+1] = { -- cgit v1.2.3 From 011f95c71a96ddb2c15a75b95d42c0fddf6f37cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Tue, 6 Aug 2024 20:21:46 +0800 Subject: =?UTF-8?q?=E9=9C=80=E8=A6=81=20statusBar=20=E9=80=89=E9=A1=B9?= =?UTF-8?q?=E6=89=8D=E4=BC=9A=E6=98=BE=E7=A4=BA=E7=8A=B6=E6=80=81=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/provider/provider.lua | 3 +++ script/service/service.lua | 4 ++++ 2 files changed, 7 insertions(+) (limited to 'script') diff --git a/script/provider/provider.lua b/script/provider/provider.lua index 3c9782c1..af01aaf8 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -1599,6 +1599,9 @@ m.register '$/psi/select' { local function refreshStatusBar() + if not client.getOption('statusBar') then + return + end local valid = config.get(nil, 'Lua.window.statusBar') for _, scp in ipairs(workspace.folders) do if not config.get(scp.uri, 'Lua.window.statusBar') then diff --git a/script/service/service.lua b/script/service/service.lua index c3afd4cf..a9a02316 100644 --- a/script/service/service.lua +++ b/script/service/service.lua @@ -13,6 +13,7 @@ local time = require 'bee.time' local fw = require 'filewatch' local furi = require 'file-uri' local net = require 'service.net' +local client = require 'client' require 'jsonc' require 'json-beautify' @@ -202,6 +203,9 @@ end local showStatusTip = math.random(100) == 1 function m.reportStatus() + if not client.getOption('statusBar') then + return + end local info = {} if m.workingClock and time.monotonic() - m.workingClock > 100 then info.text = '$(loading~spin)Lua' -- cgit v1.2.3 From a7a40a5b095f0d7dde928ec14560af1818aa3f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Tue, 6 Aug 2024 21:00:43 +0800 Subject: =?UTF-8?q?=E8=AF=AD=E8=A8=80=E8=AE=BE=E7=BD=AE=E6=8C=AA=E5=88=B0?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E9=87=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/provider/language-configuration.lua | 86 ++++++++++++++++++++++++++++++ script/provider/provider.lua | 12 +++++ 2 files changed, 98 insertions(+) create mode 100644 script/provider/language-configuration.lua (limited to 'script') diff --git a/script/provider/language-configuration.lua b/script/provider/language-configuration.lua new file mode 100644 index 00000000..1d34f765 --- /dev/null +++ b/script/provider/language-configuration.lua @@ -0,0 +1,86 @@ +-- Enumeration of commonly encountered syntax token types. +local SyntaxTokenType = { + Other = 0, -- Everything except tokens that are part of comments, string literals and regular expressions. + Comment = 1, -- A comment. + String = 2, -- A string literal. + RegEx = 3 -- A regular expression. +} + +-- Describes what to do with the indentation when pressing Enter. +local IndentAction = { + None = 0, -- Insert new line and copy the previous line's indentation. + Indent = 1, -- Insert new line and indent once (relative to the previous line's indentation). + IndentOutdent = 2, -- Insert two new lines: the first one indented which will hold the cursor, and the second one at the same indentation level. + Outdent = 3 -- Insert new line and outdent once (relative to the previous line's indentation). +} + +local languageConfiguration = { + id = 'lua', + configuration = { + autoClosingPairs = { + { open = "{", close = "}" }, + { open = "[", close = "]" }, + { open = "(", close = ")" }, + { open = "'", close = "'", notIn = { SyntaxTokenType.String } }, + { open = '"', close = '"', notIn = { SyntaxTokenType.String } }, + { open = "[=", close = "=]" }, + { open = "[==", close = "==]" }, + { open = "[===", close = "===]" }, + { open = "[====", close = "====]" }, + { open = "[=====", close = "=====]" }, + }, + onEnterRules = { + { + beforeText = [[\)\s*$]], + afterText = [[^\s*end\b]], + action = { + indentAction = IndentAction.IndentOutdent, + } + }, + { + beforeText = [[\b()\s*$]], + afterText = [[^\s*end\b]], + action = { + indentAction = IndentAction.IndentOutdent, + } + }, + { + beforeText = [[\b(repeat)\s*$]], + afterText = [[^\s*until\b]], + action = { + indentAction = IndentAction.IndentOutdent, + } + }, + { + beforeText = [[^\s*---@]], + action = { + indentAction = IndentAction.None, + appendText = "---@" + } + }, + { + beforeText = [[^\s*--- @]], + action = { + indentAction = IndentAction.None, + appendText = "--- @" + } + }, + { + beforeText = [[^\s*--- ]], + action = { + indentAction = IndentAction.None, + appendText = "--- " + } + }, + { + beforeText = [[^\s*---]], + action = { + indentAction = IndentAction.None, + appendText = "---" + } + }, + }, + }, +} + +return languageConfiguration diff --git a/script/provider/provider.lua b/script/provider/provider.lua index af01aaf8..6a4b2406 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -1597,6 +1597,18 @@ m.register '$/psi/select' { end } +local function refreshLanguageConfiguration() + if not client.getOption('languageConfiguration') then + return + end + proto.notify('$/languageConfiguration', require 'provider.language-configuration') +end + +config.watch(function (uri, key, value) + if key == '' then + refreshLanguageConfiguration() + end +end) local function refreshStatusBar() if not client.getOption('statusBar') then -- cgit v1.2.3 From 1dbe571cfe8b003f539f09385d7b719f7f13b381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Tue, 6 Aug 2024 21:09:01 +0800 Subject: =?UTF-8?q?=E5=BA=94=E8=AF=A5=E4=BD=BF=E7=94=A8=E6=9C=80=E5=90=8E?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E6=9C=89=E6=95=88=E8=A1=8C=E7=9A=84=E7=BC=A9?= =?UTF-8?q?=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/core/fix-indent.lua | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'script') diff --git a/script/core/fix-indent.lua b/script/core/fix-indent.lua index c0aaeee1..59adfb7b 100644 --- a/script/core/fix-indent.lua +++ b/script/core/fix-indent.lua @@ -122,18 +122,19 @@ local function fixWrongIndent(state, change) local position = guide.positionOf(change.range.start.line, change.range.start.character) local row = guide.rowColOf(position) local myIndent = getIndent(state, row + 1) - local lastIndent = getIndent(state, row) - if #myIndent <= #lastIndent then + local lastOffset = lookBackward.findAnyOffset(state.lua, guide.positionToOffset(state, position)) + if not lastOffset then return end - if not util.stringStartWith(myIndent, lastIndent) then + local lastPosition = guide.offsetToPosition(state, lastOffset) + local lastRow = guide.rowColOf(lastPosition) + local lastIndent = getIndent(state, lastRow) + if #myIndent <= #lastIndent then return end - local lastOffset = lookBackward.findAnyOffset(state.lua, guide.positionToOffset(state, position)) - if not lastOffset then + if not util.stringStartWith(myIndent, lastIndent) then return end - local lastPosition = guide.offsetToPosition(state, lastOffset) if isInBlock(state, lastPosition) then return end -- cgit v1.2.3 From 15c716da6c690b7b8dcb90d9eec13a449dfc0e05 Mon Sep 17 00:00:00 2001 From: SeanTheBuilder1 Date: Sat, 3 Aug 2024 14:26:12 +0800 Subject: feat: flip binary operator check if failed if vm.runOperator fails try again with flipped arguments this emulates how lua checks the binary metaevents in which if there is no corresponding binary metaevent for the left operand it checks the right operand instead. This also works when both operands are tables. This change affects: - __add - __sub - __mul - __div - __idiv - __mod - __pow - __concat - __band - __bor - __bxor - __shl - __shr --- script/vm/operator.lua | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'script') diff --git a/script/vm/operator.lua b/script/vm/operator.lua index 7ce2b30d..07ce19eb 100644 --- a/script/vm/operator.lua +++ b/script/vm/operator.lua @@ -261,6 +261,9 @@ vm.binarySwitch = util.switch() }) else local node = vm.runOperator(binaryMap[op], source[1], source[2]) + if not node then + node = vm.runOperator(binaryMap[op], source[2], source[1]) + end if node then vm.setNode(source, node) end @@ -300,6 +303,9 @@ vm.binarySwitch = util.switch() }) else local node = vm.runOperator(binaryMap[op], source[1], source[2]) + if not node then + node = vm.runOperator(binaryMap[op], source[2], source[1]) + end if node then vm.setNode(source, node) return @@ -396,6 +402,9 @@ vm.binarySwitch = util.switch() return end local node = vm.runOperator(binaryMap[source.op.type], source[1], source[2]) + if not node then + node = vm.runOperator(binaryMap[source.op.type], source[2], source[1]) + end if node then vm.setNode(source, node) end -- cgit v1.2.3 From 40fd1d7c4c9bed4842acfdfe4e1cbb0307bab941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Wed, 7 Aug 2024 17:13:42 +0800 Subject: say hello at first to make everyone happy --- script/service/service.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'script') diff --git a/script/service/service.lua b/script/service/service.lua index a9a02316..3fad865a 100644 --- a/script/service/service.lua +++ b/script/service/service.lua @@ -249,6 +249,10 @@ function m.testVersion() end end +function m.sayHello() + proto.notify('$/hello', 'world') +end + function m.lockCache() local fs = require 'bee.filesystem' local sp = require 'bee.subprocess' @@ -284,6 +288,8 @@ function m.start() require 'provider' + m.sayHello() + m.eventLoop() end -- cgit v1.2.3 From e6a5b41f7424ad56a12efdf950efd2f20ad5f322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Thu, 8 Aug 2024 18:09:50 +0800 Subject: ignored error --- script/vm/def.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'script') diff --git a/script/vm/def.lua b/script/vm/def.lua index ffd2de7a..41f735b2 100644 --- a/script/vm/def.lua +++ b/script/vm/def.lua @@ -93,7 +93,7 @@ function vm.getDefs(source) return results end -local HAS_DEF_ERR = {''} -- the error object for comparing +local HAS_DEF_ERR = false -- the error object for comparing local function checkHasDef(checkFunc, source, pushResult) local _, err = pcall(checkFunc, source, pushResult) return err == HAS_DEF_ERR -- cgit v1.2.3 From aaf16240f77bb75a3d8db89c2a99934c8b6022ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Thu, 8 Aug 2024 18:11:16 +0800 Subject: fix memory leak with `---@enum(partical)` --- script/vm/type.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'script') diff --git a/script/vm/type.lua b/script/vm/type.lua index d2a859d0..d3ce7a92 100644 --- a/script/vm/type.lua +++ b/script/vm/type.lua @@ -70,7 +70,7 @@ local function checkParentEnum(parentName, child, uri, mark, errs) if enums then enums = util.arrayMerge(enums, denums) else - enums = denums + enums = util.arrayMerge({}, denums) end end end -- cgit v1.2.3 From 7f7c5920e91e147fad12e10c2de7c25b15df66e6 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 14 Aug 2024 12:04:55 +0100 Subject: fix: improve textDocument/definition ordering --- script/core/definition.lua | 63 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) (limited to 'script') diff --git a/script/core/definition.lua b/script/core/definition.lua index 3619916e..207fc9cc 100644 --- a/script/core/definition.lua +++ b/script/core/definition.lua @@ -7,18 +7,73 @@ local rpath = require 'workspace.require-path' local jumpSource = require 'core.jump-source' local wssymbol = require 'core.workspace-symbol' -local function sortResults(results) +--- @param s string +--- @return string[] +local function split(s) + local r = {} + s:gsub('[^/]+', function (w) + r[#r+1] = w:gsub("~1", "/"):gsub("~0", "~") + end) + return r +end + +--- Returns the Levenshtein distance between the two given string arrays +--- @param a string[] +--- @param b string[] +--- @return number +local function levenshteinDistance(a, b) + local a_len, b_len = #a, #b + local matrix = {} --- @type integer[][] + + -- Initialize the matrix + for i = 1, a_len + 1 do + matrix[i] = { [1] = i } + end + + for j = 1, b_len + 1 do + matrix[1][j] = j + end + + -- Compute the Levenshtein distance + for i = 1, a_len do + for j = 1, b_len do + local cost = (a[i] == b[j]) and 0 or 1 + matrix[i + 1][j + 1] = + math.min(matrix[i][j + 1] + 1, matrix[i + 1][j] + 1, matrix[i][j] + cost) + end + end + + -- Return the Levenshtein distance + return matrix[a_len + 1][b_len + 1] +end + +--- @param path1 string +--- @param path2 string +--- @return number +local function pathSimilarityRatio(path1, path2) + local parts1 = split(path1) + local parts2 = split(path2) + local distance = levenshteinDistance(parts1, parts2) + return distance * 2 / (#parts1 + #parts2) +end + +local function sortResults(results, uri) -- 先按照顺序排序 + -- Sort in order first + local simularity_cache = {} --- @type table table.sort(results, function (a, b) local u1 = guide.getUri(a.target) local u2 = guide.getUri(b.target) if u1 == u2 then return a.target.start < b.target.start else - return u1 < u2 + simularity_cache[u1] = simularity_cache[u1] or pathSimilarityRatio(uri, u1) + simularity_cache[u2] = simularity_cache[u2] or pathSimilarityRatio(uri, u2) + return simularity_cache[u1] < simularity_cache[u2] end end) -- 如果2个结果处于嵌套状态,则取范围小的那个 + -- If two results are nested, take the one with the smaller range local lf, lu for i = #results, 1, -1 do local res = results[i].target @@ -141,7 +196,7 @@ return function (uri, offset) local results = {} local uris = checkRequire(source) if uris then - for i, uri in ipairs(uris) do + for _, uri in ipairs(uris) do results[#results+1] = { uri = uri, source = source, @@ -230,7 +285,7 @@ return function (uri, offset) return nil end - sortResults(results) + sortResults(results, uri) jumpSource(results) return results -- cgit v1.2.3 From 390cf8fd09fa577f9bdc7a4e3c82e6f3b2b3eacd Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 14 Aug 2024 12:34:02 +0100 Subject: fixup! fast path for matching strings --- script/core/definition.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'script') diff --git a/script/core/definition.lua b/script/core/definition.lua index 207fc9cc..f94d3628 100644 --- a/script/core/definition.lua +++ b/script/core/definition.lua @@ -51,6 +51,9 @@ end --- @param path2 string --- @return number local function pathSimilarityRatio(path1, path2) + if path1 == path2 then + return 0 + end local parts1 = split(path1) local parts2 = split(path2) local distance = levenshteinDistance(parts1, parts2) -- cgit v1.2.3 From d6d3d4b96b249310552ef6081dc35a401a219239 Mon Sep 17 00:00:00 2001 From: OmentaElvis Date: Thu, 15 Aug 2024 01:51:49 +0300 Subject: FIX: Changed hello param to valid JSONRPC The previous hello jsonrpc message caused sadness since it caused lsp clients to exit as it was not a correct way to say hello. --- script/service/service.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'script') diff --git a/script/service/service.lua b/script/service/service.lua index 3fad865a..c7675f1b 100644 --- a/script/service/service.lua +++ b/script/service/service.lua @@ -250,7 +250,7 @@ function m.testVersion() end function m.sayHello() - proto.notify('$/hello', 'world') + proto.notify('$/hello', {'world'}) end function m.lockCache() -- cgit v1.2.3 From c51f0389096e12a02711b911b7272f49910b1f1b Mon Sep 17 00:00:00 2001 From: Tyler Miller Date: Sun, 11 Aug 2024 00:54:00 -0700 Subject: fix(hint): attempt to index a nil value Fixes: #2788 --- script/core/hint.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'script') diff --git a/script/core/hint.lua b/script/core/hint.lua index 9d098aa9..b0ff5aa7 100644 --- a/script/core/hint.lua +++ b/script/core/hint.lua @@ -287,6 +287,8 @@ local function semicolonHint(uri, results, start, finish) ---@async guide.eachSourceTypes(state.ast, blockTypes, function (src) await.delay() + if #src < 1 then return end + for i = 1, #src - 1 do local current = src[i] local next = src[i+1] @@ -313,6 +315,7 @@ local function semicolonHint(uri, results, start, finish) end end end + if mode == 'All' then local last = src[#src] results[#results+1] = { -- cgit v1.2.3 From a05f52abf03c47992b4488ede95ad0c4b6484bed Mon Sep 17 00:00:00 2001 From: "Wu, Zhenyu" Date: Tue, 30 Jul 2024 01:04:55 +0800 Subject: Fix lua-language-server --check (#2683) --- script/cli/check.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'script') diff --git a/script/cli/check.lua b/script/cli/check.lua index 8b314f24..c3aac0e3 100644 --- a/script/cli/check.lua +++ b/script/cli/check.lua @@ -8,7 +8,12 @@ local util = require 'utility' local numThreads = tonumber(NUM_THREADS or 1) -local exe = arg[-1] +local exe +local minIndex = -1 +while arg[minIndex] do + exe = arg[minIndex] + minIndex = minIndex - 1 +end -- TODO: is this necessary? got it from the shell.lua helper in bee.lua tests if platform.os == 'windows' and not exe:match('%.[eE][xX][eE]$') then exe = exe..'.exe' -- cgit v1.2.3 From b71cb7aecd9337c9463a4dfbdb9d06cac7b825fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Thu, 15 Aug 2024 14:50:24 +0800 Subject: Revert "fix: improve textDocument/definition ordering" --- script/core/definition.lua | 66 +++------------------------------------------- 1 file changed, 4 insertions(+), 62 deletions(-) (limited to 'script') diff --git a/script/core/definition.lua b/script/core/definition.lua index f94d3628..3619916e 100644 --- a/script/core/definition.lua +++ b/script/core/definition.lua @@ -7,76 +7,18 @@ local rpath = require 'workspace.require-path' local jumpSource = require 'core.jump-source' local wssymbol = require 'core.workspace-symbol' ---- @param s string ---- @return string[] -local function split(s) - local r = {} - s:gsub('[^/]+', function (w) - r[#r+1] = w:gsub("~1", "/"):gsub("~0", "~") - end) - return r -end - ---- Returns the Levenshtein distance between the two given string arrays ---- @param a string[] ---- @param b string[] ---- @return number -local function levenshteinDistance(a, b) - local a_len, b_len = #a, #b - local matrix = {} --- @type integer[][] - - -- Initialize the matrix - for i = 1, a_len + 1 do - matrix[i] = { [1] = i } - end - - for j = 1, b_len + 1 do - matrix[1][j] = j - end - - -- Compute the Levenshtein distance - for i = 1, a_len do - for j = 1, b_len do - local cost = (a[i] == b[j]) and 0 or 1 - matrix[i + 1][j + 1] = - math.min(matrix[i][j + 1] + 1, matrix[i + 1][j] + 1, matrix[i][j] + cost) - end - end - - -- Return the Levenshtein distance - return matrix[a_len + 1][b_len + 1] -end - ---- @param path1 string ---- @param path2 string ---- @return number -local function pathSimilarityRatio(path1, path2) - if path1 == path2 then - return 0 - end - local parts1 = split(path1) - local parts2 = split(path2) - local distance = levenshteinDistance(parts1, parts2) - return distance * 2 / (#parts1 + #parts2) -end - -local function sortResults(results, uri) +local function sortResults(results) -- 先按照顺序排序 - -- Sort in order first - local simularity_cache = {} --- @type table table.sort(results, function (a, b) local u1 = guide.getUri(a.target) local u2 = guide.getUri(b.target) if u1 == u2 then return a.target.start < b.target.start else - simularity_cache[u1] = simularity_cache[u1] or pathSimilarityRatio(uri, u1) - simularity_cache[u2] = simularity_cache[u2] or pathSimilarityRatio(uri, u2) - return simularity_cache[u1] < simularity_cache[u2] + return u1 < u2 end end) -- 如果2个结果处于嵌套状态,则取范围小的那个 - -- If two results are nested, take the one with the smaller range local lf, lu for i = #results, 1, -1 do local res = results[i].target @@ -199,7 +141,7 @@ return function (uri, offset) local results = {} local uris = checkRequire(source) if uris then - for _, uri in ipairs(uris) do + for i, uri in ipairs(uris) do results[#results+1] = { uri = uri, source = source, @@ -288,7 +230,7 @@ return function (uri, offset) return nil end - sortResults(results, uri) + sortResults(results) jumpSource(results) return results -- cgit v1.2.3