diff options
author | Hirokazu Hata <h.hata.ai.t@gmail.com> | 2020-02-22 21:20:38 +0900 |
---|---|---|
committer | Hirokazu Hata <h.hata.ai.t@gmail.com> | 2020-03-01 09:10:02 +0900 |
commit | 16262472cda88d0a4dc5c6729cfef36264569324 (patch) | |
tree | a2262b0ccd3a957c9f27114365dff0f835bbc71c /runtime/lua/vim/lsp | |
parent | f157fdef7eccba6601c6d3b1475847466b60c25b (diff) | |
download | rneovim-16262472cda88d0a4dc5c6729cfef36264569324.tar.gz rneovim-16262472cda88d0a4dc5c6729cfef36264569324.tar.bz2 rneovim-16262472cda88d0a4dc5c6729cfef36264569324.zip |
lsp: add 'textDocument/documentSymbol’ callback
Spec: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentSymbol
Diffstat (limited to 'runtime/lua/vim/lsp')
-rw-r--r-- | runtime/lua/vim/lsp/callbacks.lua | 10 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/protocol.lua | 26 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 57 |
3 files changed, 70 insertions, 23 deletions
diff --git a/runtime/lua/vim/lsp/callbacks.lua b/runtime/lua/vim/lsp/callbacks.lua index 99093216d9..63b5c4d493 100644 --- a/runtime/lua/vim/lsp/callbacks.lua +++ b/runtime/lua/vim/lsp/callbacks.lua @@ -38,7 +38,13 @@ end M['textDocument/references'] = function(_, _, result) if not result then return end - util.set_qflist(result) + util.set_qflist(util.locations_to_items(result)) +end + +M['textDocument/documentSymbol'] = function(_, _, result, _, bufnr) + if not result or vim.tbl_isempty(result) then return end + + util.set_qflist(util.symbols_to_items(result, bufnr)) api.nvim_command("copen") api.nvim_command("wincmd p") end @@ -97,7 +103,7 @@ local function location_callback(_, method, result) end util.jump_to_location(result[1]) if #result > 1 then - util.set_qflist(result) + util.set_qflist(util.locations_to_items(result)) api.nvim_command("copen") api.nvim_command("wincmd p") end diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index f64b0b50e7..41e8119c8c 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -663,19 +663,19 @@ function protocol.make_client_capabilities() documentHighlight = { dynamicRegistration = false }; - -- documentSymbol = { - -- dynamicRegistration = false; - -- symbolKind = { - -- valueSet = (function() - -- local res = {} - -- for k in pairs(protocol.SymbolKind) do - -- if type(k) == 'string' then table.insert(res, k) end - -- end - -- return res - -- end)(); - -- }; - -- hierarchicalDocumentSymbolSupport = false; - -- }; + documentSymbol = { + dynamicRegistration = false; + symbolKind = { + valueSet = (function() + local res = {} + for k in pairs(protocol.SymbolKind) do + if type(k) == 'number' then table.insert(res, k) end + end + return res + end)(); + }; + hierarchicalDocumentSymbolSupport = true; + }; }; workspace = nil; experimental = nil; diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 5f0fe8ceb4..72c84b8471 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -834,23 +834,60 @@ function M.locations_to_items(locations) return items end --- locations is Location[] --- Only sets for the current window. -function M.set_loclist(locations) +function M.set_loclist(items) vim.fn.setloclist(0, {}, ' ', { title = 'Language Server'; - items = M.locations_to_items(locations); + items = items; }) end --- locations is Location[] -function M.set_qflist(locations) +function M.set_qflist(items) vim.fn.setqflist({}, ' ', { title = 'Language Server'; - items = M.locations_to_items(locations); + items = items; }) end +--- Convert symbols to quickfix list items +--- +--@symbols DocumentSymbol[] or SymbolInformation[] +function M.symbols_to_items(symbols, bufnr) + local function _symbols_to_items(_symbols, _items, _bufnr) + for _, symbol in ipairs(_symbols) do + if symbol.location then -- SymbolInformation type + local range = symbol.location.range + local kind = protocol.SymbolKind[symbol.kind] + table.insert(_items, { + filename = vim.uri_to_fname(symbol.location.uri), + lnum = range.start.line + 1, + col = range.start.character + 1, + kind = kind, + text = '['..kind..'] '..symbol.name, + }) + elseif symbol.range then -- DocumentSymbole type + local kind = protocol.SymbolKind[symbol.kind] + table.insert(_items, { + -- bufnr = _bufnr, + filename = vim.api.nvim_buf_get_name(_bufnr), + lnum = symbol.range.start.line + 1, + col = symbol.range.start.character + 1, + kind = kind, + text = '['..kind..'] '..symbol.name + }) + if symbol.children then + for _, child in ipairs(symbol) do + for _, v in ipairs(_symbols_to_items(child, _items, _bufnr)) do + vim.list_extend(_items, v) + end + end + end + end + end + return _items + end + return _symbols_to_items(symbols, {}, bufnr) +end + -- Remove empty lines from the beginning and end. function M.trim_empty_lines(lines) local start = 1 @@ -903,11 +940,15 @@ function M.make_position_params() local line = api.nvim_buf_get_lines(0, row, row+1, true)[1] col = str_utfindex(line, col) return { - textDocument = { uri = vim.uri_from_bufnr(0) }; + textDocument = M.make_text_document_params(); position = { line = row; character = col; } } end +function M.make_text_document_params() + return { uri = vim.uri_from_bufnr(0) } +end + -- @param buf buffer handle or 0 for current. -- @param row 0-indexed line -- @param col 0-indexed byte offset in line |