2025-04-12 23:49:02 +01:00
-- [[ Basic Keymaps ]]
-- See `:help vim.keymap.set()`
-- Swap : and ; around
2025-04-13 22:53:08 +01:00
vim.keymap . set ( { ' n ' , ' v ' } , ' : ' , ' ; ' )
vim.keymap . set ( { ' n ' , ' v ' } , ' ; ' , ' : ' )
2025-04-12 23:49:02 +01:00
-- Clear highlights on search when pressing <Esc> in normal mode
-- See `:help hlsearch`
vim.keymap . set ( ' n ' , ' <Esc> ' , ' <cmd>nohlsearch<CR> ' )
-- Diagnostic keymaps
vim.keymap . set ( ' n ' , ' <leader>q ' , vim.diagnostic . setloclist , { desc = ' Open diagnostic [Q]uickfix list ' } )
-- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier
-- for people to discover. Otherwise, you normally need to press <C-\><C-n>, which
-- is not what someone will guess without a bit more experience.
--
-- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping
-- or just use <C-\><C-n> to exit terminal mode
vim.keymap . set ( ' t ' , ' <Esc><Esc> ' , ' <C- \\ ><C-n> ' , { desc = ' Exit terminal mode ' } )
-- Keybinds to make split navigation easier.
-- Use CTRL+<hjkl> to switch between windows
--
-- See `:help wincmd` for a list of all window commands
vim.keymap . set ( ' n ' , ' <C-h> ' , ' <C-w><C-h> ' , { desc = ' Move focus to the left window ' } )
vim.keymap . set ( ' n ' , ' <C-l> ' , ' <C-w><C-l> ' , { desc = ' Move focus to the right window ' } )
vim.keymap . set ( ' n ' , ' <C-j> ' , ' <C-w><C-j> ' , { desc = ' Move focus to the lower window ' } )
vim.keymap . set ( ' n ' , ' <C-k> ' , ' <C-w><C-k> ' , { desc = ' Move focus to the upper window ' } )
vim.keymap . set ( ' n ' , ' <C-S-h> ' , ' <C-w>H ' , { desc = ' Move window to the left ' } )
vim.keymap . set ( ' n ' , ' <C-S-l> ' , ' <C-w>L ' , { desc = ' Move window to the right ' } )
vim.keymap . set ( ' n ' , ' <C-S-j> ' , ' <C-w>J ' , { desc = ' Move window to the lower ' } )
vim.keymap . set ( ' n ' , ' <C-S-k> ' , ' <C-w>K ' , { desc = ' Move window to the upper ' } )
2025-04-13 22:53:08 +01:00
-- Overriding CTRL mappings because some of them are stupid
2025-04-14 11:38:42 +01:00
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-S-B> ' , ' <CMD>Git blame<CR> ' , { desc = ' Git blame ' } )
2025-04-13 22:53:08 +01:00
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-Q> ' , ' <CMD>Telescope lsp_document_symbols<CR> ' , { desc = ' Show symbols in current document ' } )
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-S-Q> ' , ' <CMD>Telescope lsp_workspace_symbols<CR> ' , { desc = ' Show symbols in workspace ' } )
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-E> ' , ' <CMD>Telescope oldfiles<CR> ' , { desc = ' Show recently opened files ' } )
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-P> ' , function ( )
2025-04-15 20:48:35 +01:00
require ( ' telescope.builtin ' ) . find_files {
show_untracked = true ,
no_ignore = false ,
hidden = true ,
}
2025-04-14 15:20:54 +01:00
end , { desc = ' Find all files ' } )
2025-04-13 22:53:08 +01:00
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-S-P> ' , function ( )
require ( ' telescope.builtin ' ) . find_files {
2025-04-14 15:20:54 +01:00
show_untracked = true ,
2025-04-13 22:53:08 +01:00
no_ignore = true ,
hidden = true ,
}
end , { desc = ' Find all files ' } )
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-F> ' , function ( )
require ( ' telescope.builtin ' ) . live_grep {
hidden = true ,
}
end , { desc = ' Search within the whole project ' } )
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-Y> ' , ' <CMD>Telescope quickfix<CR> ' , { desc = ' Show quickfix list ' } )
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-S-Y> ' , ' <CMD>Telescope quickfixhistory<CR> ' , { desc = ' Show quickfix history ' } )
2025-04-14 11:38:42 +01:00
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-A> ' , ' <CMD>CodeCompanionChat Toggle<CR> ' , { desc = ' Open AI Actions ' } )
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-S-A> ' , ' <CMD>CodeCompanionActions<CR> ' , { desc = ' Open AI Actions ' } )
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-S> ' , function ( )
require ( ' snacks ' ) . scratch ( )
end , { desc = ' Open scratchpad ' } )
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-S-S> ' , function ( )
require ( ' snacks ' ) . scratch.select ( )
end , { desc = ' Open scratchpad buffers ' } )
vim.keymap . set ( { ' n ' , ' v ' , ' c ' , ' i ' } , ' <C-T> ' , function ( )
require ( ' snacks ' ) . terminal.toggle ( )
end , { desc = ' Open terminal ' } )
2025-04-13 22:53:08 +01:00
-- Editing helpers
vim.keymap . set ( ' i ' , ' <C-O> ' , ' <Esc>o ' , { desc = ' Add line below ' } )
vim.keymap . set ( ' i ' , ' <C-S-O> ' , ' <Esc>O ' , { desc = ' Add line above ' } )
2025-04-17 08:53:20 +01:00
local esc_keys = { ' jj ' , ' jk ' , ' kk ' }
for _ , key in ipairs ( esc_keys ) do
vim.keymap . set ( ' i ' , key , ' <Esc> ' , { desc = ' Exit insert mode ' } )
end
2025-04-13 22:53:08 +01:00
vim.keymap . set ( ' i ' , ' <C-D> ' , ' <Esc>ddi ' , { desc = ' Delete line ' } )
vim.keymap . set ( ' i ' , ' <Leader>; ' , ' <Esc>mzA;<Esc>`za ' , { desc = ' Append a semicolon ' } )
vim.keymap . set ( ' n ' , ' <Leader>; ' , ' mzA;<Esc>`za ' , { desc = ' Append a semicolon ' } )
vim.keymap . set ( ' n ' , ' <Leader>{ ' , ' mzF[`a<CR><Esc>``%i<CR><Esc>`z ' , { desc = ' Indent an array ' } )
vim.keymap . set ( ' n ' , ' <Leader>} ' , ' mzF[`a<CR><Esc>``%i<CR><Esc>`zvi[:s/, \\ s*/, \\ r/g<CR>vi[=<Esc>`z:nohlsearch<CR> ' , { desc = ' Indent an array some other way? ' } )
-- Git mappings
vim.keymap . set ( ' n ' , ' <Leader>gaf ' , ' <CMD>Git add %<CR> ' , { desc = ' Git add current file ' } )
vim.keymap . set ( ' n ' , ' <Leader>gaa ' , ' <CMD>Git add --all<CR> ' , { desc = ' Git add all unstaged changes ' } )
vim.keymap . set ( ' n ' , ' <Leader>gap ' , ' <CMD>Git add --patch --all<CR> ' , { desc = ' Git add all unstaged changes interactively ' } )
vim.keymap . set ( ' n ' , ' <Leader>gb ' , ' <CMD>Git blame<CR> ' , { desc = ' Git blame ' } )
2025-04-14 15:20:54 +01:00
vim.keymap . set ( ' n ' , ' <Leader>gcm ' , ' <CMD>Git commit -v<CR> ' , { desc = ' Git commit ' } )
2025-04-13 22:53:08 +01:00
vim.keymap . set ( ' n ' , ' <Leader>gp ' , ' <CMD>Git push<CR> ' , { desc = ' Git push ' } )
vim.keymap . set ( ' n ' , ' <Leader>gup ' , ' <CMD>Git pull --rebase<CR> ' , { desc = ' Git pull --rebase ' } )
2025-04-14 11:38:42 +01:00
vim.keymap . set ( ' n ' , ' <Leader>gsb ' , ' <CMD>Git status<CR> ' , { desc = ' Git status ' } )
2025-04-13 22:53:08 +01:00
vim.keymap . set ( ' n ' , ' <Leader>gd ' , ' <CMD>Git diff<CR> ' , { desc = ' Git diff ' } )
2025-04-14 15:20:54 +01:00
vim.keymap . set ( ' n ' , ' <Leader>gdc ' , ' <CMD>Git diff --cached<CR> ' , { desc = ' Git diff ' } )
2025-04-13 22:53:08 +01:00
vim.keymap . set ( ' n ' , ' <Leader>gl ' , ' <CMD>Git log<CR> ' , { desc = ' Git log ' } )
vim.keymap . set ( ' n ' , ' <Leader>gun ' , ' <CMD>Git reset -- %<CR> ' , { desc = ' Git unstage file ' } )
2025-04-15 20:48:35 +01:00
vim.keymap . set ( ' n ' , ' <Leader>gco ' , ' <CMD>Git checkout -- %<CR> ' , { desc = ' Git checkout ' } )
2025-04-13 22:53:08 +01:00
vim.keymap . set ( ' n ' , ' <Leader>G ' , ' <CMD>Git ' , { desc = ' Git ' } )
vim.keymap . set ( ' n ' , ' <Leader>gsta ' , ' <CMD>Git stash push<CR> ' , { desc = ' Git stash ' } )
vim.keymap . set ( ' n ' , ' <Leader>gstA ' , ' <CMD>Git stash apply<CR> ' , { desc = ' Git stash apply ' } )
vim.keymap . set ( ' n ' , ' <Leader>gstp ' , ' <CMD>Git stash pop<CR> ' , { desc = ' Git stash pop ' } )
-- AI mappings
vim.keymap . set ( ' v ' , ' <Leader>ae ' , ' <CMD>CodeCompanion<CR> ' , { desc = ' Edit selection with AI ' } )
vim.keymap . set ( ' n ' , ' <Leader>ac ' , ' <CMD>CodeCompanionCmd<CR> ' , { desc = ' Run Neovim commands with AI ' } )
-- Search mappings
vim.keymap . set ( ' n ' , ' <Leader>sGb ' , ' <CMD>Telescope git_branches<CR> ' , { desc = ' Search git branches ' } )
vim.keymap . set ( ' n ' , ' <Leader>sGc ' , ' <CMD>Telescope git_commits<CR> ' , { desc = ' Search git history ' } )
vim.keymap . set ( ' n ' , ' <Leader>sGh ' , ' <CMD>Telescope git_bcommits<CR> ' , { desc = ' Search git history within current buffer/selection ' } )
vim.keymap . set ( ' n ' , ' <Leader>sGs ' , ' <CMD>Telescope git_status<CR> ' , { desc = ' Search git status ' } )
vim.keymap . set ( ' n ' , ' <Leader>sGS ' , ' <CMD>Telescope git_stash<CR> ' , { desc = ' Search git stash ' } )
-- Misc
vim.keymap . set ( ' n ' , ' <Leader>] ' , ' <CMD>cnext<CR> ' , { desc = ' Next item in quickfix list ' } )
vim.keymap . set ( ' n ' , ' <Leader>[ ' , ' <CMD>cprevious<CR> ' , { desc = ' Previous item in quickfix list ' } )
vim.keymap . set ( ' n ' , ' gd ' , ' <CMD>Telescope lsp_definitions<CR> ' , { desc = ' Go to definition ' } )
2025-04-17 08:53:20 +01:00
local function open_test ( )
require ( ' neotest ' ) . summary.open ( )
require ( ' neotest ' ) . output_panel.open ( )
end
-- Testing
local test_maps = {
{
keys = { ' <F12> ' , ' <Leader>tn ' } ,
action = function ( )
require ( ' neotest ' ) . run.run ( )
open_test ( )
end ,
desc = ' Run nearest test ' ,
} ,
{
keys = { ' <F9> ' , ' <Leader>ta ' } ,
action = function ( )
require ( ' neotest ' ) . run.run { suite = true }
open_test ( )
end ,
desc = ' Run all tests in the project ' ,
} ,
{
keys = { ' <F11> ' , ' <Leader>tp ' } ,
action = function ( )
require ( ' neotest ' ) . run.run_last ( )
open_test ( )
end ,
desc = ' Run previous test again ' ,
} ,
{
keys = { ' <F10> ' , ' <Leader>td ' } ,
action = function ( )
require ( ' neotest ' ) . run.run_last { strategy = ' dap ' }
require ( ' neotest ' ) . summary.open ( ) -- Note: Doesn't call open_test() like the others
end ,
desc = ' Run last test with debugger ' ,
} ,
}
for _ , map_info in ipairs ( test_maps ) do
for _ , key in ipairs ( map_info.keys ) do
vim.keymap . set ( ' n ' , key , map_info.action , { desc = map_info.desc } )
end
end
vim.keymap . set ( ' n ' , ' <Leader>tf ' , function ( )
require ( ' neotest ' ) . run.run ( vim.fn . expand ' % ' )
open_test ( )
end , { desc = ' Run all tests in the current file ' } )
vim.keymap . set ( ' n ' , ' <Leader>tc ' , function ( )
require ( ' neotest ' ) . summary.close ( )
require ( ' neotest ' ) . output_panel.close ( )
end , { desc = ' Close test panels ' } )
2025-04-13 22:53:08 +01:00
-- Leaving this commented out, I will try the format command instead
-- "A command to properly indent json code
-- command! FormatJSON %!python -m json.tool
2025-04-12 23:49:02 +01:00
require ( ' helpers ' ) . edit_cf ( ' k ' , ' /lua/keymap.lua ' )