I’ve made quite a few changes recently to my terminal/command line set up, and come across some interesting tools, so I thought it would be worth writing a quick update post.
This is probably the biggest change to my command line workflows. I have been a happy user of iTerm for years. It is extremely powerful, but configuring it doesn’t play particularly well with my Nix Home Manager set up as it does not use standard Unix config files. I tried a few other alternatives before settling on kitty. I had actually tried it before, but I think I was put off by the sheer number of options available. This time around, I read the manual thoroughly and took the time to set it up in the way that worked best for me. Since it stores its configuration files in
~/.config/kitty/ I can easily ensure that my setup is the same on my work and personal computer, and as kitty is available in Nixpkgs, it’s also easy to install.
Since shifting back to Neovim, I had been looking around for a kind of ‘project’ plugin to help me to isolate work on different projects, but switch between them easily. There are several of these, but as I got more familiar with kitty, it struck me that kitty could handle projects for me instead. It has a system of tabs and panes (‘windows’) within those tabs, which can be split in a variety of ways or layered so that only one is visible at a time. I settled on a system whereby each tab houses a project of a kind (often a git repository), associated with a directory. Within each of these tabs I open two or three windows including a Neovim instance, which I usually layer on top of each other so that I see one at a time, but I can easily switch layout with a keyboard shortcut. The shortcuts I use to switch tabs in browsers and other apps switches between tabs, and the shortcut for back and forward in the browser cycles through my windows. It’s really slick and fast. I have floating terminal windows set up inside Neovim and sometimes use those, but it can be just as easy to pop a real terminal window open in a tab and zap between my editor and the shell.
You can set up startup sessions, defining tabs, windows, tab names, working directories, programs and so on. I use this to build three tabs on start up, with my most used projects set up the way I like them, but I can easily open new tabs on the fly if needed. Kitty has its own powerful scripting setup, including ‘kittens’ which can do things like previewing images in the terminal and so on. I’m using only a fraction of the power and flexibility available, but I’m really enjoying it. Just to seal the deal, people have created some great alternative icons. The default one is pretty cute, but when I saw these guys, I couldn’t resist. Is that ridiculously shallow? Of course, but it makes me smile each time I see the icon in the app switcher.
Berkeley Mono typeface
I don’t remember where I saw the Berkeley Mono typeface mentioned, but the time from me visiting the link to paying for it was pretty short. I had been switching between Iosevka and JetBrains Mono — both of which are very nice fonts — but there was something about Berkeley Mono which immediately appealed to me. I am not an expert on typography, but to me it has both rounded and square aspects which make it a bit quirky and friendly-looking, but not so much that it gets in your face. It is extremely readable, has nice ligatures if you like them (they are optional), as well as a choice of zero styles (I went dotted).
I write a lot of prose in the terminal as well as coding (such as this article!), and I love the ease of reading large blocks of text in this typeface. It’s so good that it makes me want to use it in other apps where you would usually not use a monospaced font. It’s just a delight all round, and makes spending time in a terminal window a pleasure. It even comes with a web font included in the price, so I might set it up on this blog too at some point, so that my code snippets look even nicer.
I’ve written briefly about Lazygit before. It is a really well designed terminal UI for git, similar in some ways to the awesome Magit for Emacs, but editor agnostic. Essentially, you can pop up a floating window in which you can use modal keys to zip through 99% of the day-to-day git workflow most people use. I’ve set up a shortcut in kitty to open a Lazygit window for the project directory, so I can pop it open, hit a few keys, type a commit message, then hit
q to get right back where I was in the terminal. I love it. I also have a leader key to open it within Neovim, but since setting up the tabs system in kitty as I described above, it doesn’t matter much whether I open it from the shell or within Neovim.
I have GUI git apps that I sometimes use for particular tasks, but they all feel a bit ponderous and pointy-clicky after Lazygit.
This handy little Ruby Gem written by Brett Terpstra combines project documentation in Markdown with a simple but powerful task runner. I have occasionally used Makefiles in projects, but I never remember the syntax. Howzit lets you put a
buildnotes.md file in a project directory with a series of headings with task descriptions and code to run tasks. You can then run
howzit build in your project directory to view (or choose between) headings with the text ‘build’. If you want to run the tasks, you append
-r and it runs instead of showing you the text.
I love this because I have projects that I might use frequently for a while, then set aside and come back to months later. At this point, I usually realise that I have completely forgotten how to build or deploy the thing. This lets me document it in place, and run the code too. I am gradually setting up these notes in all my project directories, standardising the task names, even if the projects all use different actual code to run in dev mode or deploy. It’s a lovely little tool, and full of the nice touches and polish that Brett does so well.
So then I went down a Terpstra rabbit hole and tried his Snibbets. This is a cheatsheet tool, and lets you collect together and document snippets of code, then search them using
fzf if you have it installed. I like this for the little bits of code that aren’t project specific, but you always find yourself having to google. For example, I must use the code in R to format a
ggplot graph axis as a percentage multiple times a month, but can I get it right on the first go without looking it up? Can I heck.
You can also set it up so that all (or just the current)
snibbet code snippet that you have searched for gets automatically copied to the clipboard so that you can get on with building your graph with barely a blip in your stride, other than marvelling again that you find it so hard to remember one simple line of code. There’s also syntax highlighting, and you can use tags to group snippets logically to make it easier to find all your
cheat does a similar job, but once again I enjoyed the Terpstra approach to the problem and slightly preferred the workflow of snibbets.
Atuin stores your shell history in a database, and then lets you search it easily in a variety of ways. You can also use it to sync your shell history between computers, but I don’t use that aspect of it. I haven’t been using it long, but it has already saved me lots of time typing long commands in. It is particularly useful that you can switch between global history, just the current session, or just the current directory. The latter is really handy for my project-focussed tabs, so that I only see commands relevant to that project.
These tools have made spending more time in a terminal window more productive and much more pleasant.