local keymap = {} --- Table of |:map-arguments|. --- Same as |nvim_set_keymap()| {opts}, except: --- - {replace_keycodes} defaults to `true` if "expr" is `true`. --- --- Also accepts: --- @class vim.keymap.set.Opts : vim.api.keyset.keymap --- @inlinedoc --- --- Creates buffer-local mapping, `0` or `true` for current buffer. --- @field buffer? integer|boolean --- --- Make the mapping recursive. Inverse of {noremap}. --- (Default: `false`) --- @field remap? boolean --- Defines a |mapping| of |keycodes| to a function or keycodes. --- --- Examples: --- --- ```lua --- -- Map "x" to a Lua function: --- vim.keymap.set('n', 'x', function() print("real lua function") end) --- -- Map "x" to multiple modes for the current buffer: --- vim.keymap.set({'n', 'v'}, 'x', vim.lsp.buf.references, { buffer = true }) --- -- Map to an expression (|:map-|): --- vim.keymap.set('i', '', function() --- return vim.fn.pumvisible() == 1 and "" or "" --- end, { expr = true }) --- -- Map "[%%" to a mapping: --- vim.keymap.set('n', '[%%', '(MatchitNormalMultiBackward)') --- ``` --- ---@param mode string|string[] Mode "short-name" (see |nvim_set_keymap()|), or a list thereof. ---@param lhs string Left-hand side |{lhs}| of the mapping. ---@param rhs string|function Right-hand side |{rhs}| of the mapping, can be a Lua function. ---@param opts? vim.keymap.set.Opts --- ---@see |nvim_set_keymap()| ---@see |maparg()| ---@see |mapcheck()| ---@see |mapset()| function keymap.set(mode, lhs, rhs, opts) vim.validate({ mode = { mode, { 's', 't' } }, lhs = { lhs, 's' }, rhs = { rhs, { 's', 'f' } }, opts = { opts, 't', true }, }) opts = vim.deepcopy(opts or {}, true) ---@cast mode string[] mode = type(mode) == 'string' and { mode } or mode if opts.expr and opts.replace_keycodes ~= false then opts.replace_keycodes = true end if opts.remap == nil then -- default remap value is false opts.noremap = true else -- remaps behavior is opposite of noremap option. opts.noremap = not opts.remap opts.remap = nil ---@type boolean? end if type(rhs) == 'function' then opts.callback = rhs rhs = '' end if opts.buffer then local bufnr = opts.buffer == true and 0 or opts.buffer --[[@as integer]] opts.buffer = nil ---@type integer? for _, m in ipairs(mode) do vim.api.nvim_buf_set_keymap(bufnr, m, lhs, rhs, opts) end else opts.buffer = nil for _, m in ipairs(mode) do vim.api.nvim_set_keymap(m, lhs, rhs, opts) end end end --- @class vim.keymap.del.Opts --- @inlinedoc --- --- Remove a mapping from the given buffer. --- When `0` or `true`, use the current buffer. --- @field buffer? integer|boolean --- Remove an existing mapping. --- Examples: --- --- ```lua --- vim.keymap.del('n', 'lhs') --- --- vim.keymap.del({'n', 'i', 'v'}, 'w', { buffer = 5 }) --- ``` --- ---@param modes string|string[] ---@param lhs string ---@param opts? vim.keymap.del.Opts ---@see |vim.keymap.set()| function keymap.del(modes, lhs, opts) vim.validate({ mode = { modes, { 's', 't' } }, lhs = { lhs, 's' }, opts = { opts, 't', true }, }) opts = opts or {} modes = type(modes) == 'string' and { modes } or modes --- @cast modes string[] local buffer = false ---@type false|integer if opts.buffer ~= nil then buffer = opts.buffer == true and 0 or opts.buffer --[[@as integer]] end if buffer == false then for _, mode in ipairs(modes) do vim.api.nvim_del_keymap(mode, lhs) end else for _, mode in ipairs(modes) do vim.api.nvim_buf_del_keymap(buffer, mode, lhs) end end end return keymap