diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:57:09 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:57:09 +0800 |
commit | 4ca61ec457822dd14966afa0752340ae8ce180a1 (patch) | |
tree | ae8adb1ad82c717868e551e699fd3cf3bb290089 /script/core/command/solve.lua | |
parent | c63b2e404d8d2bb984afe3678a5ba2b2836380cc (diff) | |
download | lua-language-server-4ca61ec457822dd14966afa0752340ae8ce180a1.zip |
no longer beta
Diffstat (limited to 'script/core/command/solve.lua')
-rw-r--r-- | script/core/command/solve.lua | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/script/core/command/solve.lua b/script/core/command/solve.lua new file mode 100644 index 00000000..d3b8f94e --- /dev/null +++ b/script/core/command/solve.lua @@ -0,0 +1,96 @@ +local files = require 'files' +local define = require 'proto.define' +local guide = require 'parser.guide' +local proto = require 'proto' +local lang = require 'language' + +local opMap = { + ['+'] = true, + ['-'] = true, + ['*'] = true, + ['/'] = true, + ['//'] = true, + ['^'] = true, + ['<<'] = true, + ['>>'] = true, + ['&'] = true, + ['|'] = true, + ['~'] = true, + ['..'] = true, +} + +local literalMap = { + ['number'] = true, + ['boolean'] = true, + ['string'] = true, + ['table'] = true, +} + +return function (data) + local uri = data.uri + local lines = files.getLines(uri) + local text = files.getText(uri) + local ast = files.getAst(uri) + if not ast then + return + end + + local start = define.offsetOfWord(lines, text, data.range.start) + local finish = define.offsetOfWord(lines, text, data.range['end']) + + local result = guide.eachSourceContain(ast.ast, start, function (source) + if source.start ~= start + or source.finish ~= finish then + return + end + if not source.op or source.op.type ~= 'or' then + return + end + local first = source[1] + local second = source[2] + -- a + b or 0 --> a + (b or 0) + do + if first.op + and opMap[first.op.type] + and first.type ~= 'unary' + and not second.op + and literalMap[second.type] then + return { + start = source[1][2].start, + finish = source[2].finish, + } + end + end + -- a or b + c --> (a or b) + c + do + if second.op + and opMap[second.op.type] + and second.type ~= 'unary' + and not first.op + and literalMap[second[1].type] then + return { + start = source[1].start, + finish = source[2][1].finish, + } + end + end + end) + + if not result then + return + end + + proto.awaitRequest('workspace/applyEdit', { + label = lang.script.COMMAND_REMOVE_SPACE, + edit = { + changes = { + [uri] = { + { + range = define.range(lines, text, result.start, result.finish), + newText = ('(%s)'):format(text:sub(result.start, result.finish)), + } + }, + } + }, + }) +end |