diff --git a/lua/which-key/buf.lua b/lua/which-key/buf.lua index c04badb6..9f4a5016 100644 --- a/lua/which-key/buf.lua +++ b/lua/which-key/buf.lua @@ -242,13 +242,6 @@ function M.clear(opts) M.bufs[b]:clear(opts) end end - if opts.check ~= false then - M.check() - end end -M.check = Util.debounce(50, function() - M.get() -end) - return M diff --git a/lua/which-key/mappings.lua b/lua/which-key/mappings.lua index dd9c8bdc..384aa82f 100644 --- a/lua/which-key/mappings.lua +++ b/lua/which-key/mappings.lua @@ -276,7 +276,7 @@ function M.add(mapping, ret, opts) local modes = mapping.mode or { "n" } --[[@as string|string[] ]] modes = type(modes) == "string" and vim.split(modes, "") or modes --[[@as string[] ]] for _, mode in ipairs(modes) do - if mode ~= "v" and mode ~= Util.mapmode({ mode = mode }) then + if mode ~= "v" and mode ~= Util.mapmode(mode) then M.warn("Invalid mode `" .. mode .. "`", mapping) end local m = vim.deepcopy(mapping) diff --git a/lua/which-key/state.lua b/lua/which-key/state.lua index e0a7ec72..24eacd4b 100644 --- a/lua/which-key/state.lua +++ b/lua/which-key/state.lua @@ -57,10 +57,8 @@ function M.setup() callback = function(ev) Util.debug(ev.event) if ev.event == "RecordingEnter" then - Buf.clear({ buf = ev.buf, check = false }) + Buf.clear({ buf = ev.buf }) M.stop() - else - Buf.check() end end, }) @@ -89,16 +87,11 @@ function M.setup() return Config.defer(ctx) end - -- this prevents restarting which-key in the same tick local cooldown = Util.cooldown() - - -- cache the mode, since it can change outside of ModeChanged events - Util.mode = vim.api.nvim_get_mode().mode - + -- this prevents restarting which-key in the same tick vim.api.nvim_create_autocmd("ModeChanged", { group = group, callback = function(ev) - Util.mode = vim.api.nvim_get_mode().mode Util.trace("ModeChanged(" .. ev.match .. ")") local mode = Buf.get() @@ -147,16 +140,32 @@ function M.setup() end, }) + local current_buf = vim.api.nvim_get_current_buf() vim.api.nvim_create_autocmd({ "BufEnter" }, { group = group, callback = function(ev) + current_buf = ev.buf ---@type number Util.trace(ev.event .. "(" .. ev.buf .. ")") Buf.get() Util.trace() end, }) - Buf.check() + -- HACK: ModeChanged does not always trigger, so we need to manually + -- check for mode changes. This seems to be due to the usage of `:norm` in autocmds. + -- See https://github.com/folke/which-key.nvim/issues/787 + local last_mode = nil ---@type string? + local last_buf = nil ---@type number? + local timer = uv.new_timer() + timer:start(0, 50, function() + local mode = vim.api.nvim_get_mode().mode + if mode == last_mode and last_buf == current_buf then + return + end + last_mode = mode + last_buf = current_buf + vim.schedule(Buf.get) + end) end function M.stop() diff --git a/lua/which-key/util.lua b/lua/which-key/util.lua index c067c2ae..53733685 100644 --- a/lua/which-key/util.lua +++ b/lua/which-key/util.lua @@ -17,7 +17,6 @@ M.BS = M.t("") M.EXIT = M.t("") M.LUA_CALLBACK = "\x80\253g" M.CMD = "\x80\253h" -M.mode = "n" function M.exit() vim.api.nvim_feedkeys(M.EXIT, "n", false) @@ -77,10 +76,9 @@ function M.keys(lhs, opts) return ret end ----@param opts? {mode?: string, cached?: boolean} -function M.mapmode(opts) - opts = opts or {} - local mode = opts.mode or (opts.cached ~= false and M.mode) or vim.api.nvim_get_mode().mode +---@param mode? string +function M.mapmode(mode) + mode = mode or vim.api.nvim_get_mode().mode mode = mode:gsub(M.t(""), "v"):gsub(M.t(""), "s"):lower() if mode:sub(1, 2) == "no" then return "o"