DEV Community

Jeremy Friesen
Jeremy Friesen

Posted on • Originally published at on

Creating a Documentation Dashboard and Emacs Function

Reducing Friction on Adding Placeholders for My Future Self

This post further builds on Slowing Down to Synthesize and also incorporates ideas from Alex Schroeder: 2021-09-17 Writing to learn.

When I started at Forem, there were lots of new web pages that I didn’t want to forget. I wanted to annotate and tag those web pages. I chose not to use my browser’s bookmarks and instead chose to create an Org-mode 🔍 document. That document resides in my private repository for Forem Org-roam 🔍 directory.

Crash Course Org Mode

Here is one of the several entries in my Dashboard:

** [[][Forem Team 🌱]] :communication:documentation:

This is where we have long-running conversations
Enter fullscreen mode Exit fullscreen mode

The leading ** indicates a heading level two in org-mode; analog to Markdown’s ##.

The [[url][text]] is a link and it’s text.

The :communication:documentation: are two tags that I’ve assigned to that heading. And last the This is where… is a paragraph description.

My goal was to write down and remember these different sources of possible information or tools to use.

Scripting the Dashboard

With a place to capture the data, I then wrote a Ruby script to open each of those web pages in my default browser. I wrapped that Ruby script with an Emacs 🔍 function. Later, I replaced that Ruby script with a ripgrep invocation.

I mapped that Emacs function Cmd+Opt+Ctrl+d to open my dashbard files in the browser. I also added a bit of logic that said if you first type Emacs’s universal modifier (e.g., C-u, that is Ctrl+u) then invoke the function it will instead open the Dashboard’s source file.

Below is that code:

(defconst jnf/forem-dashboard-filename
      "The file to the dashboard documentation and links for Forem.")
;; In OS X this is CMD+OPT+CTRL+d
(global-set-key (kbd "C-M-s-d") 'jnf/open-dashboard)
(cl-defun jnf/open-dashboard (&key (filename jnf/forem-dashboard-filename))
  "For the given FILENAME open the links in the default browser.

With the universal prefix (e.g. C-u) open the file instead."
  (if (equal current-prefix-arg nil)
       ;; Double escaped because I'm passing this
       ;; string to the command line.
       (concat "rg \"\\[\\[(.*)\\]\\[\" "
               " --only-matching"
               " | rg \"[^\\[|\\]]+\" --only-matching"
               " | xargs open"))
    (find-file filename)))
Enter fullscreen mode Exit fullscreen mode

Let’s dive into the above ripgrep command (for convenience I’m removing the double escaping):

First we have rg "\[\[(.*)\]\[" filename --only-matching. That command finds only the [[url] portion in the given filename.

Then we pipe that to rg "[^\[|\]]+" --only-matching. This further narrows that search to only select the url.

And last, I pipe this to xargs open. In essence, that then runs the open command from OS X on each of the matching URLs.
open on a URL string will open that URL in the default browser.

My plans for this function are to prompt for a tag, and limit opening only web pages with matching tags. So far, I haven’t needed it.


In the early days of a new job, there’s a lot of information intake. I created a Dashboard document to provide a consistent place to capture that information; I knew I didn’t want to lose track of it. The Dashboard document reduces the friction of deciding where to put things.

It was rather quick to write up the functions (Ruby, Ripgrep, and Lisp). Most important to me, is that writing these functions helps re-iterate that my text editor configuration is a continual work in progress. My text editor is an extension of my current understanding, and I should use it and extend it to help me learn and capture ideas.

Top comments (0)