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}:
9let
10 keyRemap = mode: key: action: { inherit mode key action; };
11 keyCmd =
12 mode: key: cmd:
13 keyRemap mode key ":${cmd}<Return>";
14in
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}