-- Custom keymaps local map = vim.keymap.set -- ───────────────────────────────────────────────────────────────────────────── -- Terminal -- ───────────────────────────────────────────────────────────────────────────── -- LazyVim uses t* for the Test group (neotest). Putting terminal -- splits under capital T avoids that collision while staying mnemonic. map("n", "Th", function() vim.cmd("split | terminal") vim.cmd("startinsert") end, { desc = "Terminal (horizontal split)" }) map("n", "Tv", function() vim.cmd("vsplit | terminal") vim.cmd("startinsert") end, { desc = "Terminal (vertical split)" }) map("t", "", "", { desc = "Exit terminal mode" }) -- ───────────────────────────────────────────────────────────────────────────── -- Explorer (Snacks) -- ───────────────────────────────────────────────────────────────────────────── map({ "n", "i" }, "", function() Snacks.explorer() end, { desc = "Toggle Explorer" }) -- ───────────────────────────────────────────────────────────────────────────── -- Window navigation -- ───────────────────────────────────────────────────────────────────────────── map("n", "", "h", { desc = "Go left window" }) map("n", "", "j", { desc = "Go to lower window" }) map("n", "", "k", { desc = "Go to upper window" }) map("n", "", "l", { desc = "Go to right window" }) -- Resize windows with arrows map("n", "", "resize +2", { desc = "Increase window height" }) map("n", "", "resize -2", { desc = "Decrease window height" }) map("n", "", "vertical resize -2", { desc = "Decrease window width" }) map("n", "", "vertical resize +2", { desc = "Increase window width" }) -- ───────────────────────────────────────────────────────────────────────────── -- Buffers / editing -- ───────────────────────────────────────────────────────────────────────────── map("n", "", "bprevious", { desc = "Prev Buffer" }) map("n", "", "bnext", { desc = "Next Buffer" }) map("n", "", "nohlsearch", { desc = "Clear search highlight" }) map({ "n", "i", "v", "s" }, "", "w", { desc = "Save file" }) map("v", "<", "", ">gv", { desc = "Indent right, keep selection" }) map("n", "", "m .+1==", { desc = "Move line down" }) map("n", "", "m .-2==", { desc = "Move line up" }) map("n", "", ":m '>+1gv=gv", { desc = "Move selection down" }) map("n", "", ":m '<-2gv=gv", { desc = "Move selection up" }) -- ───────────────────────────────────────────────────────────────────────────── -- AI (OpenCode) -- ───────────────────────────────────────────────────────────────────────────── map({ "n", "x" }, "aa", function() require("opencode").ask("@this: ", { submit = true }) end, { desc = "AI Ask" }) map({ "n", "x" }, "ax", function() require("opencode").select() end, { desc = "AI Ask (selection)" }) map({ "n", "t" }, "at", function() require("opencode").toggle() end, { desc = "AI Toggle" }) map({ "n", "x" }, "go", function() return require("opencode").operator("@this ") end, { desc = "Add range to AI chat", expr = true }) map("n", "goo", function() return require("opencode").operator("@this ") .. "_" end, { desc = "Add line to AI chat", expr = true }) map("n", "", function() require("opencode").command("sesion.half.page.up") end, { desc = "Scroll AI chat up" }) map("n", "", function() require("opencode").command("session.half.page.down") end, { desc = "Scroll AI chat down" }) -- ───────────────────────────────────────────────────────────────────────────── -- Database (vim-dadbod) -- ───────────────────────────────────────────────────────────────────────────── -- Moved off db to free that for the DAP breakpoint default. map("n", "Du", "DBUIToggle", { desc = "Toggle DB UI" }) map("n", "Da", "DBUIAddConnection", { desc = "Add DB Connection" }) map("n", "Df", "DBUIFindBuffer", { desc = "Find DB Buffer" }) -- ───────────────────────────────────────────────────────────────────────────── -- Tests (neotest) -- ───────────────────────────────────────────────────────────────────────────── -- IMPORTANT: do NOT `require("neotest")` at module top — it eager-loads the -- plugin on every startup. Wrap each binding in a function so the require -- happens at keypress time, letting Lazy.nvim load on demand. map("n", "tt", function() require("neotest").run.run() end, { desc = "Run nearest test" }) map("n", "tf", function() require("neotest").run.run(vim.fn.expand("%")) end, { desc = "Run test file" }) map("n", "ts", function() require("neotest").summary.toggle() end, { desc = "Toggle test summary" }) map("n", "to", function() require("neotest").output.open() end, { desc = "Open test output" }) map("n", "tc", "Coverage", { desc = "Show coverage" }) -- ───────────────────────────────────────────────────────────────────────────── -- Go: benchmarks & profiling -- ───────────────────────────────────────────────────────────────────────────── -- Using cg* (Code > Go) to avoid colliding with Git's g group. map("n", "cgb", function() vim.cmd("!go test -bench=. -benchmem ./...") end, { desc = "Go benchmarks" }) map("n", "cgpc", function() vim.cmd("!go test -run=^$ -bench=. -cpuprofile cpu.out ./...") end, { desc = "Go CPU profile" }) map("n", "cgpm", function() vim.cmd("!go test -run=^$ -bench=. -memprofile mem.out ./...") end, { desc = "Go memory profile" }) map("n", "cgpt", function() vim.cmd("!go test -run=^$ -bench=. -trace trace.out ./...") end, { desc = "Go trace profile" }) -- ───────────────────────────────────────────────────────────────────────────── -- Overseer -- ───────────────────────────────────────────────────────────────────────────── map("n", "or", "OverseerRun", { desc = "Run task" }) map("n", "ot", "OverseerToggle", { desc = "Task list" }) -- ───────────────────────────────────────────────────────────────────────────── -- Symbols / outline -- ───────────────────────────────────────────────────────────────────────────── map("n", "so", "AerialToggle", { desc = "Symbols outline" }) map("n", "sh", vim.lsp.buf.incoming_calls, { desc = "Incoming calls" }) map("n", "sc", vim.lsp.buf.outgoing_calls, { desc = "Outgoing calls" }) -- ───────────────────────────────────────────────────────────────────────────── -- Diagnostics (Trouble) -- ───────────────────────────────────────────────────────────────────────────── map("n", "xx", "Trouble diagnostics toggle", { desc = "Diagnostics (Trouble)" }) map("n", "xw", "Trouble workspace_diagnostics", { desc = "Workspace diagnostics" }) map("n", "xt", "Trouble todo", { desc = "TODOs (Trouble)" }) -- ───────────────────────────────────────────────────────────────────────────── -- Git -- ───────────────────────────────────────────────────────────────────────────── -- LazyVim's gg is lazygit by default; mapping Neogit to gn. map("n", "gn", "Neogit", { desc = "Neogit" })