‹ back home

senpai: a modern IRC terminal client

2023-07-05 #irc #open-source

I’ve been writing some IRC-related experiments using a bouncer lately. I don’t have anything useful yet. My code so far connects to a bouncer, enumerates bouncer networks, opens a second connection to the bouncer (you need an additional connection per upstream network), and then crashes.

While trying to find some details on the AUTHENTICATE command using SASL (do I know what I’m doing at this point?), I ended up falling down a rabbit hole where I came across a particular IRC client I that had somehow slipped under my radar:


After testing it for a couple of days, I can say that senpai works impressively well. I didn’t have a configuration file the first time that I ran it, and it prompted my for some basic connection details to create one for me. Additional configuration is documented in senpai(5).

I’m using sourcehut’s IRC bouncer, so my server is chat.sr.ht, username whynothugo and the password is an OAuth token. The quickstart guide for chat.sr.ht has a handy link titled “Visit the personal access token issuance page with this specially-crafted link”. Any time that I need an sourcehut OAuth token for IRC, this is the simplest path.

After a short test drive, I moved the token out of the configuration file and into [himitsu]. senpai supports a password-cmd configuration directive, which is exactly what it seems: a command that gets executed for senpai to retrieve a password. I replaced password in my configuration with:

password-cmd hiq -dFpassword proto=irc address=chat.sr.ht nickname=whynothugo

Now when I start senpai, it will run hiq, which queries himitsu (the secret store) for the bouncer password. I’ll get a quick prompt to authorise this and it connects right away.

senpai is quite geared towards use with a bouncer. It starts up super fast, and immediately shows all channel that I’ve joined. It’s a very fast an effortless experience TBH.

Switching between buffers can be done by clicking on the buffers on the left-hand sidebar, or simply by typing /buffer N, where N is the buffers number. There doesn’t seem to be a shortcut for this, but the buffer names show up once I type /buf.

I haven’t tried this on the road yet, so I’m not sure how well it work with slow connections. When putting the system to sleep and waking it up a few hours later, I notice that it shows no indication of being offline, but if I send a command to the server, it warns about being disconnected, and re-connects very quickly. I got an impression that history re-sync immediately, so messages that arrived while the system was asleep showed up fine.

Terminal hints

I added this directive to the configuration file:

on-highlight-beep true

This makes senpai send a “terminal bell” whenever I’m mentioned in a channel. Terminal bells are that “beep” that you used to hear from the speaker inside the computer CPU in the nineties, but nowadays terminals can map this to an urgency hint.

I have the following in the configuration file for my terminal, foot:


This makes foot set the “urgency hint” for its window whenever an application tries to “ring the bell”. The effect is that the window and its workspace are highlighted in red in sway.


senpai also supports showing notifications when one is mentioned, by running a custom script when this happens. I tried putting the following script in ~/.config/senpai/highlight:

echo -e "\033]777;notify;senpai;You've been mentioned on IRC\a"

Regrettably, this didn’t work for me, even though the script was getting executed. This script emits a terminal sequence which tells the terminal to emit a notification. The terminal then relays it to the notification daemon. This indirection makes notifications show up even if senpai is being run over SSH on a remote system.

This didn’t work because the senpai runs the script while sending its output to /dev/null (this usually makes sense to avoid scripts from messing up what’s on screen). But in this case, this means that the escape sequence never reaches the terminal. I figure out a hacky way around the issue and opened a ticket to discuss a cleaner fix, but a cleaner implementation is blocked by the terminal library implementing the escape sequence upstream.

In the meantime, I’ve replaced ~/.config/senpai/highlight with the following instead:

notify-send -a senpai -i foot "senpai" "New message from $SENDER"

This won’t work via SSH, but should be fine 99% of the time for me anyway.

Nice and clean code

senpai had a quirk which I’ve been finding quite annoying: when it starts up it won’t highlight channels which have received messages while it wasn’t running. It also won’t highlight channels with mentions.

I decided to have a look at the code and try to fix this myself. I managed to produce a patch for that, as well as a patch to add an “unread” ruler in channels. Both of these have been merged upstream and will be out on the next release.

I have to say that, from what I can tell so far, senpai’s codebase is very clean and easy to understand (it’s written in go, in case you’re wondering).

If you’re on the lookout for a good IRC client, I recommend trying this out (you’ll have to use the version from git if you want my patches).

— § —