diff options
-rw-r--r-- | runtime/doc/lsp.txt | 11 | ||||
-rw-r--r-- | runtime/doc/news.txt | 4 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/handlers.lua | 5 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 42 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 20 |
5 files changed, 61 insertions, 21 deletions
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 25ef7f24cc..954d21ec34 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -2376,12 +2376,17 @@ stylize_markdown({bufnr}, {contents}, {opts}) Return: ~ (`table`) stripped content -symbols_to_items({symbols}, {bufnr}) *vim.lsp.util.symbols_to_items()* + *vim.lsp.util.symbols_to_items()* +symbols_to_items({symbols}, {bufnr}, {position_encoding}) Converts symbols to quickfix list items. Parameters: ~ - • {symbols} (`lsp.DocumentSymbol[]|lsp.SymbolInformation[]`) - • {bufnr} (`integer?`) + • {symbols} (`lsp.DocumentSymbol[]|lsp.SymbolInformation[]`) + list of symbols + • {bufnr} (`integer?`) buffer handle or 0 for current, + defaults to current + • {position_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) default to first + client of buffer Return: ~ (`vim.quickfix.entry[]`) See |setqflist()| for the format diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 90a020bb4d..92492d0448 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -133,6 +133,7 @@ LSP • |vim.lsp.util.make_position_params()|, |vim.lsp.util.make_range_params()| and |vim.lsp.util.make_given_range_params()| now require the `position_encoding` parameter. +• |vim.lsp.util.symbols_to_items()| now requires the `position_encoding` parameter. LUA @@ -277,7 +278,8 @@ LSP • `:checkhealth vim.lsp` displays the server version (if available). • Completion side effects (including snippet expansion, execution of commands and application of additional text edits) is now built-in. -• |vim.lsp.util.locations_to_items()| sets `end_col` and `end_lnum` fields. +• |vim.lsp.util.locations_to_items()| and |vim.lsp.util.symbols_to_items()| now + sets `end_col` and `end_lnum` fields. • |vim.lsp.buf.format()| now supports passing a list of ranges via the `range` parameter (this requires support for the `textDocument/rangesFormatting` request). diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index b35140dfad..25f87a7164 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -231,7 +231,7 @@ end --- --- The returned function has an optional {config} parameter that accepts |vim.lsp.ListOpts| --- ----@param map_result fun(resp, bufnr: integer): table to convert the response +---@param map_result fun(resp, bufnr: integer, position_encoding: 'utf-8'|'utf-16'|'utf-32'): table to convert the response ---@param entity string name of the resource used in a `not found` error message ---@param title_fn fun(ctx: lsp.HandlerContext): string Function to call to generate list title ---@return lsp.Handler @@ -244,7 +244,8 @@ local function response_to_list(map_result, entity, title_fn) end config = config or {} local title = title_fn(ctx) - local items = map_result(result, ctx.bufnr) + local client = assert(vim.lsp.get_client_by_id(ctx.client_id)) + local items = map_result(result, ctx.bufnr, client.offset_encoding) local list = { title = title, items = items, context = ctx } if config.on_list then diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index e16a905c44..86c0a2b3db 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1775,39 +1775,57 @@ end --- Converts symbols to quickfix list items. --- ----@param symbols lsp.DocumentSymbol[]|lsp.SymbolInformation[] ----@param bufnr? integer +---@param symbols lsp.DocumentSymbol[]|lsp.SymbolInformation[] list of symbols +---@param bufnr? integer buffer handle or 0 for current, defaults to current +---@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.symbols_to_items(symbols, bufnr) - bufnr = bufnr or 0 +function M.symbols_to_items(symbols, bufnr, position_encoding) + bufnr = vim._resolve_bufnr(bufnr) + if position_encoding == nil then + vim.notify_once( + 'symbols_to_items must be called with valid position encoding', + vim.log.levels.WARN + ) + position_encoding = vim.lsp.get_clients({ bufnr = 0 })[1].offset_encoding + end + local items = {} --- @type vim.quickfix.entry[] for _, symbol in ipairs(symbols) do - --- @type string?, lsp.Position? - local filename, pos + --- @type string?, lsp.Range? + local filename, range if symbol.location then --- @cast symbol lsp.SymbolInformation filename = vim.uri_to_fname(symbol.location.uri) - pos = symbol.location.range.start + range = symbol.location.range elseif symbol.selectionRange then --- @cast symbol lsp.DocumentSymbol filename = api.nvim_buf_get_name(bufnr) - pos = symbol.selectionRange.start + range = symbol.selectionRange end - if filename and pos then + if filename and range then local kind = protocol.SymbolKind[symbol.kind] or 'Unknown' + + local lnum = range['start'].line + 1 + local col = get_line_byte_from_position(bufnr, range['start'], position_encoding) + 1 + local end_lnum = range['end'].line + 1 + local end_col = get_line_byte_from_position(bufnr, range['end'], position_encoding) + 1 + items[#items + 1] = { filename = filename, - lnum = pos.line + 1, - col = pos.character + 1, + lnum = lnum, + col = col, + end_lnum = end_lnum, + end_col = end_col, kind = kind, text = '[' .. kind .. '] ' .. symbol.name, } end if symbol.children then - list_extend(items, M.symbols_to_items(symbol.children, bufnr)) + list_extend(items, M.symbols_to_items(symbol.children, bufnr, position_encoding)) end end diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index db3ab8ed98..a0064f741e 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -2930,6 +2930,8 @@ describe('LSP', function() local expected = { { col = 1, + end_col = 1, + end_lnum = 2, filename = '', kind = 'File', lnum = 2, @@ -2937,6 +2939,8 @@ describe('LSP', function() }, { col = 1, + end_col = 1, + end_lnum = 4, filename = '', kind = 'Module', lnum = 4, @@ -2944,6 +2948,8 @@ describe('LSP', function() }, { col = 1, + end_col = 1, + end_lnum = 6, filename = '', kind = 'Namespace', lnum = 6, @@ -3036,7 +3042,7 @@ describe('LSP', function() }, }, } - return vim.lsp.util.symbols_to_items(doc_syms, nil) + return vim.lsp.util.symbols_to_items(doc_syms, nil, 'utf-16') end) ) end) @@ -3045,6 +3051,8 @@ describe('LSP', function() local expected = { { col = 1, + end_col = 1, + end_lnum = 2, filename = '', kind = 'File', lnum = 2, @@ -3052,6 +3060,8 @@ describe('LSP', function() }, { col = 1, + end_col = 1, + end_lnum = 6, filename = '', kind = 'Namespace', lnum = 6, @@ -3115,7 +3125,7 @@ describe('LSP', function() }, }, } - return vim.lsp.util.symbols_to_items(doc_syms, nil) + return vim.lsp.util.symbols_to_items(doc_syms, nil, 'utf-16') end) ) end) @@ -3125,6 +3135,8 @@ describe('LSP', function() local expected = { { col = 1, + end_col = 1, + end_lnum = 3, filename = '/test_a', kind = 'File', lnum = 2, @@ -3132,6 +3144,8 @@ describe('LSP', function() }, { col = 1, + end_col = 1, + end_lnum = 5, filename = '/test_b', kind = 'Module', lnum = 4, @@ -3181,7 +3195,7 @@ describe('LSP', function() containerName = 'TestBContainer', }, } - return vim.lsp.util.symbols_to_items(sym_info, nil) + return vim.lsp.util.symbols_to_items(sym_info, nil, 'utf-16') end) ) end) |