diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2021-09-23 22:15:47 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2021-09-23 22:15:47 +0800 |
commit | c95e9c91236bccb4593a0d9d218dca78bcb06ae0 (patch) | |
tree | 08109d0b434bdc799758936fc759d89ae8dd0266 /script | |
parent | 291a7b3a7fcaee5bc761722ca46265f3cd7f70f3 (diff) | |
download | lua-language-server-c95e9c91236bccb4593a0d9d218dca78bcb06ae0.zip |
update
Diffstat (limited to 'script')
-rw-r--r-- | script/files.lua | 20 | ||||
-rw-r--r-- | script/parser/guide.lua | 24 | ||||
-rw-r--r-- | script/parser/lines.lua | 20 | ||||
-rw-r--r-- | script/proto/converter.lua | 72 |
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 |