Posts Tagged ‘emacs’

Creating an Emacs package: ‘password-menu’

Monday, April 8th, 2024

TL;DR

This post documents the development journey and some implementation details of a relatively simple Emacs package and is arguably overkill for such a small piece of functionality. On the other hand, some of these details may be useful for others who want to develop similar functionality.

If you're not interested, skip to the last section for a brief package description, or see the full package here: password-menu.

Making life easier

The need to automate something usually becomes apparent when an often-used workflow is awkward or inefficient. The effort to create the automation will hopefully pay off over time. I.e. ideally, the ROI will be high. This is why Emacs users spend so much time tweaking their configurations, even though I suspect the ROI may not be as high as they'd like!

In my case, the pain point was about the repeated need to provide passwords and tokens in a variety of situations. This is a common scenario — websites, CLI logins, curl/Postman, etc. all need credentials.

In addition to using auth-source (authinfo.gpg) I had gotten into the bad habit of scattering credentials around various org-mode files (unencrypted! 😞). When I needed a password, it required a search, buffer open, select, copy, and then paste to the target to complete. This is (and felt) very clumsy and inefficient. The addition of Org Mode custom link: copy to clipboard made the select/copy a little easier, but the overall experience still sucked.

The search for an existing solution came up empty. This was surprising given that the Emacs package ecosystem (Melpa) is extensive and has been around for a long time.

One of the distinguishing features of Emacs is the ability to customize and extend its functionality with Elisp. So, here we go.

Feature #1: Transient prefix menu

My approach was to use the auth-source-search API along with the transient package to provide the menu UI. This type of "porcelain" has become popular for Emacs projects that have complex user interfaces (Magit! being the best example). My use case is far simpler, but the UI style was still desirable.

The only real Elisp challenge (for me anyway) was creating a dynamic transient prefix list. I couldn't find any examples of this. Transient prefixes are implemented as vectors. Also, note that the transient interface is very complex (Prefixes, Suffixes, Infixes) but this use case only needed prefixes.

A typical transient prefix group looks like this (excerpted from transient-showcase).

Dynamically creating a vector like this can be implemented with this pseudocode:

You won't find this code in password-menu.el because it was refactored with macros as described below.

An Elisp expert could have knocked out this implementation without breaking a sweat, but it was a learning experience for me.

The development of the picker string functionality (1..0, a1..a0, b1..b0,...) was also a lot of fun.

Feature #2: Completing-read menu

All done, right? In the middle of the transient work, I ran across a post that included a good description of using completing-read with a list. The completing-read list interface could leverage the same core transient prefix list elements. Specifically, the user@host string menu item and the lambda that gets the password. The prefix picker string is not needed.

The implementation was refactored with a couple of macros so both UI interfaces could share the list generation. I won't dig into the details here, but the password-menu.el code should be self-explanatory. Getting the completing-read list boiled down to this:

The transient version uses these same two macros, but is a little more complex. This shows the usefulness of macros and was another Elisp learning experience.

Feature #3: Kill ring and clipboard expiration

Finally, while investigating other password management packages I ran across this kill ring expiration implementation. It makes sense to remove the secret from the kill ring and system clipboard automatically so I incorporated their code pretty much unmodified.

This additional functionality is like icing on the cake.

Epilogue

I've been dogfooding password-menu for a while. I use it often and can safely say it has improved the "get credential" experience. Before, it was "Oh crap, here we go...". Now it's simply C-x j 3 from anywhere, then paste. Easy peasy!

The other benefit is that I've now removed all those unencrypted secrets from my org files and have everything tucked away in one secure place: authinfo.gpg. That's a big win too.

The password-menu package

Password-menu is a UI wrapper ("porcelain") for the built-in Emacs auth-source secrets library. This package allows you to display auth-source entries in the minibuffer with either completing-read or transient. The password for the selected entry is copied to the kill ring and system clipboard and automatically removed later.

Transient

Completing-read

Introducing elfeed-curate

Monday, October 2nd, 2023

The Need

I read a lot of RSS feeds on a select set of topics (see About | Bob's Content of Interest). I sometimes tweet/toot about individual posts but have the desire to expand that capability. I'd like to be able to regularly (and efficiently) publish a curated collection of articles. There are three primary functional requirements needed to accomplish this:

Collection: Deciding which articles you want to export (publish). Filtering can be done based on their title, subject matter (tags), and time constraints. My preference is to specifically mark (or tag) selected entries independent of their subject matter (see below).

Annotation: Some article titles speak for themselves, but others are best presented with associated comments that allow the reader to know what's special about the content. You need the ability to add annotations to individual articles that are included in the published result.

Publication: Once a set of articles has been identified, exporting them in an easily consumable format is the next step. One important component of exporting this content is grouping the articles based on their subject matter.

The Investigation

There are many RSS feed aggregators out there, but there was no solution that even came near to addressing the curation requirements listed above. Apparently, all of those link collection sites are just rolling their own.

As a software developer, finding such a glaring functionality gap that needs to be filled is a real win-win! 🎉 Not only is this something I want to use, but there are probably a few others who will also find a solution helpful.

Now all I had to do was design and develop that solution. I've been using Emacs and Elfeed as my RSS reader for many years. Extending Emacs functionality is a cult-like activity that attracts many. I'm not brain-washed, but even as a (non-evil) Doom user, I do spend a lot of time tweaking my Emacs configuration.

Anyway, providing this RSS curation functionality as an elfeed extension was not only the ideal technical solution, but it was also the perfect opportunity to author my first Emacs package (another win, I hope).

The Solution

Elfeed-curate is an add-on to the elfeed Emacs-based RSS feed management system that provides the ability to easily curate RSS feed entries.

Elfeed's tagging and search functionality takes care of the collection requirements and elfeed-curate adds annotation and publication (exporting) capabilities.

I have an opinionated workflow that looks like this:

See Curation Workflow for details.

A key factor (essentially, a non-functional requirement) for making this workflow practical is that each step (marking, annotation, export review, etc.) has to be fast. I think the combination of elfeed and elfeed-curate accomplishes this. I'm also sure there will be refinements and improvements in the future.

Export example

The same content exported to Hugo is here: 21-Sep-2023 Content of Interest

Feedback is always welcome. Thanks!