summaryrefslogtreecommitdiff
path: root/script/core/code-action.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script/core/code-action.lua')
-rw-r--r--script/core/code-action.lua144
1 files changed, 75 insertions, 69 deletions
diff --git a/script/core/code-action.lua b/script/core/code-action.lua
index 64f862f9..8256107e 100644
--- a/script/core/code-action.lua
+++ b/script/core/code-action.lua
@@ -1,63 +1,49 @@
-local files = require 'files'
-local lang = require 'language'
-local util = require 'utility'
-local sp = require 'bee.subprocess'
-local guide = require "parser.guide"
+local files = require 'files'
+local lang = require 'language'
+local util = require 'utility'
+local sp = require 'bee.subprocess'
+local guide = require "parser.guide"
+local converter = require 'proto.converter'
local function checkDisableByLuaDocExits(uri, row, mode, code)
- local lines = files.getLines(uri)
- local ast = files.getState(uri)
- local text = files.getOriginText(uri)
- local line = lines[row]
- if ast.ast.docs and line then
- for _, doc in ipairs(ast.ast.docs) do
- if doc.start >= line.start
- and doc.finish <= line.finish then
- if doc.type == 'doc.diagnostic' then
- if doc.mode == mode then
- if doc.names then
- return {
- start = doc.finish,
- finish = doc.finish,
- newText = text:sub(doc.finish, doc.finish)
- .. ', '
- .. code
- }
- else
- return {
- start = doc.finish,
- finish = doc.finish,
- newText = text:sub(doc.finish, doc.finish)
- .. ': '
- .. code
- }
- end
- end
+ if row < 0 then
+ return nil
+ end
+ local state = files.getState(uri)
+ local lines = state.lines
+ if state.ast.docs and lines then
+ return guide.eachSourceBetween(state.ast.docs, guide.positionOf(row, 0), guide.positionOf(row + 1, 0), function (doc)
+ if doc.type == 'doc.diagnostic'
+ and doc.mode == mode then
+ if doc.names then
+ return {
+ start = doc.finish,
+ finish = doc.finish,
+ newText = ', ' .. code,
+ }
+ else
+ return {
+ start = doc.finish,
+ finish = doc.finish,
+ newText = ': ' .. code,
+ }
end
end
- end
+ end)
end
return nil
end
local function checkDisableByLuaDocInsert(uri, row, mode, code)
- local lines = files.getLines(uri)
- local ast = files.getState(uri)
- local text = files.getOriginText(uri)
- -- 先看看上一行是不是已经有了
- -- 没有的话就插入一行
- local line = lines[row]
return {
- start = line.start,
- finish = line.start,
- newText = '---@diagnostic ' .. mode .. ': ' .. code .. '\n'
- .. text:sub(line.start, line.start)
+ start = guide.positionOf(row, 0),
+ finish = guide.positionOf(row, 0),
+ newText = '---@diagnostic ' .. mode .. ': ' .. code .. '\n',
}
end
local function disableDiagnostic(uri, code, start, results)
- local lines = files.getLines(uri)
- local row = guide.positionOf(lines, start)
+ local row = guide.rowColOf(start)
results[#results+1] = {
title = lang.script('ACTION_DISABLE_DIAG', code),
kind = 'quickfix',
@@ -90,8 +76,8 @@ local function disableDiagnostic(uri, code, start, results)
checkDisableByLuaDocExits (uri, row - 1, 'disable-next-line', code)
or checkDisableByLuaDocInsert(uri, row, 'disable-next-line', code))
pushEdit(lang.script('ACTION_DISABLE_DIAG_FILE', code),
- checkDisableByLuaDocExits (uri, 1, 'disable', code)
- or checkDisableByLuaDocInsert(uri, 1, 'disable', code))
+ checkDisableByLuaDocExits (uri, 0, 'disable', code)
+ or checkDisableByLuaDocInsert(uri, 0, 'disable', code))
end
local function markGlobal(uri, name, results)
@@ -134,8 +120,8 @@ end
local function solveUndefinedGlobal(uri, diag, results)
local ast = files.getState(uri)
- local offset = files.offsetOfWord(uri, diag.range.start)
- guide.eachSourceContain(ast.ast, offset, function (source)
+ local start = converter.unpackRange(uri, diag.range)
+ guide.eachSourceContain(ast.ast, start, function (source)
if source.type ~= 'getglobal' then
return
end
@@ -153,8 +139,8 @@ end
local function solveLowercaseGlobal(uri, diag, results)
local ast = files.getState(uri)
- local offset = files.offsetOfWord(uri, diag.range.start)
- guide.eachSourceContain(ast.ast, offset, function (source)
+ local start = converter.unpackRange(uri, diag.range)
+ guide.eachSourceContain(ast.ast, start, function (source)
if source.type ~= 'setglobal' then
return
end
@@ -168,7 +154,7 @@ local function findSyntax(uri, diag)
local ast = files.getState(uri)
for _, err in ipairs(ast.errs) do
if err.type:lower():gsub('_', '-') == diag.code then
- local range = files.range(uri, err.start, err.finish)
+ local range = converter.packRange(uri, err.start, err.finish)
if util.equal(range, diag.range) then
return err
end
@@ -197,8 +183,13 @@ local function solveSyntaxByAddDoEnd(uri, err, results)
[uri] = {
{
start = err.start,
+ finish = err.start,
+ newText = 'do ',
+ },
+ {
+ start = err.finish,
finish = err.finish,
- newText = ('do %s end'):format(text:sub(err.start, err.finish)),
+ newText = ' end',
},
}
}
@@ -265,7 +256,7 @@ local function solveSyntax(uri, diag, results)
end
local function solveNewlineCall(uri, diag, results)
- local start = files.unrange(uri, diag.range)
+ local start = converter.unpackRange(uri, diag.range)
results[#results+1] = {
title = lang.script.ACTION_ADD_SEMICOLON,
kind = 'quickfix',
@@ -349,18 +340,18 @@ local function checkQuickFix(results, uri, start, diagnostics)
end
local function checkSwapParams(results, uri, start, finish)
- local ast = files.getState(uri)
- local text = files.getText(uri)
- if not ast then
+ local state = files.getState(uri)
+ local text = files.getText(uri)
+ if not state then
return
end
local args = {}
- guide.eachSourceBetween(ast.ast, start, finish, function (source)
+ guide.eachSourceBetween(state.ast, start, finish, function (source)
if source.type == 'callargs'
or source.type == 'funcargs' then
local targetIndex
for index, arg in ipairs(source) do
- if arg.start - 1 <= finish and arg.finish >= start then
+ if arg.start <= finish and arg.finish >= start then
-- should select only one param
if targetIndex then
return
@@ -373,11 +364,17 @@ local function checkSwapParams(results, uri, start, finish)
end
local node
if source.type == 'callargs' then
- node = text:sub(source.parent.node.start, source.parent.node.finish)
+ node = text:sub(
+ guide.positionToOffset(state, source.parent.node.start) + 1,
+ guide.positionToOffset(state, source.parent.node.finish)
+ )
elseif source.type == 'funcargs' then
local var = source.parent.parent
if guide.isSet(var) then
- node = text:sub(var.start, var.finish)
+ node = text:sub(
+ guide.positionToOffset(state, var.start) + 1,
+ guide.positionToOffset(state, var.finish)
+ )
else
node = lang.script.SYMBOL_ANONYMOUS
end
@@ -411,12 +408,18 @@ local function checkSwapParams(results, uri, start, finish)
{
start = myArg.start,
finish = myArg.finish,
- newText = text:sub(targetArg.start, targetArg.finish),
+ newText = text:sub(
+ guide.positionToOffset(state, targetArg.start) + 1,
+ guide.positionToOffset(state, targetArg.finish)
+ ),
},
{
start = targetArg.start,
finish = targetArg.finish,
- newText = text:sub(myArg.start, myArg.finish),
+ newText = text:sub(
+ guide.positionToOffset(state, myArg.start) + 1,
+ guide.positionToOffset(state, myArg.finish)
+ ),
},
}
}
@@ -499,13 +502,16 @@ end
--end
local function checkJsonToLua(results, uri, start, finish)
- local text = files.getText(uri)
- local jsonStart = text:match ('()[%{%[]', start)
+ local text = files.getText(uri)
+ local state = files.getState(uri)
+ local startOffset = guide.positionToOffset(state, start)
+ local finishOffset = guide.positionToOffset(state, finish)
+ local jsonStart = text:match ('()[%{%[]', startOffset + 1)
if not jsonStart then
return
end
local jsonFinish
- for i = math.min(finish, #text), jsonStart + 1, -1 do
+ for i = math.min(finishOffset, #text), jsonStart + 1, -1 do
local char = text:sub(i, i)
if char == ']'
or char == '}' then
@@ -528,8 +534,8 @@ local function checkJsonToLua(results, uri, start, finish)
arguments = {
{
uri = uri,
- start = jsonStart,
- finish = jsonFinish,
+ start = guide.offsetToPosition(state, jsonStart) - 1,
+ finish = guide.offsetToPosition(state, jsonFinish),
}
}
},