local M = {} local Log = require "lvim.core.log" local generic_opts_any = { noremap = true, silent = true } local generic_opts = { insert_mode = generic_opts_any, normal_mode = generic_opts_any, visual_mode = generic_opts_any, visual_block_mode = generic_opts_any, command_mode = generic_opts_any, term_mode = { silent = true }, } local mode_adapters = { insert_mode = "i", normal_mode = "n", term_mode = "t", visual_mode = "v", visual_block_mode = "x", command_mode = "c", } ---@class Keys ---@field insert_mode table ---@field normal_mode table ---@field terminal_mode table ---@field visual_mode table ---@field visual_block_mode table ---@field command_mode table local defaults = { insert_mode = { -- 'jk' for quitting insert mode ["jk"] = "", -- 'kj' for quitting insert mode ["kj"] = "", -- 'jj' for quitting insert mode ["jj"] = "", -- Move current line / block with Alt-j/k ala vscode. [""] = ":m .+1==gi", -- Move current line / block with Alt-j/k ala vscode. [""] = ":m .-2==gi", -- navigation [""] = "k", [""] = "j", [""] = "h", [""] = "l", }, normal_mode = { -- Better window movement [""] = "h", [""] = "j", [""] = "k", [""] = "l", -- Resize with arrows [""] = ":resize -2", [""] = ":resize +2", [""] = ":vertical resize -2", [""] = ":vertical resize +2", -- Tab switch buffer [""] = ":BufferLineCycleNext", [""] = ":BufferLineCyclePrev", -- Move current line / block with Alt-j/k a la vscode. [""] = ":m .+1==", [""] = ":m .-2==", -- QuickFix ["]q"] = ":cnext", ["[q"] = ":cprev", [""] = ":call QuickFixToggle()", }, term_mode = { -- Terminal window navigation [""] = "h", [""] = "j", [""] = "k", [""] = "l", }, visual_mode = { -- Better indenting ["<"] = ""] = ">gv", -- ["p"] = '"0p', -- ["P"] = '"0P', }, visual_block_mode = { -- Move selected line / block of text in visual mode ["K"] = ":move '<-2gv-gv", ["J"] = ":move '>+1gv-gv", -- Move current line / block with Alt-j/k ala vscode. [""] = ":m '>+1gv-gv", [""] = ":m '<-2gv-gv", }, command_mode = { -- navigate tab completion with and -- runs conditionally [""] = { 'pumvisible() ? "\\" : "\\"', { expr = true, noremap = true } }, [""] = { 'pumvisible() ? "\\" : "\\"', { expr = true, noremap = true } }, }, } if vim.fn.has "mac" == 1 then defaults.normal_mode[""] = defaults.normal_mode[""] defaults.normal_mode[""] = defaults.normal_mode[""] defaults.normal_mode[""] = defaults.normal_mode[""] defaults.normal_mode[""] = defaults.normal_mode[""] Log:debug "Activated mac keymappings" end -- Unsets all keybindings defined in keymaps -- @param keymaps The table of key mappings containing a list per mode (normal_mode, insert_mode, ..) function M.clear(keymaps) local default = M.get_defaults() for mode, mappings in pairs(keymaps) do local translated_mode = mode_adapters[mode] or mode for key, _ in pairs(mappings) do -- some plugins may override default bindings that the user hasn't manually overridden if default[mode][key] ~= nil or (default[translated_mode] ~= nil and default[translated_mode][key] ~= nil) then pcall(vim.keymap.del, translated_mode, key) end end end end -- Unsets all keybindings defined in keymaps -- @param keymaps The table of key mappings containing a list per mode (normal_mode, insert_mode, ..) function M.clear(keymaps) local default = M.get_defaults() for mode, mappings in pairs(keymaps) do local translated_mode = mode_adapters[mode] and mode_adapters[mode] or mode for key, _ in pairs(mappings) do -- some plugins may override default bindings that the user hasn't manually overriden if default[mode][key] ~= nil or (default[translated_mode] ~= nil and default[translated_mode][key] ~= nil) then pcall(vim.api.nvim_del_keymap, translated_mode, key) end end end end -- Set key mappings individually -- @param mode The keymap mode, can be one of the keys of mode_adapters -- @param key The key of keymap -- @param val Can be form as a mapping or tuple of mapping and user defined opt function M.set_keymaps(mode, key, val) local opt = generic_opts[mode] or generic_opts_any if type(val) == "table" then opt = val[2] val = val[1] end if val then vim.keymap.set(mode, key, val, opt) else pcall(vim.api.nvim_del_keymap, mode, key) end end -- Load key mappings for a given mode -- @param mode The keymap mode, can be one of the keys of mode_adapters -- @param keymaps The list of key mappings function M.load_mode(mode, keymaps) mode = mode_adapters[mode] or mode for k, v in pairs(keymaps) do M.set_keymaps(mode, k, v) end end -- Load key mappings for all provided modes -- @param keymaps A list of key mappings for each mode function M.load(keymaps) keymaps = keymaps or {} for mode, mapping in pairs(keymaps) do M.load_mode(mode, mapping) end end -- Load the default keymappings function M.load_defaults() M.load(M.get_defaults()) lvim.keys = lvim.keys or {} for idx, _ in pairs(defaults) do if not lvim.keys[idx] then lvim.keys[idx] = {} end end end -- Get the default keymappings function M.get_defaults() return defaults end return M