diff options
author | EuAndreh <eu@euandre.org> | 2025-04-18 02:17:12 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2025-04-18 02:48:42 -0300 |
commit | 020c1e77489b772f854bb3288b9c8d2818a6bf9d (patch) | |
tree | 142aec725a52162a446ea7d947cb4347c9d573c9 /src/content/blog/2021/01/26/remembering-ann.adoc | |
parent | Makefile: Remove security.txt.gz (diff) | |
download | euandre.org-020c1e77489b772f854bb3288b9c8d2818a6bf9d.tar.gz euandre.org-020c1e77489b772f854bb3288b9c8d2818a6bf9d.tar.xz |
git mv src/content/* src/content/en/
Diffstat (limited to 'src/content/blog/2021/01/26/remembering-ann.adoc')
-rw-r--r-- | src/content/blog/2021/01/26/remembering-ann.adoc | 216 |
1 files changed, 0 insertions, 216 deletions
diff --git a/src/content/blog/2021/01/26/remembering-ann.adoc b/src/content/blog/2021/01/26/remembering-ann.adoc deleted file mode 100644 index 6786b3c..0000000 --- a/src/content/blog/2021/01/26/remembering-ann.adoc +++ /dev/null @@ -1,216 +0,0 @@ -= ANN: remembering - Add memory to dmenu, fzf and similar tools -:categories: ann - -:remembering: https://euandreh.xyz/remembering/ -:dmenu: https://tools.suckless.org/dmenu/ -:fzf: https://github.com/junegunn/fzf - -Today I pushed v0.1.0 of {remembering}[remembering], a tool to enhance the -interactive usability of menu-like tools, such as {dmenu}[dmenu] and {fzf}[fzf]. - -== Previous solution - -:yeganesh: https://dmwit.com/yeganesh/ - -I previously used {yeganesh}[yeganesh] to fill this gap, but as I started to -rely less on Emacs, I added fzf as my go-to tool for doing fuzzy searching on -the terminal. But I didn't like that fzf always showed the same order of -things, when I would only need 3 or 4 commonly used files. - -For those who don't know: yeganesh is a wrapper around dmenu that will remember -your most used programs and put them on the beginning of the list of -executables. This is very convenient for interactive prolonged use, as with -time the things you usually want are right at the very beginning. - -But now I had this thing, yeganesh, that solved this problem for dmenu, but -didn't for fzf. - -I initially considered patching yeganesh to support it, but I found it more -coupled to dmenu than I would desire. I'd rather have something that knows -nothing about dmenu, fzf or anything, but enhances tools like those in a useful -way. - -== Implementation - -:v-010: https://euandre.org/git/remembering/tree/remembering?id=v0.1.0 -:getopts: https://www.opengroup.org/onlinepubs/9699919799/utilities/getopts.html -:sort: https://www.opengroup.org/onlinepubs/9699919799/utilities/sort.html -:awk: https://www.opengroup.org/onlinepubs/9699919799/utilities/awk.html -:spencer-quote: https://en.wikipedia.org/wiki/Henry_Spencer#cite_note-3 - -Other than being decoupled from dmenu, another improvement I though that could -be made on top of yeganesh is the programming language choice. Instead of -Haskell, I went with POSIX sh. Sticking to POSIX sh makes it require less -build-time dependencies. There aren't any, actually. Packaging is made much -easier due to that. - -The good thing is that the program itself is small enough ({v-010}[119 lines] on -v0.1.0) that POSIX sh does the job just fine, combined with other POSIX -utilities such as {getopts}[getopts], {sort}[sort] and {awk}[awk]. - -The behaviour is: given a program that will read from STDIN and write a single -entry to STDOUT, `remembering` wraps that program, and rearranges STDIN so that -previous choices appear at the beginning. - -Where you would do: - -[source,sh] ----- -$ seq 5 | fzf - - 5 - 4 - 3 - 2 -> 1 - 5/5 -> ----- - -And every time get the same order of numbers, now you can write: - -[source,sh] ----- -$ seq 5 | remembering -p seq-fzf -c fzf - - 5 - 4 - 3 - 2 -> 1 - 5/5 -> ----- - -On the first run, everything is the same. If you picked 4 on the previous -example, the following run would be different: - -[source,sh] ----- -$ seq 5 | remembering -p seq-fzf -c fzf - - 5 - 3 - 2 - 1 -> 4 - 5/5 -> ----- - -As time passes, the list would adjust based on the frequency of your choices. - -I aimed for reusability, so that I could wrap diverse commands with -`remembering` and it would be able to work. To accomplish that, a "profile" -(the `-p something` part) stores data about different runs separately. - -I took the idea of building something small with few dependencies to other -places too: - the manpages are written in troff directly; - the tests are just -more POSIX sh files; - and a POSIX Makefile to `check` and `install`. - -I was aware of the value of sticking to coding to standards, but I had past -experience mostly with programming language standards, such as ECMAScript, -Common Lisp, Scheme, or with IndexedDB or DOM APIs. It felt good to rediscover -these nice POSIX tools, which makes me remember of a quote by -{spencer-quote}[Henry Spencer]: - -____ -Those who do not understand Unix are condemned to reinvent it, poorly. -____ - -== Usage examples - -Here are some functions I wrote myself that you may find useful: - -=== Run a command with fzf on `$PWD` - -[source,sh] ----- -f() { - profile="$f-shell-function(pwd | sed -e 's_/_-_g')" - file="$(git ls-files | \ - remembering -p "$profile" \ - -c "fzf --select-1 --exit -0 --query \"$2\" --preview 'cat {}'")" - if [ -n "$file" ]; then - # shellcheck disable=2068 - history -s f $@ - history -s "$1" "$file" - "$1" "$file" -fi -} ----- - -This way I can run `f vi` or `f vi config` at the root of a repository, and the -list of files will always appear on the most used order. Adding `pwd` to the -profile allows it to not mix data for different repositories. - -=== Copy password to clipboard - -:pass: https://www.passwordstore.org/ - -[source,sh] ----- -choice="$(find "$HOME/.password-store" -type f | \ - grep -Ev '(.git|.gpg-id)' | \ - sed -e "s|$HOME/.password-store/||" -e 's/\.gpg$//' | \ - remembering -p password-store \ - -c 'dmenu -l 20 -i')" - - -if [ -n "$choice" ]; then - pass show "$choice" -c -fi ----- - -Adding the above to a file and binding it to a keyboard shortcut, I can access -the contents of my {pass}[password store], with the entries ordered by usage. - -=== Replacing yeganesh - -Where I previously had: - -[source,sh] ----- -exe=$(yeganesh -x) && exec $exe ----- - -Now I have: - -[source,sh] ----- -exe=$(dmenu_path | remembering -p dmenu-exec -c dmenu) && exec $exe ----- - -This way, the executables appear on order of usage. - -If you don't have `dmenu_path`, you can get just the underlying `stest` tool -that looks at the executables available in your `$PATH`. Here's a juicy -one-liner to do it: - -[source,sh] ----- -$ wget -O- https://dl.suckless.org/tools/dmenu-5.0.tar.gz | \ - tar Ozxf - dmenu-5.0/arg.h dmenu-5.0/stest.c | \ - sed 's|^#include "arg.h"$|// #include "arg.h"|' | \ - cc -xc - -o stest ----- - -With the `stest` utility you'll be able to list executables in your `$PATH` and -pipe them to dmenu or something else yourself: - -[source,sh] ----- -$ (IFS=:; ./stest -flx $PATH;) | sort -u | remembering -p another-dmenu-exec -c dmenu | sh ----- - -In fact, the code for `dmenu_path` is almost just like that. - -== Conclusion - -:packaged: https://euandre.org/git/package-repository/ - -For my personal use, I've {packaged}[packaged] `remembering` for GNU Guix and -Nix. Packaging it to any other distribution should be trivial, or just -downloading the tarball and running `[sudo] make install`. - -Patches welcome! |