From c693d2fbd4e9dbdf9911aa5b43da6cf29dffac7f Mon Sep 17 00:00:00 2001 From: Kalle Jepsen Date: Sun, 22 Oct 2023 21:38:14 +0200 Subject: [PATCH] lsp: make key bindings configurable This exposes the keybindings for the lsp commands to the configuration and maps a few more commands (e.g. `vim.lsp.buf.format()`) It also adds a description to be picked up by whichkey to make the whichkey UX a bit nicer (ie. we're now showing "Go to definition" instead of just "vim.lsp.buf.definition()") --- docs/release-notes/rl-0.5.adoc | 2 + modules/lsp/config.nix | 42 +++++++++++++-------- modules/lsp/module.nix | 69 ++++++++++++++++++++++++++++++---- 3 files changed, 90 insertions(+), 23 deletions(-) diff --git a/docs/release-notes/rl-0.5.adoc b/docs/release-notes/rl-0.5.adoc index 444ee39..12e6ab7 100644 --- a/docs/release-notes/rl-0.5.adoc +++ b/docs/release-notes/rl-0.5.adoc @@ -79,3 +79,5 @@ https://github.com/ksonj[ksonj]: * Add black-and-isort python formatter * Removed redundant "Enable ..." in `mkEnableOption` descriptions + +* Add options to modify LSP key bindings and add proper whichkey descriptions diff --git a/modules/lsp/config.nix b/modules/lsp/config.nix index 83da30b..f140240 100644 --- a/modules/lsp/config.nix +++ b/modules/lsp/config.nix @@ -8,31 +8,41 @@ with lib; with builtins; let cfg = config.vim.lsp; usingNvimCmp = config.vim.autocomplete.enable && config.vim.autocomplete.type == "nvim-cmp"; + self = import ./module.nix {inherit config lib pkgs;}; + + mappingDefinitions = self.options.vim.lsp.mappings; + mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; + mkBinding = binding: action: "vim.api.nvim_buf_set_keymap(bufnr, 'n', '${binding.value}', 'lua ${action}', {noremap=true, silent=true, desc='${binding.description}'})"; in { config = mkIf cfg.enable { vim.startPlugins = optional usingNvimCmp "cmp-nvim-lsp"; vim.autocomplete.sources = {"nvim_lsp" = "[LSP]";}; - vim.luaConfigRC.lsp-setup = '' vim.g.formatsave = ${boolToString cfg.formatOnSave}; local attach_keymaps = function(client, bufnr) - local opts = { noremap=true, silent=true } - - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'lgD', 'lua vim.lsp.buf.declaration()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'lgd', 'lua vim.lsp.buf.definition()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'lgt', 'lua vim.lsp.buf.type_definition()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'lgn', 'lua vim.diagnostic.goto_next()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'lgp', 'lua vim.diagnostic.goto_prev()', opts) - - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'lwa', 'lua vim.lsp.buf.add_workspace_folder()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'lwr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'lwl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) - - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'lh', 'lua vim.lsp.buf.hover()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'ls', 'lua vim.lsp.buf.signature_help()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'ln', 'lua vim.lsp.buf.rename()', opts) + ${mkBinding mappings.goToDeclaration "vim.lsp.buf.declaration()"} + ${mkBinding mappings.goToDefinition "vim.lsp.buf.definition()"} + ${mkBinding mappings.goToDeclaration "vim.lsp.buf.declaration()"} + ${mkBinding mappings.goToDefinition "vim.lsp.buf.definition()"} + ${mkBinding mappings.goToType "vim.lsp.buf.type_definition()"} + ${mkBinding mappings.listImplementations "vim.lsp.buf.implementation()"} + ${mkBinding mappings.listReferences "vim.lsp.buf.references()"} + ${mkBinding mappings.nextDiagnostic "vim.diagnostic.goto_next()"} + ${mkBinding mappings.previousDiagnostic "vim.diagnostic.goto_prev()"} + ${mkBinding mappings.openDiagnosticFloat "vim.diagnostic.open_float()"} + ${mkBinding mappings.documentHighlight "vim.lsp.buf.document_highlight()"} + ${mkBinding mappings.listDocumentSymbols "vim.lsp.buf.document_symbol()"} + ${mkBinding mappings.addWorkspaceFolder "vim.lsp.buf.add_workspace_folder()"} + ${mkBinding mappings.removeWorkspaceFolder "vim.lsp.buf.remove_workspace_folder()"} + ${mkBinding mappings.listWorkspaceFolders "print(vim.inspect(vim.lsp.buf.list_workspace_folders()))"} + ${mkBinding mappings.listWorkspaceSymbols "vim.lsp.buf.workspace_symbol()"} + ${mkBinding mappings.hover "vim.lsp.buf.hover()"} + ${mkBinding mappings.signatureHelp "vim.lsp.buf.signature_help()"} + ${mkBinding mappings.renameSymbol "vim.lsp.buf.rename()"} + ${mkBinding mappings.codeAction "vim.lsp.buf.code_action()"} + ${mkBinding mappings.format "vim.lsp.buf.format()"} end -- Enable formatting diff --git a/modules/lsp/module.nix b/modules/lsp/module.nix index 88a2811..9b24825 100644 --- a/modules/lsp/module.nix +++ b/modules/lsp/module.nix @@ -1,13 +1,68 @@ -{ - config, - lib, - pkgs, - ... -}: +{lib, ...}: with lib; -with builtins; { +with builtins; let +in { options.vim.lsp = { enable = mkEnableOption "LSP, also enabled automatically through null-ls and lspconfig options"; formatOnSave = mkEnableOption "format on save"; + mappings = { + goToDefinition = + mkMappingOption "Go to definition" + "lgd"; + goToDeclaration = + mkMappingOption "Go to declaration" + "lgD"; + goToType = + mkMappingOption "Go to type" + "lgt"; + listImplementations = + mkMappingOption "List implementations" + "lgi"; + listReferences = + mkMappingOption "List references" + "lgr"; + nextDiagnostic = + mkMappingOption "Go to next diagnostic" + "lgn"; + previousDiagnostic = + mkMappingOption "Go to previous diagnostic" + "lgp"; + openDiagnosticFloat = + mkMappingOption "Open diagnostic float" + "le"; + documentHighlight = + mkMappingOption "Document highlight" + "lH"; + listDocumentSymbols = + mkMappingOption "List document symbols" + "lS"; + addWorkspaceFolder = + mkMappingOption "Add workspace folder" + "lwa"; + removeWorkspaceFolder = + mkMappingOption "Remove workspace folder" + "lwr"; + listWorkspaceFolders = + mkMappingOption "List workspace folders" + "lwl"; + listWorkspaceSymbols = + mkMappingOption "List workspace symbols" + "lws"; + hover = + mkMappingOption "Trigger hover" + "lh"; + signatureHelp = + mkMappingOption "Signature help" + "ls"; + renameSymbol = + mkMappingOption "Rename symbol" + "ln"; + codeAction = + mkMappingOption "Code action" + "la"; + format = + mkMappingOption "Format" + "lf"; + }; }; }