emacs-which-key icon indicating copy to clipboard operation
emacs-which-key copied to clipboard

Lots of time spent inside which-key--maybe-replace

Open peterhoeg opened this issue 4 years ago • 47 comments

I think this is a which-key issue and not specifically related to spacemacs as it happens in multiple different major modes (ruby and org).

I found this but it is not related as I am on the most recent spacemacs develop and I have tried with the most recent which-key as well.

Output from profiler:

- timer-event-handler                                            4120  74%
 - apply                                                         4119  74%
  - which-key--update                                            4068  73%
   - which-key--create-buffer-and-show                           4068  73%
    - which-key--get-bindings                                    3761  68%
     - which-key--format-and-replace                             3713  67%
      - which-key--maybe-replace                                 3658  66%
         which-key--match-replacement                              50   0%
       + which-key--get-pseudo-binding                             35   0%
      + which-key--propertize-description                          17   0%
      + kbd                                                        14   0%
      + which-key--propertize                                       1   0%
        which-key--extract-key                                      1   0%
        which-key--maybe-add-docstring                              1   0%
      + which-key--propertize-key                                   1   0%
     + which-key--get-current-bindings                             45   0%
     + sort                                                         1   0%
    + which-key--show-page                                        173   3%
    + which-key--create-pages                                     133   2%
  + sp-show--pair-function                                         11   0%

Description :octocat:

emacs gets really slugging when hitting a key that triggers which-key and it takes several seconds for the menu to show during which time emacs is maxing out a core.

Reproduction guide :beetle:

  • Start Emacs
  • Fiddle around in either org mode or ruby (might be others too)

Observed behaviour: :eyes: :broken_heart: emacs gets really slugging when hitting a key that triggers which-key and it takes several seconds for the menu to show during which time emacs is maxing out a core.

Expected behaviour: :heart: :smile: which-key to react instantly

System Info :computer:

  • OS: gnu/linux
  • Emacs: 26.3
  • Spacemacs: 0.300.0
  • Spacemacs branch: peter_develop (rev. 8916788d5)
  • Graphic display: t
  • Distribution: spacemacs
  • Editing style: vim
  • Completion: ivy
  • Layers:
