From 4ca61ec457822dd14966afa0752340ae8ce180a1 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, 20 Nov 2020 21:57:09 +0800 Subject: no longer beta --- script/core/command/solve.lua | 96 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 script/core/command/solve.lua (limited to 'script/core/command/solve.lua') 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 -- cgit v1.2.3