summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid T. Sadler <davidtsadler@googlemail.com>2026-02-10 21:12:45 +0000
committerDavid T. Sadler <davidtsadler@googlemail.com>2026-02-10 21:12:45 +0000
commitaabcc30883850faec416aa84f7706ddad1795805 (patch)
treeef5746767def3dc52153ea00ff7be6f2e878c06a
parentfd69d280737b2e41ac8d1dd440c98730e4004927 (diff)
Update Neovim key mappings
-rw-r--r--nvim/.config/nvim/lua/config/keymaps.lua157
1 files changed, 113 insertions, 44 deletions
diff --git a/nvim/.config/nvim/lua/config/keymaps.lua b/nvim/.config/nvim/lua/config/keymaps.lua
index bb3758f..8e7dc0a 100644
--- a/nvim/.config/nvim/lua/config/keymaps.lua
+++ b/nvim/.config/nvim/lua/config/keymaps.lua
@@ -2,47 +2,116 @@
local set = vim.keymap.set
--- Move lines up/down
-set('n', '<C-j>', ':m .+1<CR>==', { desc = 'Move line down' })
-set('n', '<C-k>', ':m .-2<CR>==', { desc = 'Move line up' })
-set('i', '<C-j>', '<Esc>:m .+1<CR>==gi', { desc = 'Move line down' })
-set('i', '<A-k>', '<Esc>:m .-2<CR>==gi', { desc = 'Move line up' })
-set('v', '<C-j>', ":m '>+1<CR>gv=gv", { desc = 'Move selection down' })
-set('v', '<C-k>', ":m '<-2<CR>gv=gv", { desc = 'Move selection up' })
-
--- Better indenting in visual mode
-set('v', '<', '<gv', { desc = 'Indent left and reselect' })
-set('v', '>', '>gv', { desc = 'Indent right and reselect' })
-
--- Buffer navigation
-set('n', '<leader>bn', ':bnext<CR>', { desc = 'Next buffer' })
-set('n', '<leader>bp', ':bprevious<CR>', { desc = 'Previous buffer' })
-
--- Splitting & Resizing
-set('n', '<leader>sv', ':vsplit<CR>', { desc = 'Split window vertically' })
-set('n', '<leader>sh', ':split<CR>', { desc = 'Split window horizontally' })
-set('n', '<leader>se', '<C-w>=', { desc = 'Make split windows equal width & height' })
-set('n', '<C-Up>', ':resize +2<CR>', { desc = 'Increase window height' })
-set('n', '<C-Down>', ':resize -2<CR>', { desc = 'Decrease window height' })
-set('n', '<C-Left>', ':vertical resize -2<CR>', { desc = 'Decrease window width' })
-set('n', '<C-Right>', ':vertical resize +2<CR>', { desc = 'Increase window width' })
-
--- Center screen when jumping
-set('n', 'n', 'nzzzv', { desc = 'Next search result (centered)' })
-set('n', 'N', 'Nzzzv', { desc = 'Previous search result (centered)' })
-set('n', '<C-d>', '<C-d>zz', { desc = 'Half page down (centered)' })
-set('n', '<C-u>', '<C-u>zz', { desc = 'Half page up (centered)' })
-
--- Better paste behavior
-set('x', '<leader>p', '"_dP', { desc = 'Paste without yanking' })
-
--- Delete without yanking
-set({ 'n', 'v' }, '<leader>d', '"_d', { desc = 'Delete without yanking' })
-
--- Toggle visible whitespace characters
-set('n', '<leader>l', ':set list!<CR>', { desc = 'Toggle hidden characters' })
-
--- Quickly source current file / execute Lua code
-set('n', '<leader>xx', '<Cmd>source %<CR>', { desc = 'Source current file' })
-set('n', '<leader>x', '<Cmd>:.lua<CR>', { desc = 'Lua: execute current line' })
-set('v', '<leader>x', '<Cmd>:lua<CR>', { desc = 'Lua: execute current selection' })
+-- Better up/down though display lines instead of logical lines.
+-- But still allow count when jumping by logical lines.
+set({ 'n', 'x' }, 'j', "v:count == 0 ? 'gj' : 'j'", { desc = 'Down', expr = true, silent = true })
+set({ 'n', 'x' }, '<Down>', "v:count == 0 ? 'gj' : 'j'", { desc = 'Down', expr = true, silent = true })
+set({ 'n', 'x' }, 'k', "v:count == 0 ? 'gk' : 'k'", { desc = 'Up', expr = true, silent = true })
+set({ 'n', 'x' }, '<Up>', "v:count == 0 ? 'gk' : 'k'", { desc = 'Up', expr = true, silent = true })
+
+-- Window using <ctrl> arrow keys.
+set('n', '<C-Up>', '<cmd>resize +2<cr>', { desc = 'Increase Window Height' })
+set('n', '<C-Down>', '<cmd>resize -2<cr>', { desc = 'Decrease Window Height' })
+set('n', '<C-Left>', '<cmd>vertical resize -2<cr>', { desc = 'Decrease Window Width' })
+set('n', '<C-Right>', '<cmd>vertical resize +2<cr>', { desc = 'Increase Window Width' })
+
+-- Move lines up/down.
+set('n', '<C-j>', "<cmd>execute 'move .+' . v:count1<cr>==", { desc = 'Move Down' })
+set('n', '<C-k>', "<cmd>execute 'move .-' . (v:count1 + 1)<cr>==", { desc = 'Move Up' })
+set('i', '<C-j>', '<esc><cmd>m .+1<cr>==gi', { desc = 'Move Down' })
+set('i', '<C-k>', '<esc><cmd>m .-2<cr>==gi', { desc = 'Move Up' })
+set('v', '<C-j>', ":<C-u>execute \"'<,'>move '>+\" . v:count1<cr>gv=gv", { desc = 'Move Down' })
+set('v', '<C-k>', ":<C-u>execute \"'<,'>move '<-\" . (v:count1 + 1)<cr>gv=gv", { desc = 'Move Up' })
+
+-- Buffer navigation.
+set('n', '<S-h>', '<cmd>bprevious<cr>', { desc = 'Prev Buffer' })
+set('n', '<S-l>', '<cmd>bnext<cr>', { desc = 'Next Buffer' })
+set('n', '[b', '<cmd>bprevious<cr>', { desc = 'Prev Buffer' })
+set('n', ']b', '<cmd>bnext<cr>', { desc = 'Next Buffer' })
+set('n', '<leader>bb', '<cmd>e #<cr>', { desc = 'Switch to Other Buffer' })
+set('n', '<leader>`', '<cmd>e #<cr>', { desc = 'Switch to Other Buffer' })
+
+-- https://github.com/mhinz/vim-galore#saner-behavior-of-n-and-n
+-- Saner search behavior: n always goes forward, N always goes backward.
+-- Added 'zz' to keep the result centered.
+set('n', 'n', "'Nn'[v:searchforward].'zzzv'", { expr = true, desc = 'Next Search Result' })
+set('x', 'n', "'Nn'[v:searchforward]", { expr = true, desc = 'Next Search Result' })
+set('o', 'n', "'Nn'[v:searchforward]", { expr = true, desc = 'Next Search Result' })
+set('n', 'N', "'nN'[v:searchforward].'zzzv'", { expr = true, desc = 'Prev Search Result' })
+set('x', 'N', "'nN'[v:searchforward]", { expr = true, desc = 'Prev Search Result' })
+set('o', 'N', "'nN'[v:searchforward]", { expr = true, desc = 'Prev Search Result' })
+
+-- Have undo breakpoints set every time a punctuation mark is typed.
+-- Ensures more granular history is preserved during undo.
+set('i', ',', ',<c-g>u', { desc = 'Undo Breakpoint: ,' })
+set('i', '.', '.<c-g>u', { desc = 'Undo Breakpoint: .' })
+set('i', ';', ';<c-g>u', { desc = 'Undo Breakpoint: ;' })
+
+-- Save file with Ctrl+S
+set({ 'i', 'x', 'n', 's' }, '<C-s>', '<cmd>w<cr><esc>', { desc = 'Save File' })
+
+-- Use built-in 'K' to access Linux man pages directly (essential for C/Shell dev).
+set('n', '<leader>K', '<cmd>norm! K<cr>', { desc = 'Lookup System Manual' })
+
+-- Better indenting in visual mode.
+set('v', '<', '<gv', { desc = 'Indent Left And Reselect' })
+set('v', '>', '>gv', { desc = 'Indent Right And Reselect' })
+
+-- Commenting.
+set('n', 'gco', 'o<esc>Vcx<esc><cmd>normal gcc<cr>fxa<bs>', { desc = 'Add Comment Below' })
+set('n', 'gcO', 'O<esc>Vcx<esc><cmd>normal gcc<cr>fxa<bs>', { desc = 'Add Comment Above' })
+
+-- Quickfix list
+set('n', '<leader>xq', function()
+ local success, err = pcall(vim.fn.getqflist({ winid = 0 }).winid ~= 0 and vim.cmd.cclose or vim.cmd.copen)
+ if not success and err then
+ vim.notify(err, vim.log.levels.ERROR)
+ end
+end, { desc = 'Quickfix List' })
+
+set('n', '[q', vim.cmd.cprev, { desc = 'Previous Quickfix' })
+set('n', ']q', vim.cmd.cnext, { desc = 'Next Quickfix' })
+
+-- LSP Diagnostic Navigation.
+local diagnostic_goto = function(next, severity)
+ return function()
+ vim.diagnostic.jump({
+ count = (next and 1 or -1) * vim.v.count1,
+ severity = severity and vim.diagnostic.severity[severity] or nil,
+ float = true,
+ })
+ end
+end
+set('n', '<leader>cd', vim.diagnostic.open_float, { desc = 'Line Diagnostics' })
+set('n', ']d', diagnostic_goto(true), { desc = 'Next Diagnostic' })
+set('n', '[d', diagnostic_goto(false), { desc = 'Prev Diagnostic' })
+set('n', ']e', diagnostic_goto(true, 'ERROR'), { desc = 'Next Error' })
+set('n', '[e', diagnostic_goto(false, 'ERROR'), { desc = 'Prev Error' })
+set('n', ']w', diagnostic_goto(true, 'WARN'), { desc = 'Next Warning' })
+set('n', '[w', diagnostic_goto(false, 'WARN'), { desc = 'Prev Warning' })
+
+-- Highlights under cursor.
+set('n', '<leader>ui', vim.show_pos, { desc = 'Inspect Pos' })
+set('n', '<leader>uI', function() vim.treesitter.inspect_tree() vim.api.nvim_input('I') end, { desc = 'Inspect Tree' })
+
+-- Window Splitting.
+set('n', '<leader>sh', '<C-W>s', { desc = 'Split Window Below' })
+set('n', '<leader>sv', '<C-W>v', { desc = 'Split Window Right' })
+set('n', '<leader>wd', '<C-W>c', { desc = 'Delete Window', remap = true })
+set('n', '<leader>se', '<C-w>=', { desc = 'Make Split Windows Equal Width & Height' })
+
+-- Center screen when jumping.
+set('n', '<C-d>', '<C-d>zz', { desc = 'Half Page down (Centered)' })
+set('n', '<C-u>', '<C-u>zz', { desc = 'Half Page Up (Centered)' })
+
+-- Better paste behavior.
+set('x', '<leader>p', '"_dP', { desc = 'Paste Without Yanking' })
+
+-- Delete without yanking.
+set({ 'n', 'v' }, '<leader>d', '"_d', { desc = 'Delete Without Yanking' })
+
+-- Toggle visible whitespace characters....
+set('n', '<leader>l', '<cmd>set list!<cr>', { desc = 'Toggle Hidden Characters' })
+
+-- Quickly source current file.
+set('n', '<leader>xx', '<cmd>source %<cr>', { desc = 'Source Current File' })