local K = vim.keymap.set local builtin local wk = require("which-key") local F = require("keybind-functions") local M = {} -------------------------------------------- --- Keybindings --- M.setup = function() F.setup() -- Prevent dependency loop builtin = require("telescope.builtin") -- Change default behavior K("n", "Y", "y$") K("v", "p", "pgvy") K("n", "J", "mzJ`z") -- dont move cursor to end of line K("n", "", "zz") -- stay in the middle K("n", "", "zz") K("n", "n", "nzzzv") K("n", "N", "Nzzzv") K("x", "p", "\"_dP") -- dont overwrite clipboard when pasting visually -- Remap for dealing with word wrap K("n", "k", [[v:count == 0 ? "gk" : "k"]], { expr = true, silent = true }) K("n", "j", [[v:count == 0 ? "gj" : "j"]], { expr = true, silent = true }) -- Tab/Shift+Tab functionality K("n", "", ">>_") K("n", "", "<<_") K("i", "", "") K("v", "", ">gv") K("v", "", "+1gv=gv") K("v", "K", ":m '<-2gv=gv") -- Switch to previous buffer K("n", "", "") -- Center buffer with Ctrl+L K("n", "", "zz") -- Close buffer with Alt-w K("n", "", F.buffer_close) -- Hungry delete K("i", "", F.hungry_delete_backspace()) K("i", "", F.hungry_delete()) ---------------------------------------- --- Leader keys --- K("n", "", builtin.commands, { desc = "Execute command" }) F.wk("b", "buffer/bookmark") K("n", "bb", builtin.buffers, { desc = "Switch buffer" }) K("n", "bd", F.buffer_dashboard, { desc = "Dashboard" }) F.wk("c", "comment") -- numToStr/Comment.nvim K("n", "cc", "(comment_toggle_linewise_current)", { desc = "Comment toggle linewise" }) K("n", "cp", "(comment_toggle_blockwise_current)", { desc = "Comment toggle blockwise" }) K("x", "cc", "(comment_toggle_linewise_visual)", { desc = "Comment toggle linewise (visual)" }) K("x", "cp", "(comment_toggle_blockwise_visual)", { desc = "Comment toggle blockwise (visual)" }) F.wk("e", "eval") K("n", "eb", ":w:source %", { desc = "Evaluate buffer" }) F.wk("f", "file") K("n", "fc", F.file_config, { desc = "Config file" }) K("n", "ff", F.file_find, { desc = "Find file" }) K("n", "fh", F.file_find_home, { desc = "Find file in ~" }) K("n", "fr", F.file_find_recent, { desc = "Find recent file" }) K("n", "fs", F.file_save, { desc = "Save file" }) F.wk("h", "help") K("n", "hh", builtin.help_tags, { desc = "Describe" }) K("n", "hk", builtin.keymaps, { desc = "Describe key" }) K("n", "hm", builtin.man_pages, { desc = "Describe manpage" }) F.wk("g", "goto") K("n", "ge", F.goto_trouble, { desc = "Goto trouble" }) K("n", "gt", F.goto_todos_telescope, { desc = "Goto todos (Telescope)" }) K("n", "gT", F.goto_todos_trouble, { desc = "Goto todos (Trouble)" }) F.wk("p", "project") K("n", "pf", F.project_file, { desc = "Find project file" }) K("n", "pg", F.project_grep, { desc = "Find in project" }) K("n", "pp", F.project_list, { desc = "List projects" }) F.wk("s", "search") K("n", "ss", F.search_buffer, { desc = "Search buffer" }) K("n", "sq", ":nohlsearch", { desc = "Stop search", silent = true }) F.wk("v", "git") -- version control K("n", "vr", F.vc_select_repo, { desc = "Select repo" }) K("n", "vv", F.vc_status, { desc = "Neogit status" }) K({ "n", "v" }, "w", "", { remap = true }) -- keymap and which-key should *both* be triggered wk.add({ { mode = { "n", "v" }, { "w", group = "window" }, { "w+", desc = "Increase height" }, { "w-", desc = "Decrease height" }, { "w<", desc = "Decrease width" }, { "w=", desc = "Equally high and wide" }, { "w>", desc = "Increase width" }, { "wT", desc = "Break out into a new tab" }, { "w_", desc = "Max out the height" }, { "wh", desc = "Go to the left window" }, { "wj", desc = "Go to the down window" }, { "wk", desc = "Go to the up window" }, { "wl", desc = "Go to the right window" }, { "wo", desc = "Close all other windows" }, { "wq", desc = "Quit a window" }, { "ws", desc = "Split window" }, { "wv", desc = "Split window vertically" }, { "ww", desc = "Switch windows" }, { "wx", desc = "Swap current with next" }, { "w|", desc = "Max out the width" }, }, }) -- https://github.com/folke/which-key.nvim/issues/270 -- https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/misc.lua end -------------------------------------------- --- Plugin specific --- -- This function gets run when an LSP connects to a particular buffer. M.lspconfig_on_attach = function(_, bufnr) local nnoremap = function(keys, func, desc) vim.keymap.set("n", keys, func, { buffer = bufnr, desc = desc }) end F.wk("l", "lsp", bufnr) nnoremap("la", vim.lsp.buf.code_action, "Code action") nnoremap("lf", F.lsp_format_buffer, "Format buffer") nnoremap("lr", vim.lsp.buf.rename, "Rename") F.wk("lg", "goto", bufnr) nnoremap("lga", builtin.lsp_dynamic_workspace_symbols, "Workspace symbols") nnoremap("lgd", vim.lsp.buf.declaration, "Declaration") nnoremap("lgg", vim.lsp.buf.definition, "Definition") -- builtin.lsp_definitions nnoremap("lgi", builtin.lsp_implementations, "Implementation") nnoremap("lgr", builtin.lsp_references, "References") nnoremap("lgs", builtin.lsp_document_symbols, "Document symbols") nnoremap("lgt", builtin.lsp_type_definitions, "Type definition") -- See `:help K` for why this keymap nnoremap("K", vim.lsp.buf.hover, "Hover Documentation") nnoremap("", vim.lsp.buf.signature_help, "Signature Documentation") end -- Keybindings for nvim-cmp popup M.nvim_cmp = function() local cmp = require("cmp") local luasnip = require("luasnip") return cmp.mapping.preset.insert({ [""] = cmp.mapping.abort(), [""] = cmp.mapping.select_next_item(), [""] = cmp.mapping.select_prev_item(), [""] = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = true, }), [""] = cmp.mapping.abort(), [""] = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = true, }), [""] = cmp.mapping.complete(), [""] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif luasnip.expand_or_locally_jumpable() then luasnip.expand_or_jump() else fallback() end end, { "i", "s" }), [""] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() elseif luasnip.locally_jumpable(-1) then luasnip.jump(-1) else fallback() end end, { "i", "s" }), }) end -- Telescope picker generic mappings M.telescope_default_mappings = function() local actions = require("telescope.actions") return { n = { [""] = actions.close, [""] = actions.move_selection_next, [""] = actions.move_selection_previous, [""] = actions.select_default, }, i = { [""] = actions.close, [""] = actions.move_selection_next, [""] = actions.move_selection_previous, [""] = actions.select_default, [""] = actions.select_default, } } end return M