summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-09-23 22:15:47 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-09-23 22:15:47 +0800
commitc95e9c91236bccb4593a0d9d218dca78bcb06ae0 (patch)
tree08109d0b434bdc799758936fc759d89ae8dd0266 /script
parent291a7b3a7fcaee5bc761722ca46265f3cd7f70f3 (diff)
downloadlua-language-server-c95e9c91236bccb4593a0d9d218dca78bcb06ae0.zip
update
Diffstat (limited to 'script')
-rw-r--r--script/files.lua20
-rw-r--r--script/parser/guide.lua24
-rw-r--r--script/parser/lines.lua20
-rw-r--r--script/proto/converter.lua72
4 files changed, 97 insertions, 39 deletions
diff --git a/script/files.lua b/script/files.lua
index 19f4da89..659a1aa0 100644
--- a/script/files.lua
+++ b/script/files.lua
@@ -112,6 +112,7 @@ local function pluginOnSetText(file, text)
suc, result, diffs = xpcall(smerger.mergeDiff, log.error, text, result)
if suc then
file._diffInfo = diffs
+ file.originLines = parser.lines(text)
return result
else
if DEVELOP and result then
@@ -291,6 +292,17 @@ function m.getOriginText(uri)
return file.originText
end
+--- 获取文件原始行表
+---@param uri uri
+---@return integer[]
+function m.getOriginLines(uri)
+ local file = m.fileMap[uri]
+ if not file then
+ return nil
+ end
+ return file.originLines
+end
+
function m.getChildFiles(uri)
local results = {}
local uris = m.getAllUris()
@@ -576,6 +588,14 @@ function m.diffedOffsetBack(uri, offset)
return smerger.getOffsetBack(file._diffInfo, offset)
end
+function m.hasDiffed(uri)
+ local file = m.getFile(uri)
+ if not file then
+ return false
+ end
+ return file._diffInfo ~= nil
+end
+
--- 获取文件的自定义缓存信息(在文件内容更新后自动失效)
function m.getCache(uri)
local file = m.fileMap[uri]
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index 28a275cf..b65d9680 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -759,17 +759,19 @@ function m.positionOf(row, col)
return row * 10000 + col
end
+function m.positionToOffsetByLines(lines, position)
+ local row, col = m.rowColOf(position)
+ return lines[row] + col - 1
+end
+
--- 返回全文光标位置
---@param state any
---@param position integer
function m.positionToOffset(state, position)
- local lines = state.lines
- local row, col = m.rowColOf(position)
- return lines[row] + col - 1
+ return m.positionToOffsetByLines(state.lines, position)
end
-function m.offsetToPosition(state, offset)
- local lines = state.lines
+function m.offsetToPositionByLines(lines, offset)
local left = 0
local right = #lines
local row = 0
@@ -794,16 +796,8 @@ function m.offsetToPosition(state, offset)
return m.positionOf(row, col)
end
-function m.lineContent(lines, text, row, ignoreNL)
- local line = lines[row]
- if not line then
- return ''
- end
- if ignoreNL then
- return text:sub(line.start, line.range)
- else
- return text:sub(line.start, line.finish)
- end
+function m.offsetToPosition(state, offset)
+ return m.offsetToPositionByLines(state.lines, offset)
end
local isSetMap = {
diff --git a/script/parser/lines.lua b/script/parser/lines.lua
index 06023df1..964aabf4 100644
--- a/script/parser/lines.lua
+++ b/script/parser/lines.lua
@@ -5,30 +5,20 @@ local ssub = string.sub
return function (text)
local current = 1
local lines = {}
- local i = 1
+ lines[0] = 1
+ local i = 0
while true do
local pos = sfind(text,'[\r\n]', current)
if not pos then
break
end
- local line = {
- start = current - 1,
- range = pos - 1,
- }
- lines[i] = line
i = i + 1
if ssub(text, pos, pos + 1) == '\r\n' then
- current = pos + 2
- line.finish = pos + 1
+ current = pos + 2
else
- current = pos + 1
- line.finish = pos
+ current = pos + 1
end
+ lines[i] = current
end
- lines[i] = {
- start = current - 1,
- finish = #text,
- range = #text,
- }
return lines
end
diff --git a/script/proto/converter.lua b/script/proto/converter.lua
index 53b65b12..5fb73c14 100644
--- a/script/proto/converter.lua
+++ b/script/proto/converter.lua
@@ -3,13 +3,9 @@ local files = require 'files'
local m = {}
-
---@alias position {line: integer, character: integer}
----@param uri uri
----@param pos integer
----@return position
-function m.packPosition(uri, pos)
+local function rawPackPosition(uri, pos)
local row, col = guide.rowColOf(pos)
if col > 0 then
local state = files.getState(uri)
@@ -25,10 +21,39 @@ function m.packPosition(uri, pos)
}
end
----@param uri uri
----@param position position
----@return integer
-function m.unpackPosition(uri, position)
+
+local function diffedPackPosition(uri, originPos)
+ local state = files.getState(uri)
+ local originLines = files.getOriginLines(uri)
+ local originOffset = guide.positionToOffsetByLines(originLines, originPos)
+ local offset = files.diffedOffsetBack(uri, originOffset)
+ local pos = guide.offsetToPosition(state, offset)
+ local row, col = guide.rowColOf(pos)
+ if col > 0 then
+ local text = files.getOriginText(uri)
+ if text then
+ local lineOffset = originLines[row]
+ col = utf8.len(text, lineOffset, lineOffset + col - 1, true)
+ end
+ end
+ return {
+ line = row,
+ character = col,
+ }
+end
+
+---@param uri uri
+---@param pos integer
+---@return position
+function m.packPosition(uri, pos)
+ if files.hasDiffed(uri) then
+ return diffedPackPosition(uri, pos)
+ else
+ return rawPackPosition(uri, pos)
+ end
+end
+
+local function rawUnpackPosition(uri, position)
local row, col = position.line, position.character
if col > 0 then
local state = files.getState(uri)
@@ -42,6 +67,35 @@ function m.unpackPosition(uri, position)
return pos
end
+local function diffedUnpackPosition(uri, position)
+ local row, col = position.line, position.character
+ local originLines = files.getOriginLines(uri)
+ if col > 0 then
+ local text = files.getOriginText(uri)
+ if text then
+ local lineOffset = originLines[row]
+ col = utf8.offset(text, col + 1, lineOffset) - lineOffset
+ end
+ end
+ local state = files.getState(uri)
+ local originPos = guide.positionOf(row, col)
+ local originOffset = guide.positionToOffsetByLines(originLines, originPos)
+ local offset = files.diffedOffset(originOffset)
+ local pos = guide.offsetToPosition(state, offset)
+ return pos
+end
+
+---@param uri uri
+---@param position position
+---@return integer
+function m.unpackPosition(uri, position)
+ if files.hasDiffed(uri) then
+ return diffedUnpackPosition(uri, position)
+ else
+ return rawUnpackPosition(uri, position)
+ end
+end
+
---@alias range {start: position, end: position}
---@param uri uri