TranslateProject/sources/tech/20210111 an even better video wharf.md
DarkSun 59f771e526 选题[tech]: 20210111 an even better video wharf
sources/tech/20210111 an even better video wharf.md
2022-07-21 16:29:04 +08:00

5.4 KiB

an even better video wharf

A couple of days ago, i was writing about embark and my first experiment defining a new embarking to play remote video streams. Omar Antolín Camarena, embark's author, has been kind enough to not only read it, but comment on a couple of significant improvements that i think well deserve this follow-up.

First, you'll remember that we were defining a function to detect a video URL:


    (defun jao-video-finder ()
      "Check whether we're looking at a video URL.
    Return (video-url . <URL>) if so."
      (when-let ((url (thing-at-point-url-at-point)))
        (when (string-match-p jao-video-url-rx url)
          (cons 'video-url url))))

Once we've got a non-null url value, even if it's not a video URL, it's still certainly a URL, and embark has a url category, so we could save a new parsing by the default URL finder by saying:


    (when-let ((url (thing-at-point-url-at-point)))
      (cons (if (string-match-p jao-video-url-rx url) 'video-url 'url) url))

This has the potential drawback that we're overriding embark's finder, embark-target-url-at-point, and we might prefer to keep the latter.

Turns out that we can do that thanks to embark's target transformers. One can add to embark-transformers-alist an arbitrary function to be applied to a target of any given category, and embark will apply its actions to the transformed value. Omar calls this process, very aptly, a refinement of the target; here's how we would do it:


    (defun jao-refine-url-type (url)
      "Refine type of URL in case it is a video."
      (cons (if (string-match-p jao-video-url-rx url) 'video-url 'url) url))

    (add-to-list 'embark-transformer-alist '(url . jao-refine-url-type))

With this strategy, we don't need jao-video-finder at all, and it also makes lots of sense, conceptually, to have our video-url defined as a refinement rather than a new target1. Omar's second suggestion is also in line with this concept: surely we want all actions available for url also for our video-url, don't we? Well, that's exactly the reason why the embark-define-keymap macro we used to define our actions can inherit all the actions already defined in another keymap, using the :parent keyword2:


    (embark-define-keymap jao-video-url-map
      "Actions on URLs pointing to remote video streams."
      :parent embark-url-map
      ("p" jao-play-video-url))

    (add-to-list 'embark-keymap-alist '(video-url . jao-video-url-map))

It is worth noting that this ability to inherit a keymap is not really an embark add-on: vanilla Emacs keymaps already have it, via the standard function set-keymap-parent. You could actually define jao-video-url-map without using embark-define-keymap at all, and it'd work exactly the same.

So, our code has become shorter and more featureful: thanks, Omar!

Footnotes:

1

There's a scenario where keeping jao-video-finder could make sense, namely, if we want to alter the URL detection function. For instance, i use emacs-w3m, and there often a URL is stored as a text property (the actual text being the link text). To retrieve the URL at point there, one needs to call w3m-anchor, and embark-target-url-at-point will miss it. For that scenario, i ended up writing (and using) jao-video-finder defined with:


    (when-let ((url (or (w3m-anchor) (thing-at-point-url-at-point))))
      (cons (if (string-match-p jao-video-url-rx url) 'video-url 'url) url))

Another way of accomplishing the same thing (with another tip of the hat to Omar) would be to add a specific finder for w3m anchors (and keep using the transformer for video-url):


    (defun jao-w3m-url-finder ()
      (when-let ((url (w3m-anchor)))
        (cons 'url url)))

    (add-to-list 'embark-target-finders #'jao-w3m-url-finder)

This way is more modular and, depending on your taste, more elegant. These functions are small and there's not a big difference between the two approaches, but if one keeps adding finders, things can easily get uglier with the former approach.

2

In my original example, i was adding also browse-url and browse-url-firefox to the video map. The former is no longer necessary, because it's already present in embark-url-map. If we wanted to make browse-url-firefox available to all URLs, we could add it to embark-url-map (remember, embark's keymaps are just Emacs keymaps). That's yet another simple way of extending embark.

Tags: emacs


via: https://jao.io/blog/2021-01-11-an-even-better-video-wharf.html

作者:jao 选题:lujun9972 译者:译者ID 校对:校对者ID

本文由 LCTT 原创编译,Linux中国 荣誉推出