fix(icons): pattern match should take precedence over plugin#935
fix(icons): pattern match should take precedence over plugin#935minusfive wants to merge 2 commits intofolke:mainfrom
Conversation
Otherwise all plugin keymaps are forced to use the same icon, can't be granularly customized
fbd211c to
76b1cef
Compare
|
@folke if/when you have a chance, mind taking a look at this one? |
|
Wanted to chime in and say that I was just looking for a solution to this! I was getting annoyed at all the little candy icons in my which-key window as I have maybe 20 different searches with snacks pickers. Adding a bunch of custom rules just to override this (what I may even call a bug) was a chore. Nice PR! |
|
This PR is stale because it has been open 30 days with no activity. |
|
This will definitely be handy for overwriting specific icons without having to go through the trouble to disable the entry for plugin and then having to define all kinds of different patterns so that they can take effect. |
|
After some thought and experimenting, this PR will change all the keymaps that are I went a different approach, that is the user should be able to overwrite diff --git a/lua/which-key/icons.lua b/lua/which-key/icons.lua
index 43aaabc..491cd1f 100644
--- a/lua/which-key/icons.lua
+++ b/lua/which-key/icons.lua
@@ -14,6 +14,7 @@ local M = {}
---@type wk.IconRule[]
M.rules = {
+ { pattern = "undotree", desc = true, icon = " ", color = "orange" },
{ plugin = "fzf-lua", cat = "filetype", name = "fzf" },
{ plugin = "neo-tree.nvim", cat = "filetype", name = "neo-tree" },
{ plugin = "octo.nvim", cat = "filetype", name = "git" },
@@ -149,7 +150,12 @@ function M._get(rules, opts, check_ft)
-- plugin icons
if plugin then
for _, icon in ipairs(rules) do
- if icon.plugin == plugin then
+ if icon.desc and icon.pattern and opts.desc:lower():find(icon.pattern) then
+ local ico, hl = M.get_icon(icon)
+ if ico then
+ return ico, hl
+ end
+ elseif icon.plugin == plugin then
local ico, hl = M.get_icon(icon)
if ico then
return ico, hl
diff --git a/lua/which-key/types.lua b/lua/which-key/types.lua
index 8d985d8..0ffd585 100644
--- a/lua/which-key/types.lua
+++ b/lua/which-key/types.lua
@@ -31,6 +31,7 @@
---@class wk.IconRule: wk.Icon
---@field pattern? string
---@field plugin? string
+---@field desc? boolean
---@class wk.Keymap: vim.api.keyset.keymap
---@field lhs stringThis way we can put rules like Ultimately, I believe this comes down to preferences. Folke will have to make a decision. |
|
This is my final function function M._get(rules, opts, check_ft)
opts = opts or {}
opts.ft = type(opts.ft) == "string" and { opts.ft } or opts.ft
---@type string?
local plugin
local fts = opts.ft or {} --[[@as string[] ]]
---@type string?
local desc = opts.desc and opts.desc:lower()
if opts.keymap and package.loaded.lazy then
local LazyUtil = require("lazy.core.util")
local Keys = require("lazy.core.handler").handlers.keys --[[@as LazyKeysHandler]]
local keys = Keys.parse(opts.keymap.lhs, opts.keymap.mode)
plugin = Keys.managed[keys.id]
if plugin then
fts[#fts + 1] = LazyUtil.normname(plugin)
end
end
-- plugin icons (pattern takes precedence)
if plugin then
if desc then
-- explicit override by desc for non-plugin rules
-- Example: `{ pattern = "undotree", override_plugin = true, icon = " ", color = "orange" }`
for _, icon in ipairs(rules) do
if not icon.plugin and icon.override_plugin == true and icon.pattern and desc:find(icon.pattern) then
local ico, hl = M.get_icon(icon)
if ico then
return ico, hl
end
end
end
-- plugin + pattern
for _, icon in ipairs(rules) do
if icon.plugin == plugin and icon.pattern and desc:find(icon.pattern) then
local ico, hl = M.get_icon(icon)
if ico then
return ico, hl
end
end
end
end
-- plugin only (fallback)
for _, icon in ipairs(rules) do
if icon.plugin == plugin and not icon.pattern then
local ico, hl = M.get_icon(icon)
if ico then
return ico, hl
end
end
end
end
-- filetype icons
if check_ft then
if opts.keymap and opts.keymap.buffer and opts.keymap.buffer ~= 0 then
pcall(function()
fts[#fts + 1] = vim.bo[opts.keymap.buffer].filetype
end)
end
for _, ft in ipairs(fts) do
local icon, hl = M.get_icon({ cat = "filetype", name = ft })
if icon then
return icon, hl
end
end
end
-- pattern icons
if desc then
for _, icon in ipairs(rules) do
-- This will match pattern in both plugin and non-plugin rules, so order matters.
-- The first pattern match will be used, so non-plugin patterns should be defined
-- before plugin patterns to match non-plugin mapings that apply for the same pattern.
-- Example:
-- ```lua
-- { plugin = "snacks.nvim", pattern = "file", icon = "🔍" }
-- { pattern = "file", icon = "📁" }
-- ```
-- First rule takes precedence over second, so mappings with "file" in desc will get "🔍" icon,
-- not "📁" when they are not Snacks plugin mappings. The order should be reversed.
if icon.pattern and desc:find(icon.pattern) then
local ico, hl = M.get_icon(icon)
if ico then
return ico, hl
end
end
end
end
endI opted into different loops inside Again, this implementation is based on the current idea that Of course, I don't know myself which approach should be preferred. My way of thinking is that you use |
Description
Otherwise all plugin keymaps are forced to use the same icon, can't be granularly customized. This seems to fix a bunch of icons on LazyVim.
E.g. adding an
undotreepattern match forSnacks.picker.undo()(#936 😉) is ignored because pluginsnacks.nvimwas already matched and handled. Thus, all snacks pickers are forced to use the same icon.Related Issue(s)
N/A
Screenshots
<leader>Before<leader>After<leader>gBefore<leader>gAfter<leader>sBefore<leader>sAfter<leader>fBefore<leader>fAfter<leader>uBefore<leader>uAfter