diff options
author | Yi Ming <ofseed@foxmail.com> | 2024-11-21 04:19:07 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-20 12:19:07 -0800 |
commit | 629483e24eed3f2c07e55e0540c553361e0345a2 (patch) | |
tree | 0ac4969929cef4cdc272362bf8e6d01c40669179 /runtime/lua/vim/lsp/util.lua | |
parent | 1b6442034f6a821d357fe59cd75fdae47a7f7cff (diff) | |
download | rneovim-629483e24eed3f2c07e55e0540c553361e0345a2.tar.gz rneovim-629483e24eed3f2c07e55e0540c553361e0345a2.tar.bz2 rneovim-629483e24eed3f2c07e55e0540c553361e0345a2.zip |
feat(lsp): require `offset_encoding` param #31249
Problem:
Since [version 3.17](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocuments),
LSP supports specifying the position encoding (aka offset encoding) supported by
the client through `positionEncoding`. Since #31209, Nvim fully supports
`utf-8`, `utf-16`, and `utf-32` encodings.
Previously, nvim assumed all clients for a buffer had the same
`offset_encoding`, so:
* Nvim provides `vim.lsp._get_offset_encoding()` to get `offset_encoding`, but
this function is incorrect because `offset_encoding` is per-client, not
per-buffer.
* Based on the strategy of `vim.lsp._get_offset_encoding()`,
`vim.lsp.util.make_position_params()`, `vim.lsp.util.make_range_params()`, and
`vim.lsp.util.make_given_range_params()` do not require the caller to pass
`offset_encoding`, which is invalid.
* https://github.com/neovim/neovim/issues/25272
Solution:
* Mark `vim.lsp._get_offset_encoding()` as `@deprecated`.
* Change the type annotations of `vim.lsp.util.make_position_params()`,
`vim.lsp.util.make_range_params()`, `vim.lsp.util.make_given_range_params()`
to require the `offset_encoding` param.
Diffstat (limited to 'runtime/lua/vim/lsp/util.lua')
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 9e352dbcfd..cfa8a194d9 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1848,12 +1848,11 @@ 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'? defaults to `offset_encoding` of first client of buffer of `window` +---@param offset_encoding 'utf-8'|'utf-16'|'utf-32' local function make_position_param(window, offset_encoding) window = window or 0 local buf = api.nvim_win_get_buf(window) local row, col = unpack(api.nvim_win_get_cursor(window)) - offset_encoding = offset_encoding or M._get_offset_encoding(buf) row = row - 1 local line = api.nvim_buf_get_lines(buf, row, row + 1, true)[1] if not line then @@ -1868,13 +1867,19 @@ 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'? defaults to `offset_encoding` of first client of buffer of `window` +---@param offset_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) window = window or 0 local buf = api.nvim_win_get_buf(window) - offset_encoding = offset_encoding or M._get_offset_encoding(buf) + if offset_encoding == nil then + vim.notify_once( + 'warning: offset_encoding is required, using the offset_encoding from the first client', + vim.log.levels.WARN + ) + offset_encoding = M._get_offset_encoding(buf) + end return { textDocument = M.make_text_document_params(buf), position = make_position_param(window, offset_encoding), @@ -1882,6 +1887,7 @@ function M.make_position_params(window, offset_encoding) end --- Utility function for getting the encoding of the first LSP client on the given buffer. +---@deprecated ---@param bufnr integer buffer handle or 0 for current, defaults to current ---@return string encoding first client if there is one, nil otherwise function M._get_offset_encoding(bufnr) @@ -1904,7 +1910,7 @@ function M._get_offset_encoding(bufnr) offset_encoding = this_offset_encoding elseif offset_encoding ~= this_offset_encoding then vim.notify_once( - 'warning: multiple different client offset_encodings detected for buffer, this is not supported yet', + 'warning: multiple different client offset_encodings detected for buffer, vim.lsp.util._get_offset_encoding() uses the offset_encoding from the first client', vim.log.levels.WARN ) end @@ -1919,12 +1925,17 @@ end --- `textDocument/rangeFormatting`. --- ---@param window integer? window handle or 0 for current, defaults to current ----@param offset_encoding "utf-8"|"utf-16"|"utf-32"? defaults to `offset_encoding` of first client of buffer of `window` ----@return table { textDocument = { uri = `current_file_uri` }, range = { start = ----`current_position`, end = `current_position` } } +---@param offset_encoding "utf-8"|"utf-16"|"utf-32" +---@return { textDocument: { uri: lsp.DocumentUri }, range: lsp.Range } function M.make_range_params(window, offset_encoding) local buf = api.nvim_win_get_buf(window or 0) - offset_encoding = offset_encoding or M._get_offset_encoding(buf) + if offset_encoding == nil then + vim.notify_once( + 'warning: offset_encoding is required, using the offset_encoding from the first client', + vim.log.levels.WARN + ) + offset_encoding = M._get_offset_encoding(buf) + end local position = make_position_param(window, offset_encoding) return { textDocument = M.make_text_document_params(buf), @@ -1940,15 +1951,20 @@ 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'? defaults to `offset_encoding` of first client of `bufnr` ----@return table { textDocument = { uri = `current_file_uri` }, range = { start = ----`start_position`, end = `end_position` } } +---@param offset_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) validate('start_pos', start_pos, 'table', true) validate('end_pos', end_pos, 'table', true) validate('offset_encoding', offset_encoding, 'string', true) bufnr = bufnr or api.nvim_get_current_buf() - offset_encoding = offset_encoding or M._get_offset_encoding(bufnr) + if offset_encoding == nil then + vim.notify_once( + 'warning: offset_encoding is required, using the offset_encoding from the first client', + vim.log.levels.WARN + ) + offset_encoding = M._get_offset_encoding(bufnr) + end --- @type [integer, integer] local A = { unpack(start_pos or api.nvim_buf_get_mark(bufnr, '<')) } --- @type [integer, integer] |