aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp/util.lua
diff options
context:
space:
mode:
authorMichael Lingelbach <m.j.lbach@gmail.com>2022-01-13 02:34:04 -0800
committerGitHub <noreply@github.com>2022-01-13 02:34:04 -0800
commitbc722c8a74766e14aff3a8e2fc46db72ed864053 (patch)
treececc2c9445d080161ac03be09a39657f8b1b13e7 /runtime/lua/vim/lsp/util.lua
parente7cd81156755c2f588752d469bceee9e48377b4e (diff)
downloadrneovim-bc722c8a74766e14aff3a8e2fc46db72ed864053.tar.gz
rneovim-bc722c8a74766e14aff3a8e2fc46db72ed864053.tar.bz2
rneovim-bc722c8a74766e14aff3a8e2fc46db72ed864053.zip
fix(lsp): strictly enforce passing offset encoding (#17049)
This removes the "fallback" to utf-16 in many of our helper functions. We should always explicitly pass these around when possible except in two locations: * generating params with help utilities called by buf.lua functions * the buf.lua functions themselves Anything that is called by the handler should be passed the offset encoding.
Diffstat (limited to 'runtime/lua/vim/lsp/util.lua')
-rw-r--r--runtime/lua/vim/lsp/util.lua62
1 files changed, 43 insertions, 19 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index a00f7f3673..d09865be89 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -277,7 +277,7 @@ end
---@private
--- Position is a https://microsoft.github.io/language-server-protocol/specifications/specification-current/#position
--- Returns a zero-indexed column, since set_lines() does the conversion to
----@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to utf-16
+---@param offset_encoding string utf-8|utf-16|utf-32
--- 1-indexed
local function get_line_byte_from_position(bufnr, position, offset_encoding)
-- LSP's line and characters are 0-indexed
@@ -360,15 +360,14 @@ end
--- Applies a list of text edits to a buffer.
---@param text_edits table list of `TextEdit` objects
---@param bufnr number Buffer id
----@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to encoding of first client of `bufnr`
+---@param offset_encoding string utf-8|utf-16|utf-32 defaults to encoding of first client of `bufnr`
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit
function M.apply_text_edits(text_edits, bufnr, offset_encoding)
validate {
text_edits = { text_edits, 't', false };
bufnr = { bufnr, 'number', false };
- offset_encoding = { offset_encoding, 'string', true };
+ offset_encoding = { offset_encoding, 'string', false };
}
- offset_encoding = offset_encoding or M._get_offset_encoding(bufnr)
if not next(text_edits) then return end
if not api.nvim_buf_is_loaded(bufnr) then
vim.fn.bufload(bufnr)
@@ -517,9 +516,12 @@ end
---@param text_document_edit table: a `TextDocumentEdit` object
---@param index number: Optional index of the edit, if from a list of edits (or nil, if not from a list)
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit
-function M.apply_text_document_edit(text_document_edit, index)
+function M.apply_text_document_edit(text_document_edit, index, offset_encoding)
local text_document = text_document_edit.textDocument
local bufnr = vim.uri_to_bufnr(text_document.uri)
+ if offset_encoding == nil then
+ vim.notify_once("apply_text_document_edit must be called with valid offset encoding", vim.log.levels.WARN)
+ end
-- For lists of text document edits,
-- do not check the version after the first edit.
@@ -538,7 +540,7 @@ function M.apply_text_document_edit(text_document_edit, index)
return
end
- M.apply_text_edits(text_document_edit.edits, bufnr)
+ M.apply_text_edits(text_document_edit.edits, bufnr, offset_encoding)
end
--- Parses snippets in a completion entry.
@@ -737,7 +739,10 @@ end
---
---@param workspace_edit (table) `WorkspaceEdit`
--see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit
-function M.apply_workspace_edit(workspace_edit)
+function M.apply_workspace_edit(workspace_edit, offset_encoding)
+ if offset_encoding == nil then
+ vim.notify_once("apply_workspace_edit must be called with valid offset encoding", vim.log.levels.WARN)
+ end
if workspace_edit.documentChanges then
for idx, change in ipairs(workspace_edit.documentChanges) do
if change.kind == "rename" then
@@ -753,7 +758,7 @@ function M.apply_workspace_edit(workspace_edit)
elseif change.kind then
error(string.format("Unsupported change: %q", vim.inspect(change)))
else
- M.apply_text_document_edit(change, idx)
+ M.apply_text_document_edit(change, idx, offset_encoding)
end
end
return
@@ -984,12 +989,16 @@ end
--- Jumps to a location.
---
----@param location (`Location`|`LocationLink`)
+---@param location table (`Location`|`LocationLink`)
+---@param offset_encoding string utf-8|utf-16|utf-32 (required)
---@returns `true` if the jump succeeded
-function M.jump_to_location(location)
+function M.jump_to_location(location, offset_encoding)
-- location may be Location or LocationLink
local uri = location.uri or location.targetUri
if uri == nil then return end
+ if offset_encoding == nil then
+ vim.notify_once("jump_to_location must be called with valid offset encoding", vim.log.levels.WARN)
+ end
local bufnr = vim.uri_to_bufnr(uri)
-- Save position in jumplist
vim.cmd "normal! m'"
@@ -1004,7 +1013,7 @@ function M.jump_to_location(location)
api.nvim_buf_set_option(bufnr, 'buflisted', true)
local range = location.range or location.targetSelectionRange
local row = range.start.line
- local col = get_line_byte_from_position(bufnr, range.start)
+ local col = get_line_byte_from_position(bufnr, range.start, offset_encoding)
api.nvim_win_set_cursor(0, {row + 1, col})
-- Open folds under the cursor
vim.cmd("normal! zv")
@@ -1513,11 +1522,13 @@ do --[[ References ]]
---
---@param bufnr number Buffer id
---@param references table List of `DocumentHighlight` objects to highlight
- ---@param offset_encoding string One of "utf-8", "utf-16", "utf-32", or nil. Defaults to `offset_encoding` of first client of `bufnr`
+ ---@param offset_encoding string One of "utf-8", "utf-16", "utf-32".
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#documentHighlight
function M.buf_highlight_references(bufnr, references, offset_encoding)
- validate { bufnr = {bufnr, 'n', true} }
- offset_encoding = offset_encoding or M._get_offset_encoding(bufnr)
+ validate {
+ bufnr = {bufnr, 'n', true},
+ offset_encoding = { offset_encoding, 'string', false };
+ }
for _, reference in ipairs(references) do
local start_line, start_char = reference["range"]["start"]["line"], reference["range"]["start"]["character"]
local end_line, end_char = reference["range"]["end"]["line"], reference["range"]["end"]["character"]
@@ -1550,9 +1561,14 @@ end)
--- The result can be passed to the {list} argument of |setqflist()| or
--- |setloclist()|.
---
----@param locations (table) list of `Location`s or `LocationLink`s
+---@param locations table list of `Location`s or `LocationLink`s
+---@param offset_encoding string offset_encoding for locations utf-8|utf-16|utf-32
---@returns (table) list of items
-function M.locations_to_items(locations)
+function M.locations_to_items(locations, offset_encoding)
+ if offset_encoding == nil then
+ vim.notify_once("locations_to_items must be called with valid offset encoding", vim.log.levels.WARN)
+ end
+
local items = {}
local grouped = setmetatable({}, {
__index = function(t, k)
@@ -1592,7 +1608,7 @@ function M.locations_to_items(locations)
local pos = temp.start
local row = pos.line
local line = lines[row] or ""
- local col = pos.character
+ local col = M._str_byteindex_enc(line, pos.character, offset_encoding)
table.insert(items, {
filename = filename,
lnum = row + 1,
@@ -1776,7 +1792,13 @@ function M._get_offset_encoding(bufnr)
local offset_encoding
for _, client in pairs(vim.lsp.buf_get_clients(bufnr)) do
- local this_offset_encoding = client.offset_encoding or "utf-16"
+ if client.offset_encoding == nil then
+ vim.notify_once(
+ string.format("Client (id: %s) offset_encoding is nil. Do not unset offset_encoding.", client.id),
+ vim.log.levels.ERROR
+ )
+ end
+ local this_offset_encoding = client.offset_encoding
if not offset_encoding then
offset_encoding = this_offset_encoding
elseif offset_encoding ~= this_offset_encoding then
@@ -1905,7 +1927,9 @@ end
---@returns (number, number) `offset_encoding` index of the character in line {row} column {col} in buffer {buf}
function M.character_offset(buf, row, col, offset_encoding)
local line = get_line(buf, row)
- offset_encoding = offset_encoding or M._get_offset_encoding(buf)
+ if offset_encoding == nil then
+ vim.notify_once("character_offset must be called with valid offset encoding", vim.log.levels.WARN)
+ end
-- If the col is past the EOL, use the line length.
if col > #line then
return _str_utfindex_enc(line, nil, offset_encoding)