diff --git a/README.md b/README.md index 814ed39..7c5e22f 100644 --- a/README.md +++ b/README.md @@ -276,6 +276,8 @@ require'navigator'.setup({ keymaps = {{key = "gK", func = vim.lsp.declaration, desc = 'declaration'}}, -- a list of key maps -- this kepmap gK will override "gD" mapping function declaration() in default kepmap -- please check mapping.lua for all keymaps + -- rule of overriding: if func and mode ('n' by default) is same + -- it can be overrided treesitter_analysis = true, -- treesitter variable context treesitter_navigation = true, -- bool|table false: use lsp to navigate between symbol ']r/[r', table: a list of --lang using TS navigation diff --git a/lua/navigator/dochighlight.lua b/lua/navigator/dochighlight.lua index 4158f25..4e15bdc 100644 --- a/lua/navigator/dochighlight.lua +++ b/lua/navigator/dochighlight.lua @@ -223,7 +223,7 @@ local nav_doc_hl = function(bufnr) trace('nav_doc_hl', bufnr) bufnr = bufnr or vim.api.nvim_get_current_buf() local ref_params = vim.lsp.util.make_position_params() - vim.lsp.for_each_buffer_client(bufnr, function(client, _, _) + util.for_each_buffer_client(bufnr, function(client, _, _) if client.server_capabilities.documentHighlightProvider == true then trace('sending doc highlight', client.name, bufnr) client.request('textDocument/documentHighlight', ref_params, handle_document_highlight, bufnr) diff --git a/lua/navigator/hover.lua b/lua/navigator/hover.lua index 83e03c8..6594263 100644 --- a/lua/navigator/hover.lua +++ b/lua/navigator/hover.lua @@ -1,59 +1,42 @@ local lsp = vim.lsp local util = lsp.util local nutils = require('navigator.util') +local api = vim.api local log = nutils.log local M = {} + function M.handler(_, result, ctx, config) config = config or {} config.focus_id = ctx.method - config.zindex = 53 - if not (result and result.contents) then - -- vim.notify('No information available') - vim.schedule(function() - vim.lsp.buf.signature_help() - end) + if api.nvim_get_current_buf() ~= ctx.bufnr then + -- Ignore result since buffer changed. This happens for slow language servers. return end - local ft = vim.bo.ft - -- require('navigator.util').log(result) - local markdown_lines = util.convert_input_to_markdown_lines(result.contents) - markdown_lines = nutils.trim_empty_lines(markdown_lines) - if vim.tbl_isempty(markdown_lines) then + if not (result and result.contents) then + if config.silent ~= true then + vim.notify('No information available') + end vim.schedule(function() + -- fallback to signature help vim.lsp.buf.signature_help() end) return end - - local opts = {} - opts.wrap = true -- wrapping by default - opts.stylize_markdown = true - opts.focus = true - local contents = markdown_lines - if vim.fn.has('nvim-0.10') == 0 then - contents = util._trim(markdown_lines, opts) -- function removed in 0.10 + local format = 'markdown' + local contents ---@type string[] + if type(result.contents) == 'table' and result.contents.kind == 'plaintext' then + format = 'plaintext' + contents = vim.split(result.contents.value or '', '\n', { trimempty = true }) else - contents = markdown_lines + contents = util.convert_input_to_markdown_lines(result.contents) end - - -- applies the syntax and sets the lines to the buffer - local bufnr, winnr = util.open_floating_preview(contents, 'markdown', config) - - vim.api.nvim_buf_set_option(bufnr, 'modifiable', true) - contents = lsp.util.stylize_markdown(bufnr, contents, opts) - vim.api.nvim_buf_set_option(bufnr, 'modifiable', false) - if _NgConfigValues.lsp.hover.keymaps then - for key, v in pairs(_NgConfigValues.lsp.hover.keymaps) do - if v[ft] == nil or v[ft] == true then - local f = v.default or function() end - vim.keymap.set('n', key, f, { noremap = true, silent = true, buffer = bufnr }) - else - local f = v[ft] - vim.keymap.set('n', key, f, { noremap = true, silent = true, buffer = bufnr }) - end + if vim.tbl_isempty(contents) then + if config.silent ~= true then + vim.notify('No information available') end + return end - return bufnr, winnr + return util.open_floating_preview(contents, format, config) end return M diff --git a/lua/navigator/lspclient/mapping.lua b/lua/navigator/lspclient/mapping.lua index 0d28914..7e98758 100644 --- a/lua/navigator/lspclient/mapping.lua +++ b/lua/navigator/lspclient/mapping.lua @@ -12,152 +12,54 @@ if vim.diagnostic == nil then end local double = { '╔', '═', '╗', '║', '╝', '═', '╚', '║' } local single = { '╭', '─', '╮', '│', '╯', '─', '╰', '│' } --- TODO https://github.com/neovim/neovim/pull/16591 use vimkeymap.set/del --- LuaFormatter off +-- stylua: ignore start local key_maps = { { key = 'gr', func = require('navigator.reference').async_ref, desc = 'async_ref' }, { key = 'gr', func = require('navigator.reference').reference, desc = 'reference' }, -- reference deprecated - { - mode = 'i', - key = '', - func = vim.lsp.buf.signature_help, - desc = 'signature_help', - }, - { - key = '', - func = vim.lsp.buf.signature_help, - desc = 'signature_help', - }, - { - key = 'g0', - func = require('navigator.symbols').document_symbols, - desc = 'document_symbols', - }, - { - key = 'gW', - func = require('navigator.workspace').workspace_symbol_live, - desc = 'workspace_symbol_live', - }, + { mode = 'i', key = '', func = vim.lsp.buf.signature_help, desc = 'signature_help' }, + { key = '', func = vim.lsp.buf.signature_help, desc = 'signature_help' }, + { key = 'g0', func = require('navigator.symbols').document_symbols, desc = 'document_symbols' }, + { key = 'gW', func = require('navigator.workspace').workspace_symbol_live, desc = 'workspace_symbol_live' }, { key = '', func = require('navigator.definition').definition, desc = 'definition' }, { key = 'gd', func = require('navigator.definition').definition, desc = 'definition' }, { key = 'gD', func = vim.lsp.buf.declaration, desc = 'declaration' }, - - { - key = 'gt', - func = vim.lsp.buf.type_definition, - desc = 'type_definition', - }, - { - key = 'gp', - func = require('navigator.definition').definition_preview, - desc = 'definition_preview', - }, - { - key = 'gP', - func = require('navigator.definition').type_definition_preview, - desc = 'type_definition_preview', - }, + { key = 'gt', func = vim.lsp.buf.type_definition, desc = 'type_definition' }, + { key = 'gp', func = require('navigator.definition').definition_preview, desc = 'definition_preview' }, + { key = 'gP', func = require('navigator.definition').type_definition_preview, desc = 'type_definition_preview' }, { key = 'gt', func = require('navigator.treesitter').buf_ts, desc = 'buf_ts' }, { key = 'gT', func = require('navigator.treesitter').bufs_ts, desc = 'bufs_ts' }, { key = 'ct', func = require('navigator.ctags').ctags, desc = 'ctags' }, - { - key = 'ca', - mode = 'n', - func = require('navigator.codeAction').code_action, - desc = 'code_action', - }, - { - key = 'ca', - mode = 'v', - func = require('navigator.codeAction').range_code_action, - desc = 'range_code_action', - }, + { key = 'ca', mode = 'n', func = require('navigator.codeAction').code_action, desc = 'code_action' }, + { key = 'ca', mode = 'v', func = require('navigator.codeAction').range_code_action, desc = 'range_code_action' }, -- { key = 're', func = 'rename()' }, { key = 'rn', func = require('navigator.rename').rename, desc = 'rename' }, { key = 'gi', func = vim.lsp.buf.incoming_calls, desc = 'incoming_calls' }, { key = 'go', func = vim.lsp.buf.outgoing_calls, desc = 'outgoing_calls' }, { key = 'gi', func = vim.lsp.buf.implementation, desc = 'implementation' }, { key = 'D', func = vim.lsp.buf.type_definition, desc = 'type_definition' }, - { - key = 'gL', - func = require('navigator.diagnostics').show_diagnostics, - desc = 'show_diagnostics', - }, - { - key = 'gG', - func = require('navigator.diagnostics').show_buf_diagnostics, - desc = 'show_buf_diagnostics', - }, - { - key = 'dt', - func = require('navigator.diagnostics').toggle_diagnostics, - desc = 'toggle_diagnostics', - }, - { - key = ']d', - func = vim.diagnostic.goto_next, - desc = 'next diagnostics', - }, - { - key = '[d', - func = vim.diagnostic.goto_prev, - desc = 'prev diagnostics', - }, - { - key = ']O', - func = vim.diagnostic.set_loclist, - desc = 'diagnostics set loclist', - }, + { key = 'gL', func = require('navigator.diagnostics').show_diagnostics, desc = 'show_diagnostics' }, + { key = 'gG', func = require('navigator.diagnostics').show_buf_diagnostics, desc = 'show_buf_diagnostics' }, + { key = 'dt', func = require('navigator.diagnostics').toggle_diagnostics, desc = 'toggle_diagnostics' }, + { key = ']d', func = vim.diagnostic.goto_next, desc = 'next diagnostics' }, + { key = '[d', func = vim.diagnostic.goto_prev, desc = 'prev diagnostics' }, + { key = ']O', func = vim.diagnostic.set_loclist, desc = 'diagnostics set loclist' }, { key = ']r', func = require('navigator.treesitter').goto_next_usage, desc = 'goto_next_usage' }, - { - key = '[r', - func = require('navigator.treesitter').goto_previous_usage, - desc = 'goto_previous_usage', - }, - { - key = '', - func = vim.lsp.buf.definition, - desc = 'definition', - }, - { - key = 'g', - func = vim.lsp.buf.implementation, - desc = 'implementation', - }, - { - key = 'k', - func = require('navigator.dochighlight').hi_symbol, - desc = 'hi_symbol', - }, - { - key = 'wa', - func = require('navigator.workspace').add_workspace_folder, - desc = 'add_workspace_folder', - }, - { - key = 'wr', - func = require('navigator.workspace').remove_workspace_folder, - desc = 'remove_workspace_folder', - }, + { key = '[r', func = require('navigator.treesitter').goto_previous_usage, desc = 'goto_previous_usage' }, + { key = '', func = vim.lsp.buf.definition, desc = 'definition' }, + { key = 'g', func = vim.lsp.buf.implementation, desc = 'implementation' }, + { key = 'k', func = require('navigator.dochighlight').hi_symbol, desc = 'hi_symbol' }, + { key = 'wa', func = require('navigator.workspace').add_workspace_folder, desc = 'add_workspace_folder' }, + { key = 'wr', func = require('navigator.workspace').remove_workspace_folder, desc = 'remove_workspace_folder' }, { key = 'ff', func = vim.lsp.buf.format, mode = 'n', desc = 'format' }, { key = 'ff', func = vim.lsp.buf.range_formatting, mode = 'v', desc = 'range format' }, + { key = 'gm', func = require('navigator.formatting').range_format, mode = 'n', desc = 'range format operator e.g gmip' }, + { key = 'wl', func = require('navigator.workspace').list_workspace_folders, desc = 'list_workspace_folders' }, { - key = 'gm', - func = require('navigator.formatting').range_format, - mode = 'n', - desc = 'range format operator e.g gmip', - }, - { - key = 'wl', - func = require('navigator.workspace').list_workspace_folders, - desc = 'list_workspace_folders', - }, - { - key = 'la', - mode = 'n', + key = 'la', mode = 'n', func = require('navigator.codelens').run_action, desc = 'run code lens action', - }, + } + -- stylua: ignore end } if _NgConfigValues.lsp.hover then @@ -260,13 +162,6 @@ local function set_mapping(lsp_attach_info) end end - local function set_keymap(...) - vim.api.nvim_buf_set_keymap(bufnr, ...) - end - - -- local function buf_set_option(...) - -- vim.api.nvim_buf_set_option(bufnr, ...) - -- end local doc_fmt, range_fmt, ccls = check_cap(lsp_attach_info) if ccls then @@ -279,6 +174,7 @@ local function set_mapping(lsp_attach_info) local exists = false for _, default in pairs(key_maps) do if + -- override only if func and mode are the same v.func == default.func and (v.mode or 'n') == (default.mode or 'n') and not default.override @@ -292,6 +188,7 @@ local function set_mapping(lsp_attach_info) end end else + -- disable default mapping key_maps = _NgConfigValues.keymaps or {} log('setting maps to ', key_maps) end @@ -481,8 +378,6 @@ function M.setup(attach_opts) require('navigator.diagnostics').diagnostic_handler end - -- TODO: when active signature merge to neovim, remove this setup: - if vim.fn.empty(_NgConfigValues.signature_help_cfg) == 0 or _NgConfigValues.lsp_signature_help then diff --git a/lua/navigator/lspwrapper.lua b/lua/navigator/lspwrapper.lua index f31ebab..af8527a 100644 --- a/lua/navigator/lspwrapper.lua +++ b/lua/navigator/lspwrapper.lua @@ -495,7 +495,7 @@ end function M.request(method, hdlr) -- e.g textDocument/reference local bufnr = vim.api.nvim_get_current_buf() local ref_params = vim.lsp.util.make_position_params() - vim.lsp.for_each_buffer_client(bufnr, function(client, _, _) + util.for_each_buffer_client(bufnr, function(client, _, _) client.request(method, ref_params, hdlr, bufnr) end) end diff --git a/lua/navigator/symbols.lua b/lua/navigator/symbols.lua index b3ef133..f01f464 100644 --- a/lua/navigator/symbols.lua +++ b/lua/navigator/symbols.lua @@ -1,7 +1,8 @@ local gui = require('navigator.gui') local M = {} -local log = require('navigator.util').log -local trace = require('navigator.util').trace +local util = require('navigator.util') +local log = util.log +local trace = util.trace local lsphelper = require('navigator.lspwrapper') local symbol_kind = require('navigator.lspclient.lspkind').symbol_kind local symbols_to_items = lsphelper.symbols_to_items @@ -10,7 +11,7 @@ function M.workspace_symbols(query) query = query or pcall(vim.fn.input, 'Query: ') local bufnr = vim.api.nvim_get_current_buf() local params = { query = query } - vim.lsp.for_each_buffer_client(bufnr, function(client, _, _bufnr) + util.for_each_buffer_client(bufnr, function(client, _, _bufnr) if client.server_capabilities.workspaceSymbolProvider then client.request('workspace/symbol', params, M.workspace_symbol_handler, _bufnr) end @@ -23,7 +24,7 @@ function M.document_symbols(opts) loc = 'top_center', prompt = true, -- rawdata = true, - api = ' ', + api = '󰌱 ', } local bufnr = opts.bufnr or vim.api.nvim_get_current_buf() @@ -31,7 +32,7 @@ function M.document_symbols(opts) local params = vim.lsp.util.make_position_params() params.context = { includeDeclaration = true } params.query = opts.prompt or '' - vim.lsp.for_each_buffer_client(bufnr, function(client, _, _bufnr) + util.for_each_buffer_client(bufnr, function(client, _, _bufnr) if client.name ~= 'null-ls' and client.server_capabilities.documentSymbolProvider then client.request('textDocument/documentSymbol', params, M.document_symbol_handler, _bufnr) end diff --git a/lua/navigator/util.lua b/lua/navigator/util.lua index 25ca2c3..e9921f6 100644 --- a/lua/navigator/util.lua +++ b/lua/navigator/util.lua @@ -563,7 +563,6 @@ function M.sub_match(str) return str end - function M.try_trim_markdown_code_blocks(lines) local language_id = lines[1]:match('^```(.*)') if language_id then @@ -595,4 +594,16 @@ function M.trim_empty_lines(lines) return new_list end +function M.for_each_buffer_client(bufnr, fn) + local clients + if vim.lsp.get_clients then -- nightly nvim 0.10 + clients = vim.lsp.get_clients({ bufnr = bufnr }) + else + clients = vim.lsp.buf_get_clients() + end + for _, client in pairs(clients) do + fn(client, client.id, bufnr) + end +end + return M