From 5d50f2022af09e7ecf358e681b4ce6f0818fffe0 Mon Sep 17 00:00:00 2001 From: ANGkeith Date: Sun, 10 Nov 2024 22:05:42 +0800 Subject: [PATCH] fix(state): recursion in hydra mode when mapping does not exist --- lua/which-key/state.lua | 14 +++++++++++++- lua/which-key/util.lua | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lua/which-key/state.lua b/lua/which-key/state.lua index dbd190ae..025c3ca2 100644 --- a/lua/which-key/state.lua +++ b/lua/which-key/state.lua @@ -18,6 +18,7 @@ local M = {} M.state = nil M.recursion = 0 M.recursion_timer = uv.new_timer() +M.hydra_mode = nil ---@return boolean safe, string? reason function M.safe(mode_change) @@ -235,6 +236,15 @@ function M.execute(state, key, node) end Util.debug("feedkeys", tostring(state.mode), keystr) local feed = vim.api.nvim_replace_termcodes(keystr, true, true, true) + + if M.hydra_mode then + -- prevent recursion in hydra mode when keying non-existing keymap + if not Util.has_mapping(state.mode.mode, feed) then + Util.debug(" mapping not found!") + return + end + end + vim.api.nvim_feedkeys(feed, "mit", false) end @@ -273,6 +283,7 @@ function M.start(opts) end) opts = opts or {} + M.hydra_mode = opts.loop opts.update = true local mode = Buf.get(opts) opts.update = nil @@ -294,7 +305,8 @@ function M.start(opts) M.recursion = 0 end) - if M.recursion > 50 then + recursion_threshold = M.hydra_mode and 200 or 50 + if M.recursion > recursion_threshold then Util.error({ "Recursion detected.", "Are you manually loading which-key in a keymap?", diff --git a/lua/which-key/util.lua b/lua/which-key/util.lua index ba532f5e..a6ce749a 100644 --- a/lua/which-key/util.lua +++ b/lua/which-key/util.lua @@ -39,6 +39,21 @@ function M.norm(lhs) return M.cache.norm[lhs] end +--- checks if lhs has a mapping +---@param mode string +---@param lhs string +function M.has_mapping(mode, lhs) + local maps = vim.api.nvim_get_keymap(mode) + for _, value in ipairs(maps) do + if + vim.api.nvim_replace_termcodes(value.lhs, true, true, true) + == vim.api.nvim_replace_termcodes(lhs, true, true, true) + then + return value + end + end +end + -- Default register function M.reg() -- this will be set to 2 if there is a non-empty clipboard