histctx: A better way to handle context switching in your shell
26 Dec 2024Like any sane IT person, I use my shell history on a daily basis. It can be because I don't exactly remember what arguments should I use with this complicated CLI and the --help
output is like one thousand lines, or just because I'm too lazy to type this very long and boring command. In either case, I can use my history and search it using ctrl+r
or grep
. But what should I do when I don't even remember what command I wanted to run in the first place? 😳 ctrl+r
and grep
will be of no use here...
🚨 The issue
I often use my shell history because I need to work on a project that I haven't worked on for a long time. If it is a personal project that I had on my free time, it is possible that I didn't even bother to write a README about it. And sometimes I run commands that aren't documented and make my life easier, and this can even happen in big open-source projects. I think we all have found one day that very nice command that fits our specific needs, but just because we sometimes like to work in a way other people maybe don't, we cannot really ask for it to be documented.
Anyway... Many times, I found myself cd
into a project directory, just to realize that I cannot remember anything about how to set up and run the development stack, and the last hint I could use was waaaaaay back in my bash history. So one day, I finally had what seemed to me like a wonderful idea: histctx! 🎉 A history manager for my shell!
💡 The idea
So my idea was to split my bash histories based on the project I was working on. This way, I could always find the last commands I ran while working on a project, and everything would be much easier! I should also have a "global" history (like the one we all use), because not all commands I run are directly linked to a project. I would need to name histories, list them, remove them, and even rename them!
Ok, one last idea: I could make use of a temporary history that would empty itself on reboot. You know... to tinker and try shitty commands full of typos without worrying about seeing them ever again (I used to "clean" my history sometimes — yeah, maybe I'm crazy, but it is none of your concern 😏). Who said to hide proofs that I'm a notorious hacker at the head of a worldwide cybercriminal organization?! *silently asks his lieutenant to get rid of the snitch*
🛠️ The implementation
Ok good, I have an idea, now what? We are in June 2021 and ChatGPT hasn't been released yet, so I guess I will have to do all the dirty work myself... *takes a drag on his Cohiba before crushing it in the ashtray*. Note: histctx
is implemented specifically for bash and may not work with other shells.
First, we need a way to set the location of our history file. This way, we can use one file per project, or "context" like I like to call them. Fortunately, bash recognizes the environment variable $HISTFILE
that allows us to do exactly that! So every time we try to open a context, histctx
will start a new bash instance (or replace it if it is already running) with the $HISTFILE
variable set to the location of the required history. I will store all histories in ~/.bash_history.d/<CONTEXT_NAME>
. And when I want a global history, I think the easiest way is the good old one: vanilla bash — it works well already, no need to use a tool for that.
Second, we need to choose a language to implement it. Since it is a helper for bash, and I want it to be simple to deploy, with no compilation and no external dependencies, bash seems to be the perfect candidate for that.
So here we go! I implemented all of this using bash, added a way to open the last context by typing histctx
without arguments (it will be helpful when opening multiple panes in my terminal) by saving the last history name in ~/.histctx
, and I added commands to manage our contexts. I also added a completion script, written by hand, because why not? By the way, it was the first time I wrote a completion script, so I was happy to learn about how it worked. And here it is, my marvelous tool for memory-challenged engineers like me, handling bash histories like a charm: histctx.
🎯 Conclusion
Now I know what y'all are thinking: "yeah great project: you learnt a lot, wrote a post about it, blah, blah, blah... But do you really use it?.." The answer is simply YES, I do use it on a daily basis. Actually, I cannot even try to imagine my work without it. It is such a pleasure to always find your history well compartmentalized, to never spend long minutes trying to find a command you ran 2 months ago. When I run the history
command, I know that I will only find relevant history, free from the garbage and noise of all commands that I run every day on my computer for X or Y reason — it is GOLD.
Now, I can only encourage you to go and try it! It is open-source and under the MIT license, so feel free to open issues, fork it, submit pull requests, and maybe adapt it to your shell if you're not using bash. It would make me so happy if my little tool were helpful to others!
Source code: https://github.com/plaffitt/histctx
Last update: 03 Jan 2025