Casting Confidence

Tagged as elisp, emacs, functions

Written on 2021-06-02

I realize that I'm not really a full Clojurian or Lisper, yet.

Deciding to learn a language is not the same as speaking it, nor is it being fluent enough to really claim membership. I've read parts of a couple books, and run a few prewritten programs. But the other day, I did something that (after the fact) I realized was worth talking here about. Something that made me smile.

A Package

I was poking around in Emacs, as I do from time to time, and I found (among others) a package based around the I Ching. I installed it, and found it to be fairly functional. It was slightly annoying that it wasn't possible to cast (randomly determine a hexagram) and interpret (describe the meanings associated with the hexagram), but that was simple enough to do in sequence.

It had one problem, though: It would display everything in the minibuffer—even if the text to display was paragraphs long.

This was a problem for me for a couple of reasons. First, I'm a fan of keeping my minibuffer exactly one character tall. Not a huge deal, honestly, but definitely a preference. But the bigger reason was a matter I take fairly seriously.

A Problem

If it displays the result in the minibuffer, I can't do anything while I am looking at the information.

If I open a buffer, run a command, type a character... as if it were a squirrel encountering a human child for the first time, the result dashes off into the understory, never to be seen again. So, naturally, I needed to solve this problem. And with my recent focus on Lisp in general, I actually felt confident I'd be able to do it.

With a quick C-h f to lookup the definition of the function I was calling, I was off into the library's file.

I knew from learning the basics of Lisp that the functions I was calling would return the last value listed in their definition. The casting function, i-ching-cast, returned one of two things: either one hexagram, or two if doing a more complicated pull. For now, I decided to stick with a simple cast to make the function output simple: It would return 1 hexagram, in unicode.

Which was helpful, because the next package function I needed was i-ching-interpretation, which could either take the hexagram number, or the hexagram itself, as a parameter. I now could, in one function, randomly determine and reliably describe a hexagram in the minibuffer.

Now I just had to send that result to a temporary buffer.

A Solution

I looked online for a solution, but like many things in life it was actually an accident that would lead me to the answer. I was looking at the functions I was given by the package when I stumbled across one I'd yet to use: i-ching-query. It did nearly what I meant to do to begin with: randomly determine a hexagram and describe it in a temporary buffer (albeit after requiring the user to enter a string). But there were a few other choices that were made that I disagreed with.

Obviously, the question-string prompt had to go, since it would slow down the result. (It was also discarded, so entering it was purely an exercise for the user.) But the resulting buffer was also not wrapped at 70 columns. And there were a few extra function calls that seemed unnecessary, at least for my purposes.

(defun i-ching-pull ()
  "Casts and Displays the Interpretation of a Hexagram."
  (let ((cast (i-ching-interpretation (i-ching-cast)))
    (reading-buffer (get-buffer-create "*I Ching*")))
    (with-current-buffer reading-buffer
      (insert cast)
      (fill-individual-paragraphs (point-min) (point-max)))
    (display-buffer reading-buffer))

Here's what I eventually came up with. Writing this function taught me a lot about working with functions in elisp, but also about working with libraries and functions in any Lisp. And while it ended up being a fairly minor thing that can still definitely be improved, it showed me that I am learning.

But most importantly, it confirmed how much I grok working with secret alien technology.

Unless otherwise credited all material Creative Commons License by Christopher Rodriguez