diff options
author | Yi Ming <ofseed@foxmail.com> | 2024-11-26 00:06:05 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-25 08:06:05 -0800 |
commit | 165b099fa38c5f4a9855cda3d13575bf63767647 (patch) | |
tree | 543a209711e32e98f37883d77eb8de883a128bef | |
parent | a811d4babd22e21a3cd598b097fa0824fcff7fc6 (diff) | |
download | rneovim-165b099fa38c5f4a9855cda3d13575bf63767647.tar.gz rneovim-165b099fa38c5f4a9855cda3d13575bf63767647.tar.bz2 rneovim-165b099fa38c5f4a9855cda3d13575bf63767647.zip |
refactor(lsp): rename `offset_encoding` to `position_encoding` #31286
Problem:
LSP spec uses the term "position encoding" where we say "offset encoding".
Solution:
- Rename it everywhere except `vim.lsp.Client.offset_encoding` (which would be breaking).
- Mention "position encoding" in the documentation for `vim.lsp.Client.offset_encoding`.
-rw-r--r-- | runtime/doc/lsp.txt | 98 | ||||
-rw-r--r-- | runtime/doc/news.txt | 2 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/_changetracking.lua | 10 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/_tagfunc.lua | 16 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 8 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/client.lua | 11 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/completion.lua | 6 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/diagnostic.lua | 6 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/sync.lua | 52 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 140 | ||||
-rw-r--r-- | test/functional/plugin/lsp/incremental_sync_spec.lua | 10 | ||||
-rw-r--r-- | test/functional/script/luacats_grammar_spec.lua | 4 |
12 files changed, 188 insertions, 175 deletions
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 3cb3e590f4..1253c01547 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -904,8 +904,9 @@ Lua module: vim.lsp.client *lsp-client* • {rpc} (`vim.lsp.rpc.PublicClient`) RPC client object, for low level interaction with the client. See |vim.lsp.rpc.start()|. - • {offset_encoding} (`string`) The encoding used for communicating - with the server. You can modify this in the + • {offset_encoding} (`string`) Called "position encoding" in LSP + spec, the encoding used for communicating with + the server. You can modify this in the `config`'s `on_init` method before text is sent to the server. • {handlers} (`table<string,lsp.Handler>`) The handlers @@ -1062,9 +1063,10 @@ Lua module: vim.lsp.client *lsp-client* • {get_language_id}? (`fun(bufnr: integer, filetype: string): string`) Language ID as string. Defaults to the buffer filetype. - • {offset_encoding}? (`'utf-8'|'utf-16'|'utf-32'`) The encoding that - the LSP server expects. Client does not verify - this is correct. + • {offset_encoding}? (`'utf-8'|'utf-16'|'utf-32'`) Called "position + encoding" in LSP spec, the encoding that the LSP + server expects. Client does not verify this is + correct. • {on_error}? (`fun(code: integer, err: string)`) Callback invoked when the client operation throws an error. `code` is a number describing the error. @@ -1840,7 +1842,7 @@ Lua module: vim.lsp.util *lsp-util* *vim.lsp.util.apply_text_document_edit()* -apply_text_document_edit({text_document_edit}, {index}, {offset_encoding}) +apply_text_document_edit({text_document_edit}, {index}, {position_encoding}) Applies a `TextDocumentEdit`, which is a list of changes to a single document. @@ -1848,30 +1850,30 @@ apply_text_document_edit({text_document_edit}, {index}, {offset_encoding}) • {text_document_edit} (`lsp.TextDocumentEdit`) • {index} (`integer?`) Optional index of the edit, if from a list of edits (or nil, if not from a list) - • {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) + • {position_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) See also: ~ • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit *vim.lsp.util.apply_text_edits()* -apply_text_edits({text_edits}, {bufnr}, {offset_encoding}) +apply_text_edits({text_edits}, {bufnr}, {position_encoding}) Applies a list of text edits to a buffer. Parameters: ~ - • {text_edits} (`lsp.TextEdit[]`) - • {bufnr} (`integer`) Buffer id - • {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`) + • {text_edits} (`lsp.TextEdit[]`) + • {bufnr} (`integer`) Buffer id + • {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`) See also: ~ • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit *vim.lsp.util.apply_workspace_edit()* -apply_workspace_edit({workspace_edit}, {offset_encoding}) +apply_workspace_edit({workspace_edit}, {position_encoding}) Applies a `WorkspaceEdit`. Parameters: ~ - • {workspace_edit} (`lsp.WorkspaceEdit`) - • {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`) (required) + • {workspace_edit} (`lsp.WorkspaceEdit`) + • {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`) (required) See also: ~ • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit @@ -1883,13 +1885,13 @@ buf_clear_references({bufnr}) *vim.lsp.util.buf_clear_references()* • {bufnr} (`integer?`) Buffer id *vim.lsp.util.buf_highlight_references()* -buf_highlight_references({bufnr}, {references}, {offset_encoding}) +buf_highlight_references({bufnr}, {references}, {position_encoding}) Shows a list of document highlights for a certain buffer. Parameters: ~ - • {bufnr} (`integer`) Buffer id - • {references} (`lsp.DocumentHighlight[]`) objects to highlight - • {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`) + • {bufnr} (`integer`) Buffer id + • {references} (`lsp.DocumentHighlight[]`) objects to highlight + • {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`) See also: ~ • https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent @@ -1964,7 +1966,7 @@ get_effective_tabstop({bufnr}) *vim.lsp.util.get_effective_tabstop()* • 'shiftwidth' *vim.lsp.util.locations_to_items()* -locations_to_items({locations}, {offset_encoding}) +locations_to_items({locations}, {position_encoding}) Returns the items with the byte position calculated correctly and in sorted order, for display in quickfix and location lists. @@ -1975,9 +1977,9 @@ locations_to_items({locations}, {offset_encoding}) |setloclist()|. Parameters: ~ - • {locations} (`lsp.Location[]|lsp.LocationLink[]`) - • {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) default to first - client of buffer + • {locations} (`lsp.Location[]|lsp.LocationLink[]`) + • {position_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) default to first + client of buffer Return: ~ (`vim.quickfix.entry[]`) See |setqflist()| for the format @@ -2012,33 +2014,33 @@ make_formatting_params({options}) • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting *vim.lsp.util.make_given_range_params()* -make_given_range_params({start_pos}, {end_pos}, {bufnr}, {offset_encoding}) +make_given_range_params({start_pos}, {end_pos}, {bufnr}, {position_encoding}) Using the given range in the current buffer, creates an object that is similar to |vim.lsp.util.make_range_params()|. Parameters: ~ - • {start_pos} (`[integer,integer]?`) {row,col} mark-indexed - position. Defaults to the start of the last visual - selection. - • {end_pos} (`[integer,integer]?`) {row,col} mark-indexed - position. Defaults to the end of the last visual - selection. - • {bufnr} (`integer?`) buffer handle or 0 for current, - defaults to current - • {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`) + • {start_pos} (`[integer,integer]?`) {row,col} mark-indexed + position. Defaults to the start of the last + visual selection. + • {end_pos} (`[integer,integer]?`) {row,col} mark-indexed + position. Defaults to the end of the last visual + selection. + • {bufnr} (`integer?`) buffer handle or 0 for current, + defaults to current + • {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`) Return: ~ (`{ textDocument: { uri: lsp.DocumentUri }, range: lsp.Range }`) *vim.lsp.util.make_position_params()* -make_position_params({window}, {offset_encoding}) +make_position_params({window}, {position_encoding}) Creates a `TextDocumentPositionParams` object for the current buffer and cursor position. Parameters: ~ - • {window} (`integer?`) window handle or 0 for current, - defaults to current - • {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`) + • {window} (`integer?`) window handle or 0 for current, + defaults to current + • {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`) Return: ~ (`lsp.TextDocumentPositionParams`) @@ -2047,16 +2049,16 @@ make_position_params({window}, {offset_encoding}) • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams *vim.lsp.util.make_range_params()* -make_range_params({window}, {offset_encoding}) +make_range_params({window}, {position_encoding}) Using the current position in the current buffer, creates an object that can be used as a building block for several LSP requests, such as `textDocument/codeAction`, `textDocument/colorPresentation`, `textDocument/rangeFormatting`. Parameters: ~ - • {window} (`integer?`) window handle or 0 for current, - defaults to current - • {offset_encoding} (`"utf-8"|"utf-16"|"utf-32"`) + • {window} (`integer?`) window handle or 0 for current, + defaults to current + • {position_encoding} (`"utf-8"|"utf-16"|"utf-32"`) Return: ~ (`{ textDocument: { uri: lsp.DocumentUri }, range: lsp.Range }`) @@ -2138,17 +2140,17 @@ rename({old_fname}, {new_fname}, {opts}) *vim.lsp.util.rename()* • {ignoreIfExists}? (`boolean`) *vim.lsp.util.show_document()* -show_document({location}, {offset_encoding}, {opts}) +show_document({location}, {position_encoding}, {opts}) Shows document and optionally jumps to the location. Parameters: ~ - • {location} (`lsp.Location|lsp.LocationLink`) - • {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) - • {opts} (`table?`) A table with the following fields: - • {reuse_win}? (`boolean`) Jump to existing window - if buffer is already open. - • {focus}? (`boolean`) Whether to focus/jump to - location if possible. (defaults: true) + • {location} (`lsp.Location|lsp.LocationLink`) + • {position_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) + • {opts} (`table?`) A table with the following fields: + • {reuse_win}? (`boolean`) Jump to existing + window if buffer is already open. + • {focus}? (`boolean`) Whether to focus/jump to + location if possible. (defaults: true) Return: ~ (`boolean`) `true` if succeeded diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index c0d0f7b1bc..58ab7ef44c 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -100,7 +100,7 @@ LSP vim.diagnostic.config(config, vim.lsp.diagnostic.get_namespace(client_id)) < • |vim.lsp.util.make_position_params()|, |vim.lsp.util.make_range_params()| - and |vim.lsp.util.make_given_range_params()| now require the `offset_encoding` + and |vim.lsp.util.make_given_range_params()| now require the `position_encoding` parameter. LUA diff --git a/runtime/lua/vim/lsp/_changetracking.lua b/runtime/lua/vim/lsp/_changetracking.lua index 8588502697..c2ff66b90e 100644 --- a/runtime/lua/vim/lsp/_changetracking.lua +++ b/runtime/lua/vim/lsp/_changetracking.lua @@ -18,14 +18,14 @@ local M = {} --- --- None: One group for all clients --- Full: One group for all clients ---- Incremental: One group per `offset_encoding` +--- Incremental: One group per `position_encoding` --- --- Sending changes can be debounced per buffer. To simplify the implementation the --- smallest debounce interval is used and we don't group clients by different intervals. --- --- @class vim.lsp.CTGroup --- @field sync_kind integer TextDocumentSyncKind, considers config.flags.allow_incremental_sync ---- @field offset_encoding "utf-8"|"utf-16"|"utf-32" +--- @field position_encoding "utf-8"|"utf-16"|"utf-32" --- --- @class vim.lsp.CTBufferState --- @field name string name of the buffer @@ -46,7 +46,7 @@ local M = {} ---@return string local function group_key(group) if group.sync_kind == protocol.TextDocumentSyncKind.Incremental then - return tostring(group.sync_kind) .. '\0' .. group.offset_encoding + return tostring(group.sync_kind) .. '\0' .. group.position_encoding end return tostring(group.sync_kind) end @@ -72,7 +72,7 @@ local function get_group(client) end return { sync_kind = sync_kind, - offset_encoding = client.offset_encoding, + position_encoding = client.offset_encoding, } end @@ -310,7 +310,7 @@ local function send_changes_for_group(bufnr, firstline, lastline, new_lastline, -- The contents would further change and startline/endline may no longer fit local changes = incremental_changes( buf_state, - group.offset_encoding, + group.position_encoding, bufnr, firstline, lastline, diff --git a/runtime/lua/vim/lsp/_tagfunc.lua b/runtime/lua/vim/lsp/_tagfunc.lua index f6ffc63824..554f0cb991 100644 --- a/runtime/lua/vim/lsp/_tagfunc.lua +++ b/runtime/lua/vim/lsp/_tagfunc.lua @@ -6,12 +6,12 @@ local ms = lsp.protocol.Methods ---@param name string ---@param range lsp.Range ---@param uri string ----@param offset_encoding string +---@param position_encoding string ---@return {name: string, filename: string, cmd: string, kind?: string} -local function mk_tag_item(name, range, uri, offset_encoding) +local function mk_tag_item(name, range, uri, position_encoding) local bufnr = vim.uri_to_bufnr(uri) -- This is get_line_byte_from_position is 0-indexed, call cursor expects a 1-indexed position - local byte = util._get_line_byte_from_position(bufnr, range.start, offset_encoding) + 1 + local byte = util._get_line_byte_from_position(bufnr, range.start, position_encoding) + 1 return { name = name, filename = vim.uri_to_fname(uri), @@ -32,9 +32,9 @@ local function query_definition(pattern) --- @param range lsp.Range --- @param uri string - --- @param offset_encoding string - local add = function(range, uri, offset_encoding) - table.insert(results, mk_tag_item(pattern, range, uri, offset_encoding)) + --- @param position_encoding string + local add = function(range, uri, position_encoding) + table.insert(results, mk_tag_item(pattern, range, uri, position_encoding)) end local remaining = #clients @@ -78,11 +78,11 @@ local function query_workspace_symbols(pattern) local results = {} for client_id, responses in pairs(assert(results_by_client)) do local client = lsp.get_client_by_id(client_id) - local offset_encoding = client and client.offset_encoding or 'utf-16' + local position_encoding = client and client.offset_encoding or 'utf-16' local symbols = responses.result --[[@as lsp.SymbolInformation[]|nil]] for _, symbol in pairs(symbols or {}) do local loc = symbol.location - local item = mk_tag_item(symbol.name, loc.range, loc.uri, offset_encoding) + local item = mk_tag_item(symbol.name, loc.range, loc.uri, position_encoding) item.kind = lsp.protocol.SymbolKind[symbol.kind] or 'Unknown' table.insert(results, item) end diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 10c0dbefdc..aca6bf27f4 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -638,14 +638,14 @@ function M.rename(new_name, opts) local cword = vim.fn.expand('<cword>') --- @param range lsp.Range - --- @param offset_encoding string - local function get_text_at_range(range, offset_encoding) + --- @param position_encoding string + local function get_text_at_range(range, position_encoding) return api.nvim_buf_get_text( bufnr, range.start.line, - util._get_line_byte_from_position(bufnr, range.start, offset_encoding), + util._get_line_byte_from_position(bufnr, range.start, position_encoding), range['end'].line, - util._get_line_byte_from_position(bufnr, range['end'], offset_encoding), + util._get_line_byte_from_position(bufnr, range['end'], position_encoding), {} )[1] end diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 3b79da99ea..7c2b7192f5 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -94,7 +94,8 @@ local validate = vim.validate --- Language ID as string. Defaults to the buffer filetype. --- @field get_language_id? fun(bufnr: integer, filetype: string): string --- ---- The encoding that the LSP server expects. Client does not verify this is correct. +--- Called "position encoding" in LSP spec, the encoding that the LSP server expects. +--- Client does not verify this is correct. --- @field offset_encoding? 'utf-8'|'utf-16'|'utf-32' --- --- Callback invoked when the client operation throws an error. `code` is a number describing the error. @@ -148,8 +149,10 @@ local validate = vim.validate --- See |vim.lsp.rpc.start()|. --- @field rpc vim.lsp.rpc.PublicClient --- ---- The encoding used for communicating with the server. You can modify this in ---- the `config`'s `on_init` method before text is sent to the server. +--- Called "position encoding" in LSP spec, +--- the encoding used for communicating with the server. +--- You can modify this in the `config`'s `on_init` method +--- before text is sent to the server. --- @field offset_encoding string --- --- The handlers used by the client as described in |lsp-handler|. @@ -278,7 +281,7 @@ local function validate_encoding(encoding) return valid_encodings[encoding:lower()] or error( string.format( - "Invalid offset encoding %q. Must be one of: 'utf-8', 'utf-16', 'utf-32'", + "Invalid position encoding %q. Must be one of: 'utf-8', 'utf-16', 'utf-32'", encoding ) ) diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index 0f388a88fd..1e950f625e 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -550,7 +550,7 @@ local function on_complete_done() return end - local offset_encoding = client.offset_encoding or 'utf-16' + local position_encoding = client.offset_encoding or 'utf-16' local resolve_provider = (client.server_capabilities.completionProvider or {}).resolveProvider local function clear_word() @@ -576,7 +576,7 @@ local function on_complete_done() if completion_item.additionalTextEdits and next(completion_item.additionalTextEdits) then clear_word() - lsp.util.apply_text_edits(completion_item.additionalTextEdits, bufnr, offset_encoding) + lsp.util.apply_text_edits(completion_item.additionalTextEdits, bufnr, position_encoding) apply_snippet_and_command() elseif resolve_provider and type(completion_item) == 'table' then local changedtick = vim.b[bufnr].changedtick @@ -591,7 +591,7 @@ local function on_complete_done() if err then vim.notify_once(err.message, vim.log.levels.WARN) elseif result and result.additionalTextEdits then - lsp.util.apply_text_edits(result.additionalTextEdits, bufnr, offset_encoding) + lsp.util.apply_text_edits(result.additionalTextEdits, bufnr, position_encoding) if result.command then completion_item.command = result.command end diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua index 8fd30c7668..12984f8c26 100644 --- a/runtime/lua/vim/lsp/diagnostic.lua +++ b/runtime/lua/vim/lsp/diagnostic.lua @@ -77,7 +77,7 @@ end local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id) local buf_lines = get_buf_lines(bufnr) local client = vim.lsp.get_client_by_id(client_id) - local offset_encoding = client and client.offset_encoding or 'utf-16' + local position_encoding = client and client.offset_encoding or 'utf-16' --- @param diagnostic lsp.Diagnostic --- @return vim.Diagnostic return vim.tbl_map(function(diagnostic) @@ -95,9 +95,9 @@ local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id) --- @type vim.Diagnostic return { lnum = start.line, - col = vim.str_byteindex(line, offset_encoding, start.character, false), + col = vim.str_byteindex(line, position_encoding, start.character, false), end_lnum = _end.line, - end_col = vim.str_byteindex(line, offset_encoding, _end.character, false), + end_col = vim.str_byteindex(line, position_encoding, _end.character, false), severity = severity_lsp_to_vim(diagnostic.severity), message = message, source = diagnostic.source, diff --git a/runtime/lua/vim/lsp/sync.lua b/runtime/lua/vim/lsp/sync.lua index 3df45ebff0..621f63b25f 100644 --- a/runtime/lua/vim/lsp/sync.lua +++ b/runtime/lua/vim/lsp/sync.lua @@ -48,21 +48,21 @@ local str_utfindex = vim.str_utfindex local str_utf_start = vim.str_utf_start local str_utf_end = vim.str_utf_end --- Given a line, byte idx, alignment, and offset_encoding convert to the aligned +-- Given a line, byte idx, alignment, and position_encoding convert to the aligned -- utf-8 index and either the utf-16, or utf-32 index. ---@param line string the line to index into ---@param byte integer the byte idx ----@param offset_encoding string utf-8|utf-16|utf-32|nil (default: utf-8) +---@param position_encoding string utf-8|utf-16|utf-32|nil (default: utf-8) ---@return integer byte_idx of first change position ---@return integer char_idx of first change position -local function align_end_position(line, byte, offset_encoding) +local function align_end_position(line, byte, position_encoding) local char --- @type integer -- If on the first byte, or an empty string: the trivial case if byte == 1 or #line == 0 then char = byte -- Called in the case of extending an empty line "" -> "a" elseif byte == #line + 1 then - char = str_utfindex(line, offset_encoding) + 1 + char = str_utfindex(line, position_encoding) + 1 else -- Modifying line, find the nearest utf codepoint local offset = str_utf_start(line, byte) @@ -73,9 +73,9 @@ local function align_end_position(line, byte, offset_encoding) end if byte <= #line then --- Convert to 0 based for input, and from 0 based for output - char = str_utfindex(line, offset_encoding, byte - 1) + 1 + char = str_utfindex(line, position_encoding, byte - 1) + 1 else - char = str_utfindex(line, offset_encoding) + 1 + char = str_utfindex(line, position_encoding) + 1 end -- Extending line, find the nearest utf codepoint for the last valid character end @@ -93,7 +93,7 @@ end ---@param firstline integer firstline from on_lines, adjusted to 1-index ---@param lastline integer lastline from on_lines, adjusted to 1-index ---@param new_lastline integer new_lastline from on_lines, adjusted to 1-index ----@param offset_encoding string utf-8|utf-16|utf-32|nil (fallback to utf-8) +---@param position_encoding string utf-8|utf-16|utf-32|nil (fallback to utf-8) ---@return vim.lsp.sync.Range result table include line_idx, byte_idx, and char_idx of first change position local function compute_start_range( prev_lines, @@ -101,7 +101,7 @@ local function compute_start_range( firstline, lastline, new_lastline, - offset_encoding + position_encoding ) local char_idx --- @type integer? local byte_idx --- @type integer? @@ -115,7 +115,7 @@ local function compute_start_range( if line then line_idx = firstline - 1 byte_idx = #line + 1 - char_idx = str_utfindex(line, offset_encoding) + 1 + char_idx = str_utfindex(line, position_encoding) + 1 else line_idx = firstline byte_idx = 1 @@ -152,11 +152,11 @@ local function compute_start_range( char_idx = 1 elseif start_byte_idx == #prev_line + 1 then byte_idx = start_byte_idx - char_idx = str_utfindex(prev_line, offset_encoding) + 1 + char_idx = str_utfindex(prev_line, position_encoding) + 1 else byte_idx = start_byte_idx + str_utf_start(prev_line, start_byte_idx) --- Convert to 0 based for input, and from 0 based for output - char_idx = vim.str_utfindex(prev_line, offset_encoding, byte_idx - 1) + 1 + char_idx = vim.str_utfindex(prev_line, position_encoding, byte_idx - 1) + 1 end -- Return the start difference (shared for new and prev lines) @@ -174,7 +174,7 @@ end ---@param firstline integer ---@param lastline integer ---@param new_lastline integer ----@param offset_encoding string +---@param position_encoding string ---@return vim.lsp.sync.Range prev_end_range ---@return vim.lsp.sync.Range curr_end_range local function compute_end_range( @@ -184,7 +184,7 @@ local function compute_end_range( firstline, lastline, new_lastline, - offset_encoding + position_encoding ) -- A special case for the following `firstline == new_lastline` case where lines are deleted. -- Even if the buffer has become empty, nvim behaves as if it has an empty line with eol. @@ -193,7 +193,7 @@ local function compute_end_range( return { line_idx = lastline - 1, byte_idx = #prev_line + 1, - char_idx = str_utfindex(prev_line, offset_encoding) + 1, + char_idx = str_utfindex(prev_line, position_encoding) + 1, }, { line_idx = 1, byte_idx = 1, char_idx = 1 } end -- If firstline == new_lastline, the first change occurred on a line that was deleted. @@ -259,7 +259,7 @@ local function compute_end_range( prev_end_byte_idx = 1 end local prev_byte_idx, prev_char_idx = - align_end_position(prev_line, prev_end_byte_idx, offset_encoding) + align_end_position(prev_line, prev_end_byte_idx, position_encoding) local prev_end_range = { line_idx = prev_line_idx, byte_idx = prev_byte_idx, char_idx = prev_char_idx } @@ -274,7 +274,7 @@ local function compute_end_range( curr_end_byte_idx = 1 end local curr_byte_idx, curr_char_idx = - align_end_position(curr_line, curr_end_byte_idx, offset_encoding) + align_end_position(curr_line, curr_end_byte_idx, position_encoding) curr_end_range = { line_idx = curr_line_idx, byte_idx = curr_byte_idx, char_idx = curr_char_idx } end @@ -317,7 +317,7 @@ local function extract_text(lines, start_range, end_range, line_ending) end end --- rangelength depends on the offset encoding +-- rangelength depends on the position encoding -- bytes for utf-8 (clangd with extension) -- codepoints for utf-16 -- codeunits for utf-32 @@ -326,10 +326,10 @@ end ---@param lines string[] ---@param start_range vim.lsp.sync.Range ---@param end_range vim.lsp.sync.Range ----@param offset_encoding string +---@param position_encoding string ---@param line_ending string ---@return integer -local function compute_range_length(lines, start_range, end_range, offset_encoding, line_ending) +local function compute_range_length(lines, start_range, end_range, position_encoding, line_ending) local line_ending_length = #line_ending -- Single line case if start_range.line_idx == end_range.line_idx then @@ -339,7 +339,7 @@ local function compute_range_length(lines, start_range, end_range, offset_encodi local start_line = lines[start_range.line_idx] local range_length --- @type integer if start_line and #start_line > 0 then - range_length = str_utfindex(start_line, offset_encoding) + range_length = str_utfindex(start_line, position_encoding) - start_range.char_idx + 1 + line_ending_length @@ -352,7 +352,7 @@ local function compute_range_length(lines, start_range, end_range, offset_encodi for idx = start_range.line_idx + 1, end_range.line_idx - 1 do -- Length full line plus newline character if #lines[idx] > 0 then - range_length = range_length + str_utfindex(lines[idx], offset_encoding) + #line_ending + range_length = range_length + str_utfindex(lines[idx], position_encoding) + #line_ending else range_length = range_length + line_ending_length end @@ -372,7 +372,7 @@ end ---@param firstline integer line to begin search for first difference ---@param lastline integer line to begin search in old_lines for last difference ---@param new_lastline integer line to begin search in new_lines for last difference ----@param offset_encoding string encoding requested by language server +---@param position_encoding string encoding requested by language server ---@param line_ending string ---@return lsp.TextDocumentContentChangeEvent : see https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent function M.compute_diff( @@ -381,7 +381,7 @@ function M.compute_diff( firstline, lastline, new_lastline, - offset_encoding, + position_encoding, line_ending ) -- Find the start of changes between the previous and current buffer. Common between both. @@ -393,7 +393,7 @@ function M.compute_diff( firstline + 1, lastline + 1, new_lastline + 1, - offset_encoding + position_encoding ) -- Find the last position changed in the previous and current buffer. -- prev_end_range is sent to the server as as the end of the changed range. @@ -405,7 +405,7 @@ function M.compute_diff( firstline + 1, lastline + 1, new_lastline + 1, - offset_encoding + position_encoding ) -- Grab the changed text of from start_range to curr_end_range in the current buffer. @@ -414,7 +414,7 @@ function M.compute_diff( -- Compute the range of the replaced text. Deprecated but still required for certain language servers local range_length = - compute_range_length(prev_lines, start_range, prev_end_range, offset_encoding, line_ending) + compute_range_length(prev_lines, start_range, prev_end_range, position_encoding, line_ending) -- convert to 0 based indexing local result = { diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 0f608ffbd1..3de76f93a6 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -277,9 +277,9 @@ end --- Position is a https://microsoft.github.io/language-server-protocol/specifications/specification-current/#position ---@param position lsp.Position ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32' +---@param position_encoding 'utf-8'|'utf-16'|'utf-32' ---@return integer -local function get_line_byte_from_position(bufnr, position, offset_encoding) +local function get_line_byte_from_position(bufnr, position, position_encoding) -- LSP's line and characters are 0-indexed -- Vim's line and columns are 1-indexed local col = position.character @@ -287,7 +287,7 @@ local function get_line_byte_from_position(bufnr, position, offset_encoding) -- character if col > 0 then local line = get_line(bufnr, position.line) or '' - return vim.str_byteindex(line, offset_encoding, col, false) + return vim.str_byteindex(line, position_encoding, col, false) end return col end @@ -295,12 +295,12 @@ end --- Applies a list of text edits to a buffer. ---@param text_edits lsp.TextEdit[] ---@param bufnr integer Buffer id ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32' +---@param position_encoding 'utf-8'|'utf-16'|'utf-32' ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit -function M.apply_text_edits(text_edits, bufnr, offset_encoding) +function M.apply_text_edits(text_edits, bufnr, position_encoding) validate('text_edits', text_edits, 'table', false) validate('bufnr', bufnr, 'number', false) - validate('offset_encoding', offset_encoding, 'string', false) + validate('position_encoding', position_encoding, 'string', false) if not next(text_edits) then return @@ -359,9 +359,9 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding) -- Convert from LSP style ranges to Neovim style ranges. local start_row = text_edit.range.start.line - local start_col = get_line_byte_from_position(bufnr, text_edit.range.start, offset_encoding) + local start_col = get_line_byte_from_position(bufnr, text_edit.range.start, position_encoding) local end_row = text_edit.range['end'].line - local end_col = get_line_byte_from_position(bufnr, text_edit.range['end'], offset_encoding) + local end_col = get_line_byte_from_position(bufnr, text_edit.range['end'], position_encoding) local text = vim.split(text_edit.newText, '\n', { plain = true }) local max = api.nvim_buf_line_count(bufnr) @@ -430,14 +430,14 @@ end --- ---@param text_document_edit lsp.TextDocumentEdit ---@param index? integer: Optional index of the edit, if from a list of edits (or nil, if not from a list) ----@param offset_encoding? 'utf-8'|'utf-16'|'utf-32' +---@param position_encoding? 'utf-8'|'utf-16'|'utf-32' ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit -function M.apply_text_document_edit(text_document_edit, index, offset_encoding) +function M.apply_text_document_edit(text_document_edit, index, position_encoding) local text_document = text_document_edit.textDocument local bufnr = vim.uri_to_bufnr(text_document.uri) - if offset_encoding == nil then + if position_encoding == nil then vim.notify_once( - 'apply_text_document_edit must be called with valid offset encoding', + 'apply_text_document_edit must be called with valid position encoding', vim.log.levels.WARN ) return @@ -459,7 +459,7 @@ function M.apply_text_document_edit(text_document_edit, index, offset_encoding) return end - M.apply_text_edits(text_document_edit.edits, bufnr, offset_encoding) + M.apply_text_edits(text_document_edit.edits, bufnr, position_encoding) end local function path_components(path) @@ -619,12 +619,12 @@ end --- Applies a `WorkspaceEdit`. --- ---@param workspace_edit lsp.WorkspaceEdit ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32' (required) +---@param position_encoding 'utf-8'|'utf-16'|'utf-32' (required) ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit -function M.apply_workspace_edit(workspace_edit, offset_encoding) - if offset_encoding == nil then +function M.apply_workspace_edit(workspace_edit, position_encoding) + if position_encoding == nil then vim.notify_once( - 'apply_workspace_edit must be called with valid offset encoding', + 'apply_workspace_edit must be called with valid position encoding', vim.log.levels.WARN ) return @@ -641,7 +641,7 @@ function M.apply_workspace_edit(workspace_edit, offset_encoding) elseif change.kind then --- @diagnostic disable-line:undefined-field error(string.format('Unsupported change: %q', vim.inspect(change))) else - M.apply_text_document_edit(change, idx, offset_encoding) + M.apply_text_document_edit(change, idx, position_encoding) end end return @@ -654,7 +654,7 @@ function M.apply_workspace_edit(workspace_edit, offset_encoding) for uri, changes in pairs(all_changes) do local bufnr = vim.uri_to_bufnr(uri) - M.apply_text_edits(changes, bufnr, offset_encoding) + M.apply_text_edits(changes, bufnr, position_encoding) end end @@ -904,17 +904,20 @@ end --- Shows document and optionally jumps to the location. --- ---@param location lsp.Location|lsp.LocationLink ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32'? +---@param position_encoding 'utf-8'|'utf-16'|'utf-32'? ---@param opts? vim.lsp.util.show_document.Opts ---@return boolean `true` if succeeded -function M.show_document(location, offset_encoding, opts) +function M.show_document(location, position_encoding, opts) -- location may be Location or LocationLink local uri = location.uri or location.targetUri if uri == nil then return false end - if offset_encoding == nil then - vim.notify_once('show_document must be called with valid offset encoding', vim.log.levels.WARN) + if position_encoding == nil then + vim.notify_once( + 'show_document must be called with valid position encoding', + vim.log.levels.WARN + ) return false end local bufnr = vim.uri_to_bufnr(uri) @@ -946,7 +949,7 @@ function M.show_document(location, offset_encoding, opts) if range then -- Jump to new location (adjusting for encoding of characters) local row = range.start.line - local col = get_line_byte_from_position(bufnr, range.start, offset_encoding) + local col = get_line_byte_from_position(bufnr, range.start, position_encoding) api.nvim_win_set_cursor(win, { row + 1, col }) vim._with({ win = win }, function() -- Open folds under the cursor @@ -961,12 +964,12 @@ end --- ---@deprecated use `vim.lsp.util.show_document` with `{focus=true}` instead ---@param location lsp.Location|lsp.LocationLink ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32'? +---@param position_encoding 'utf-8'|'utf-16'|'utf-32'? ---@param reuse_win boolean? Jump to existing window if buffer is already open. ---@return boolean `true` if the jump succeeded -function M.jump_to_location(location, offset_encoding, reuse_win) +function M.jump_to_location(location, position_encoding, reuse_win) vim.deprecate('vim.lsp.util.jump_to_location', nil, '0.12') - return M.show_document(location, offset_encoding, { reuse_win = reuse_win, focus = true }) + return M.show_document(location, position_encoding, { reuse_win = reuse_win, focus = true }) end --- Previews a location in a floating window @@ -1661,18 +1664,18 @@ do --[[ References ]] --- ---@param bufnr integer Buffer id ---@param references lsp.DocumentHighlight[] objects to highlight - ---@param offset_encoding 'utf-8'|'utf-16'|'utf-32' + ---@param position_encoding 'utf-8'|'utf-16'|'utf-32' ---@see https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent - function M.buf_highlight_references(bufnr, references, offset_encoding) + function M.buf_highlight_references(bufnr, references, position_encoding) validate('bufnr', bufnr, 'number', true) - validate('offset_encoding', offset_encoding, 'string', false) + validate('position_encoding', position_encoding, 'string', false) for _, reference in ipairs(references) do local range = reference.range local start_line = range.start.line local end_line = range['end'].line - local start_idx = get_line_byte_from_position(bufnr, range.start, offset_encoding) - local end_idx = get_line_byte_from_position(bufnr, range['end'], offset_encoding) + local start_idx = get_line_byte_from_position(bufnr, range.start, position_encoding) + local end_idx = get_line_byte_from_position(bufnr, range['end'], position_encoding) local document_highlight_kind = { [protocol.DocumentHighlightKind.Text] = 'LspReferenceText', @@ -1706,16 +1709,16 @@ end) --- |setloclist()|. --- ---@param locations lsp.Location[]|lsp.LocationLink[] ----@param offset_encoding? 'utf-8'|'utf-16'|'utf-32' +---@param position_encoding? 'utf-8'|'utf-16'|'utf-32' --- default to first client of buffer ---@return vim.quickfix.entry[] # See |setqflist()| for the format -function M.locations_to_items(locations, offset_encoding) - if offset_encoding == nil then +function M.locations_to_items(locations, position_encoding) + if position_encoding == nil then vim.notify_once( - 'locations_to_items must be called with valid offset encoding', + 'locations_to_items must be called with valid position encoding', vim.log.levels.WARN ) - offset_encoding = vim.lsp.get_clients({ bufnr = 0 })[1].offset_encoding + position_encoding = vim.lsp.get_clients({ bufnr = 0 })[1].offset_encoding end local items = {} --- @type vim.quickfix.entry[] @@ -1752,8 +1755,8 @@ function M.locations_to_items(locations, offset_encoding) local end_row = end_pos.line local line = lines[row] or '' local end_line = lines[end_row] or '' - local col = vim.str_byteindex(line, offset_encoding, pos.character, false) - local end_col = vim.str_byteindex(end_line, offset_encoding, end_pos.character, false) + local col = vim.str_byteindex(line, position_encoding, pos.character, false) + local end_col = vim.str_byteindex(end_line, position_encoding, end_pos.character, false) items[#items + 1] = { filename = filename, @@ -1864,8 +1867,8 @@ function M.try_trim_markdown_code_blocks(lines) end ---@param window integer?: window handle or 0 for current, defaults to current ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32' -local function make_position_param(window, offset_encoding) +---@param position_encoding 'utf-8'|'utf-16'|'utf-32' +local function make_position_param(window, position_encoding) window = window or 0 local buf = api.nvim_win_get_buf(window) local row, col = unpack(api.nvim_win_get_cursor(window)) @@ -1875,7 +1878,7 @@ local function make_position_param(window, offset_encoding) return { line = 0, character = 0 } end - col = vim.str_utfindex(line, offset_encoding, col, false) + col = vim.str_utfindex(line, position_encoding, col, false) return { line = row, character = col } end @@ -1883,22 +1886,22 @@ end --- Creates a `TextDocumentPositionParams` object for the current buffer and cursor position. --- ---@param window integer?: window handle or 0 for current, defaults to current ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32' +---@param position_encoding 'utf-8'|'utf-16'|'utf-32' ---@return lsp.TextDocumentPositionParams ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams -function M.make_position_params(window, offset_encoding) +function M.make_position_params(window, position_encoding) window = window or 0 local buf = api.nvim_win_get_buf(window) - if offset_encoding == nil then + if position_encoding == nil then vim.notify_once( - 'warning: offset_encoding is required, using the offset_encoding from the first client', + 'warning: position_encoding is required, using the offset_encoding from the first client', vim.log.levels.WARN ) - offset_encoding = M._get_offset_encoding(buf) + position_encoding = M._get_offset_encoding(buf) end return { textDocument = M.make_text_document_params(buf), - position = make_position_param(window, offset_encoding), + position = make_position_param(window, position_encoding), } end @@ -1941,18 +1944,18 @@ end --- `textDocument/rangeFormatting`. --- ---@param window integer? window handle or 0 for current, defaults to current ----@param offset_encoding "utf-8"|"utf-16"|"utf-32" +---@param position_encoding "utf-8"|"utf-16"|"utf-32" ---@return { textDocument: { uri: lsp.DocumentUri }, range: lsp.Range } -function M.make_range_params(window, offset_encoding) +function M.make_range_params(window, position_encoding) local buf = api.nvim_win_get_buf(window or 0) - if offset_encoding == nil then + if position_encoding == nil then vim.notify_once( - 'warning: offset_encoding is required, using the offset_encoding from the first client', + 'warning: position_encoding is required, using the offset_encoding from the first client', vim.log.levels.WARN ) - offset_encoding = M._get_offset_encoding(buf) + position_encoding = M._get_offset_encoding(buf) end - local position = make_position_param(window, offset_encoding) + local position = make_position_param(window, position_encoding) return { textDocument = M.make_text_document_params(buf), range = { start = position, ['end'] = position }, @@ -1967,19 +1970,19 @@ end ---@param end_pos [integer,integer]? {row,col} mark-indexed position. --- Defaults to the end of the last visual selection. ---@param bufnr integer? buffer handle or 0 for current, defaults to current ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32' +---@param position_encoding 'utf-8'|'utf-16'|'utf-32' ---@return { textDocument: { uri: lsp.DocumentUri }, range: lsp.Range } -function M.make_given_range_params(start_pos, end_pos, bufnr, offset_encoding) +function M.make_given_range_params(start_pos, end_pos, bufnr, position_encoding) validate('start_pos', start_pos, 'table', true) validate('end_pos', end_pos, 'table', true) - validate('offset_encoding', offset_encoding, 'string', true) + validate('position_encoding', position_encoding, 'string', true) bufnr = bufnr or api.nvim_get_current_buf() - if offset_encoding == nil then + if position_encoding == nil then vim.notify_once( - 'warning: offset_encoding is required, using the offset_encoding from the first client', + 'warning: position_encoding is required, using the offset_encoding from the first client', vim.log.levels.WARN ) - offset_encoding = M._get_offset_encoding(bufnr) + position_encoding = M._get_offset_encoding(bufnr) end --- @type [integer, integer] local A = { unpack(start_pos or api.nvim_buf_get_mark(bufnr, '<')) } @@ -1988,12 +1991,12 @@ function M.make_given_range_params(start_pos, end_pos, bufnr, offset_encoding) -- convert to 0-index A[1] = A[1] - 1 B[1] = B[1] - 1 - -- account for offset_encoding. + -- account for position_encoding. if A[2] > 0 then - A[2] = M.character_offset(bufnr, A[1], A[2], offset_encoding) + A[2] = M.character_offset(bufnr, A[1], A[2], position_encoding) end if B[2] > 0 then - B[2] = M.character_offset(bufnr, B[1], B[2], offset_encoding) + B[2] = M.character_offset(bufnr, B[1], B[2], position_encoding) end -- we need to offset the end character position otherwise we loose the last -- character of the selection, as LSP end position is exclusive @@ -2100,9 +2103,9 @@ end ---@param bufnr integer ---@param start_line integer ---@param end_line integer ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32' +---@param position_encoding 'utf-8'|'utf-16'|'utf-32' ---@return lsp.Range -local function make_line_range_params(bufnr, start_line, end_line, offset_encoding) +local function make_line_range_params(bufnr, start_line, end_line, position_encoding) local last_line = api.nvim_buf_line_count(bufnr) - 1 ---@type lsp.Position @@ -2111,7 +2114,12 @@ local function make_line_range_params(bufnr, start_line, end_line, offset_encodi if end_line == last_line and not vim.bo[bufnr].endofline then end_pos = { line = end_line, - character = M.character_offset(bufnr, end_line, #get_line(bufnr, end_line), offset_encoding), + character = M.character_offset( + bufnr, + end_line, + #get_line(bufnr, end_line), + position_encoding + ), } else end_pos = { line = end_line + 1, character = 0 } diff --git a/test/functional/plugin/lsp/incremental_sync_spec.lua b/test/functional/plugin/lsp/incremental_sync_spec.lua index f60e159d64..0bca1fa4ca 100644 --- a/test/functional/plugin/lsp/incremental_sync_spec.lua +++ b/test/functional/plugin/lsp/incremental_sync_spec.lua @@ -23,7 +23,7 @@ before_each(function() -- local line_ending = format_line_ending[vim.api.nvim_get_option_value('fileformat', {})] --- @diagnostic disable-next-line:duplicate-set-field - function _G.test_register(bufnr, id, offset_encoding, line_ending) + function _G.test_register(bufnr, id, position_encoding, line_ending) local prev_lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, true) local function callback(_, bufnr0, _changedtick, firstline, lastline, new_lastline) @@ -38,7 +38,7 @@ before_each(function() firstline, lastline, new_lastline, - offset_encoding, + position_encoding, line_ending ) @@ -63,15 +63,15 @@ local function test_edit( prev_buffer, edit_operations, expected_text_changes, - offset_encoding, + position_encoding, line_ending ) - offset_encoding = offset_encoding or 'utf-16' + position_encoding = position_encoding or 'utf-16' line_ending = line_ending or '\n' api.nvim_buf_set_lines(0, 0, -1, true, prev_buffer) exec_lua(function() - return _G.test_register(0, 'test1', offset_encoding, line_ending) + return _G.test_register(0, 'test1', position_encoding, line_ending) end) for _, edit in ipairs(edit_operations) do diff --git a/test/functional/script/luacats_grammar_spec.lua b/test/functional/script/luacats_grammar_spec.lua index 8bc55879d4..6e73f6894b 100644 --- a/test/functional/script/luacats_grammar_spec.lua +++ b/test/functional/script/luacats_grammar_spec.lua @@ -118,9 +118,9 @@ describe('luacats grammar', function() type = '"rfc2396" | "rfc2732" | "rfc3986" | nil', }) - test('@param offset_encoding "utf-8" | "utf-16" | "utf-32" | nil', { + test('@param position_encoding "utf-8" | "utf-16" | "utf-32" | nil', { kind = 'param', - name = 'offset_encoding', + name = 'position_encoding', type = '"utf-8" | "utf-16" | "utf-32" | nil', }) |