diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2024-08-01 17:52:53 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2024-08-01 17:52:53 +0800 |
commit | d87be6dff95dfe00244e109c69aadb8a3c102928 (patch) | |
tree | f0bdd455f5adc5c6822369fa682a9facad580bc2 | |
parent | 1c7755b317d1e811a3f71f3ec745800555575fd0 (diff) | |
download | lua-language-server-d87be6dff95dfe00244e109c69aadb8a3c102928.zip |
fix wrong indent
-rw-r--r-- | changelog.md | 6 | ||||
-rw-r--r-- | script/core/fix-indent.lua | 123 | ||||
-rw-r--r-- | script/parser/guide.lua | 2 |
3 files changed, 121 insertions, 10 deletions
diff --git a/changelog.md b/changelog.md index fadf1296..0bf05c01 100644 --- a/changelog.md +++ b/changelog.md @@ -14,7 +14,11 @@ * `CHG` Change spacing of parameter inlay hints to match other LSPs, like `rust-analyzer` * `FIX` Inconsistent type narrow behavior of function call args [#2758](https://github.com/LuaLS/lua-language-server/issues/2758) * `FIX` Typos in annotation descriptions -* `NEW` You can now click on "References" in CodeLen to display the reference list +* `NEW` You can now click on "References" in CodeLen to display the reference list(VSCode) +* `NEW` Improved behavior for inserting new lines: + + When inside an annotation, an annotation tag will be added at the beginning of the line (VSCode). + + When between `function () end` or similar constructs, the format will be adjusted to a more reasonable one (VSCode) and leading/trailing spaces will be removed (generic). + + Attempts to semantically fix improper indentation (generic). ## 3.9.3 `2024-6-11` 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, |