reddit / emacs

Integrating embark & link-hint

EFLS_ · 2022-04-29 11:56
Now that I'm using Embark more and more, I'd like to make it play nice together with `link-hint` (https://github.com/noctuid/link-hint.el). What I'm after is: a way to select a link from the screen (with Avy-hints, like `link-hint` does), and then use Embark to open said link. Before I try to achieve this: this probably has been done before? Or do you have some code or ideas to share? (Neither the Wiki's of Embark or link-hint, nor DDG'ing yielded any results...)
akirakom · 2022-04-29 13:42
This issue seems to be related: https://github.com/noctuid/link-hint.el/issues/38
oantolin · 2022-04-29 14:23
I use this in my personal configuration: (defun avy-embark-act (pt) "Use Embark to act on the completion at PT." (unwind-protect (save-excursion (goto-char pt) (embark-act)) (select-window (cdr (ring-ref avy-ring 0))) t)) (add-to-list 'avy-dispatch-alist '(?\; . avy-embark-act)) The ordering of the keys you need to press to us this is a little weird: link-hint, avy-embark-act, select link, select embark action. 🤷 You also should check out the great blog post [Avy can do anything](https://karthinks.com/software/avy-can-do-anything/) by u/karthink, which also has that function (I think maybe with a different name and assigned to a different key), and many other great Avy tips.
EFLS_ · 2022-04-29 18:48
Ah yeah, calling embark directly from avy that might be a good approach. Thanks for the snippet. I read Karthink's post previously, and it didn't occur to me to put Avy first and call Embark from there for this specific issue. Thanks for your reply (and for writing Embark!)
oldjawbone · 2022-04-29 19:55
You might consider something comparable to my [link-hint-aw-select](https://localauthor.github.io/posts/aw-select.html) \-- `link-hint-embark-act`? Compared to u/oantolin's suggestion, it's a bit more involved in the setup, but maybe more streamlined in usage? You wouldn't have to call `avy-embark-act` before selecting a link, but you would have to call the specific `link-hint-embark-act` function instead of the more general `link-hint-open-link`. You would also have to define the action for each link type you wanted to use it on. You would first define the function: (defun link-hint-embark-act () "Use avy to call 'embark-act' on a link." (interactive) (avy-with link-hint-embark (link-hint--one :embark-act))) Then you would have to specify the action to take (namely, embark-act) for each link type you want to use it on; for example: (link-hint-define-type 'org-link :embark-act #'(lambda () (call-interactively #'embark-act))) (link-hint-define-type 'file-link :embark-act #'(lambda () (call-interactively #'embark-act))) EDIT: If you're feeling adventurous, you could define the above action for all link types at once: (mapc (lambda (x) (let ((fn (string-trim-left (symbol-name x) "link-hint-"))) (link-hint-define-type `,(intern fn) :embark-act #'(lambda () (call-interactively #'embark-act))))) link-hint-types)
oantolin · 2022-04-29 22:45
This very nice! Thanks for posting it. As a tiny simplificaction, it's not necessary to call `embark-act` interactively here, so you can just use `#'embark-act` as the link-hint action directly. (Also, even if you did the need the lambda, there is no need or benefit from using `#'` with a lambda.) One advantage of my less streamlined setup is that I get `embark-act` as an avy action for all avy commands, not just link-hint-open-link. I often use it with `avy-goto-word-1`, for example to act on a non-link thing I can see on screen.
oldjawbone · 2022-04-30 04:53
I tried calling embark-act non-interactively first, but oddly the embark target was always off by one, such that it was necessary to call embark-cycle once to get the correct target for the link at point. I tried using edebug to step through embark-act to see what was going on, but I got lost :) Can you replicate that result? If not there may be something fishy on my end.
EFLS_ · 2022-04-30 12:33
Oh hi local-author! Thanks for your suggestion. This is precisely what I'm looking for. Works almost: Embark doesn't seem to recognize the links as 'links', but as 'expression'. I'll probably also have to add Org-links as Embark target. > If you're feeling adventurous... I know my way around basic Elisp, but that goes over my head :) I'll keep it simple even if it is a bit more elaborate.
oantolin · 2022-04-30 16:18
True, good catch! I hadn't noticed, but apparently the avy-action is getting called with a prefix argument of 1. You don't need to call embark-act interactively but you do want to call it without a prefix, so `(lambda () (embark-act))` works too.
oldjawbone · 2022-05-01 07:04
Hey EFLS! 👋 I’m curious about the prospect of using embark on org-links, since it’s such a varied type of link. What actions would you hope to invoke on an org-link other than open-at-point? Also, that mapc function can just be evaluated as it is, no need for elisp knowledge. ;) I can explain what it does if interested. But of course, there’s more than one way to get the same result in the end. Whatever works.
EFLS_ · 2022-05-01 09:27
> What actions would you hope to invoke on an org-link other than open-at-point? I've got mostly links to either PDF files that I sometimes want to view within Emacs and sometimes in an external application. The same goes for websites. > Also, that mapc function can just be evaluated as it is, no need for elisp knowledge Yeah I see, but I prefer understanding the things I put in my config, so I can debug them when needed.
oldjawbone · 2022-05-07 11:25
You might be interested to know that there’s an “embark-org.el” being developed right now, to allow embark to recognize org elements, including links: https://github.com/oantolin/embark/blob/master/embark-org.el
EFLS_ · 2022-05-08 13:26
Thanks, looks promising!