A Fish shortcut for rapidly appending clipboard data to text files
Text editors are for normies
I have a very textfile-centric computing workflow. All my writing, and most of my life admin lists, are text files. I capture ideas and links countless times per day, and when I was on a long trip sitting in a car with my laptop, I got bored of waiting for my text editor to load every time I had an idea, and wrote a script for appending to my most-used text files ultra rapidly.
The system has two parts: a Bash script, and Fish abbreviations.
The shell script is a glorified wrapper for >> append to file redirection. The problem with just doing echo “stuff into” >> file is that when I pull up the snippet with ctrl+r reverse history search, the cursor is in the wrong place.
I put the following in my dotfiles, at bin/append, and made it executable with chmod +x append. (dotfiles/bin is on my $PATH, and this, combined with dropping the extension, makes it feel like a real program.)
#!/bin/bash
if [[ "$2" ]]; then
if [[ "$1" = "t" ]]; then
file="/home/$USER/path/to/tabs.md"
echo "${2}" >> "$file"
tail -n 2 "$file"
elif [[ "$1" = "r" ]]; then
file="/home/$USER/path/to/reading-list.md"
echo "- ${2}" >> "$file"
tail -n 2 "$file"
elif [[ "$1" = "s" ]]; then
file="/home/$USER/path/to/info.txt"
echo "
${2}" >> "$file"
tail -n 2 "$file"
elif [[ "$1" = "i" ]]; then
file="/home/$USER/path/to/ideas.txt"
echo "
$(date -I): ${2}" >> "$file"
tail -n 2 "$file"
else
echo "Invalid file: $1" >&2
fi
else
echo "Invalid append item: ${2}"
fi
Okay, so this is all very self-explanatory. There’s a 1-letter code for different life admin files. The command is run with append t autodidacts.io to append this domain to the inbox section of my weblink capture file (which I started when between read-it-later services).
Notice that the data now comes last, so when this is called up from history, I can hit ctrl+w and be ready for action (or, populate history with a version without the final argument).
But this is still too slow. Too much typing and pasting!
The good stuff is in config.fish:
abbr -a a append
abbr -a aci "xsel -b | xargs -0 -I{} append i \"{}\""
abbr -a acs "xsel -b | xargs -0 -I{} append s \"{}\""
abbr -a acr "xsel -b | xargs -0 -I{} append r \"{}\""
abbr -a act "xsel -b | xargs -0 -I{} append t \"{}\""
At first, I thought I just needed to shorten the append command to “a”. (Who would have guessed there isn’t a binary called “a” on my machine? What luck!)
But that’s not good enough. That’s: a, space, i|t|r|s, space, ctrl+shift+v, enter.
I realized that I usually have the thing I want to append already on my clipboard, from a URL, scratch buffer, or some other text file.
So I set the shortest possible abbreviations (getting rid of the spaces), and had them pipe the output of xsel (read clipboard data) into my append function via xargs (since append doesn’t read from STDIN). (The -0 is important. Otherwise, single quotes cause problems.)
So now the workflow is, for example, ctrl+l (focus and select URL in Firefox address bar), ctrl+c, super+c (launch-or-raise Ghostty with Tmux and Fish), act (append[from] clipboard [to] tabs [file]), and we’re done!
Notice that the append shell script prints out the last two lines after appending (tail -n 2 "$file"), so I can visually confirm that it worked, and put it in the right place. It also automatically dates ideas, and adds the Markdown list syntax for books added to my reading list.
Two files, ~31 lines of code, and a six hundred word blogpost later, we have saved several keystrokes!
But this is just the beginning. Wait til I tell you about my sed snippet for inserting text into the middle of a file…