Extra-fuzzy History Searching with Mnem
Update: mcfly already existed, with a slightly different approach (neural network instead of structural analysis) with a lack of fuzzy searching its only real downside, so I added that there. Use mcfly instead!
I use a lot of Rust command-line tools: ripgrep, fd, dust, and more. So when I had my own idea for a better command-line mousetrap, it seemed like the way to go.
Shells log the commands you enter to a history file. Bash has .bash_history
, zsh uses .histfile
. The EXTENDED_HISTORY
option in the latter adds timestamps, but that's about as fancy as it gets. Both shells (and presumably others) also have "reverse search" functionality which lets you look backwards and forwards through it, one line at a time.
Functional! But not especially friendly. Only seeing one result at a time makes it difficult to evaluate multiple similar matches; matching is strictly linear, as you can see by my typos; and the chronological is only sometimes the most useful order.
I do a lot with the AWS CLI, SaltStack, and other complicated command-line interfaces. I want to compare invocations to see how I've combined verbs and flags in the past, and for tasks I repeat just often enough to forget how to do them sorting by overall frequency is more useful than sorting by time.
Enter Mnem (regrettably, I missed getting clio
, the Muse of history, by a matter of weeks):
The idea is pretty simple: load the history file, and reduce every command to its syntactic structure. git commit -m "some message here"
becomes git commit -m <val>
; mv "hither" "thither"
turns into mv <arg1> <arg2>
. Many entries will have the same structure, especially if switches are sorted consistently, so counting up occurrences yields each structure's overall popularity.
Picking one such aggregate yields a second selector over the original incidences, and selecting one of those prints it to stdout. This can be referenced, copied and pasted, or even eval
ed in the shell.
So far I've released Mnem to the Arch AUR and a Homebrew tap:
brew tap dmfay/mnem https://gitlab.com/dmfay/homebrew-mnem.git
brew install dmfay/mnem/mnem