-- Tab mappings --- vim.keymap.set("n", "tn", vim.cmd.tabnew) vim.keymap.set("n", "tq", vim.cmd.tabclose) -- Clipboard if vim.env.TMUX ~= nil and vim.fn.executable("tmux") == 1 then vim.keymap.set( { "n", "x" }, "y", "\"+y:call system('tmux load-buffer -w -', @+)" ) else vim.keymap.set({ "n", "x" }, "y", '"+y') end vim.keymap.set({ "n", "x" }, "p", '"+p') vim.keymap.set({ "n", "x" }, "P", '"+P') vim.keymap.set({ "n", "x" }, "+", ":call setreg('+', @\")") -- Exit insert mode in terminal using vim.keymap.set("t", "", "") -- Feed ESC in terminal mode using vim.keymap.set("t", "", function() vim.api.nvim_feedkeys( vim.api.nvim_replace_termcodes("", true, false, true), "n", false ) end) -- Enable window commands in terminal mode vim.keymap.set("t", "", "") -- Use :diffput/get instead of normal one to allow staging visual selection vim.keymap.set({ "n", "x" }, "dp", ":diffput") vim.keymap.set({ "n", "x" }, "do", ":diffget") local close_pum = function() if vim.fn.pumvisible() ~= 0 then return "pclose" end for _, winid in pairs(vim.api.nvim_tabpage_list_wins(0)) do if vim.api.nvim_win_get_config(winid).relative ~= "" then return "fclose" end end end vim.keymap.set({ "n", "i" }, "", function() return close_pum() end, { expr = true }) ---@param force boolean local function delete_buffer(force) local buffers = vim.split(vim.fn.execute("buffers t"), "\n", { trimempty = true }) if #buffers < 2 then return end local b1 = buffers[1] --[[@as -nil]] local b2 = buffers[2] --[[@as -nil]] local current = tonumber(b1:match("^%s*(%d+)")) --[[@as integer?]] local previous = tonumber(b2:match("^%s*(%d+)")) --[[@as integer?]] if not current or not previous then return end if not force and vim.bo[current].modified then vim.api.nvim_echo( { { "Buffer has unsaved changes", "ErrorMsg" } }, false, {} ) return end vim.api.nvim_set_current_buf(previous) vim.api.nvim_buf_delete(current, { force = force }) end vim.keymap.set("n", "", function() delete_buffer(false) end) vim.keymap.set("n", "", function() delete_buffer(true) end) vim.keymap.set("n", "", ":b#") -- Allow (de)indenting without deselecting vim.keymap.set({ "x" }, "<", "", ">gv") -- Remove default mappings vim.keymap.set("", "", "") vim.keymap.set("n", "gr", "") -- Remove right-click menu items vim.cmd.aunmenu({ "PopUp.-1-" }) vim.cmd.aunmenu({ "PopUp.How-to\\ disable\\ mouse" }) -- Insert-mode Emacs bindings (C-f/C-b live further down inside hover_scroll_map) vim.keymap.set("i", "", "^") vim.keymap.set("i", "", function() -- Fall through to Vim's default (close popup + revert) during completion. return vim.fn.pumvisible() ~= 0 and "" or "$" end, { expr = true, replace_keycodes = true }) -- vim.keymap.set('i', '', 'x') -- Overrides de-indent vim.keymap.set("i", "", "w") vim.keymap.set("i", "", "b") vim.keymap.set("i", "", "dw") vim.keymap.set("i", "", "db") -- Command-mode Emacs bindings vim.keymap.set("c", "", "") vim.keymap.set("c", "", "") vim.keymap.set("c", "", "") vim.keymap.set("c", "", "") vim.keymap.set("c", "", "") vim.keymap.set("c", "", "") vim.keymap.set("c", "", "") vim.keymap.set("c", "", "") vim.keymap.set("c", "", "") vim.keymap.set("n", "ve", function() if vim.o.virtualedit == "all" then vim.o.virtualedit = "block" else vim.o.virtualedit = "all" end end) -- Replace all occurrences of word vim.keymap.set("n", "r", function() local word = vim.fn.expand("") local replacement = vim.fn.input('Replace "' .. word .. '" by? ') if replacement ~= "" then local cursor_pos = vim.api.nvim_win_get_cursor(0) vim.cmd(":%s/\\<" .. word .. "\\>/" .. replacement .. "/g") vim.api.nvim_win_set_cursor(0, cursor_pos) end end) vim.keymap.set("n", "[d", function() vim.diagnostic.jump({ count = -1, float = true }) end) vim.keymap.set("n", "]d", function() vim.diagnostic.jump({ count = 1, float = true }) end) vim.keymap.set("n", "gD", vim.lsp.buf.declaration) vim.keymap.set("n", "K", function() vim.lsp.buf.hover({ max_width = 80 }) end) vim.keymap.set({ "i", "s" }, "", function() local winid = vim.b.lsp_floating_preview if winid and vim.api.nvim_win_is_valid(winid) then vim.api.nvim_win_close(winid, false) return end vim.lsp.buf.signature_help({ max_width = 80 }) end) ---@param mode string | string[] ---@param key string ---@param direction "up" | "down" ---@param count integer ---@param fallback? string local function hover_scroll_map(mode, key, direction, count, fallback) vim.keymap.set(mode, key, function() local winid = vim.b.lsp_floating_preview if not winid or not vim.api.nvim_win_is_valid(winid) then return fallback or key end vim.schedule(function() local scroll_key = direction == "down" and vim.keycode("") or vim.keycode("") vim.api.nvim_win_call(winid, function() vim.cmd.normal({ args = { count .. scroll_key }, bang = true, }) end) end) return "" end, { expr = true, replace_keycodes = true }) end hover_scroll_map({ "n", "s" }, "", "down", 5) hover_scroll_map({ "n", "s" }, "", "up", 5) hover_scroll_map("i", "", "down", 5, "") hover_scroll_map("i", "", "up", 5, "") ---@param key string ---@param dir 1 | -1 local function snippet_jump_map(key, dir) vim.keymap.set({ "i", "s" }, key, function() if vim.snippet.active({ direction = dir }) then return string.format("lua vim.snippet.jump(%d)", dir) end return key end, { expr = true, replace_keycodes = true }) end snippet_jump_map("", 1) snippet_jump_map("", -1) vim.keymap.set({ "n", "i" }, "", vim.lsp.buf.document_highlight) vim.keymap.set({ "n", "x" }, "lf", vim.lsp.buf.format) vim.keymap.set("n", "grl", function() require("lsp.codelens").toggle() end) vim.keymap.set("n", "ld", function() vim.diagnostic.enable( not vim.diagnostic.is_enabled({ bufnr = 0 }), { bufnr = 0 } ) end) vim.keymap.set({ "n", "i" }, "", function() vim.lsp.buf.clear_references() vim.cmd.nohlsearch() vim.schedule(vim.cmd.diffupdate) vim.snippet.stop() return "" end, { expr = true }) vim.keymap.set("n", "fd", vim.diagnostic.setloclist) vim.keymap.set("n", "fD", vim.diagnostic.setqflist) vim.keymap.set("n", "grt", vim.lsp.buf.type_definition) vim.keymap.set("n", "gd", vim.lsp.buf.definition) vim.keymap.set("n", "gd", function() require("git.diff").split({ vertical = true }) end) vim.keymap.set("n", "gD", function() require("git.diff").split({ rev = "HEAD", vertical = true }) end) vim.keymap.set("n", "gh", function() require("git.diff").split({ vertical = false }) end) vim.keymap.set("n", "gH", function() require("git.diff").split({ rev = "HEAD", vertical = false }) end) vim.keymap.set("n", "gg", function() require("git.status_view").toggle() end) vim.keymap.set("n", "gc", function() require("git.commit").commit() end) vim.keymap.set("n", "ga", function() require("git.commit").commit({ args = { "--amend" } }) end) vim.keymap.set("n", "gl", function() require("git.log_view").open({ max_count = 1000 }) end)