How I manage my terminals
Lucas Werkmeister, .
Inspired by Diomedis Spinellis’ not so recent blog post,
I wanted to share how I (currently) manage my terminals.
The key component is tmux
,
plus a useful little function of my own devising which you might find useful as well.
(Source code is at the bottom.)
My first boost in terminal use effectiveness came when I started to use tmux
(terminal multiplexer) for all my local terminals, with no exceptions:
previously I’d sometimes fire up tmux
when I thought that I was embarking on some task where I would want a terminal multiplexer,
but more often than not I found myself knee deep into a task already by the time I’d realize that it would be great to be in a tmux
session right now –
so one day, I configured GNOME Terminal to use tmux
as command instead of running my shell directly,
and I haven’t looked back since.
Soon after, I stopped using GNOME Terminal’s native tabs in favor of tmux
windows.
The second, much more significant boost came from the realization
that the default directory for new windows and panes in a tmux
session isn’t necessarily your home directory –
it’s a property of each session,
by default the working directory of the initial process creating the session (for new sessions launched by GNOME Terminal, $HOME)
but configurable with tmux new-session -c DIRECTORY.
And if I’m working in some Git repository,
setting the start directory of my tmux
session to that repository makes creating new windows and panes significantly less painful,
since they immediately start out in the right directory.
To facilitate this, I created a shell function which could launch a new tmux
session
in a certain directory in a new terminal window, to be used like this:
lterm formatter ~/git/ceylon/ceylon.formatter
And I quickly realized that I usually needed the same directories fairly often,
so I added the capability to read the location from symlinks in ~/.config/lterm/
(respecting XDG variables and falling back to /etc
and all that, of course):
lterm formatter
lterm ceylon
lterm systemd
lterm mw # MediaWiki
lterm wbqc # Wikibase Quality constraints
With this setup, it’s extremely painless to just launch a quick auxiliary shell for a command
when your main shell is currently occupied by a less
, emacs
, etc.,
since any new window in the session will start out in the right directory automatically.
Eventually, however, I started using so many terminal windows that I felt myself almost drowning in them,
and just navigating to the right one could be a nuisance.
GNOME’s Alt+Key above Tab
(e. g. Alt+` on US keyboards or Alt+^ on German keyboards)
shortcut helped with this:
it cycles between all the windows of the same application
(while Alt+Tab cycles between different applications),
so I could use that shortcut to switch between the most recent terminals,
no matter how many other windows (Firefox, IDE, etc.) were also opened in between.
However, I eventually added another feature to lterm
to solve this problem properly:
If a certain tmux
session already existed, lterm
would fail to create it –
but what if instead it switched to that window?
Fortunately, my tmux
was already set up to set the GNOME Terminal window title according to the tmux
session name inside it
(e. g. systemd:1:bash - "hostname" – session name, window number, window name (usually process), and hostname),
so I could just activate the window with a title matching the expected session name from lterm
and be set.
I implemented that using xdotool
(and then later had to reimplement it using GNOME Shell’s dbus / JavaScript bindings due to xdotool
not working in Wayland sessions),
and now I could bring up any terminal using lterm foo, regardless of whether that terminal had already been running or not.
2022-04-23 edit: The reimplementation based on org.gnome.Shell.Eval
eventually broke,
so I created a custom GNOME Shell extension, Activate Window By Title
(source code),
to offer a custom D-Bus interface for just this purpose.
As a minor bonus, lterm
exits if it’s the first command in an interactive shell –
so if you start a new terminal window using Ctrl+Alt+T only to launch a “real” terminal with lterm
,
then the temporary terminal window will quietly close itself behind your back automatically,
since you don’t need it anymore.
Another bonus: lterm
has automatic completion for all pre-configured locations.
If you want this functionality for yourself, feel free to copy the source code from my GitHub home repository:
the lterm function itself
and the underlying term function it uses
(which you might want to tweak if you prefer a different terminal emulator, like Konsole ☺).
There is also a similar rterm function for remote terminals.
Place those functions somewhere in your shell initialization files,
and make sure the set-titles
option is enabled in your tmux.conf,
and everything should work!
(2022-04-23 edit: you’ll also want to copy activate-window,
and install Activate Window By Title.)