feat(keys): refactor code and allow disabling keymaps per mode. mode no longer needs to be exactly the same in order to disable.

This commit is contained in:
Folke Lemaitre 2023-10-08 10:11:25 +02:00
parent 62745a7320
commit b79099cc9d
No known key found for this signature in database
GPG Key ID: 41F8B1FBACAE2040
4 changed files with 68 additions and 35 deletions

View File

@ -5,6 +5,7 @@ local Config = require("lazy.core.config")
---@field type LazyHandlerTypes ---@field type LazyHandlerTypes
---@field extends? LazyHandler ---@field extends? LazyHandler
---@field active table<string,table<string,string>> ---@field active table<string,table<string,string>>
---@field managed table<string,string>
---@field super LazyHandler ---@field super LazyHandler
local M = {} local M = {}
@ -64,6 +65,7 @@ function M.new(type)
local self = setmetatable({}, { __index = setmetatable(handler, { __index = super }) }) local self = setmetatable({}, { __index = setmetatable(handler, { __index = super }) })
self.super = super self.super = super
self.active = {} self.active = {}
self.managed = {}
self.type = type self.type = type
return self return self
end end
@ -94,6 +96,7 @@ function M:add(plugin)
self.active[key] = {} self.active[key] = {}
self:_add(value) self:_add(value)
end end
self.managed[key] = self.managed[key]
self.active[key][plugin.name] = plugin.name self.active[key][plugin.name] = plugin.name
end end
end end

View File

