Bidirectional links with eev

Eduardo Ochs

The following image shows where the talk is in the schedule for Sat 2022-12-03. Solid lines show talks with Q&A via BigBlueButton. Dashed lines show talks with Q&A via IRC or Etherpad.

Format: 8-min talk followed by IRC Q&A (#emacsconf-dev)
Discuss on IRC: #emacsconf-dev
Status: Q&A finished, IRC and pad will be archived on this page


Consider the two sexps below:

(code-c-d "foobar" "/tmp/foo/bar/" :anchor)
(code-c-d "fb"     "/tmp/foo/bar/" :anchor)

Each one of them defines several "short hyperlink" functions. After running them the three sexps below are roughly equivalent:

(find-file "/tmp/foo/bar/plic.txt")
(find-foobarfile "plic.txt")
(find-fbfile "plic.txt")

The "code-c-d"s above also define functions with even shorter names – find-foobar and find-fb - that point to "anchors" in files in the directory /tmp/foo/bar/. The three sexps below are roughly equivalent -

(find-fline "/tmp/foo/bar/plic.txt" "«bletch»")
(find-foobar "plic.txt" "bletch")
(find-fb "plic.txt" "bletch")

Until feb/2022 the only way that I had to produce these hyperlinks to anchors quickly required a LOT of muscle memory… I had to type this,

M-1 M-h M-w  M-h M-h  9*<down>  M-h M-2  M-h M-y  M-h M--  M-h M-w  M-k

where the number of "<down>"s depended on whether I preferred find-foobar of find-fb - i.e., of on what is my preferred "code" for the "directory" /tmp/foo/bar/; either "foobar" or "fb".

In this presentation I will show a much better way to generate short hyperlinks to anchors and push these short hyperlinks to the kill ring, and how I use that to create bidirectional hyperlinks between my notes on a language $LANGUAGE and programs written in that language.

For more info see this page.


  • Q: Can you say why you like all your links to be elisp expressions rather than something more textual? Is it just so you can always evaluate the expressions?
    • A: rswgnu5: it is quicker to create hyperlinks that don't have titles, and many years ago I had some problems when I gave titles that were not very good, and I ended up with links that didn't do what I expected, so I sort of stopped trusting links whose actions are hidden and only their titles are shown. also, I am trying to write code in which all parts are easy to understand.
  • Q: I am fond of and inspired by your idea of Lisp Markup & Interfaces. Have you thought of other Lisp Markup uses than Links? How do you think of incorporating tree-sitter? If that makes sense to you or at all.
    • A: can you explain your idea? I haven't had time to play with tree-sitter yet, but my holidays will start in a few weeks... I sometimes get stuck trying to understand the inner details of things whose inner details shouldn't be relevant... I had this problem with both Org and Hyperbole several times, and I guess that I will have it with tree-sitter too...
      • edrx: I don't have a concrete idea. I just have been thinking of the intersection of Markup, minimalist Textinterfaces and little Languages | language oriented programming for a while. Eg Lisp is a nice List/ tree data syntax. You use it for links. Do you have other markup like uses for? And speaking of tree data, tree-sitter is a tool to incrementally & robust build a tree from a flat text buffer.
        • do you know this?
  • Bi-directional links is a good idea.
  • I look forward to trying it out and seeing how it feels. It certainly looked cool!
  • awesome! btw edrx i'd really enjoyed the last eev workshop, would be totally down to attend another one later too
  • An interesting link type to add would be org id for org roam or denote id link types.
  • I've been trying to use eev to explore parts of Emacs that I don't understand... a basic example is M-x list-packages
  • Something to love about org mode, hyperbole, and eev is how they push the idea of links further


Hi! My name is Eduardo Ochs. I'm the author of an Emacs package called eev, and the name of this presentation is: "Bidirectional links in eev". Let me present things in a weird order, starting by the new feature, and then I'm going to explain the whole context. One of the main features that we are going to see here is this function here, M-x kla, and kla is a mnemonic for "kill Link to Anchor". Let me explain... let me demonstrate how it works. This thing here with the green angle brackets is an anchor, this thing between the green angle brackets is a tag of an anchor, and if I type M-x kla here it highlights this tag for a second and it says "Copied to the kill ring: blah blah blah..." and this thing here is a link. I can insert the link here, I can insert the link in my notes... and if I execute this thing this link here it goes to this anchor in this file. If you have a recent version of eev installed then trying this feature should be very easy... you just need to open the this file here, in which everything is defined, and then go to this section at the beginning of the file, and then run the three blocks of tests that are there. This block corresponds roughly to what we have just done... this other block is slightly different because it shows some variants of kla... one is with f instead of an a here, let me show how it works... if we type M-x eeklf or just M-x klf we get a link to this file that does not point to an anchor, and if we type M-x klt we get another kind of link that is a link to an anchor in the same file... and the third block is more interesting because it lets people create links to files that are elsewhere, and that do not have anchors in them... let me execute this... this will run this sexp here and display the target at the window at the right... this is one of the source files of Emacs. Let's imagine that I want to create a link to this string here... then I can type M-x klfs, and this will create a link to a file and to a string in that file. So if I type ENTER here it says: "Copied to the kill ring: ...\ and this is a link to this file here, and to the first occurrence of this string in this file. So: how does this work (inside)?... when I was trying to write the documentation of this I tried to write a summary of how the algorithm works, and I failed and I tried again, and I failed again, several times... and then I gave up and I decided to write an intro - a tutorial, this one - that explains everything with lots of details, and with lots of sections with "Try it!"s, that have examples that you you can run to understand things, to examine how some functions work, how the data structures work, and so on... the problem is that sometimes we have several hyperlinks that point to the to the same file. Let me give an example. In the configuration in which I am now, in this file here... the old way of generating hyperlinks to this file with find-here-links will generate a temporary buffer like this, and then I would have to choose which one of these hyperlinks I find best, which one I prefer, and then copy it to my notes... so instead of choosing a hyperlink this thing here shows all the options. And in the new way, in M-x kla and friends, there's an algorithm that chooses the best short hyperlink by itself, and this algorithm is a bit hard to explain... let me demonstrate it here. Again, we have all these options here, of hyperlinks to this file... and if I type M-x klf it chooses one of them. And of course I can copy it to my notes, it's going to work, it's going to point to here... and so on. Well, the title of this presentation was "Bidirectional links with eev"... let me show what I mean by bi-directional hyperlinks, and how we can use this thing to create bidirectional hyperlinks very quickly. I will have to use a smaller font... let me open these two files here. This one at the left is a program in Haskell, and this one is a file with my notes on Haskell. How do I create a link from... to this file in Haskell to put it in this file here? I can put the cursor here, in any position after this anchor here, and type M-x kla... it copies this link here to the kill ring and then I can can go here and either insert it with C-y (yank), or insert it with M-k kli, that adds a comment prefix here. So this is a way to create a link from here to there in which every comment has to be given explicitly... but I also implemented a way to create the two links at the same time. I don't use it much, it's mostly for demos, because it's impressive, I wanted to show that in this presentation... Anyway, let me show it here. Note that that in this file here the point is here, in this file the point is here... My trick is going to create a link to this anchor and put it in this file, and it's going to create a link to this anchor and put it in this file... So, here it goes: M-x kla2... ta-da! it highlighted the true anchors for a second, and it created these things here and inserted them with the right prefixes, I mean, the right comment prefixes. And that's it! So... that's it. If you found this thing interesting just install a recent version of eev and run the tutorial, either with this thing here, M-x find-kla-intro, or by running this sexp, or open this file here in the eev directory, and follow the tutorials... most things that there are well documented, but the thing that I don't use much and that is mostly for demos, which is the the thing that creates bi-directional hyperlinks, is not yet well documented, but the rest is. So: that's it! Bye! Have fun! =)

Questions or comments? Please e-mail