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

Better way to run a pre-action-hook + default-action? #729

Open
karthink opened this issue Aug 21, 2024 · 0 comments
Open

Better way to run a pre-action-hook + default-action? #729

karthink opened this issue Aug 21, 2024 · 0 comments

Comments

@karthink
Copy link
Contributor

Hi @oantolin,

I have a question about using embark-around-action-hooks to run a function before running the default action. This is not an issue or bug with Embark, but I didn't see a discussions page so I'm posting here.

I often use Embark to run the default action but in a different window, for example to run bookmark-jump but then open the bookmark in another tab or split, or in a window specified by ace-window. I was previously defining custom actions for each category/embark keymap, but this doesn't work uniformly. For example, this kind of dispatch is unavailable when running org-roam-node-find, and when running Embark inside a diff in magit-status (to decide where to open the diff). Following the method listed in the wiki that uses embark-around-action-hooks, I switched to the following code instead:

;; Dummy function, will be overridden by running `embark-around-action-hooks'
(defun my/embark-window-prefix-dummy () (interactive))

(setf (alist-get 'my/embark-window-prefix-dummy embark-around-action-hooks)
      '(my/embark--call-prefix-action))

(defvar-keymap my/window-prefix-map
  :doc "Keymap for various window-prefix maps"
  :suppress 'nodigits
  "o" #'ace-window-prefix
  "0" #'ace-window-prefix
  "1" #'same-window-prefix
  "2" #'split-window-vertically
  "3" #'split-window-horizontally
  "4" #'other-window-prefix
  "5" #'other-frame-prefix
  "6" #'other-tab-prefix
  "t" #'other-tab-prefix)

;; Look up the key in `my/window-prefix-map' and call that function first.
;; Then run the default embark action.
(cl-defun my/embark--call-prefix-action (&rest rest &key run type &allow-other-keys)
  (when-let ((cmd (keymap-lookup
                   my/window-prefix-map
                   (key-description (this-command-keys-vector)))))
    (funcall cmd))
  (apply run :action (embark--default-action type) :type type rest))

(map-keymap (lambda (key cmd)
              (keymap-set embark-general-map (key-description (make-vector 1 key))
                          #'my/embark-window-prefix-dummy))
            my/window-prefix-map)

This runs a *-window-prefix command right before calling the default action, so the display-buffer action that's the result of the default action is shown in the desired destination.

(Note: ace-window-prefix is like other-window-prefix but you can decide where you want to display the buffer just-in-time using an ace-window action, it's documented here.)

This works but has two issues:

  1. For multi-category commands like consult-buffer, the default action is not run correctly. For example, pressing t when using embark-act with consult-buffer opens a new tab, but not the buffer/file in that tab. I'm not sure why. Single source commands all work as expected with this embark action.

  2. It seems roundabout to have to define a dummy function (my/embark-window-prefix-dummy) and a hook that does the actual calling. Is there an easier way to define an embark action that runs some code followed by the default action? I looked into embark-pre-action-hooks but this requires about the same amount of indirection (or more, I'm not sure) to work.

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

1 participant