@ -1,60 +1,89 @@
local Util = require("lazy.core.util") local Util = require("lazy.core.util")
local Loader = require("lazy.core.loader") local Loader = require("lazy.core.loader")
---@class LazyKeys ---@class LazyKeysBase
---@field [1] string lhs
---@field [2]? string|fun()|false rhs
---@field desc? string ---@field desc? string
---@field mode? string|string[]
---@field noremap? boolean ---@field noremap? boolean
---@field remap? boolean ---@field remap? boolean
---@field expr? boolean ---@field expr? boolean
---@field nowait? boolean
---@field ft? string|string[] ---@field ft? string|string[]
---@class LazyKeysSpec: LazyKeysBase
---@field [1] string lhs
---@field [2]? string|fun()|false rhs
---@field mode? string|string[]
---@class LazyKeys: LazyKeysBase
---@field lhs string lhs
---@field rhs? string|fun() rhs
---@field mode? string
---@field id string ---@field id string
---@class LazyKeysHandler:LazyHandler ---@class LazyKeysHandler:LazyHandler
local M = {} local M = {}
---@param value string|LazyKeys ---@param value string|LazyKeysSpec
function M.parse(value) ---@param mode? string
local ret = vim.deepcopy(value) ---@return LazyKeys
ret = type(ret) == "string" and { ret } or ret --[[@as LazyKeys]] function M.parse(value, mode)
ret.mode = ret.mode or "n" value = type(value) == "string" and { value } or value --[[@as LazyKeysSpec]]
ret.id = vim.api.nvim_replace_termcodes(ret[1] or "", true, true, true) local ret = vim.deepcopy(value) --[[@as LazyKeys]]
if ret.mode then ret.lhs = ret[1] or ""
local mode = ret.mode ret.rhs = ret[2]
if type(mode) == "table" then ---@diagnostic disable-next-line: no-unknown
---@cast mode string[] ret[1] = nil
table.sort(mode) ---@diagnostic disable-next-line: no-unknown
mode = table.concat(mode, ", ") ret[2] = nil
end ret.mode = mode or "n"
if mode ~= "n" then ret.id = vim.api.nvim_replace_termcodes(ret.lhs, true, true, true)
ret.id = ret.id .. " (" .. mode .. ")" if ret.mode ~= "n" then
end ret.id = ret.id .. " (" .. ret.mode .. ")"
end end
return ret return ret
end end
---@param lhs string
---@param mode? string
function M:have(lhs, mode)
local keys = M.parse(lhs, mode)
return self.managed[keys.id]
end
---@param plugin LazyPlugin ---@param plugin LazyPlugin
function M:values(plugin) function M:values(plugin)
---@type table<string,any> return M.resolve(plugin.keys)
end
---@param spec? (string|LazyKeysSpec)[]
function M.resolve(spec)
---@type LazyKeys[]
local values = {} local values = {}
---@diagnostic disable-next-line: no-unknown ---@diagnostic disable-next-line: no-unknown
for _, value in ipairs(plugin[self.type] or {}) do for _, value in ipairs(spec or {}) do
local keys = M.parse(value) value = type(value) == "string" and { value } or value --[[@as LazyKeysSpec]]
if keys[2] == vim.NIL or keys[2] == false then value.mode = value.mode or "n"
local modes = (type(value.mode) == "table" and value.mode or { value.mode }) --[=[@as string[]]=]
for _, mode in ipairs(modes) do
local keys = M.parse(value, mode)
if keys.rhs == vim.NIL or keys.rhs == false then
values[keys.id] = nil values[keys.id] = nil
else else
values[keys.id] = keys values[keys.id] = keys
end end
end end
end
return values return values
end end
---@param keys LazyKeys
function M.opts(keys) function M.opts(keys)
local opts = {} local skip = { mode = true, id = true, ft = true, rhs = true, lhs = true }
local opts = {} ---@type LazyKeysBase
---@diagnostic disable-next-line: no-unknown
for k, v in pairs(keys) do for k, v in pairs(keys) do
if type(k) ~= "number" and k ~= "mode" and k ~= "id" and k ~= "ft" then if type(k) ~= "number" and not skip[k] then
---@diagnostic disable-next-line: no-unknown
opts[k] = v opts[k] = v
end end
end end
@ -63,7 +92,7 @@ end
---@param keys LazyKeys ---@param keys LazyKeys
function M:_add(keys) function M:_add(keys)
local lhs = keys[1] local lhs = keys.lhs
local opts = M.opts(keys) local opts = M.opts(keys)
---@param buf? number ---@param buf? number
@ -121,7 +150,7 @@ end
-- mapping when needed -- mapping when needed
---@param keys LazyKeys ---@param keys LazyKeys
function M:_del(keys) function M:_del(keys)
pcall(vim.keymap.del, keys.mode, keys[1]) pcall(vim.keymap.del, keys.mode, keys.lhs)
-- make sure to create global mappings when needed -- make sure to create global mappings when needed
-- buffer-local mappings are managed by lazy -- buffer-local mappings are managed by lazy
if not keys.ft then if not keys.ft then
@ -133,10 +162,11 @@ end
---@param keys LazyKeys ---@param keys LazyKeys
---@param buf number? ---@param buf number?
function M:_set(keys, buf) function M:_set(keys, buf)
if keys[2] then if keys.rhs then
local opts = M.opts(keys) local opts = M.opts(keys)
---@diagnostic disable-next-line: inject-field
opts.buffer = buf opts.buffer = buf
vim.keymap.set(keys.mode, keys[1], keys[2], opts) vim.keymap.set(keys.mode, keys.lhs, keys.rhs, opts)
end end
end end

View File

@ -32,7 +32,7 @@
---@field event? string[] ---@field event? string[]
---@field cmd? string[] ---@field cmd? string[]
---@field ft? string[] ---@field ft? string[]
---@field keys? (string|LazyKeys)[] ---@field keys? (string|LazyKeysSpec)[]
---@field module? false ---@field module? false
---@class LazyPluginRef ---@class LazyPluginRef

View File

@ -331,7 +331,7 @@ function M:reason(reason, opts)
value = value:match("User (.*)") or value value = value:match("User (.*)") or value
end end
if key == "keys" then if key == "keys" then
value = type(value) == "string" and value or value[1] value = type(value) == "string" and value or value.lhs
end end
local hl = "LazyReason" .. key:sub(1, 1):upper() .. key:sub(2) local hl = "LazyReason" .. key:sub(1, 1):upper() .. key:sub(2)
local icon = Config.options.ui.icons[key] local icon = Config.options.ui.icons[key]