diff --git a/lua/navigator/gui.lua b/lua/navigator/gui.lua index f522a80..1d79eeb 100644 --- a/lua/navigator/gui.lua +++ b/lua/navigator/gui.lua @@ -52,6 +52,7 @@ function M._preview_location(opts) --location, width, pos_x, pos_y local win_opts = {syntax = syntax, width = opts.width, pos_x = opts.offset_x or 0, pos_y = opts.offset_y or 10} win_opts.items = contents win_opts.hl_line = opts.lnum - range.start.line + log (opts.lnum, range.start.line, win_opts.hl_line) local w = M.new_preview(win_opts) return w diff --git a/lua/navigator/hierarchy.lua b/lua/navigator/hierarchy.lua index 933eb99..bc66960 100644 --- a/lua/navigator/hierarchy.lua +++ b/lua/navigator/hierarchy.lua @@ -19,7 +19,7 @@ local function call_hierarchy_handler(direction, err, _, result, _, _, error_mes local call_hierarchy_item = call_hierarchy_call[direction] local kind = ' ' if call_hierarchy_item.kind then - kind = require'navigator.lspclient.lspkind'.kind(call_hierarchy_item.kind) .. ' ' + kind = require'navigator.lspclient.lspkind'.symbol_kind(call_hierarchy_item.kind) .. ' ' end for _, range in pairs(call_hierarchy_call.fromRanges) do local filename = assert(vim.uri_to_fname(call_hierarchy_item.uri)) @@ -47,13 +47,13 @@ local call_hierarchy_handler_to = partial(call_hierarchy_handler, "to") local function incoming_calls_handler(bang, err, method, result, client_id, bufnr) local results = call_hierarchy_handler_from(err, method, result, client_id, bufnr, "Incoming calls not found") - gui.new_list_view({items = results, api = 'incomming'}) + gui.new_list_view({items = results, api = ' '}) end local function outgoing_calls_handler(bang, err, method, result, client_id, bufnr) local results = call_hierarchy_handler_to(err, method, result, client_id, bufnr, "Outgoing calls not found") - gui.new_list_view({items =results, api = 'outgoing'}) + gui.new_list_view({items =results, api = ' '}) --fzf_locations(bang, "", "Outgoing Calls", results, false) end diff --git a/lua/navigator/lspclient/lspkind.lua b/lua/navigator/lspclient/lspkind.lua index 225136a..9c01e9c 100644 --- a/lua/navigator/lspclient/lspkind.lua +++ b/lua/navigator/lspclient/lspkind.lua @@ -1,38 +1,128 @@ local kind_symbols = { - Text = '', - Method = 'ƒ', - Function = '', - Constructor = '', - Field = 'ﴲ', - Variable = '', - Class = 'פּ', - Interface = '蘒', - Module = '', - Property = '', - Unit = '塞', - Value = '', - Enum = '了', - Keyword = '', - Snippet = '', - Color = '', - File = '', - Reference = '', - Folder = '', - EnumMember = '', - Constant = '', - Struct = ' ', - Event = 'ﳅ', - Operator ='', - TypeParameter = '', - Default = '', + Text = "", + Method = "ƒ", + Function = "", + Constructor = "", + Field = "ﴲ", + Variable = "", + Class = "פּ", + Interface = "蘒", + Module = "", + Property = "", + Unit = "塞", + Value = "", + Enum = "了", + Keyword = "", + Snippet = "", + Color = "", + File = "", + Reference = "", + Folder = "", + EnumMember = "", + Constant = "", + Struct = " ", + Event = "ﳅ", + Operator = "", + TypeParameter = "", + Default = "" } -local CompletionItemKind = {'', 'ƒ', '', '', 'ﴲ', '', '', 'ﰮ', '', '', '', '', '了', '', '﬌', '', '', '', '', '', '', '', 'ﳅ', '', '', ''} -function lspkind.kind(kind) - -- require('vim.lsp.protocol').CompletionItemKind = {'', 'ƒ', '', '', 'ﴲ', '', '', 'ﰮ', '', '', '', '', '了', '', '﬌', '', '', '', '', '', '', '', 'ﳅ', '', '', ''} - return CompletionItemKind[kind] -end +local CompletionItemKind = { + " ", + "ƒ ", + " ", + " ", + "ﴲ ", + " ", + " ", + "ﰮ ", + " ", + " ", + " ", + " ", + "了", + " ", + "﬌ ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "ﳅ ", + " ", + " ", + " " +} + +-- A symbol kind. +local SymbolKind = { + File = 1, + Module = 2, + Namespace = 3, + Package = 4, + Class = 5, + Method = 6, + Property = 7, + Field = 8, + Constructor = 9, + Enum = 10, + Interface = 11, + Function = 12, + Variable = 13, + Constant = 14, + String = 15, + Number = 16, + Boolean = 17, + Array = 18, + Object = 19, + Key = 20, + Null = 21, + EnumMember = 22, + Struct = 23, + Event = 24, + Operator = 25, + TypeParameter = 26 +} +local SymbolItemKind = { + " ", + " ", + " ", + " ", + "פּ ", + "ƒ ", + " ", + "ﴲ ", + " ", + "了", + "蘒", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "ﳠ ", + " ", + " ", + "ﳅ ", + " ", + " ", + "" +} + +local lspkind = {} +function lspkind.comp_kind(kind) + return CompletionItemKind[kind] or "" +end +function lspkind.symbol_kind(kind) + return SymbolItemKind[kind] or "" +end return lspkind diff --git a/lua/navigator/lspclient/mapping.lua b/lua/navigator/lspclient/mapping.lua index 928e67e..9f62e9c 100644 --- a/lua/navigator/lspclient/mapping.lua +++ b/lua/navigator/lspclient/mapping.lua @@ -132,8 +132,8 @@ function M.setup(user_opts) vim.lsp.handlers["textDocument/typeDefinition"] = require "navigator.definition".typeDefinition_handler vim.lsp.handlers["textDocument/implementation"] = require "navigator.implementation".implementation_handler - vim.lsp.handlers["textDocument/documentSymbol"] = require "navigator.symbols".symbol_handler - vim.lsp.handlers["workspace/symbol"] = require "navigator.symbols".symbol_handler + vim.lsp.handlers["textDocument/documentSymbol"] = require "navigator.symbols".document_symbol_handler + vim.lsp.handlers["workspace/symbol"] = require "navigator.symbols".workspace_symbol_handler vim.lsp.handlers["textDocument/publishDiagnostics"] = require'navigator.diagnostics'.diagnostic_handler -- vim.lsp.handlers["textDocument/hover"] = require 'navigator.hover'.hover_handler diff --git a/lua/navigator/lspwrapper.lua b/lua/navigator/lspwrapper.lua index b9ed26a..c0c6c8e 100644 --- a/lua/navigator/lspwrapper.lua +++ b/lua/navigator/lspwrapper.lua @@ -111,18 +111,45 @@ function M.locations_to_items(locations) table.insert(items, item) end - -- insert data into lines and loc - -- for i, loc in ipairs(items) do - -- log(items[i], locations[i]) - -- local filename = loc.filename:gsub(cwd .. "/", "./", 1) - -- items[i].uri = locations[i].uri - -- items[i].range = locations[i].range - -- items[i].filename = assert(vim.uri_to_fname(loc.uri)) - -- items[i].display_filename = filename or items[i].filename - -- items[i].rpath = util.get_relative_path(cwd, loc.filename) - -- log(items[i], locations[i]) - -- end return items end +function M.symbol_to_items(locations) + local cwd = vim.fn.getcwd(0) + if not locations or vim.tbl_isempty(locations) then + print("list not avalible") + return + end + + local items = {} -- lsp.util.locations_to_items(locations) + -- items and locations may not matching + table.sort( + locations, + function(i, j) + if i.uri == j.uri then + if i.range and i.range.start then + return i.range.start.line < j.range.start.line + end + return false + else + return i.uri < j.uri + end + end + ) + for i, loc in ipairs(locations) do + local item = {} -- lsp.util.locations_to_items({loc})[1] + item.uri = locations[i].uri + item.range = locations[i].range + item.filename = assert(vim.uri_to_fname(item.uri)) + local filename = item.filename:gsub(cwd .. "/", "./", 1) + item.display_filename = filename or item.filename + item.rpath = util.get_relative_path(cwd, item.filename) + table.insert(items, item) + end + + return items +end + + + return M diff --git a/lua/navigator/protocal.json b/lua/navigator/protocal.json index 6922d88..0691664 100644 --- a/lua/navigator/protocal.json +++ b/lua/navigator/protocal.json @@ -451,3 +451,466 @@ definition.lua:9: { { kind = "source.organizeImports", title = "Organize Imports" } } + + + + -- workspace symbols + +{ { + containerName = "std", + kind = 5, + location = { + range = { + end = { + character = 44, + line = 277 + }, + start = { + character = 23, + line = 277 + } + }, + uri = "file:///Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c%2B%2B/v1/mutex" + }, + name = "recursive_timed_mutex" + }, { + containerName = "std::recursive_timed_mutex", + kind = 9, + location = { + range = { + end = { + character = 25, + line = 288 + }, + start = { + character = 4, + line = 288 + } + }, + uri = "file:///Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c%2B%2B/v1/mutex" + }, + name = "recursive_timed_mutex" + }, { + containerName = "std::recursive_timed_mutex", + kind = 9, + location = { + range = { + end = { + character = 26, + line = 284 + }, + start = { + character = 5, + line = 284 + } + }, + uri = "file:///Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c%2B%2B/v1/mutex" + }, + name = "recursive_timed_mutex" + }, { + containerName = "std", + kind = 5, + location = { + range = { + end = { + character = 41, + line = 683 + }, + start = { + character = 27, + line = 683 + } + }, + uri = "file:///Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c%2B%2B/v1/type_traits" + }, + name = "remove_const_t" + },} + + +-- doc symbols +{ { + children = { { + kind = 6, + name = "area", + range = { + end = { + character = 15, + line = 8 + }, + start = { + character = 1, + line = 8 + } + }, + selectionRange = { + end = { + character = 5, + line = 8 + }, + start = { + character = 1, + line = 8 + } + } + }, { + kind = 6, + name = "perim", + range = { + end = { + character = 16, + line = 9 + }, + start = { + character = 1, + line = 9 + } + }, + selectionRange = { + end = { + character = 6, + line = 9 + }, + start = { + character = 1, + line = 9 + } + } + } }, + detail = "interface{...}", + kind = 11, + name = "geometry", + range = { + end = { + character = 1, + line = 10 + }, + start = { + character = 5, + line = 7 + } + }, + selectionRange = { + end = { + character = 13, + line = 7 + }, + start = { + character = 5, + line = 7 + } + } + }, { + children = { { + detail = "float64", + kind = 8, + name = "width", + range = { + end = { + character = 22, + line = 13 + }, + start = { + character = 1, + line = 13 + } + }, + selectionRange = { + end = { + character = 6, + line = 13 + }, + start = { + character = 1, + line = 13 + } + } + }, { + detail = "float64", + kind = 8, + name = "height", + range = { + end = { + character = 22, + line = 13 + }, + start = { + character = 1, + line = 13 + } + }, + selectionRange = { + end = { + character = 14, + line = 13 + }, + start = { + character = 8, + line = 13 + } + } + } }, + detail = "struct{...}", + kind = 23, + name = "rect", + range = { + end = { + character = 1, + line = 14 + }, + start = { + character = 5, + line = 12 + } + }, + selectionRange = { + end = { + character = 9, + line = 12 + }, + start = { + character = 5, + line = 12 + } + } + }, { + children = { { + detail = "float64", + kind = 8, + name = "radius", + range = { + end = { + character = 15, + line = 17 + }, + start = { + character = 1, + line = 17 + } + }, + selectionRange = { + end = { + character = 7, + line = 17 + }, + start = { + character = 1, + line = 17 + } + } + } }, + detail = "struct{...}", + kind = 23, + name = "circle", + range = { + end = { + character = 1, + line = 18 + }, + start = { + character = 5, + line = 16 + } + }, + selectionRange = { + end = { + character = 11, + line = 16 + }, + start = { + character = 5, + line = 16 + } + } + }, { + detail = "()", + kind = 6, + name = "(rect).area", + range = { + end = { + character = 1, + line = 22 + }, + start = { + character = 0, + line = 20 + } + }, + selectionRange = { + end = { + character = 18, + line = 20 + }, + start = { + character = 14, + line = 20 + } + } + }, { + detail = "()", + kind = 6, + name = "(rect).perim", + range = { + end = { + character = 1, + line = 26 + }, + start = { + character = 0, + line = 24 + } + }, + selectionRange = { + end = { + character = 19, + line = 24 + }, + start = { + character = 14, + line = 24 + } + } + }, { + detail = "()", + kind = 6, + name = "(circle).area", + range = { + end = { + character = 1, + line = 30 + }, + start = { + character = 0, + line = 28 + } + }, + selectionRange = { + end = { + character = 20, + line = 28 + }, + start = { + character = 16, + line = 28 + } + } + }, { + detail = "()", + kind = 6, + name = "(circle).perim", + range = { + end = { + character = 1, + line = 34 + }, + start = { + character = 0, + line = 32 + } + }, + selectionRange = { + end = { + character = 21, + line = 32 + }, + start = { + character = 16, + line = 32 + } + } + }, { + detail = "(g geometry)", + kind = 12, + name = "measure", + range = { + end = { + character = 1, + line = 40 + }, + start = { + character = 0, + line = 36 + } + }, + selectionRange = { + end = { + character = 12, + line = 36 + }, + start = { + character = 5, + line = 36 + } + } + }, { + detail = "()", + kind = 12, + name = "m2", + range = { + end = { + character = 1, + line = 44 + }, + start = { + character = 0, + line = 42 + } + }, + selectionRange = { + end = { + character = 7, + line = 42 + }, + start = { + character = 5, + line = 42 + } + } + }, { + detail = "()", + kind = 12, + name = "M2", + range = { + end = { + character = 1, + line = 48 + }, + start = { + character = 0, + line = 46 + } + }, + selectionRange = { + end = { + character = 7, + line = 46 + }, + start = { + character = 5, + line = 46 + } + } + }, { + detail = "()", + kind = 12, + name = "main", + range = { + end = { + character = 1, + line = 57 + }, + start = { + character = 0, + line = 50 + } + }, + selectionRange = { + end = { + character = 9, + line = 50 + }, + start = { + character = 5, + line = 50 + } + } + } } diff --git a/lua/navigator/symbols.lua b/lua/navigator/symbols.lua index 8aaa51d..52ed05d 100644 --- a/lua/navigator/symbols.lua +++ b/lua/navigator/symbols.lua @@ -1,15 +1,17 @@ local gui = require "navigator.gui" local M = {} local log = require "navigator.util".log +local verbose = require "navigator.util".trace local lsphelper = require "navigator.lspwrapper" local locations_to_items = lsphelper.locations_to_items - +local clone = require "guihua.util".clone +local symbol_kind = require "navigator.lspclient.lspkind".symbol_kind function M.document_symbols(opts) opts = opts or {} local params = vim.lsp.util.make_position_params() params.context = {includeDeclaration = true} params.query = "" - local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/documentSymbol", params, opts.timeout or 10000) + local results_lsp = vim.lsp.buf_request_sync(0, "textDocument/documentSymbol", params, opts.timeout or 5000) local locations = {} log(results_lsp) for _, server_results in pairs(results_lsp) do @@ -35,7 +37,7 @@ function M.workspace_symbols(opts) local params = vim.lsp.util.make_position_params() params.context = {includeDeclaration = true} params.query = "" - local results_lsp = vim.lsp.buf_request_sync(0, "workspace/symbol", params, opts.timeout or 10000) + local results_lsp = vim.lsp.buf_request_sync(0, "workspace/symbol", params, opts.timeout or 15000) log(results_lsp) local locations = {} @@ -56,26 +58,103 @@ function M.workspace_symbols(opts) end end -function M.symbol_handler(_, _, result, _, bufnr) +function M.document_symbol_handler(err, _, result, _, bufnr) + if err then + print(bufnr, "failed to get document symbol") + end + if not result or vim.tbl_isempty(result) then - print("symbol not found") + print(bufnr, "symbol not found for buf") return end -- log(result) local locations = {} + local fname = vim.fn.expand("%:p:f") + local uri = vim.uri_from_fname(fname) + -- vim.list_extend(locations, vim.lsp.util.symbols_to_items(result) or {}) + -- log(locations) + for i = 1, #result do + local item = {} + item.kind = result[i].kind + local kind = symbol_kind(item.kind) + item.name = result[i].name + item.range = result[i].range + item.uri = uri + item.selectionRange = result[i].selectionRange + item.detail = result[i].detail or '' + if item.detail == '()' then item.detail = 'func' end + + item.lnum = result[i].range.start.line + 1 + item.text = "[" .. kind .. "]" .. item.detail .. " " .. item.name + + item.filename = fname + + table.insert(locations, item) + if result[i].children ~= nil then + for _, c in pairs (result[i].children) do + local child = {} + child.kind = c.kind + child.name = c.name + child.range = c.range + local ckind = symbol_kind(child.kind) + child.selectionRange = c.selectionRange + child.fname = fname + child.uri = uri + child.lnum = c.range.start.line + 1 + child.detail = c.detail or '' + child.text = "  [" .. ckind .. "] " .. child.detail .. " " .. child.name + table.insert(locations, child) + end + end + end + verbose(locations) + -- local items = locations_to_items(locations) + gui.new_list_view({items = locations, prompt = true, rawdata = true, api = '華 '}) + + -- if locations == nil or vim.tbl_isempty(locations) then + -- print "References not found" + -- return + -- end + -- local items = locations_to_items(locations) + -- gui.new_list_view({items = items}) + -- local filename = vim.api.nvim_buf_get_name(bufnr) + -- local items = vim.lsp.util.symbols_to_items(result, bufnr) + -- local data = {} + -- for i, item in pairs(action.items) do + -- data[i] = item.text + -- if filename ~= item.filename then + -- local cwd = vim.fn.getcwd(0) .. "/" + -- local add = util.get_relative_path(cwd, item.filename) + -- data[i] = data[i] .. " - " .. add + -- end + -- item.text = nil + -- end + -- opts.data = data +end + +function M.workspace_symbol_handler(err, _, result, _, bufnr) + if err then + print(bufnr, "failed to get workspace symbol") + end + if not result or vim.tbl_isempty(result) then + print(bufnr, "symbol not found for buf") + return + end + log(result) + local locations = {} for i = 1, #result do - local item = result[i].location + local item = result[i].location or {} item.kind = result[i].kind item.containerName = result[i].containerName item.name = result[i].name item.text = result[i].name if #item.containerName > 0 then - item.text = item.text:gsub(item.containerName, '', 1) + item.text = item.text:gsub(item.containerName, "", 1) end table.insert(locations, item) end local items = locations_to_items(locations) - gui.new_list_view({items = items, prompt = true}) + gui.new_list_view({items = items, prompt = true, api = '華 '}) -- if locations == nil or vim.tbl_isempty(locations) then -- print "References not found" @@ -96,20 +175,6 @@ function M.symbol_handler(_, _, result, _, bufnr) -- item.text = nil -- end -- opts.data = data - -- action.popup = popfix:new(opts) - -- if not action.popup then - -- action.items = nil - -- end - -- if action.popup.list then - -- util.setFiletype(action.popup.list.buffer, "lsputil_symbols_list") - -- end - -- if action.popup.preview then - -- util.setFiletype(action.popup.preview.buffer, "lsputil_symbols_preview") - -- end - -- if action.popup.prompt then - -- util.setFiletype(action.popup.prompt.buffer, "lsputil_symbols_prompt") - -- end - -- opts.data = nil end return M