The Problem
I have a command reference. It's a text file with lots of CLI commands I've written down because I don't want to memorise them all. For example here's a bunch of network-related commands:
nslookup -type=ns example.com
nslookup -type=txt example.com
nslookup -type=cname example.com
nslookup example.com 1.1.1.1
dig example.com txt
dig example.com cname
netstat --tcp
netstat --program
netstat --listening
When I want to look up a command, I don't always remember the actual command I want. Let's suppose I need to do a DNS lookup. I might not remember that I need dig
or nslookup
. Or I might just need something to do with networking. How can I search for all DNS commands or networking commands?
Halfway There: A Better Command Reference
I can add headings and sub-headings to the list above. Each heading starts with a hashtag to differentiate it from the actual commands.
# Networking
# DNS
nslookup -type=ns example.com
nslookup -type=txt example.com
nslookup -type=cname example.com
nslookup example.com 1.1.1.1
dig example.com txt
dig example.com cname
# See processes and ports used
netstat --tcp
netstat --program
netstat --listening
This is better, but I'd still need to search for DNS and scan over the following lines to find the command I want. A better way is to associate a bunch of tags with each line. Each tag would place the line in some category. A DNS category, a networking category. But manually writing "#dns" after every DNS command in my list would be tedious. It would also pollute the command reference with tags everywhere.
The Solution: ltag + fzf
So instead I created a tool read the above text, append the heading to every line as a tag, and print out the result. That would convert the above text to the following:
nslookup -type=ns example.com #networking #dns
nslookup -type=txt example.com #networking #dns
nslookup -type=cname example.com #networking #dns
nslookup example.com 1.1.1.1 #networking #dns
dig example.com txt #networking #dns
dig example.com cname #networking #dns
netstat --tcp #networking #see-processes-and-ports-used
netstat --program #networking #see-processes-and-ports-used
netstat --listening #networking #see-processes-and-ports-used
I call this tool "ltag", short for "Line tag". It's written in Go. Here's the git repository: mebble/ltag.
With tagging out of the way, I now have the ability to search.
The CLI search tool I use is fzf. fzf takes in any text stream and spins up a TUI for you to fuzzy search through the text. I can pipe my tool's output to fzf and violà, I can now search by command and by tag!
I still have one problem though. The purpose of looking up commands is so that I can run them. When I select a command through fzf, the tags associated with that command also get selected. I'd like to get rid of these tags once I've found the command I want. So my tool is also able to remove tags from the selected line.
I can now do a quick command lookup using a shell alias:
alias cl="cat ~/.cmd-reference.txt | ltag | fzf | ltag --trim | pbcopy"
Beyond a Command Reference
This tool could help you search through any list of things. And the list doesn't have to be in a text file. ltag reads from standard input, so you can pipe the output of any command to it.
This is my first Go project, and I'm glad I found a way to create something actually useful. So here it is, hope you find it useful as well.
Top comments (4)
This is a really cool utility! Thanks for sharing, Neil.
Thanks Michael 😄
This is really cool - thanks for sharing!
Thank you!