Understanding Clojure’s datafy and nav



Datafy and nav: an API for generic graph navigation.

“Graph navigators as user interface” is an idea that has been stuck in my mind for a while. I’ve been asking myself why I like the user interface I get from Emacs, Dired, Magit and projectile. It’s so simple. There’s a buffer with a mode and some “open thing”. Then you can do stuff on that buffer.

Web browsers are graph navigators, file managers are graph navigators. The terminal is a graph navigator.

Graph navigator Serialized location
Web browser URL
File manager Folder path
Terminal Folder path

fzf is a tool for making graph navigators. It’s user interface is amazingly simple. Put locations on STDIN, and you get the user’s selected location (or action) on stdout.

What does that have to do with datafy and nav? Datafy and nav decouples the functionality providing graph navigation capability from the user interface that lets the user choose where to navigate.

I stumbled into my curiosity about fzf after realizing how easy it is to build useful tools on top of it. I created teodorlu/browsetxt by accident exploring that. “Where’s somewhere there are locations and links?” The web. “How can one browse the web?” Let’s try! There it is.

My current conclusions, per 2023-02-14:

  1. Graph navigators are powerful UIs
  2. teodorlu/browsetxt is fun, but “cares about too much”. I believe datafy/nav could be a way to uncouple it.

API for “browsetxt on datafy/nav”:

  1. starting point
  2. function to get next location from (datafy current-location)

Datafy/nav and laziness. Putting all the data in memory is going to break down sooner or later. Datafy/nav is a way to push generic navigation functionality up to the user without giving the user the whole world. It’s a lazy view over the full graph!

Idea: text-based graph navigation over a roam database. Q: what would I use this for? Do I need it? Eeeeh.

Idea 2: exploring play.teod.eu as a graph. Q: what would I use this for? Do I need it? Can’t really think of anything.

Back to that API.

  1. starting point
  2. function to get next location from (datafy current-location)

Something like:

(fzf-nav starting-point

… but … there’s something missing. If we made a web browser on that API, we would never view pages. We’ve made a state machine that can only move around. What good is that? No good!

This is where we need a use case :)

We could port browsetxt over. Then we would need to provide:

  1. An exit
  2. A way to view a web page

Or we could use it to make fzf-quickcd. Quickly jump to different places. But why?

One why: to connect thoughts together. Right now, I’m leaning on IDE functionality to move around. I have to keep remembering things.