I’ve recently switched to using Linux on the desktop full-time after decades of being pretty much exclusively Mac for client machines (and I do mean decades - I think my favourite Mac was my Powerbook G3 “Lombard”, after all…)

The reasons for that switch are best for another time, but in general it’s not been as traumatic as you might expect - certainly less traumatic than I found the switch from BSD to SysV and then Linux on servers, anyway. But still, there are a few things I’ve missed.

One of those things is the excellent iTerm2 Terminal. A good terminal is a very personal thing (as developers we spend half our lives in them, after all,) and I’d grown very comfortable with iTerm2 on the Mac; finding a good replacement for Linux was a high priority.

Alacritty

Alacritty seems to fit the bill. It’s quick, configurable, but without distracting UI nonsense like tabs or toolbars, and I love the fact it’s entirely configurable through a YAML config file and not a GUI. I’m liking it a lot.

One feature I really missed from iTerm2 though was the ability to set up profiles that would automatically switch things like terminal colours depending on what command you were executing or your shell’s current working directory. It’s hardly a “deal breaker”, but it’s part of what makes my development environment feel like home. So I set about working out how to do the same with Alacritty.

Dynamic configuration with alacritty msg

Fortunately, Alacritty comes with a feature ‘out of the box’ that allows us to send messages to the terminal emulator from the commandline, using the command alacritty msg. This allows us to change terminal configuration, like colours, programatically by sending config messages that will dynamically change the behaviour of the terminal.

We can combine this with Shell scripts that run before and after every command to do the dynamic configurations that I want. At this point, I should probably confess that because I’m old and going grey I still use tcsh. SystemV may have won the battle, but I’m going to die on my tcsh hill before I’ll ever switch my login shell to bash. So that means I use the precmd and postcmd aliases that tcsh supports; I presume the shells that young folk use have similar features.

The Scripts

Essentially, I have two scripts. One of them sets the colour (and you can change any other config you want) based on the current working directory in the terminal; this runs precmd (i.e. before the terminal prompt is printed):

#!/bin/tcsh -f
#
# Usage: bin/alacritty-precmd <current working directory>
#
# NOTE: -f is important, we don't want to load our startup files and
# end up setting the cwdcmd/postcmd aliases in our script

if ( $?ALACRITTY_WINDOW_ID ) then
  if ("$1" =~ "/home/timwa/Development*") then
    alacritty msg config "colors.primary.background='#402A09'"
  else if ("$1" =~ "/home/timwa*") then
    alacritty msg config "colors.primary.background='#062A06'"
  else if ("$1" =~ "/tmp*") then
    alacritty msg config "colors.primary.background='#0C520C'"
  else
    alacritty msg config "colors.primary.background='#400910'"
  endif
endif

The second script runs after every command is typed, but before it is executed, and is used to set colours based not on the working directory but on the command you are about to run. This allows me to change the background to plain black when I’m editing a file in vi, or to change to a different colour when I’m shelled out to another machine:

#!/bin/tcsh -f
#
# Usage: bin/alacritty-postcmd <command that we will execute>
#
# NOTE: -f is important, we don't want to load our startup files and
# set the postcmd alias in this script to ourself (and thus get stuck in
# an infinite loop)

if ( $?ALACRITTY_WINDOW_ID ) then
  if ("$1" == "ssh") then
    alacritty msg config "colors.primary.background='#081635'"
  else if ("$1" == "vi") then
    alacritty msg config "colors.primary.background='#000000'"
  endif
endif

Now we can integrate this into our .tcshrc quite simply:

alias precmd '/home/timwa/bin/alacritty-precmd $cwd'
alias postcmd '/home/timwa/bin/alacritty-postcmd `history -h 1`'

And, hey-presto: dynamic terminal configuration that follows what I do in the terminal:

Obviously, with the power of alacritty msg, there’s potential to do a lot more than just changing the colour. The world is my oyster, and there’s one less thing I miss about my Mac…