The Terminal Setup I Put on Every Machine
Part 10 of a series on the tools I actually run.
I spend most of my day in a terminal, and over the years it’s accumulated a specific shape. Same font, same plugins, same aliases, same greeting when I log in somewhere. It’s on the Mac, it’s on every server, and getting a new machine to match takes about ten minutes.
This is that setup, and why each piece is in it.
iTerm2, and the font problem
I use iTerm2 on the Mac. Ghostty is genuinely good and I keep meaning to switch properly, but iTerm2 has been there for fifteen years, the split panes and search work the way my hands expect, and I’ve never had a compelling reason.
brew install --cask iterm2
The thing worth actually writing about is the font, because this is where most people’s terminals look subtly broken without them realising it’s fixable.
Install a Nerd Font
The problem: modern shell prompts, file listings from eza, and half the CLI tools out there want to draw icons and box-drawing characters. A normal font doesn’t have those glyphs. Your terminal falls back to whatever font on the system does have them, and the result is icons that sit a pixel too high, or get clipped, or are the wrong width and shove everything after them out of alignment.
Nerd Fonts fix this by patching a normal monospace font with all those extra glyphs, correctly sized and positioned for a terminal grid. One font, everything in it, nothing to fall back to.
brew install --cask font-meslo-lg-nerd-font
MesloLGS NF is what I use. It’s Apple’s Menlo, patched, and it was tuned specifically to render prompt glyphs cleanly. JetBrainsMono Nerd Font is the other one I’d suggest if you want something with a bit more character.
The iTerm2 setting that actually fixes alignment
Installing the font is half of it. The half everyone misses is in Settings, Profiles, Text:
Turn off “Use a different font for non-ASCII text.” If this is on, iTerm2 uses your nice Nerd Font for letters and something else for the icons, which reintroduces exactly the misalignment you just installed a Nerd Font to avoid. One font for everything.
While you’re in there, the horizontal and vertical spacing sliders are worth two minutes. Default line spacing is a touch tight for most Nerd Fonts and box-drawing characters can end up with hairline gaps between them, which makes tree or a tmux border look broken. Nudging vertical spacing up slightly usually closes them.
Also install the same font on your Linux boxes if you ever connect a monitor to one. And note that the font matters on whatever machine you’re typing on, not the one you’re connected to. Rendering happens locally.
Aliases everywhere
Every machine I own has the same alias set, kept in sync with Syncthing the way I described in the dotfiles post. A few that earn their keep:
Navigation and files
alias ll='eza -la --git'
alias lt='eza --tree --level=2'
alias ..='cd ..'
alias ...='cd ../..'
alias c='clear'
System
alias ports='sudo lsof -i -P -n | grep LISTEN'
alias myip='curl -s ifconfig.me'
alias df='df -h'
alias du1='du -h -d 1 | sort -h'
alias update='sudo apt update && sudo apt upgrade -y'
Tailscale, which I type constantly
alias ts='tailscale status'
alias tsip='tailscale ip -4'
Media, the ones from the earlier posts
alias codemusic='...' # the coding stream
alias welt='...' # German news
alias t24='...' # more German news
Those three are the same mpv invocation with different URLs, and they get used more than anything else on this list.
The reason I keep them identical across machines isn’t tidiness. It’s that muscle memory doesn’t know which host you’re on. Typing ll and getting an error because this box doesn’t have your alias is a tiny friction, and it happens forty times a day.
fastfetch on login
Every machine runs fastfetch when I connect. Hostname, distro, kernel, uptime, RAM, disk, the little logo.
brew install fastfetch # macOS
sudo apt install fastfetch # Debian/Ubuntu
It’s the maintained successor to neofetch, which was archived a while back, and it’s noticeably faster, which matters when it runs on every login.
This is partly vanity. I’ll own that. But it does a real job too: when you have ten machines on a tailnet and you’re SSHing between them all day, a glance at the banner tells you which one you’re on, how long it’s been up, and whether the disk is filling. I’ve caught a runaway log directory that way more than once.
Do not just put it in your .zshrc
The naive approach is a bare fastfetch line in your shell config. Then it runs when you open a tmux pane. And when you split that pane. And when a script spawns a shell. And when scp connects, where it can actually break the transfer by printing to a stream that’s supposed to be data.
Guard it:
# only on an interactive login over SSH, and not inside tmux
if [[ $- == *i* ]] && [[ -n "$SSH_CONNECTION" ]] && [[ -z "$TMUX" ]]; then
fastfetch
fi
Interactive shells only, only when arriving over SSH, and never inside an existing tmux session. That last condition is the one that turns it from charming to tolerable.
Two zsh plugins
These two go on every machine, and they’re the only shell plugins I bother with.
brew install zsh-autosuggestions zsh-syntax-highlighting
zsh-autosuggestions shows a greyed-out completion from your history as you type. Right arrow accepts it. Once you’ve used a machine for a week, most of what you type is something you’ve typed before, and this turns a twelve-character command into two characters and an arrow key.
zsh-syntax-highlighting colours your command line as you write it. Valid command in green, unknown command in red, quotes and paths highlighted. The value is that you see a typo before you press enter rather than after.
Sourcing them, and the order matters:
source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh
source $(brew --prefix)/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
Syntax highlighting has to be sourced last, after everything else in your .zshrc. It works by hooking the line editor, and anything sourced after it can break the highlighting in ways that are hard to diagnose. The project documentation says this and I ignored it once, so now I’m saying it too.
On Debian the paths are different, usually under /usr/share/, which is one of those things that goes in the OS-specific file from the dotfiles post.
The ten minute version
New machine, in order: install a Nerd Font locally if it’s a machine I’ll sit at, install fastfetch, zsh and the two plugins, then let Syncthing bring the dotfiles down and run the bootstrap script.
Ten minutes, and it’s my machine. The other half of this, how I actually connect to these boxes, is its own post.