{ config, lib, ... }: { programs.nixvim = { extraConfigLuaPre = '' function bool2str(bool) return bool and "on" or "off" end ''; keymaps = let helpers = config.lib.nixvim; normal = lib.mapAttrsToList ( key: {action, ...} @ attrs: { mode = "n"; inherit action key; options = attrs.options or {}; } ) { "" = { action = ""; }; # Esc to clear search results "" = { action = "noh"; }; # Backspace delete in normal "" = { action = "x"; }; # fix Y behaviour "Y" = { action = "y$"; }; # back and fourth between the two most recent files "" = { action = "b#"; }; # navigate to left/right window "[" = { action = "h"; options = { desc = "Left window"; }; }; "]" = { action = "l"; options = { desc = "Right window"; }; }; "." = { action = "j"; options = { desc = "Up window"; }; }; "," = { action = "k"; options = { desc = "Down window"; }; }; # navigate quickfix list "" = { action = "cnext"; }; "" = { action = "cprev"; }; # resize with arrows "" = { action = "resize -2"; }; "" = { action = "resize +2"; }; "" = { action = "vertical resize +2"; }; "" = { action = "vertical resize -2"; }; # move current line up/down # M = Alt key "" = { action = "move-2"; }; "" = { action = "move+"; }; "w" = { action = "w"; # Action to perform (save the file in this case) options = { desc = "Save"; }; }; "j" = { action = "v:count == 0 ? 'gj' : 'j'"; options = { desc = "Move cursor down"; expr = true; }; }; "k" = { action = "v:count == 0 ? 'gk' : 'k'"; options = { desc = "Move cursor up"; expr = true; }; }; "q" = { action = "confirm q"; options = { desc = "Quit"; }; }; "" = { action = "enew"; options = { desc = "New file"; }; }; "W" = { action = "w!"; options = { desc = "Force write"; }; }; "Q" = { action = "q!"; options = { desc = "Force quit"; }; }; "|" = { action = "vsplit"; options = { desc = "Vertical split"; }; }; "\\" = { action = "split"; options = { desc = "Horizontal split"; }; }; "bC" = { action = "%bd!"; options = { desc = "Close all buffers"; }; }; "b]" = { action = "bnext"; options = { desc = "Next buffer"; }; }; "" = { action = "bnext"; options = { desc = "Next buffer (default)"; }; }; "b[" = { action = "bprevious"; options = { desc = "Previous buffer"; }; }; "" = { action = "bprevious"; options = { desc = "Previous buffer"; }; }; "ud" = { action.__raw = '' function () vim.b.disable_diagnostics = not vim.b.disable_diagnostics if vim.b.disable_diagnostics then vim.diagnostic.disable(0) else vim.diagnostic.enable(0) end vim.notify(string.format("Buffer Diagnostics %s", bool2str(not vim.b.disable_diagnostics), "info")) end''; options = { desc = "Buffer Diagnostics toggle"; }; }; "uD" = { action.__raw = '' function () vim.g.disable_diagnostics = not vim.g.disable_diagnostics if vim.g.disable_diagnostics then vim.diagnostic.disable() else vim.diagnostic.enable() end vim.notify(string.format("Global Diagnostics %s", bool2str(not vim.g.disable_diagnostics), "info")) end''; options = { desc = "Global Diagnostics toggle"; }; }; "uf" = { action.__raw = '' function () -- vim.g.disable_autoformat = not vim.g.disable_autoformat vim.cmd('FormatToggle!') vim.notify(string.format("Buffer Autoformatting %s", bool2str(not vim.b[0].disable_autoformat), "info")) end''; options = { desc = "Buffer Autoformatting toggle"; }; }; "uF" = { action.__raw = '' function () -- vim.g.disable_autoformat = not vim.g.disable_autoformat vim.cmd('FormatToggle') vim.notify(string.format("Global Autoformatting %s", bool2str(not vim.g.disable_autoformat), "info")) end''; options = { desc = "Global Autoformatting toggle"; }; }; "uS" = { action.__raw = '' function () if vim.g.spell_enabled then vim.cmd('setlocal nospell') end if not vim.g.spell_enabled then vim.cmd('setlocal spell') end vim.g.spell_enabled = not vim.g.spell_enabled vim.notify(string.format("Spell %s", bool2str(vim.g.spell_enabled), "info")) end''; options = { desc = "Spell toggle"; }; }; "uw" = { action.__raw = '' function () vim.wo.wrap = not vim.wo.wrap vim.notify(string.format("Wrap %s", bool2str(vim.wo.wrap), "info")) end''; options = { desc = "Word Wrap toggle"; }; }; "uh" = { action.__raw = '' function () local curr_foldcolumn = vim.wo.foldcolumn if curr_foldcolumn ~= "0" then vim.g.last_active_foldcolumn = curr_foldcolumn end vim.wo.foldcolumn = curr_foldcolumn == "0" and (vim.g.last_active_foldcolumn or "1") or "0" vim.notify(string.format("Fold Column %s", bool2str(vim.wo.foldcolumn), "info")) end''; options = { desc = "Fold Column toggle"; }; }; "uc" = { action.__raw = '' function () vim.g.cmp_enabled = not vim.g.cmp_enabled vim.notify(string.format("Completions %s", bool2str(vim.g.cmp_enabled), "info")) end''; options = { desc = "Completions toggle"; }; }; }; visual = lib.mapAttrsToList ( key: {action, ...} @ attrs: { mode = "v"; inherit action key; options = attrs.options or {}; } ) { # Better indenting "" = { action = "" = { action = ">gv"; options = { desc = "Indent line"; }; }; ">" = { action = ">gv"; options = { desc = "Indent line"; }; }; # Move selected line/block in visual mode "K" = { action = "m '<-2gv=gv"; }; "J" = { action = "m '>+1gv=gv"; }; # Backspace delete in visual "" = { action = "x"; }; }; insert = lib.mapAttrsToList ( key: {action, ...} @ attrs: { mode = "i"; inherit action key; options = attrs.options or {}; } ) { # Move selected line/block in insert mode "" = { action = "gk"; }; "" = { action = ""; }; "" = { action = ""; }; "" = { action = "gj"; }; }; in helpers.keymaps.mkKeymaps {options.silent = true;} (normal ++ visual ++ insert); plugins.which-key.settings.spec = [ { __unkeyed = "w"; icon = ""; } { __unkeyed = "W"; icon = "󰽃"; } { __unkeyed = "/"; icon = ""; } ]; }; }