vifon · 2022-02-10 16:20
Hello.
I often need to act with Embark not on the symbol or plain value, but rather on the result of its evaluation. For example I'd like to be able to open the value of `user-emacs-directory` by using `embark-act` on this symbol. Is there some trick I've missed?
I tried using `M-:` after `embark-act` as it could work as a workaround, but I didn't find a way to make it ask me to edit the resulting expression either.
Could someone nudge me in the right direction? An info how to force embark to show me an interactive prompt for some commands (like it already does OOTB for some) would be a nice bonus.
EDIT: It seems the latter is possible by customizing `embark-target-injection-hooks` ([link](https://github.com/oantolin/embark#running-some-setup-after-injecting-the-target)). I correctly remembered there was a variable directly controlling this behavior but it was removed since then, hence why I couldn't find it anymore.
oantolin · 2022-02-11 00:05
The solution you found (sorry for the changes!) seems fine, namely:
(push 'embark--allow-edit
(alist-get 'eval-expression embark-target-injection-hooks))
But maybe a more direct interpretation of what you wanted is this:
(defun act-on-variable-value (variable)
(interactive "SVariable: ")
(with-temp-buffer
(insert (symbol-value variable))
(embark-act)))
(define-key embark-variable-map "V" #'act-on-variable-value)
And finally a "zero customization" solution: use the `v` action, which runs `embark-save-variable-value` to save the value on the kill-ring; then run the desired action as a normal command and yank the variable value at the minibuffer prompt.
vifon · 2022-02-11 01:21
Thanks a lot for a detailed reply! It helped a lot.
Your second example is exactly what I needed. This is what I ended up with:
(cl-pushnew 'embark--allow-edit
(alist-get 'pp-eval-expression embark-target-injection-hooks))
(defun embark-act-on-with-eval (expression)
"Evaluate EXPRESSION and call `embark-act' on the result."
(interactive "sExpression: ")
(with-temp-buffer
(insert (eval (read expression)))
(embark-act)))
(dolist (keymap (list embark-variable-map embark-expression-map))
(bind-key "v" #'embark-act-on-with-eval
keymap))
In case you're wondering: I'm fully conscious I'm replacing the default `v` binding for variables. I should be able to replicate the stock one with `v``w` here. Do you think it would be worth it to generalize it like this in the upstream?
I wonder if it's possible to utilize `eval-expression` instead, as this function is basically `insert` + `eval-expression` + `embark-act`. It's almost begging to be composable in one way or another.
oantolin · 2022-02-11 03:16
I'm glad you could solve your problem!
I hadn't realized you wanted this ability to act on values for expressions too, which is why I only wrote a version for variable values.
> Do you think it would be worth it to generalize it like this in the upstream?
My imagination is failing me, but I can't picture many uses for this generalization. Would you mind sharing your use cases?
vifon · 2022-02-11 03:29
I have lots of expressions such as:
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
In such case, it'd be (and now it *is*) very convenient to be able to `embark-act` on such expression and follow up with `find-file` on the result of its evaluation, i.e. the actual file it refers to. Works well with `no-littering.el` too.
oantolin · 2022-02-11 03:44
I see. That's pretty cool but it seems a little too specialized, so I don't think it's a great fit for Embark itself. I'd love to have it as an example on the wiki though.
vifon · 2022-02-11 17:08
FYI: I've just added it in here: https://github.com/oantolin/embark/wiki/Additional-Actions#elisp-expressionvariable-actions
Thanks for your help again, and for Embark itself!
oantolin · 2022-02-11 17:36
Awesome, thank you!