nvim/lua/config/mappings.lua
Jeremie Fraeys e8979088e6
refactor: reorganize keymaps and autocommands
- Restructure mappings.lua for better organization
- Refactor autocmds.lua with improved event handling
2026-03-23 20:32:36 -04:00

148 lines
6.9 KiB
Lua
Executable file

local utils = require('config.utils')
local builtin = require('telescope.builtin')
-------------------------------------------------------------------------------
-- Leader / mode escapes
-------------------------------------------------------------------------------
vim.keymap.set({ 'n', 'v' }, '<Space>', '<Nop>', { silent = true })
vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>', { silent = true })
vim.keymap.set('n', '<C-c>', '<Esc>', { silent = true })
-- Disable gp (avoid accidental paste-over in visual)
vim.keymap.set('n', 'gp', '<Nop>', { silent = true })
-------------------------------------------------------------------------------
-- Motion / view
-------------------------------------------------------------------------------
-- Respect wrapped lines for j/k
vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
vim.keymap.set('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
-- Keep cursor centred when scrolling / searching
vim.keymap.set('n', '<C-d>', '<C-d>zz', { desc = 'Half page down (centred)' })
vim.keymap.set('n', '<C-u>', '<C-u>zz', { desc = 'Half page up (centred)' })
vim.keymap.set('n', 'n', 'nzzzv', { desc = 'Next match (centred)' })
vim.keymap.set('n', 'N', 'Nzzzv', { desc = 'Prev match (centred)' })
-------------------------------------------------------------------------------
-- Window / split navigation
-------------------------------------------------------------------------------
vim.keymap.set('n', '<C-h>', '<C-w>h', { desc = 'Focus left split' })
vim.keymap.set('n', '<C-j>', '<C-w>j', { desc = 'Focus split below' })
vim.keymap.set('n', '<C-k>', '<C-w>k', { desc = 'Focus split above' })
vim.keymap.set('n', '<C-l>', '<C-w>l', { desc = 'Focus right split' })
-------------------------------------------------------------------------------
-- Quickfix list (project-wide: LSP refs, grep, diagnostics)
-------------------------------------------------------------------------------
vim.keymap.set('n', ']q', '<cmd>cnext<CR>zz', { desc = 'Quickfix next' })
vim.keymap.set('n', '[q', '<cmd>cprev<CR>zz', { desc = 'Quickfix prev' })
vim.keymap.set('n', ']Q', '<cmd>clast<CR>zz', { desc = 'Quickfix last' })
vim.keymap.set('n', '[Q', '<cmd>cfirst<CR>zz', { desc = 'Quickfix first' })
-- Location list (buffer-local: spell, some linters)
vim.keymap.set('n', ']l', '<cmd>lnext<CR>zz', { desc = 'Loclist next' })
vim.keymap.set('n', '[l', '<cmd>lprev<CR>zz', { desc = 'Loclist prev' })
-------------------------------------------------------------------------------
-- Buffer navigation
-------------------------------------------------------------------------------
vim.keymap.set('n', '<C-^>', '<cmd>e #<CR>', { desc = 'Alternate buffer (toggle last two)' })
vim.keymap.set('n', '<leader>bn', '<cmd>bnext<CR>', { desc = 'Buffer next' })
vim.keymap.set('n', '<leader>bp', '<cmd>bprev<CR>', { desc = 'Buffer prev' })
vim.keymap.set('n', '<leader>bd', '<cmd>bdelete<CR>', { desc = 'Buffer delete' })
vim.keymap.set('n', '<leader>bs', '<cmd>split<CR>', { desc = 'Buffer horizontal split' })
vim.keymap.set('n', '<leader>bv', '<cmd>vsplit<CR>', { desc = 'Buffer vertical split' })
-------------------------------------------------------------------------------
-- Editing
-------------------------------------------------------------------------------
-- Move selected lines up/down and reindent
vim.keymap.set('v', 'J', ":m '>+1<CR>gv=gv", { silent = true, desc = 'Move selection down' })
vim.keymap.set('v', 'K', ":m '<-2<CR>gv=gv", { silent = true, desc = 'Move selection up' })
-- Indent and keep visual selection
vim.keymap.set('v', '>', '>gv', { desc = 'Indent and reselect' })
vim.keymap.set('v', '<', '<gv', { desc = 'Dedent and reselect' })
-- Clipboard
vim.keymap.set('x', '<leader>p', '"_dP', { desc = 'Paste without overwriting register' })
vim.keymap.set({ 'n', 'v' }, '<leader>D', '"_d', { desc = 'Delete without register' })
vim.keymap.set({ 'n', 'v' }, '<leader>y', '"+y', { desc = 'Yank to system clipboard' })
vim.keymap.set('n', '<leader>Y', '"+Y', { desc = 'Yank line to system clipboard' })
-- Project-wide word rename
vim.keymap.set(
'n',
'<leader>rw',
':%s/\\<<C-r><C-w>\\>/<C-r><C-w>/gI<Left><Left><Left>',
{ desc = 'Rename word under cursor (file scope)' }
)
-------------------------------------------------------------------------------
-- File / system
-------------------------------------------------------------------------------
vim.keymap.set(
'n',
'<C-t>',
'<cmd>silent !wezterm cli spawn --cwd %:p:h<CR>',
{ desc = 'Open WezTerm tab in current dir' }
)
vim.keymap.set('n', '<leader>fx', '<cmd>!chmod +x %<CR>', { silent = true, desc = 'Make current file executable' })
-------------------------------------------------------------------------------
-- Telescope
-------------------------------------------------------------------------------
vim.keymap.set('n', '<leader>?', builtin.oldfiles, { desc = 'Recent files' })
vim.keymap.set('n', '<leader><space>', builtin.buffers, { desc = 'Open buffers' })
vim.keymap.set('n', '<leader>sr', builtin.resume, { desc = 'Search: resume last' })
vim.keymap.set('n', '<leader>sd', builtin.diagnostics, { desc = 'Search: diagnostics' })
vim.keymap.set('n', '<leader>sG', builtin.live_grep, { desc = 'Search: live grep' })
vim.keymap.set('n', '<leader>sg', '<cmd>LiveGrepGitRoot<CR>', { desc = 'Search: live grep (git root)' })
vim.keymap.set('n', '<leader>/', function()
builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown({ winblend = 10, previewer = false }))
end, { desc = 'Search: fuzzy current buffer' })
vim.keymap.set('n', '<leader>sf', builtin.find_files, { desc = 'Search: files' })
vim.keymap.set('n', '<leader>gf', builtin.git_files, { desc = 'Search: git files' })
vim.keymap.set('n', '<leader>gb', builtin.git_branches, { desc = 'Search: git branches' })
vim.keymap.set('n', '<leader>gc', builtin.git_commits, { desc = 'Search: git commits' })
vim.keymap.set({ 'n', 'v' }, '<leader>sh', function()
local q = utils.get_search_query()
builtin.help_tags({ default_text = q, initial_mode = 'insert' })
end, { desc = 'Search: help tags' })
vim.keymap.set({ 'n', 'v' }, '<leader>sw', function()
local q = utils.get_search_query()
builtin.grep_string({ default_text = q, initial_mode = 'insert' })
end, { desc = 'Search: word under cursor' })
vim.keymap.set('n', '<leader>sp', function()
builtin.grep_string({ search = vim.fn.input('Grep > ') })
end, { desc = 'Search: grep prompt' })
-- Config / plugin file pickers
vim.keymap.set('n', '<leader>fc', function()
builtin.find_files({
cwd = vim.fn.stdpath('config'),
find_command = {
'fd',
'--type',
'f',
'--exclude',
'README.md',
'--exclude',
'LICENSE.md',
'--exclude',
'init.lua',
},
})
end, { desc = 'Find: config files' })
vim.keymap.set('n', '<leader>fp', function()
builtin.find_files({ cwd = vim.fs.joinpath(vim.fn.stdpath('data'), 'lazy') })
end, { desc = 'Find: plugin files' })