work-on: A Quick Script for Context Switching

I work on a lot of projects.

$ ls ~/Projects/ | wc -l

$ ls ~/Projects/work/ | wc -l

And that’s just what I have checked out at the moment. 😇

Anywyas, working on security and operations type tasks, I end up switching between repos/projects/languages quite often. It doesn’t take long to switch to a new folder, start up an IDE (VSCode at the moment), and start up a tmux session (so I can keep multiple terminals confined to one tab in iTerm). But it could be quicker!

Is it worth the time?

I probably actually do this often enough that I’m on the left side of the chart, even if it dosn’t actually save that much time. Still, it’s fun!

So let’s right a quick script to do that all:


paths="~/Projects ~/Projects/work ~"
for path in $paths
    eval fullpath="$path/$@"
    if [[ -d $fullpath ]]
        cd $fullpath
        code .
        tmux new -A -s $(basename $(pwd) | tr -cd '[a-zA-Z0-9]_-')
        exit 0

echo "No directories found named $@ in: $paths"

Most of the magic comes in looping through a series of folders where I keep projects I work on, checking for a folder name passed on the command line. If the folder exists, we’ll open VSCode with code . and start tmux with the -A flag to re-attach (if we already had a session for that folder) and -s to name the session. The $(basename $(pwd)) gives us the name of the folder (although I could just use "$@" I guess…) and tr -cd '[a-zA-Z0-9]_-' strips out fancy characters that tmux doesn’t like using in session names.

One funny bit that you might wonder about: eval fullpath="$path/$@" All that does is expand the ~ in the path names. Without the eval, it leaves the ~ as a literal character, which isn’t actually the name of the path. Oops.

So in the end, we get one each of a VSCode and tmux session for this project (if I already had either one, it will bring that to focus instead of creating a new one). Pretty cool and pretty quick. If the folder can’t be found, I can even print out a message. Fun times.

Full source (it’s the same as above) in my dotfiles repo: work-on