From 07c65f1d3377896c59fe93a66965bda33aab99a4 Mon Sep 17 00:00:00 2001 From: Mona Mayrhofer Date: Fri, 7 Apr 2023 13:38:15 +0200 Subject: [PATCH 1/8] Keymap: Initial Exploration --- modules/filetree/nvimtreelua.nix | 21 +++++++---- modules/lib/default.nix | 1 + modules/lib/keymap.nix | 38 ++++++++++++++++++++ modules/tabline/nvim-bufferline.nix | 56 +++++++++++++++++++---------- 4 files changed, 90 insertions(+), 26 deletions(-) create mode 100644 modules/lib/keymap.nix diff --git a/modules/filetree/nvimtreelua.nix b/modules/filetree/nvimtreelua.nix index cb6f9bf..040399a 100644 --- a/modules/filetree/nvimtreelua.nix +++ b/modules/filetree/nvimtreelua.nix @@ -128,17 +128,24 @@ in { description = "The command used to open a file with the associated default program"; type = types.str; }; + + keymap = nvim.keymap.mkKeymapOptions; }; - config = mkIf cfg.enable { - vim.startPlugins = ["nvim-tree-lua"]; + config = let + actions = with nvim.keymap; { - vim.nnoremap = { - "" = ":NvimTreeToggle"; - "tr" = ":NvimTreeRefresh"; - "tg" = ":NvimTreeFindFile"; - "tf" = ":NvimTreeFocus"; + toggle = mkVimAction ":NvimTreeToggle"; + refresh = mkVimAction ":NvimTreeRefresh"; + findFile = mkVimAction ":NvimTreeFindFile"; + focus = mkVimAction ":NvimTreeFocus"; }; + in mkIf cfg.enable { + vim.startPlugins = ["nvim-tree-lua"]; + + vim.nnoremap = nvim.keymap.buildKeymap cfg.keymap.normal actions; + vim.vnoremap = nvim.keymap.buildKeymap cfg.keymap.visual actions; + vim.inoremap = nvim.keymap.buildKeymap cfg.keymap.insert actions; vim.luaConfigRC.nvimtreelua = nvim.dag.entryAnywhere '' require'nvim-tree'.setup({ diff --git a/modules/lib/default.nix b/modules/lib/default.nix index 1b0fe40..35b86cb 100644 --- a/modules/lib/default.nix +++ b/modules/lib/default.nix @@ -5,4 +5,5 @@ languages = import ./languages.nix {inherit lib;}; nmd = import ./nmd.nix; lua = import ./lua.nix {inherit lib;}; + keymap = import ./keymap.nix {inherit lib;}; } diff --git a/modules/lib/keymap.nix b/modules/lib/keymap.nix new file mode 100644 index 0000000..32a568c --- /dev/null +++ b/modules/lib/keymap.nix @@ -0,0 +1,38 @@ +{lib}: +with lib; { + mkKeymapOptions = { + normal = mkOption { + type = types.functionTo types.anything; + default = _: {}; + }; + visual = mkOption { + type = types.functionTo types.anything; + default = _: {}; + }; + insert = mkOption { + type = types.functionTo types.anything; + default = _: {}; + }; + }; + + mkVimAction = action: { + inherit action; + type = "vim"; + }; + + # mapping is a function: Actions -> AttrSet(keybind -> action) + # actions is an Actions AttrSet + # an Actions attrset looks like + # { + # "NameOfAction": { + # type = "actionType"; + # } + # } + buildKeymap = mappingFn: actions: let + mapping = mappingFn (actions + // { + executeViml = viml: lib.nvim.keymap.mkVimAction viml; + }); + in + lib.mapAttrs (_: v: v.action) (lib.filterAttrs (_: v: v.type == "vim") mapping); +} diff --git a/modules/tabline/nvim-bufferline.nix b/modules/tabline/nvim-bufferline.nix index fca433f..6cc57c9 100644 --- a/modules/tabline/nvim-bufferline.nix +++ b/modules/tabline/nvim-bufferline.nix @@ -10,10 +10,24 @@ with builtins; let in { options.vim.tabline.nvimBufferline = { enable = mkEnableOption "nvim-bufferline-lua"; + + keymap = nvim.keymap.mkKeymapOptions; }; config = mkIf cfg.enable ( let + actions = with nvim.keymap; { + cycleNext = mkVimAction ":BufferLineCycleNext"; + cyclePrev = mkVimAction ":BufferLineCyclePrev"; + pick = mkVimAction ":BufferLinePick"; + sortByExtension = mkVimAction ":BufferLineSortByExtension"; + sortByDirectory = mkVimAction ":BufferLineSortByDirectory"; + sortById = mkVimAction ":lua require'bufferline'.sort_buffers_by(function (buf_a, buf_b) return buf_a.id < buf_b.id end)"; + moveNext = mkVimAction ":BufferLineMoveNext"; + movePrev = mkVimAction ":BufferLineMovePrev"; + goToBuffer = bufferNumber: mkVimAction "BufferLineGoToBuffer ${bufferNumber}"; + }; + mouse = { right = "'vertical sbuffer %d'"; close = '' @@ -28,25 +42,29 @@ in { "bufdelete-nvim" ]; - vim.nnoremap = { - "bn" = ":BufferLineCycleNext"; - "bp" = ":BufferLineCyclePrev"; - "bc" = ":BufferLinePick"; - "bse" = ":BufferLineSortByExtension"; - "bsd" = ":BufferLineSortByDirectory"; - "bsi" = ":lua require'bufferline'.sort_buffers_by(function (buf_a, buf_b) return buf_a.id < buf_b.id end)"; - "bmn" = ":BufferLineMoveNext"; - "bmp" = ":BufferLineMovePrev"; - "b1" = "BufferLineGoToBuffer 1"; - "b2" = "BufferLineGoToBuffer 2"; - "b3" = "BufferLineGoToBuffer 3"; - "b4" = "BufferLineGoToBuffer 4"; - "b5" = "BufferLineGoToBuffer 5"; - "b6" = "BufferLineGoToBuffer 6"; - "b7" = "BufferLineGoToBuffer 7"; - "b8" = "BufferLineGoToBuffer 8"; - "b9" = "BufferLineGoToBuffer 9"; - }; + vim.nnoremap = nvim.keymap.buildKeymap (cfg.keymap.normal) actions; + vim.inoremap = nvim.keymap.buildKeymap (cfg.keymap.insert) actions; + vim.vnoremap = nvim.keymap.buildKeymap (cfg.keymap.visual) actions; + + #vim.nnoremap = { + # "bn" = ":BufferLineCycleNext"; + # "bp" = ":BufferLineCyclePrev"; + # "bc" = ":BufferLinePick"; + # "bse" = ":BufferLineSortByExtension"; + # "bsd" = ":BufferLineSortByDirectory"; + # "bsi" = ":lua require'bufferline'.sort_buffers_by(function (buf_a, buf_b) return buf_a.id < buf_b.id end)"; + # "bmn" = ":BufferLineMoveNext"; + # "bmp" = ":BufferLineMovePrev"; + # "b1" = "BufferLineGoToBuffer 1"; + # "b2" = "BufferLineGoToBuffer 2"; + # "b3" = "BufferLineGoToBuffer 3"; + # "b4" = "BufferLineGoToBuffer 4"; + # "b5" = "BufferLineGoToBuffer 5"; + # "b6" = "BufferLineGoToBuffer 6"; + # "b7" = "BufferLineGoToBuffer 7"; + # "b8" = "BufferLineGoToBuffer 8"; + # "b9" = "BufferLineGoToBuffer 9"; + #}; vim.luaConfigRC.nvimBufferline = nvim.dag.entryAnywhere '' require("bufferline").setup{ From 6bf1f4d7c9fa6e80b35e5de726a3c1b6c49bb102 Mon Sep 17 00:00:00 2001 From: Mona Mayrhofer Date: Fri, 7 Apr 2023 14:27:28 +0200 Subject: [PATCH 2/8] Keymap: Exploration of dealing with lsp --- modules/lib/keymap.nix | 12 +++++--- modules/lsp/default.nix | 68 +++++++++++++++++++++++++++++++---------- 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/modules/lib/keymap.nix b/modules/lib/keymap.nix index 32a568c..5a69b1f 100644 --- a/modules/lib/keymap.nix +++ b/modules/lib/keymap.nix @@ -15,11 +15,13 @@ with lib; { }; }; - mkVimAction = action: { + mkAction = type: action: { inherit action; - type = "vim"; + inherit type; }; + mkVimAction = action: lib.nvim.keymap.mkAction "vim" action; + # mapping is a function: Actions -> AttrSet(keybind -> action) # actions is an Actions AttrSet # an Actions attrset looks like @@ -28,11 +30,13 @@ with lib; { # type = "actionType"; # } # } - buildKeymap = mappingFn: actions: let + + buildKeymap = lib.nvim.keymap.buildKeymapOf "vim"; + buildKeymapOf = actionType: mappingFn: actions: let mapping = mappingFn (actions // { executeViml = viml: lib.nvim.keymap.mkVimAction viml; }); in - lib.mapAttrs (_: v: v.action) (lib.filterAttrs (_: v: v.type == "vim") mapping); + lib.mapAttrs (_: v: v.action) (lib.filterAttrs (_: v: v.type == actionType) mapping); } diff --git a/modules/lsp/default.nix b/modules/lsp/default.nix index e47f583..bf9b29e 100644 --- a/modules/lsp/default.nix +++ b/modules/lsp/default.nix @@ -24,9 +24,59 @@ in { options.vim.lsp = { enable = mkEnableOption "LSP, also enabled automatically through null-ls and lspconfig options"; formatOnSave = mkEnableOption "format on save"; + + keymap = nvim.keymap.mkKeymapOptions; }; - config = mkIf cfg.enable { + config = let + mkSpecialAction = nvim.keymap.mkAction "lsp"; + actions = { + gotoDeclaration = mkSpecialAction "lua vim.lsp.buf.declaration()"; + gotoDefinition = mkSpecialAction "lua vim.lsp.buf.definition()"; + gotoTypeDefinition = mkSpecialAction "lua vim.lsp.buf.type_definition()"; + nextDiagnostic = mkSpecialAction "lua vim.diagnostic.goto_next()"; + prevDiagnositc = mkSpecialAction "lua vim.diagnostic.goto_prev()"; + + addWorkspaceFolder = mkSpecialAction "lua vim.lsp.buf.add_workspace_folder()"; + removeWorkspaceFolder = mkSpecialAction "lua vim.lsp.buf.remove_workspace_folder()"; + listWorkspaceFolder = mkSpecialAction "lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))"; + + hover = mkSpecialAction "lua vim.lsp.buf.hover()"; + signatureHelp = mkSpecialAction "lua vim.lsp.buf.signature_help()"; + rename = mkSpecialAction "lua vim.lsp.buf.rename()"; + }; + + keymapString = let + makeString = mode: binding: mapping: + "vim.api.nvim_buf_set_keymap(bufnr, '${mode}', '${binding}', '${mapping}', {noremap=true, silent=true})"; + makeStrings = mode: mapping: + (mapAttrsToList (makeString mode) (nvim.keymap.buildKeymapOf "lsp" mapping actions)); + in + strings.concatStringsSep "\n" ( + (makeStrings "n" cfg.keymap.normal) ++ + (makeStrings "i" cfg.keymap.insert) ++ + (makeStrings "v" cfg.keymap.visual) + ); + + #defaultKeymap = '' + # 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) + #''; + in + mkIf cfg.enable { vim.startPlugins = optional usingNvimCmp "cmp-nvim-lsp"; vim.autocomplete.sources = {"nvim_lsp" = "[LSP]";}; @@ -35,21 +85,7 @@ in { 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) + ${traceVal keymapString} end -- Enable formatting From 048b032dbbec3fa8ac90e2451a9c2f543f9986f8 Mon Sep 17 00:00:00 2001 From: Mona Mayrhofer Date: Fri, 7 Apr 2023 15:46:12 +0200 Subject: [PATCH 3/8] Keymap: Use keymap api in telescope --- modules/telescope/default.nix | 129 ++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 43 deletions(-) diff --git a/modules/telescope/default.nix b/modules/telescope/default.nix index 67bde16..0741bb7 100644 --- a/modules/telescope/default.nix +++ b/modules/telescope/default.nix @@ -10,68 +10,111 @@ with builtins; let in { options.vim.telescope = { enable = mkEnableOption "enable telescope"; - }; - config = mkIf (cfg.enable) { - vim.startPlugins = [ - "telescope" - ]; + keymap = nvim.keymap.mkKeymapOptions; + }; - vim.nnoremap = + config = let + actions = with nvim.keymap; { - "ff" = " Telescope find_files"; - "fg" = " Telescope live_grep"; - "fb" = " Telescope buffers"; - "fh" = " Telescope help_tags"; - "ft" = " Telescope"; + findFiles = mkVimAction " Telescope find_files"; + liveGrep = mkVimAction " Telescope live_grep"; + buffers = mkVimAction " Telescope buffers"; + helpTags = mkVimAction " Telescope help_tags"; + open = mkVimAction " Telescope"; - "fvcw" = " Telescope git_commits"; - "fvcb" = " Telescope git_bcommits"; - "fvb" = " Telescope git_branches"; - "fvs" = " Telescope git_status"; - "fvx" = " Telescope git_stash"; + gitCommits = mkVimAction " Telescope git_commits"; + gitBCommits = mkVimAction " Telescope git_bcommits"; + gitBranches = mkVimAction " Telescope git_branches"; + gitStatus = mkVimAction " Telescope git_status"; + gitStash = mkVimAction " Telescope git_stash"; } // ( if config.vim.lsp.enable then { - "flsb" = " Telescope lsp_document_symbols"; - "flsw" = " Telescope lsp_workspace_symbols"; + lspDocumentSymbols = mkVimAction " Telescope lsp_document_symbols"; + lspWorkspaceSymbols = mkVimAction " Telescope lsp_workspace_symbols"; - "flr" = " Telescope lsp_references"; - "fli" = " Telescope lsp_implementations"; - "flD" = " Telescope lsp_definitions"; - "flt" = " Telescope lsp_type_definitions"; - "fld" = " Telescope diagnostics"; + lspReferences = mkVimAction " Telescope lsp_references"; + lspImplementations = mkVimAction " Telescope lsp_implementations"; + lspDefinitions = mkVimAction " Telescope lsp_definitions"; + lspTypeDefinitions = mkVimAction " Telescope lsp_type_definitions"; + lspDiagnostics = mkVimAction " Telescope diagnostics"; } else {} ) // ( if config.vim.treesitter.enable then { - "fs" = " Telescope treesitter"; + treesitter = mkVimAction " Telescope treesitter"; } else {} ); + in + mkIf (cfg.enable) { + vim.startPlugins = [ + "telescope" + ]; + + vim.nnoremap = nvim.keymap.buildKeymap cfg.keymap.normal actions; + vim.vnoremap = nvim.keymap.buildKeymap cfg.keymap.visual actions; + vim.inoremap = nvim.keymap.buildKeymap cfg.keymap.insert actions; + + #vim.nnoremap = + # { + # "ff" = " Telescope find_files"; + # "fg" = " Telescope live_grep"; + # "fb" = " Telescope buffers"; + # "fh" = " Telescope help_tags"; + # "ft" = " Telescope"; + + # "fvcw" = " Telescope git_commits"; + # "fvcb" = " Telescope git_bcommits"; + # "fvb" = " Telescope git_branches"; + # "fvs" = " Telescope git_status"; + # "fvx" = " Telescope git_stash"; + # } + # // ( + # if config.vim.lsp.enable + # then { + # "flsb" = " Telescope lsp_document_symbols"; + # "flsw" = " Telescope lsp_workspace_symbols"; - vim.luaConfigRC.telescope = nvim.dag.entryAnywhere '' - require("telescope").setup { - defaults = { - vimgrep_arguments = { - "${pkgs.ripgrep}/bin/rg", - "--color=never", - "--no-heading", - "--with-filename", - "--line-number", - "--column", - "--smart-case" - }, - pickers = { - find_command = { - "${pkgs.fd}/bin/fd", + # "flr" = " Telescope lsp_references"; + # "fli" = " Telescope lsp_implementations"; + # "flD" = " Telescope lsp_definitions"; + # "flt" = " Telescope lsp_type_definitions"; + # "fld" = " Telescope diagnostics"; + # } + # else {} + # ) + # // ( + # if config.vim.treesitter.enable + # then { + # "fs" = " Telescope treesitter"; + # } + # else {} + # ); + + vim.luaConfigRC.telescope = nvim.dag.entryAnywhere '' + require("telescope").setup { + defaults = { + vimgrep_arguments = { + "${pkgs.ripgrep}/bin/rg", + "--color=never", + "--no-heading", + "--with-filename", + "--line-number", + "--column", + "--smart-case" + }, + pickers = { + find_command = { + "${pkgs.fd}/bin/fd", + }, }, - }, + } } - } - ''; - }; + ''; + }; } From 5b68c87fd4c9429cc2672deccfae359ad6ac328f Mon Sep 17 00:00:00 2001 From: Mona Mayrhofer Date: Fri, 7 Apr 2023 19:34:44 +0200 Subject: [PATCH 4/8] Keymap: Explore basic integration of nvim-cmp --- modules/completion/default.nix | 262 ++++++++++++++++++++------------- modules/lib/keymap.nix | 16 ++ 2 files changed, 178 insertions(+), 100 deletions(-) diff --git a/modules/completion/default.nix b/modules/completion/default.nix index 3a4892c..f19cd0d 100644 --- a/modules/completion/default.nix +++ b/modules/completion/default.nix @@ -82,110 +82,172 @@ in { ''; }; }; + keymap = nvim.keymap.mkKeymapOptions; }; }; - config = mkIf cfg.enable { - vim.startPlugins = [ - "nvim-cmp" - "cmp-buffer" - "cmp-vsnip" - "cmp-path" - ]; - - vim.autocomplete.sources = { - "nvim-cmp" = null; - "vsnip" = "[VSnip]"; - "buffer" = "[Buffer]"; - "crates" = "[Crates]"; - "path" = "[Path]"; + config = let + mkCmpAction = nvim.keymap.mkAction "cmp"; + actions = { + docsDown = mkCmpAction "cmp.mapping.scroll_docs(-4)"; + docsUp = mkCmpAction "cmp.mapping.scroll_docs(4)"; + complete = mkCmpAction "cmp.mapping.complete()"; + disable = mkCmpAction "cmp.config.disable"; + close = mkCmpAction "cmp.mapping.close()"; + abort = mkCmpAction "cmp.mapping.abort()"; + confirm = mkCmpAction "cmp.mapping.confirm({ + select = true, + })"; + next = mkCmpAction '' + function (fallback) + if cmp.visible() then + cmp.select_next_item() + else + fallback() + end + end + ''; + prev = mkCmpAction '' + function (fallback) + if cmp.visible() then + cmp.select_prev_item() + else + fallback() + end + end + ''; + + # TODO Working title... also should this be seperated somehow? + doTabAction = mkCmpAction '' + function (fallback) + if cmp.visible() then + cmp.select_next_item() + elseif vim.fn['vsnip#available'](1) == 1 then + feedkey(" vsnip-expand-or-jump ", " ") + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end''; + # TODO Working title... also should this be seperated somehow? + doShiftTabAction = mkCmpAction '' + function (fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif vim.fn['vsnip#available'](-1) == 1 then + feedkeys(" vsnip-jump-prev ", " ") + end + end''; }; - vim.luaConfigRC.completion = mkIf (cfg.type == "nvim-cmp") (dagPlacement '' - local nvim_cmp_menu_map = function(entry, vim_item) - -- name for each source - vim_item.menu = ({ - ${builtMaps} - })[entry.source.name] - print(vim_item.menu) - return vim_item - end - - ${optionalString lspkindEnabled '' - lspkind_opts.before = ${cfg.formatting.format} - ''} - - local has_words_before = function() - local line, col = unpack(vim.api.nvim_win_get_cursor(0)) - return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil - end - - local feedkey = function(key, mode) - vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) - end - - local cmp = require'cmp' - cmp.setup({ - snippet = { - expand = function(args) - vim.fn["vsnip#anonymous"](args.body) - end, - }, - sources = { - ${builtSources} - }, - mapping = { - [''] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }), - [''] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c'}), - [''] = cmp.mapping(cmp.mapping.complete(), { 'i', 'c'}), - [''] = cmp.config.disable, - [''] = cmp.mapping({ - i = cmp.mapping.abort(), - c = cmp.mapping.close(), - }), - [''] = cmp.mapping.confirm({ - select = true, - }), - [''] = cmp.mapping(function (fallback) - if cmp.visible() then - cmp.select_next_item() - elseif vim.fn['vsnip#available'](1) == 1 then - feedkey("(vsnip-expand-or-jump)", "") - elseif has_words_before() then - cmp.complete() - else - fallback() - end - end, { 'i', 's' }), - [''] = cmp.mapping(function (fallback) - if cmp.visible() then - cmp.select_prev_item() - elseif vim.fn['vsnip#available'](-1) == 1 then - feedkeys("(vsnip-jump-prev)", "") - end - end, { 'i', 's' }) - }, - completion = { - completeopt = 'menu,menuone,noinsert', - }, - formatting = { - format = - ${ - if lspkindEnabled - then "lspkind.cmp_format(lspkind_opts)" - else cfg.formatting.format - }, + # TODO Create library function to unify this with lsp/default.nix + keymapString = let + singleElement = list: + if length list == 1 + then head list + else builtins.throw "Expected single element"; + makeString = binding: atoms: '' + ['${binding}'] = cmp.mapping({ + ${ + strings.concatStringsSep ",\n" (mapAttrsToList (mode: atoms: "${mode} = ${(singleElement atoms).mapping}") (groupBy (atom: atom.mode) atoms)) } - }) - ${optionalString (config.vim.autopairs.enable && config.vim.autopairs.type == "nvim-autopairs") '' - local cmp_autopairs = require('nvim-autopairs.completion.cmp') - cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done({ map_char = { text = ""} })) - ''} - ''); - - vim.snippets.vsnip.enable = - if (cfg.type == "nvim-cmp") - then true - else config.vim.snippets.vsnip.enable; - }; + }) + ''; + + makeAtom = mode: binding: mapping: { + inherit mode; + inherit binding; + inherit mapping; + }; + makeAtoms = mode: mapping: (mapAttrsToList (makeAtom mode) (nvim.keymap.buildKeymapOf "cmp" mapping actions)); + # [ {mode, binding, mapping}] + atoms = + (makeAtoms "n" cfg.keymap.normal) + ++ (makeAtoms "i" cfg.keymap.insert) + ++ (makeAtoms "v" cfg.keymap.visual) + ++ (makeAtoms "s" cfg.keymap.select) + ++ (makeAtoms "c" cfg.keymap.command) + ++ (makeAtoms "t" cfg.keymap.terminal) + ++ (makeAtoms "o" cfg.keymap.operatorPending); + + bindingStringList = mapAttrsToList makeString (groupBy (atom: atom.binding) atoms); + in + strings.concatStringsSep ",\n" bindingStringList; + in + mkIf cfg.enable { + vim.startPlugins = [ + "nvim-cmp" + "cmp-buffer" + "cmp-vsnip" + "cmp-path" + ]; + + vim.autocomplete.sources = { + "nvim-cmp" = null; + "vsnip" = "[VSnip]"; + "buffer" = "[Buffer]"; + "crates" = "[Crates]"; + "path" = "[Path]"; + }; + + vim.luaConfigRC.completion = mkIf (cfg.type == "nvim-cmp") (dagPlacement '' + local nvim_cmp_menu_map = function(entry, vim_item) + -- name for each source + vim_item.menu = ({ + ${builtMaps} + })[entry.source.name] + print(vim_item.menu) + return vim_item + end + + ${optionalString lspkindEnabled '' + lspkind_opts.before = ${cfg.formatting.format} + ''} + + local has_words_before = function() + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil + end + + local feedkey = function(key, mode) + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) + end + + local cmp = require'cmp' + cmp.setup({ + snippet = { + expand = function(args) + vim.fn["vsnip#anonymous"](args.body) + end, + }, + sources = { + ${builtSources} + }, + mapping = { + ${traceVal keymapString} + }, + completion = { + completeopt = 'menu,menuone,noinsert', + }, + formatting = { + format = + ${ + if lspkindEnabled + then "lspkind.cmp_format(lspkind_opts)" + else cfg.formatting.format + }, + } + }) + ${optionalString (config.vim.autopairs.enable && config.vim.autopairs.type == "nvim-autopairs") '' + local cmp_autopairs = require('nvim-autopairs.completion.cmp') + cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done({ map_char = { text = ""} })) + ''} + ''); + + vim.snippets.vsnip.enable = + if (cfg.type == "nvim-cmp") + then true + else config.vim.snippets.vsnip.enable; + }; } diff --git a/modules/lib/keymap.nix b/modules/lib/keymap.nix index 5a69b1f..1788aa6 100644 --- a/modules/lib/keymap.nix +++ b/modules/lib/keymap.nix @@ -9,10 +9,26 @@ with lib; { type = types.functionTo types.anything; default = _: {}; }; + select = mkOption { + type = types.functionTo types.anything; + default = _: {}; + }; insert = mkOption { type = types.functionTo types.anything; default = _: {}; }; + command = mkOption { + type = types.functionTo types.anything; + default = _: {}; + }; + terminal = mkOption { + type = types.functionTo types.anything; + default = _: {}; + }; + operatorPending = mkOption { + type = types.functionTo types.anything; + default = _: {}; + }; }; mkAction = type: action: { From fef6a05b0a70746c3dc0f6657401d74d832878bb Mon Sep 17 00:00:00 2001 From: Mona Mayrhofer Date: Wed, 12 Apr 2023 17:35:24 +0200 Subject: [PATCH 5/8] Keymap: Explore to have global keymap config --- modules/completion/default.nix | 26 ++++---------- modules/filetree/nvimtreelua.nix | 4 +-- modules/keymap.nix | 54 +++++++++++++++++++++++++++++ modules/lib/keymap.nix | 17 +++++++++ modules/lsp/default.nix | 13 ++++--- modules/modules.nix | 1 + modules/tabline/nvim-bufferline.nix | 8 ++--- modules/telescope/default.nix | 8 ++--- 8 files changed, 89 insertions(+), 42 deletions(-) create mode 100644 modules/keymap.nix diff --git a/modules/completion/default.nix b/modules/completion/default.nix index f19cd0d..6eeef2b 100644 --- a/modules/completion/default.nix +++ b/modules/completion/default.nix @@ -82,7 +82,6 @@ in { ''; }; }; - keymap = nvim.keymap.mkKeymapOptions; }; }; @@ -150,32 +149,19 @@ in { makeString = binding: atoms: '' ['${binding}'] = cmp.mapping({ ${ - strings.concatStringsSep ",\n" (mapAttrsToList (mode: atoms: "${mode} = ${(singleElement atoms).mapping}") (groupBy (atom: atom.mode) atoms)) + strings.concatStringsSep ",\n" (mapAttrsToList (mode: atoms: "${nvim.keymap.modeChar mode} = ${(singleElement atoms).action}") (groupBy (atom: atom.mode) atoms)) } }) ''; - makeAtom = mode: binding: mapping: { - inherit mode; - inherit binding; - inherit mapping; - }; - makeAtoms = mode: mapping: (mapAttrsToList (makeAtom mode) (nvim.keymap.buildKeymapOf "cmp" mapping actions)); - # [ {mode, binding, mapping}] - atoms = - (makeAtoms "n" cfg.keymap.normal) - ++ (makeAtoms "i" cfg.keymap.insert) - ++ (makeAtoms "v" cfg.keymap.visual) - ++ (makeAtoms "s" cfg.keymap.select) - ++ (makeAtoms "c" cfg.keymap.command) - ++ (makeAtoms "t" cfg.keymap.terminal) - ++ (makeAtoms "o" cfg.keymap.operatorPending); - - bindingStringList = mapAttrsToList makeString (groupBy (atom: atom.binding) atoms); + atoms = nvim.keymap.keymappingsOfType "cmp" config.nvim-flake.keymappings; + + bindingStringList = mapAttrsToList makeString (groupBy (atom: atom.binding) (traceSeq {atoms = atoms;} atoms)); in strings.concatStringsSep ",\n" bindingStringList; in mkIf cfg.enable { + nvim-flake.keymapActions = {autocomplete = actions;}; vim.startPlugins = [ "nvim-cmp" "cmp-buffer" @@ -225,7 +211,7 @@ in { ${builtSources} }, mapping = { - ${traceVal keymapString} + ${keymapString} }, completion = { completeopt = 'menu,menuone,noinsert', diff --git a/modules/filetree/nvimtreelua.nix b/modules/filetree/nvimtreelua.nix index 040399a..26be10b 100644 --- a/modules/filetree/nvimtreelua.nix +++ b/modules/filetree/nvimtreelua.nix @@ -141,11 +141,9 @@ in { focus = mkVimAction ":NvimTreeFocus"; }; in mkIf cfg.enable { + nvim-flake.keymapActions = {nvimTreeLua = actions;}; vim.startPlugins = ["nvim-tree-lua"]; - vim.nnoremap = nvim.keymap.buildKeymap cfg.keymap.normal actions; - vim.vnoremap = nvim.keymap.buildKeymap cfg.keymap.visual actions; - vim.inoremap = nvim.keymap.buildKeymap cfg.keymap.insert actions; vim.luaConfigRC.nvimtreelua = nvim.dag.entryAnywhere '' require'nvim-tree'.setup({ diff --git a/modules/keymap.nix b/modules/keymap.nix new file mode 100644 index 0000000..5620cd5 --- /dev/null +++ b/modules/keymap.nix @@ -0,0 +1,54 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; +with builtins; let + cfg = config.nvim-flake; +in { + options.vim.keymap = nvim.keymap.mkKeymapOptions; + options.nvim-flake.keymapActions = mkOption { + type = types.attrsOf types.anything; + default = {}; + }; + options.nvim-flake.keymappings = mkOption { + type = types.attrsOf types.anything; + default = {}; + }; + + config = let + actions = + cfg.keymapActions + // { + executeViml = viml: lib.nvim.keymap.mkVimAction viml; + }; + keymap = config.vim.keymap; + + keymapping = groupBy (atom: atom.type) ( + flatten ( + mapAttrsToList ( + mode: mappingsInMode: + mapAttrsToList (binding: action: { + inherit mode; + inherit binding; + inherit (action) action type; + }) + (mappingsInMode actions) + ) + keymap + ) + ); + in { + vim.nnoremap = let nmappings = nvim.keymap.buildKeymap keymap.normal actions; in traceSeq nmappings nmappings; + vim.vnoremap = nvim.keymap.buildKeymap keymap.visual actions; + vim.snoremap = nvim.keymap.buildKeymap keymap.select actions; + vim.inoremap = nvim.keymap.buildKeymap keymap.insert actions; + vim.cnoremap = nvim.keymap.buildKeymap keymap.command actions; + vim.tnoremap = nvim.keymap.buildKeymap keymap.terminal actions; + vim.onoremap = nvim.keymap.buildKeymap keymap.operatorPending actions; + + nvim-flake.keymappings = traceSeq {keymapping = keymapping;} keymapping; + }; +} diff --git a/modules/lib/keymap.nix b/modules/lib/keymap.nix index 1788aa6..701b437 100644 --- a/modules/lib/keymap.nix +++ b/modules/lib/keymap.nix @@ -55,4 +55,21 @@ with lib; { }); in lib.mapAttrs (_: v: v.action) (lib.filterAttrs (_: v: v.type == actionType) mapping); + + modeChar = mode: + { + "normal" = "n"; + "insert" = "i"; + "visual" = "v"; + "command" = "c"; + "operatorPending" = "o"; + "terminal" = "t"; + "select" = "s"; + } + .${mode}; + + keymappingsOfType = type: atoms: + if hasAttr type atoms + then getAttr type atoms + else []; } diff --git a/modules/lsp/default.nix b/modules/lsp/default.nix index d77316a..04f86b3 100644 --- a/modules/lsp/default.nix +++ b/modules/lsp/default.nix @@ -47,18 +47,17 @@ in { rename = mkSpecialAction "lua vim.lsp.buf.rename()"; }; + atoms = nvim.keymap.keymappingsOfType "lsp" config.nvim-flake.keymappings; + keymapString = let - makeString = mode: binding: mapping: - "vim.api.nvim_buf_set_keymap(bufnr, '${mode}', '${binding}', '${mapping}', {noremap=true, silent=true})"; - makeStrings = mode: mapping: - (mapAttrsToList (makeString mode) (nvim.keymap.buildKeymapOf "lsp" mapping actions)); + makeString = mode: binding: action: "vim.api.nvim_buf_set_keymap(bufnr, '${nvim.keymap.modeChar mode}', '${binding}', '${action}', {noremap=true, silent=true})"; + # makeStrings = mode: mapping: (mapAttrsToList (makeString mode) (nvim.keymap.buildKeymapOf "lsp" mapping actions)); in strings.concatStringsSep "\n" ( - (makeStrings "n" cfg.keymap.normal) ++ - (makeStrings "i" cfg.keymap.insert) ++ - (makeStrings "v" cfg.keymap.visual) + map (atom: makeString atom.mode atom.binding atom.action) atoms ); + #defaultKeymap = '' # local opts = { noremap=true, silent=true } diff --git a/modules/modules.nix b/modules/modules.nix index 12a3ef5..01e6cd6 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -21,6 +21,7 @@ ./telescope ./git ./build + ./keymap.nix ]; pkgsModule = {config, ...}: { diff --git a/modules/tabline/nvim-bufferline.nix b/modules/tabline/nvim-bufferline.nix index 6cc57c9..f157339 100644 --- a/modules/tabline/nvim-bufferline.nix +++ b/modules/tabline/nvim-bufferline.nix @@ -10,8 +10,6 @@ with builtins; let in { options.vim.tabline.nvimBufferline = { enable = mkEnableOption "nvim-bufferline-lua"; - - keymap = nvim.keymap.mkKeymapOptions; }; config = mkIf cfg.enable ( @@ -37,15 +35,13 @@ in { ''; }; in { + nvim-flake.keymapActions = {nvimBufferline = actions;}; + vim.startPlugins = [ (assert config.vim.visuals.nvimWebDevicons.enable == true; "nvim-bufferline-lua") "bufdelete-nvim" ]; - vim.nnoremap = nvim.keymap.buildKeymap (cfg.keymap.normal) actions; - vim.inoremap = nvim.keymap.buildKeymap (cfg.keymap.insert) actions; - vim.vnoremap = nvim.keymap.buildKeymap (cfg.keymap.visual) actions; - #vim.nnoremap = { # "bn" = ":BufferLineCycleNext"; # "bp" = ":BufferLineCyclePrev"; diff --git a/modules/telescope/default.nix b/modules/telescope/default.nix index 0741bb7..2ffda3b 100644 --- a/modules/telescope/default.nix +++ b/modules/telescope/default.nix @@ -10,8 +10,6 @@ with builtins; let in { options.vim.telescope = { enable = mkEnableOption "enable telescope"; - - keymap = nvim.keymap.mkKeymapOptions; }; config = let @@ -52,14 +50,12 @@ in { ); in mkIf (cfg.enable) { + nvim-flake.keymapActions = {telescope = actions;}; + vim.startPlugins = [ "telescope" ]; - vim.nnoremap = nvim.keymap.buildKeymap cfg.keymap.normal actions; - vim.vnoremap = nvim.keymap.buildKeymap cfg.keymap.visual actions; - vim.inoremap = nvim.keymap.buildKeymap cfg.keymap.insert actions; - #vim.nnoremap = # { # "ff" = " Telescope find_files"; From 413d61e9a17199d317958b1084d92bf4c46996d8 Mon Sep 17 00:00:00 2001 From: Mona Mayrhofer Date: Tue, 25 Apr 2023 13:59:58 +0200 Subject: [PATCH 6/8] debug outputs and tweaks --- modules/filetree/nvimtreelua.nix | 92 ++++++++++++++++---------------- modules/lsp/default.nix | 5 +- 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/modules/filetree/nvimtreelua.nix b/modules/filetree/nvimtreelua.nix index 26be10b..6948c85 100644 --- a/modules/filetree/nvimtreelua.nix +++ b/modules/filetree/nvimtreelua.nix @@ -134,58 +134,58 @@ in { config = let actions = with nvim.keymap; { - toggle = mkVimAction ":NvimTreeToggle"; refresh = mkVimAction ":NvimTreeRefresh"; findFile = mkVimAction ":NvimTreeFindFile"; + findFileToggle = mkVimAction ":NvimTreeFindFileToggle"; focus = mkVimAction ":NvimTreeFocus"; }; - in mkIf cfg.enable { - nvim-flake.keymapActions = {nvimTreeLua = actions;}; - vim.startPlugins = ["nvim-tree-lua"]; - - - vim.luaConfigRC.nvimtreelua = nvim.dag.entryAnywhere '' - require'nvim-tree'.setup({ - disable_netrw = ${boolToString cfg.disableNetRW}, - hijack_netrw = ${boolToString cfg.hijackNetRW}, - open_on_tab = ${boolToString cfg.openTreeOnNewTab}, - open_on_setup = ${boolToString cfg.openOnSetup}, - open_on_setup_file = ${boolToString cfg.openOnSetup}, - system_open = { - cmd = ${"'" + cfg.systemOpenCmd + "'"}, - }, - diagnostics = { - enable = ${boolToString cfg.lspDiagnostics}, - }, - view = { - width = ${toString cfg.treeWidth}, - side = ${"'" + cfg.treeSide + "'"}, - }, - renderer = { - indent_markers = { - enable = ${boolToString cfg.indentMarkers}, + in + mkIf cfg.enable { + nvim-flake.keymapActions = {nvimTreeLua = actions;}; + vim.startPlugins = ["nvim-tree-lua"]; + + vim.luaConfigRC.nvimtreelua = nvim.dag.entryAnywhere '' + require'nvim-tree'.setup({ + disable_netrw = ${boolToString cfg.disableNetRW}, + hijack_netrw = ${boolToString cfg.hijackNetRW}, + open_on_tab = ${boolToString cfg.openTreeOnNewTab}, + open_on_setup = ${boolToString cfg.openOnSetup}, + open_on_setup_file = ${boolToString cfg.openOnSetup}, + system_open = { + cmd = ${"'" + cfg.systemOpenCmd + "'"}, }, - add_trailing = ${boolToString cfg.trailingSlash}, - group_empty = ${boolToString cfg.groupEmptyFolders}, - }, - actions = { - open_file = { - quit_on_open = ${boolToString cfg.closeOnFileOpen}, - resize_window = ${boolToString cfg.resizeOnFileOpen}, + diagnostics = { + enable = ${boolToString cfg.lspDiagnostics}, }, - }, - git = { - enable = true, - ignore = ${boolToString cfg.hideIgnoredGitFiles}, - }, - filters = { - dotfiles = ${boolToString cfg.hideDotFiles}, - custom = { - ${builtins.concatStringsSep "\n" (builtins.map (s: "\"" + s + "\",") cfg.hideFiles)} + view = { + width = ${toString cfg.treeWidth}, + side = ${"'" + cfg.treeSide + "'"}, }, - }, - }) - ''; - }; + renderer = { + indent_markers = { + enable = ${boolToString cfg.indentMarkers}, + }, + add_trailing = ${boolToString cfg.trailingSlash}, + group_empty = ${boolToString cfg.groupEmptyFolders}, + }, + actions = { + open_file = { + quit_on_open = ${boolToString cfg.closeOnFileOpen}, + resize_window = ${boolToString cfg.resizeOnFileOpen}, + }, + }, + git = { + enable = true, + ignore = ${boolToString cfg.hideIgnoredGitFiles}, + }, + filters = { + dotfiles = ${boolToString cfg.hideDotFiles}, + custom = { + ${builtins.concatStringsSep "\n" (builtins.map (s: "\"" + s + "\",") cfg.hideFiles)} + }, + }, + }) + ''; + }; } diff --git a/modules/lsp/default.nix b/modules/lsp/default.nix index 04f86b3..7527dc4 100644 --- a/modules/lsp/default.nix +++ b/modules/lsp/default.nix @@ -42,6 +42,7 @@ in { removeWorkspaceFolder = mkSpecialAction "lua vim.lsp.buf.remove_workspace_folder()"; listWorkspaceFolder = mkSpecialAction "lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))"; + codeAction = mkSpecialAction "lua vim.lsp.buf.code_action()"; hover = mkSpecialAction "lua vim.lsp.buf.hover()"; signatureHelp = mkSpecialAction "lua vim.lsp.buf.signature_help()"; rename = mkSpecialAction "lua vim.lsp.buf.rename()"; @@ -77,6 +78,7 @@ in { #''; in mkIf cfg.enable { + nvim-flake.keymapActions = {lsp = actions;}; vim.startPlugins = optional usingNvimCmp "cmp-nvim-lsp"; vim.autocomplete.sources = {"nvim_lsp" = "[LSP]";}; @@ -85,7 +87,8 @@ in { vim.g.formatsave = ${boolToString cfg.formatOnSave}; local attach_keymaps = function(client, bufnr) - ${traceVal keymapString} + + ${traceSeq {inherit keymapString;} keymapString} end -- Enable formatting From c4b260baa25d42a3a715cd5396a534818edfa12b Mon Sep 17 00:00:00 2001 From: Mona Mayrhofer Date: Tue, 2 May 2023 11:27:17 +0200 Subject: [PATCH 7/8] Keymap: Add Actions for Trouble.nvim --- modules/lsp/trouble.nix | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/modules/lsp/trouble.nix b/modules/lsp/trouble.nix index a96ce5d..8c20eae 100644 --- a/modules/lsp/trouble.nix +++ b/modules/lsp/trouble.nix @@ -15,17 +15,19 @@ in { }; config = mkIf (cfg.enable && cfg.trouble.enable) { - vim.startPlugins = ["trouble"]; - - vim.nnoremap = { - "xx" = "TroubleToggle"; - "lwd" = "TroubleToggle workspace_diagnostics"; - "ld" = "TroubleToggle document_diagnostics"; - "lr" = "TroubleToggle lsp_references"; - "xq" = "TroubleToggle quickfix"; - "xl" = "TroubleToggle loclist"; + nvim-flake.keymapActions = with nvim.keymap; { + trouble = { + toggle = mkVimAction "TroubleToggle"; + workspaceDiagnostics = mkVimAction "TroubleToggle workspace_diagnostics"; + documentDiagnostics = mkVimAction "TroubleToggle document_diagnostics"; + lspReferences = mkVimAction "TroubleToggle lsp_references"; + quickfix = mkVimAction "TroubleToggle quickfix"; + loclist = mkVimAction "TroubleToggle loclist"; + }; }; + vim.startPlugins = ["trouble"]; + vim.luaConfigRC.trouble = nvim.dag.entryAnywhere '' -- Enable trouble diagnostics viewer require("trouble").setup {} From 851d2ad23c9ccfa4b3b4bf3d8758298c63123eed Mon Sep 17 00:00:00 2001 From: Mona Mayrhofer Date: Thu, 10 Aug 2023 12:27:38 +0200 Subject: [PATCH 8/8] Keymap: fix nvimtreelua after update to main branch --- modules/filetree/nvimtreelua.nix | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/filetree/nvimtreelua.nix b/modules/filetree/nvimtreelua.nix index 2e783f4..a915915 100644 --- a/modules/filetree/nvimtreelua.nix +++ b/modules/filetree/nvimtreelua.nix @@ -149,9 +149,6 @@ in { require'nvim-tree'.setup({ disable_netrw = ${boolToString cfg.disableNetRW}, hijack_netrw = ${boolToString cfg.hijackNetRW}, - open_on_tab = ${boolToString cfg.openTreeOnNewTab}, - open_on_setup = ${boolToString cfg.openOnSetup}, - open_on_setup_file = ${boolToString cfg.openOnSetup}, system_open = { cmd = ${"'" + cfg.systemOpenCmd + "'"}, },