Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

customized prefix-help-command does not work when C-h is invoked after which-key popup is displayed #3

Open
mbkamble opened this issue Oct 13, 2021 · 2 comments

Comments

@mbkamble
Copy link

mbkamble commented Oct 13, 2021

I am trying to use embark-prefix-help-command (from embark package) as the choice for C-h when which-key pop-up contains too many bindings.

These are the configurations I use for these packages:

(use-package which-key
  :blackout t
  :init
  (setq prefix-help-command #'embark-prefix-help-command)
  (which-key-mode 1))
(use-package embark
  :demand t
  :bind
  (("C-." . embark-act)         ;; pick some comfortable binding
   ("C-;" . embark-dwim)        ;; good alternative: M-.
   ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'

  :config
  ;; Optionally replace the key help with a completing-read interface
  (setq prefix-help-command #'embark-prefix-help-command)
  
  ;; Hide the mode line of the Embark live/completions buffers
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none)))))

;; using the example from hercules README
(hercules-def
 :toggle-funs #'org-babel-mode
 :keymap 'org-babel-map
 :transient t)
 
;; tweak binding to taste
(define-key org-mode-map (kbd "C-c C-v") #'org-babel-mode)

Then if I visit an org file such as README.org, and press C-c, wait for the which-key popup and then press C-h, I get the completing-read functionality of embark-prefix-help-command. But if I do C-c C-v and then C-h, it shows which-key-C-h-map bindings where the n -> next-page, p -> previous-page, etc are displayed.

How do I fix this, so that C-h uses embark-prefix-help-command even for hercules?

@mbkamble
Copy link
Author

mbkamble commented Oct 14, 2021

I realized one thing : that prefix-help-command will be triggered only if we press C-h in when the key sequence is a prefix. In case of the command defined by hercules-def, the key binding is to a leaf command. So even though we have the which-key interface to provide further commands, the command that invokes the hercules popup is not a prefix.
So, I doubt if my desired goal described above can be achieved.

Does anyone have any suggestion to support searching for target command when the keymap displayed by which-key is very densely populated?

@jeff-phil
Copy link

jeff-phil commented Feb 20, 2024

@mbkamble Just saw this after several years while submitting a new PR, not sure if still issue for you.

Here's a macro I came up with to stick C-. keycode to trigger embark-bindings-in-keymap for the hercules popup. It only adds when keymap has more than 20 items to add it in there. You can change it around below.

(cl-defmacro my/hercules-maps-helper ( show-funs keymap flatten
                                       &rest hercules-def-args)
  "Create `hercules' pop-up map.  This is basically same as using `hercules-def'
    directly, but I moved the three keys I use most SHOW-FUNS, KEYMAP and FLATTEN to
    first three parameters.  This way I don't need to be as verbose on creating. Add
    the other parameters by passing HERCULES-DEF-ARGS with same keys from
    `hercules-def'. This also adds an `embark' action \"C-.\" to list all keys when
    larger list of keys: (> (length MAP) 20)."
  (let ((which-key-sort-order nil)
        (toggle-funs `'(,@(plist-get hercules-def-args :toggle-funs)))
        (transient (plist-get hercules-def-args :transient))
        (blacklist-keys (plist-get hercules-def-args :blacklist-keys))
        (whitelist-keys (plist-get hercules-def-args :whitelist-keys))
        (blacklist-funs (plist-get hercules-def-args :blacklist-funs))
        (whitelist-funs (plist-get hercules-def-args :whitelist-funs))
        (package (plist-get hercules-def-args :package))
        (hide-funs `'(keyboard-quit
                      read-from-minibuffer
                      embark-bindings-in-keymap
                      ,@(plist-get hercules-def-args :hide-funs)))
        (map-sym (intern (format "my/hercules-helper-map-%s" keymap))))
    `(progn
       (setq ,map-sym (make-sparse-keymap))
       ;; (unless (string= (symbol-name ,show-funs) "my/show-hercules-maps")
       ;;   (keymap-set ,map-sym "H-z" #'my/show-hercules-maps))
       (when (> (length ,keymap) 20)
         ;; Remind at top about using Embark bindings
         (keymap-set ,map-sym
                     "C-."
                     '("++Embark Keys!++" .
                       (lambda ()
                         "Show all keybinds for this keymap in Embark listing."
                         (interactive)
                         (unwind-protect
                             (embark-bindings-in-keymap ,keymap)
                           (call-interactively ,show-funs))))))
       ;; Add these together.
       (set-keymap-parent ,map-sym ,keymap)
       (hercules-def
        :toggle-funs ,toggle-funs
        :show-funs ,show-funs
        :hide-funs ,hide-funs
        :keymap ',map-sym
        :flatten ,flatten
        :transient ,transient
        :blacklist-keys ,blacklist-keys
        :whitelist-keys ,whitelist-keys
        :blacklist-funs ,blacklist-funs
        :whitelist-funs ,whitelist-funs
        :package ,package))))

Then as example, here's how I create the hercules map edebug with above macro:

  (require 'edebug)
  (with-eval-after-load 'edebug
    (my/hercules-maps-helper #'my/hercules-edebug-commands edebug-mode-map t
                             :toggle-funs (edebug-mode) 
                             :hide-funs (edebug-help)) ;;"?"
    (keymap-set emacs-lisp-mode-map "H-z d" '("edebug-mode" . my/hercules-edebug-commands)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants