| 1 | # this file implements a keybind system, which is a higher level system |
| 2 | # to configure vim.keymaps (note the different name bind vs map) |
| 3 | { |
| 4 | pkgs, |
| 5 | lib, |
| 6 | config, |
| 7 | ... |
| 8 | }: |
| 9 | let |
| 10 | keyRemap = mode: key: action: { inherit mode key action; }; |
| 11 | keyCmd = |
| 12 | mode: key: cmd: |
| 13 | keyRemap mode key ":${cmd}<Return>"; |
| 14 | in |
| 15 | { |
| 16 | # default binds |
| 17 | config.vim.keybinds = { |
| 18 | search-commands = keyCmd "n" "<leader>?" "FzfLua keymaps"; |
| 19 | |
| 20 | # user interface |
| 21 | toggle-explorer = keyCmd "n" "<leader>e" "Neotree toggle"; |
| 22 | reveal-active-file = keyCmd "n" "<leader>E" "Neotree reveal<CR>:Neotree focus"; |
| 23 | lazygit = keyCmd "n" "<leader>gg" "FullscreenTerm ${pkgs.lazygit}/bin/lazygit"; |
| 24 | smart-quit = keyCmd "n" "<leader>q" "SmartQuit"; |
| 25 | |
| 26 | # pickers |
| 27 | pick-file = keyCmd "n" "<leader><leader>" "FzfLua files"; |
| 28 | pick-buffer = keyCmd "n" "<leader>b" "FzfLua buffers"; |
| 29 | pick-mark = keyCmd "n" "<leader>'" "FzfLua marks"; |
| 30 | pick-recent-command = keyCmd "n" "<leader>fc" "FzfLua command_history"; |
| 31 | pick-other = keyCmd "n" "<leader><tab>" "FzfLua builtin"; # picker of Fzf pickers |
| 32 | find-fuzzy = keyCmd "n" "<leader>ff" "FzfLua grep_project"; |
| 33 | find-grep = keyCmd "n" "<leader>fg" "FzfLua live_grep"; |
| 34 | |
| 35 | # lsp |
| 36 | code-action = |
| 37 | keyCmd "n" "<leader>ca" |
| 38 | "FzfLua lsp_code_actions winopts.height=8 winopts.width=50 winopts.backdrop=100 winopts.title=false winopts.preview.title=false winopts.row=1 winopts.preview.hidden=true silent=true"; |
| 39 | |
| 40 | # subtle nice features |
| 41 | visual-dedent = keyRemap "v" "<" "<gv"; # keep selection |
| 42 | visual-indent = keyRemap "v" ">" ">gv"; # keep selection |
| 43 | visual-overwrite = keyRemap "v" "p" "pgvygv<esc>"; # re-yank text |
| 44 | clear-search-highlights = keyRemap "n" "<esc>" ":noh<Return><esc>"; |
| 45 | }; |
| 46 | |
| 47 | # implementation |
| 48 | options.vim.keybinds = lib.mkOption { |
| 49 | type = lib.types.attrsOf ( |
| 50 | lib.types.nullOr ( |
| 51 | lib.types.submodule { |
| 52 | options = { |
| 53 | mode = lib.mkOption { type = lib.types.str; }; |
| 54 | key = lib.mkOption { type = lib.types.str; }; |
| 55 | action = lib.mkOption { type = lib.types.str; }; |
| 56 | }; |
| 57 | } |
| 58 | ) |
| 59 | ); |
| 60 | default = { }; |
| 61 | }; |
| 62 | config.vim.keymaps = |
| 63 | let |
| 64 | titleCase = |
| 65 | str: |
| 66 | lib.concatStringsSep " " ( |
| 67 | map ( |
| 68 | word: |
| 69 | lib.strings.toUpper (builtins.substring 0 1 word) |
| 70 | + builtins.substring 1 (builtins.stringLength word) word |
| 71 | ) (lib.splitString "-" str) |
| 72 | ); |
| 73 | in |
| 74 | builtins.filter (f: f != null) ( |
| 75 | lib.attrsets.mapAttrsToList ( |
| 76 | desc: bind: |
| 77 | if bind != null then |
| 78 | { |
| 79 | desc = titleCase desc; |
| 80 | inherit (bind) mode key action; |
| 81 | } |
| 82 | else |
| 83 | null |
| 84 | ) config.vim.keybinds |
| 85 | ); |
| 86 | } |