summaryrefslogtreecommitdiff
path: root/script/core/command
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2020-11-20 21:57:09 +0800
committer最萌小汐 <sumneko@hotmail.com>2020-11-20 21:57:09 +0800
commit4ca61ec457822dd14966afa0752340ae8ce180a1 (patch)
treeae8adb1ad82c717868e551e699fd3cf3bb290089 /script/core/command
parentc63b2e404d8d2bb984afe3678a5ba2b2836380cc (diff)
downloadlua-language-server-4ca61ec457822dd14966afa0752340ae8ce180a1.zip
no longer beta
Diffstat (limited to 'script/core/command')
-rw-r--r--script/core/command/removeSpace.lua56
-rw-r--r--script/core/command/solve.lua96
2 files changed, 152 insertions, 0 deletions
diff --git a/script/core/command/removeSpace.lua b/script/core/command/removeSpace.lua
new file mode 100644
index 00000000..e8b09932
--- /dev/null
+++ b/script/core/command/removeSpace.lua
@@ -0,0 +1,56 @@
+local files = require 'files'
+local define = require 'proto.define'
+local guide = require 'parser.guide'
+local proto = require 'proto'
+local lang = require 'language'
+
+local function isInString(ast, offset)
+ return guide.eachSourceContain(ast.ast, offset, function (source)
+ if source.type == 'string' then
+ return true
+ end
+ end) or false
+end
+
+return function (data)
+ local uri = data.uri
+ local lines = files.getLines(uri)
+ local text = files.getText(uri)
+ local ast = files.getAst(uri)
+ if not lines then
+ return
+ end
+
+ local textEdit = {}
+ for i = 1, #lines do
+ local line = guide.lineContent(lines, text, i, true)
+ local pos = line:find '[ \t]+$'
+ if pos then
+ local start, finish = guide.lineRange(lines, i, true)
+ start = start + pos - 1
+ if isInString(ast, start) then
+ goto NEXT_LINE
+ end
+ textEdit[#textEdit+1] = {
+ range = define.range(lines, text, start, finish),
+ newText = '',
+ }
+ goto NEXT_LINE
+ end
+
+ ::NEXT_LINE::
+ end
+
+ if #textEdit == 0 then
+ return
+ end
+
+ proto.awaitRequest('workspace/applyEdit', {
+ label = lang.script.COMMAND_REMOVE_SPACE,
+ edit = {
+ changes = {
+ [uri] = textEdit,
+ }
+ },
+ })
+end
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