diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2024-08-01 16:11:44 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2024-08-01 16:11:44 +0800 |
commit | a72aa21a2f1bdaccabc757b0c8ecef17959785fd (patch) | |
tree | c448a120efa3fa8394b271df1934fdef41e55b75 | |
parent | fcf295284b2bb71c6ed4e08ded11e8a4b8dd758f (diff) | |
download | lua-language-server-a72aa21a2f1bdaccabc757b0c8ecef17959785fd.zip |
删除多余空格
-rw-r--r-- | script/core/fix-indent.lua | 138 | ||||
-rw-r--r-- | script/core/type-formatting.lua | 195 |
2 files changed, 36 insertions, 297 deletions
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 |