((auto-completion :variables auto-complete-idle-delay 0.1 auto-completion-complete-with-key-sequence "jk" auto-completion-enable-snippets-in-popup t auto-completion-enable-help-tooltip t auto-completion-return-key-behavior nil auto-completion-tab-key-behavior 'cycle)
 better-defaults
 (dash :variables dash-docs-docset-newpath
       (cond
        ((spacemacs/system-is-linux)
         (expand-file-name "Zeal/Zeal/docsets"
                           (getenv "XDG_DATA_HOME")))
        ((spacemacs/system-is-mac)
         (expand-file-name "Library/ApplicationSupport/Dash/DocSets"
                           (getenv "HOME")))))
 evil-commentary
 (finance :variables ledger-use-iso-dates t)
 (geolocation :variables geolocation-enable-automatic-theme-changer nil geolocation-enable-location-server t geolocation-enable-weather-forecast t)
 graphviz ivy multiple-cursors
 (mu4e :variables mu4e-account-alist nil mu4e-mu-home
       (expand-file-name "mu"
                         (getenv "XDG_CACHE_HOME"))
       mu4e-maildir
       (expand-file-name "mail"
                         (getenv "XDG_CACHE_HOME"))
       mu4e-enable-async-operations nil mu4e-enable-notifications t mu4e-use-maildirs-extension nil)
 pandoc pdf plantuml
 (shell :variables shell-default-height 30 shell-default-position 'bottom shell-default-shell 'vterm shell-scripts-backend 'lsp)
 (templates :variables templates-use-default-templates t)
 theming treemacs
 (git :variables git-magit-status-fullscreen t)
 pass
 (spell-checking :variables enable-flyspell-auto-completion nil flyspell-issue-welcome-flag nil ispell-local-dictionary "en" ispell-program-name
                 (or
                  (getenv "ASPELL")
                  "/run/current-system/sw/bin/aspell")
                 ispell-really-aspell t spell-checking-enable-by-default
                 (spacemacs/system-is-linux)
                 spell-checking-enable-auto-dictionary nil)
 version-control ansible nginx terraform yaml c-c++ cmake
 (crystal :variables crystal-enable-auto-format t)
 dap emacs-lisp
 (haskell :variables flycheck-haskell-runghc-command
          '("stack" "--verbosity" "silent" "runghc" "--no-ghc-package-path" "--" "--ghc-arg=-i")
          haskell-completion-backend 'lsp haskell-enable-hindent t haskell-process-type 'stack-ghci haskell-stylish-on-save t)
 (lsp :variables lsp-auto-guess-root t lsp-navigation 'both lsp-ui-doc-use-webkit nil lsp-ui-flycheck-enable t lsp-ui-sideline-enable t)
 nixos
 (python :variables python-enable-yapf-format-on-save t)
 (ruby :variables ruby-backend 'lsp ruby-enable-enh-ruby-mode nil ruby-highlight-debugger-keywords t ruby-test-runner 'rspec ruby-version-manager nil)
 shell-scripts
 (sql :variables sql-auto-indent t sql-capitalize-keywords t)
 typescript
 (windows-scripts :variables dos-prefer-bat-mode nil)
 ruby-on-rails gtags
 (restclient :variables restclient-use-org nil)
 syntax-checking csv html
 (markdown :variables markdown-live-preview-engine 'eww)
 (org :variables org-enable-hugo-support t org-enable-jira-support t org-enable-reveal-js-support t org-enable-trello-support
      (spacemacs/system-is-linux)
      org-export-backends
      '(ascii html icalendar latex md)
      org-reveal-note-key-char nil org-use-speed-commands nil)
 (speartail :variables speartail-auto-save-interval nil)
 nix peter)
  • System configuration features: XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND DBUS GSETTINGS GLIB NOTIFY LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM MODULES THREADS XWIDGETS LIBSYSTEMD LCMS2

peterhoeg avatar Nov 26 '19 12:11 peterhoeg

Just cloned spacemacs and I'm not seeing any slow down. Can you try to narrow it down more?

justbur avatar Nov 26 '19 19:11 justbur

I have some fairly long running emacs sessions and I cannot easily reproduce it at the beginning of a session as it takes hours most of the time to trigger. I will try with a cut down config to see if I can more easily reproduce it.

peterhoeg avatar Nov 27 '19 00:11 peterhoeg

As an additional data point, this is the profiler after a restart of emacs when things are responding properly:

- timer-event-handler                                            1503  58%
 - apply                                                         1503  58%
  - which-key--update                                            1371  52%
   - which-key--create-buffer-and-show                           1369  52%
    - which-key--show-page                                        644  24%
     - which-key--show-popup                                      640  24%
      - which-key--show-buffer-side-window                        640  24%
       - display-buffer-in-side-window                            557  21%
        - window--make-major-side-window                          557  21%
         - window--display-buffer                                 536  20%
          - which-key--fit-buffer-to-window-horizontally                281  10%
           - apply                                                281  10%
            - fit-window-to-buffer                                281  10%
             - apply                                              281  10%
              - doom-modeline-redisplay                           259  10%
               - redisplay                                        256   9%
                + redisplay_internal (C function)                  23   0%
                + timer-event-handler                              10   0%
                #<compiled 0x1b28ef>                               22   0%
          - #<lambda 0x15426159d>                                 248   9%
           - fit-window-to-buffer                                 248   9%
            - apply                                               248   9%
             - doom-modeline-redisplay                            219   8%
              - redisplay                                         219   8%
               + redisplay_internal (C function)                   10   0%
               + timer-event-handler                                3   0%
             + #<compiled 0x1b28ef>                                29   1%
          + set-window-buffer                                       7   0%
         + split-window-no-error                                   21   0%
       + display-buffer-reuse-window                               83   3%
     + which-key--process-page                                      3   0%
    - which-key--get-bindings                                     615  23%
     - which-key--format-and-replace                              500  19%
      - which-key--maybe-replace                                  396  15%
         which-key--match-replacement                             102   3%
       + which-key--get-pseudo-binding                             35   1%
      + which-key--propertize-description                          57   2%
      + kbd                                                        17   0%
      + which-key--maybe-add-docstring                             11   0%
      + which-key--extract-key                                      2   0%
     + which-key--get-current-bindings                             98   3%
     + sort                                                         6   0%
    + which-key--create-pages                                     109   4%
   + which-key--start-timer                                         1   0%
  + sp-show--pair-function                                         67   2%
  + org-indent-initialize-agent                                    57   2%
  + auto-revert-buffers                                             3   0%
  + #<compiled 0x2024d3>                                            2   0%

peterhoeg avatar Nov 27 '19 01:11 peterhoeg

A few more observations:

  1. It doesn't seem to be related to the issue mention above as(length which-key-replacement-alist) hasn't gone above 285.
  2. Sometimes the problem goes away without restarting emacs but then it comes back again later.

peterhoeg avatar Nov 27 '19 09:11 peterhoeg

Thanks. If it’s an issue with how the replacement stuff is working it could very well depend on what major mode you’re in.

justbur avatar Nov 27 '19 12:11 justbur

So far I have seen it in ruby-mode (the built-in, I haven't tried enh-ruby-mode) as well as org-mode.

Never in elisp.

peterhoeg avatar Nov 27 '19 14:11 peterhoeg

I think that the profiler output is a red herring. The issue isn't actually about which-key but has to do with lsp.

I disabled the lsp layer (spacemacs) and I have not been able to reproduce it since in any of the otherwise affected modes but the profile still says that a significant amount of cpu time is spent in which-key (not quite as much though), so I'm guessing that which-key just happens to be using the most cpu but that the slow-downs is due to emacs being busy with lsp.

peterhoeg avatar Dec 06 '19 02:12 peterhoeg

Ah ok. If it’s just counting function calls it makes sense that there are quite a few in which-key.

justbur avatar Dec 09 '19 22:12 justbur

I'm seing the same issue when enbaling lsp module in doom emacs

pcharest2000 avatar Jan 19 '20 03:01 pcharest2000

@pcharest2000 - do you mind trying to run a profiler session to see if you're seeing lots of which-key activity as well?

peterhoeg avatar Jan 19 '20 13:01 peterhoeg

Peter here is the profiler output yes lots of which-key and this is a session that slow down was sporadic:

  • timer-event-handler 9419 71%
  • apply 9419 71%
  • which-key--update 8025 60%
  • which-key--create-buffer-and-show 8025 60% - which-key--get-bindings 7157 54%
    • which-key--format-and-replace 7078 53%
    • which-key--maybe-replace 6725 51% which-key--match-replacement 349 2%
    • which-key--get-pseudo-binding 128 0%
    • replace-regexp-in-string 11 0%
    • which-key--propertize-description 150 1%
    • kbd 42 0%
    • which-key--maybe-add-docstring 25 0%
    • which-key--extract-key 11 0% which-key--propertize-key 4 0%
    • which-key--get-current-bindings 54 0%
    • sort 14 0% + which-key--create-pages 861 6% + which-key--show-page 3 0%
  • lsp--on-idle 816 6%
  • company-idle-begin 360 2%
  • #<compiled 0xcd0681> 102 0%
  • lsp-ui-sideline--run 102 0%
  • #<compiled 0x20306b> 20 0%
  • #<compiled 0x1814099> 6 0% jit-lock-force-redisplay 4 0% amx-idle-update 3 0%
  • #<compiled 0x1511521> 2 0%
  • command-execute 2396 18%
  • redisplay_internal (C function) 556 4%
  • #<compiled 0x248545d> 361 2%
  • ... 304 2%
  • lsp--post-command 34 0%
  • evil--jump-hook 20 0%

pcharest2000 avatar Jan 19 '20 16:01 pcharest2000

@pcharest2000 - do you mind trying to run a profiler session to see if you're seeing lots of which-key activity as well?

I've reconfigured my doom emacs to use irony-server instead of LSP (cc) and here are the results of the profiler, LSP is bogging down something:

  • command-execute 3311 47%
  • timer-event-handler 2389 34%
  • apply 2387 34%
  • which-key--update 2015 29%
  • amx-idle-update 174 2%
  • company-idle-begin 107 1%
  • #<compiled 0x20306b> 8 0% company-echo-show 4 0%
  • ... 604 8%

pcharest2000 avatar Jan 19 '20 19:01 pcharest2000

If you suspect which-key--update is the culprit you can lengthen which-key-idle-delay then toggle which-key-mode and see if that has any effect. If you have a short delay, that function will fire a lot (but exit quickly most of the time). Or even more severely, just disable which-key-mode when you notice the slowdown and see if it goes away.

The profiler output seems pretty consistent with respect to which-key, so if you are getting slow down in certain files, it's unlikely to be which-key's fault. Having a mode that calls out to external processes, like LSP, seems like the much more likely culprit.

justbur avatar Jan 19 '20 20:01 justbur

Seting which-key-idle-delay to 0.5 and the secobndary delay to 0.1 seems to resolve the issue. But I still don't understund how this related to LSP mode. Please I am an emacs user not an expert how things works in emacs.

TKS I'll keep you posted

pcharest2000 avatar Jan 19 '20 21:01 pcharest2000

The culprit is definitely which-key.

I enabled lsp (with spacemacs) and used emacs as normal. After a while, the problem came back and disabling which-key-mode made everything snappy again.

And not just that - I realized that regardless of lsp, which-key-mode causes noticeable lag compared to no which-key where responses are simply instantaneous. I just didn't notice this before as which-key was always enabled. Increasing which-key-idle-delay to 0.5 seems to have made things acceptable again.

peterhoeg avatar Jan 20 '20 09:01 peterhoeg

I don't use lsp and I'm afraid there's not enough information here for me to track down a problem. Performance issues with which-key are rare in my experience, but that doesn't mean there isn't one here.

One important issue here is that there are many possible sources of problems here, which-key, lsp, the major mode used, spacemacs config for lsp, etc. and I don't have the time to test out each one. If someone can create a kind of minimal working example from an otherwise unconfigured emacs, I can try to make progress on this.

justbur avatar Feb 04 '20 02:02 justbur

I stumbled across this because I was having the same problems, which the same profiler behavior. Thanks for the advice. I set these two variables back to which-key defaults:

(setq which-key-idle-delay 1.0)
(setq which-key-idle-secondary-delay nil)

Emacs instantly became snappier, even without a restart.

dmusican avatar Apr 27 '20 15:04 dmusican

I stumbled across this because I was having the same problems, which the same profiler behavior. Thanks for the advice. I set these two variables back to which-key defaults:

(setq which-key-idle-delay 1.0)
(setq which-key-idle-secondary-delay nil)

Emacs instantly became snappier, even without a restart.

This doesn't work for me. In my case, which-key causes hanging only when it's triggered after 'SPC' leader key. I followed suggestions from https://github.com/justbur/emacs-which-key, which make Emacs work with no hanging.

(setq which-key-idle-delay 10000) (setq which-key-idle-secondary-delay 0.05)

Jonghyun-Yun avatar Apr 30 '20 01:04 Jonghyun-Yun

I stumbled across this because I was having the same problems, which the same profiler behavior. Thanks for the advice. I set these two variables back to which-key defaults:

(setq which-key-idle-delay 1.0)
(setq which-key-idle-secondary-delay nil)

Emacs instantly became snappier, even without a restart.

This doesn't work for me. In my case, which-key causes hanging only when it's triggered after 'SPC' leader key. I followed suggestions from https://github.com/justbur/emacs-which-key, which make Emacs work with no hanging.

(setq which-key-idle-delay 10000) (setq which-key-idle-secondary-delay 0.05)

This solution seems to work for me. Is there any drawback or potential issue?

tigerjack avatar May 06 '20 08:05 tigerjack

My earlier post did make things faster, but only partially, for a little while. This latter version:

(setq which-key-idle-delay 10000)
(setq which-key-idle-secondary-delay 0.05)

works great. In fact, this makes the difference in making Spacemacs as fast for me as my own vanilla emacs with similar packages, which I've never been able to achieve before.

The key downside is that the whick-key menus don't show anymore, so it essentially disables which-key. So I've added the option:

(setq which-key-show-early-on-C-h t)

so that I can still see the which-key menus when I want by hitting C-h. The drawback of the above is that which-key isn't as accessible as it was, but the speed bump is definitively worth it.

dmusican avatar May 06 '20 11:05 dmusican

@dmusican aren't you experiencing problems with the ESC key? I mean, my main problem with this configuration now is that often I can't exit insert mode by just pressing ESC, but I have to resort to M-x evil-normal-state. Is it just a problem of mine?

tigerjack avatar May 06 '20 11:05 tigerjack

@tigerjack I'm using holy-mode, not evil-mode, so no, I'm not seeing that...

dmusican avatar May 06 '20 12:05 dmusican

I have no interest in debugging this problem within spacemacs. In order to make progress, I'm going to need some way of reproducing the issue from a simple configuration on top of vanilla emacs.

It's true that a lower value for which-key-idle-delay will cause which-key to "check in" more often and consume more resources, but outside of this issue the resource consumption has never been a problem.

justbur avatar May 06 '20 13:05 justbur

I don't know whether this data point is helpful, but when I trigger garbage collection manually with garbage-collect, the problem disappears for a while.

ivan-lednev avatar May 10 '20 17:05 ivan-lednev

In a session that has been running for a long time, manually triggering a garbage collection also makes it faster for me, for a short time. After running garbage-collect, if I follow the procedure:

  1. Type SPC
  2. Wait for which-key to appear
  3. Type C-g
  4. Repeat

Step 2 noticeably takes a little bit longer each time.

If I restart Emacs, everything is snappy regardless of whether I run garbage-collect, and it doesn't noticeably slow down with repetition.

jakemcarthur avatar Jul 08 '20 14:07 jakemcarthur

I've ran into this problem. The issue is the dolist that ends up doing around 15k iterations per key stroke for me. @hlissner suggested a fix like this before:

(defun which-key--maybe-replace (key-binding &optional prefix)
  (let* ((pseudo-binding (which-key--get-pseudo-binding key-binding prefix))
         one-match)
    (if pseudo-binding
        pseudo-binding
      (catch 'result
        (let* ((all-repls
                (append (cdr-safe (assq major-mode which-key-replacement-alist))
                        which-key-replacement-alist)))
          (dolist (repl all-repls)
            (when (and (or which-key-allow-multiple-replacements
                           (not one-match))
                       (which-key--match-replacement key-binding repl))
              (setq one-match t
                    key-binding
                    (cond ((or (not (consp repl)) (null (cdr repl)))
                           key-binding)
                          ((functionp (cdr repl))
                           (funcall (cdr repl) key-binding))
                          ((consp (cdr repl))
                           (cons
                            (cond ((and (caar repl) (cadr repl))
                                   (replace-regexp-in-string
                                    (caar repl) (cadr repl) (car key-binding) t))
                                  ((cadr repl) (cadr repl))
                                  (t (car key-binding)))
                            (cond ((and (cdar repl) (cddr repl))
                                   (replace-regexp-in-string
                                    (cdar repl) (cddr repl) (cdr key-binding) t))
                                  ((cddr repl) (cddr repl))
                                  (t (cdr key-binding)))))))
              (unless which-key-allow-multiple-replacements
                (throw 'result key-binding)))))
        key-binding))))

does this help speed things up for anyone?

rgrinberg avatar Jul 08 '20 20:07 rgrinberg

@rgrinberg It's possible that that is a source of slow down. I have thought about speeding up that code in the past but it didn't seem to be an issue for anyone, including me. If this is indeed the source of the problem, I would consider a pr.

justbur avatar Jul 16 '20 17:07 justbur

I put up a PR in #255 @peterhoeg and other posters who experienced a slow down, would you mind trying out my patch?

rgrinberg avatar Jul 17 '20 01:07 rgrinberg

I tried it out, and this seems to be a notable improvement. Thanks!

dmusican avatar Jul 17 '20 20:07 dmusican

I still have this issue even after #255 . My profile is more specific, the looping is located in
which-key--replace-in-repl-list-many :

- timer-event-handler                                           17837  93%
 - apply                                                        17837  93%
  - which-key--update                                           17634  92%
   - which-key--create-buffer-and-show                          17634  92%
    - which-key--get-bindings                                   17154  90%
     - which-key--format-and-replace                            16898  88%
      - which-key--maybe-replace                                16728  88%
       - apply                                                  16648  87%
        - which-key--replace-in-repl-list-many                  16598  87%
           which-key--match-replacement                           210   1%
  • My which-key-replacement-alist is 140K in size.
  • garbage-collect has no effect
  • with restart it is performant again, even though which-key-replacement-alist is still big at 100K. However, the above profile still is taking 44% of the CPU. Better than 93% but still a pretty high number.

vv111y avatar Aug 17 '20 12:08 vv111y

Do you really need multiple replacements? I would suggest that you disable them as they're the main source of the slow down and are much trickier to optimize.

rgrinberg avatar Aug 17 '20 18:08 rgrinberg

I had no idea this was an option, checking ...

ADD: okay I disabled it. Let me use it for a while and see how it goes.

vv111y avatar Aug 17 '20 18:08 vv111y

I'm not sure everyone is aware of the automatic string replacement option, described here in the README. Any time it's used it subverts the "generic" replacement mechanism and should be much faster. There are some things you can't do with it, but it should cover most use cases. It also has the conceptual advantage of making it so your description for the command is defined simultaneously with the keybinding itself, making it easy to keep both together in your configuration.

justbur avatar Aug 18 '20 00:08 justbur

Now which-key--replace-in-repl-list-once is the culprit. It is not resolved.

@justbur I am trying that out now.

vv111y avatar Aug 18 '20 10:08 vv111y

@justbur

Any time it's used it subverts the "generic" replacement mechanism and should be much faster.

I am suffering from this too (in spacemacs develop branch with evil-mode).. Is there a specific reason, why which-key has to compute the replacements on every invocation? could the replacements be precomputed and stored in the same way the "automatic replacements" are stored internally? meaning: could the results of the replacements - or even the which-key output be cached?

i have disabled multiple replacements for now and am still testing it..

bitclick avatar Aug 18 '20 13:08 bitclick

I suppose we need to refactor this feature to make it even faster. Justin has an idea on how to do this here. I can take a stab at it if we agree that this is what we should do.

rgrinberg avatar Aug 18 '20 19:08 rgrinberg

Yeah, even setting which-key-enable-extended-define-key t doesn't help. I was wondering what was slow about Spacemacs that was motivating people to switch to Doom. Maybe this is a factor, except I think Doom uses which-key also.

vv111y avatar Aug 18 '20 21:08 vv111y

Maybe this is a factor, except I think Doom uses which-key also.

I use doom and we have the same problem ;) On Aug 18, 2020, 2:18 PM -0700, vv111y [email protected], wrote:

Yeah, even setting which-key-enable-extended-define-key t doesn't help. I was wondering what was slow about Spacemacs that was motivating people to switch to Doom. Maybe this is a factor, except I think Doom uses which-key also. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

rgrinberg avatar Aug 18 '20 21:08 rgrinberg

Huh, go figure. I wonder if we can also make it async (on top of hash tables) for those key-chords that are in muscle memory, but yet have it enabled for those less used features you can't quite remember.

vv111y avatar Aug 18 '20 21:08 vv111y

There’s no need to make it async. Just doing a constant time instead of a linear lookup should be more than enough to make this operation instantaneous. On Aug 18, 2020, 2:28 PM -0700, vv111y [email protected], wrote:

Huh, go figure. I wonder if we can also make it async (on top of hash tables) for those key-chords that are in muscle memory, but yet have it enabled for those less used features you can't quite remember. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

rgrinberg avatar Aug 18 '20 21:08 rgrinberg

Sounds good, I'm looking through the source myself fwiw. Anything I can do to help?

vv111y avatar Aug 18 '20 21:08 vv111y

i have disabled multiple replacements for now and am still testing it..

i can confirm that disabling multiple repacements does not resolve the issue..

bitclick avatar Aug 19 '20 17:08 bitclick

I am suffering from this too (in spacemacs develop branch with evil-mode).. Is there a specific reason, why which-key has to compute the replacements on every invocation? could the replacements be precomputed and stored in the same way the "automatic replacements" are stored internally? meaning: could the results of the replacements - or even the which-key output be cached?

For years there were no complaints, so I left it as is. The mechanism can be changed, but the features would likely have to change too. Technically, replacements can depend on state (like which minor modes are active) and this makes caching difficult. Simplifying what's possible with replacements would make caching a possibility and would speed things up. Just recognize that the problem is not trivial, because in emacs which keys are available when can be complicated. Again, not saying there's not room for improvement here.

Yeah, even setting which-key-enable-extended-define-key t doesn't help.

Doing that by itself does nothing. What that setting does is to allow for you to specify replacements withing define-key itself. These replacements are then specific to the keymap and are actually stored in the keymap itself. This makes looking up these replacements extremely fast. That setting has no effect on replacements specified using which-key-replacement-alist and friends. They are two distinct mechanisms.

I also can't help but wonder how it could be the case that which-key-replacement-alist got so large for some people. I think I have maybe 10 rules in there or something like that.

justbur avatar Aug 19 '20 18:08 justbur

fwiw I have 682 packages installed. Maybe that effects it

vv111y avatar Aug 19 '20 19:08 vv111y

fwiw I have 682 packages installed. Maybe that effects it

It's more of an issue if you have lots of layers (spacemacs) or modules (doom) enabled. Every layer/module adds keybindings and modified the which-key-replacement-alist to prettify the display. This does not scale well.

rgrinberg avatar Aug 19 '20 19:08 rgrinberg

@justbur Thanks for the clarification.

Looks like the replacement feature was not intended to be used with 100s of kilobytes of replacement data. which is not likely to happen when building the list by hand for ones individual config. Now, distributions like spacemacs rely heavily on which-key but seem to misuse the replacements by loading/defining too many rules (for the current implementation). am i understanding this correctly?

making this work in constant time would be great. If that is too much effort for now, maybe the problem could be avoided/mitigated by encouraging developers to use the extended define whenever possible. you could issue a warning message to use extended-define when the replacement list gets above 20k or so.

bitclick avatar Aug 20 '20 07:08 bitclick

fwiw I have 682 packages installed. Maybe that effects it

It's more of an issue if you have lots of layers (spacemacs) or modules (doom) enabled. Every layer/module adds keybindings and modified the which-key-replacement-alist to prettify the display. This does not scale well.

I also happen to have the issue on my spacemacs distribution. I tested with only a handful of layers activated (just helm and ibuffer). I think I had 20k of data in which-key-replacement-alist.

Setting which-key-idle-delay to a very high value seems to fix the issue for now. I've read all comments and that would be the only workaround if I understand correctly?

dindon-sournois avatar Aug 23 '20 07:08 dindon-sournois