
Malleable Computing, Emacs, and You
It all started with a routine task. I use GitHub issues for all of my public-facing projects but my preference is keeping track of things in Org Agenda. To reconcile the two, I would manually copy over the GitHub issue to an Org file, typically the title and description, like an animal .
Despite this separation, the duplicated issue allowed me to treat it as a scratchpad for anything I could express in Org. In this way, I used the duplicated issue in Org as both a dedicated area to take notes and a “staging” area to compose follow-up comments that I’d want to share in the public facing issue.
I manually copied for far longer than I care to admit. Repeat a task enough times in Emacs and the inevitable thought arises: “I should automate this.”
This post recounts how I automated this task and in doing so, highlight the malleable computing capabilities of Emacs. It should also be considered a follow-up to my earlier post “ In Emacs, Everything Looks Like a Service ”.
An essential question to ask in any automation exercise is “What do I want done?”
Another essential question to ask is “What do I not want to do?”
With the above requirements in place, the next question is “how do I build this?”
For this particular exercise, I decided to leverage my existing install of the GitHub command line utility gh . The benefits for this are:
Emacs can treat gh as a REST service to GitHub as shown in the diagram below
To flesh out the rest of our tool, we can leverage using different Elisp packages and programs:
For the user interface, the Transient and Variable Pitch Table (vtable) packages are used for menus and display respectively.
For Org to Markdown translation, ox-gfm will be used.
For Markdown to Org translation, Pandoc will be used.
Elisp native JSON support will be used for deserializing the JSON responses from gh .
The implementation of the above is published as the package fj with its source available for examination in the file fj.el . Of note is the function fj-request-issues which does the work of retrieving GitHub issues via gh as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ( defun fj-request-issues ( repo ) "Request issues for REPO." ( let* (( fields fj-browser-fields ) ( cmd-list ( list "gh" "--repo" ( format "'%s'" repo ) "issue" "list" "--limit" ( number-to-string fj-request-issue-count ) "--json" ( string-join fields "," )))) ( json-parse-string ( shell-command-to-string ( string-join cmd-list " " )) :null-object nil ))) Consider the high degree of abstraction provided by fj-request-issues :
Hacker News
news.ycombinator.com