Clone the repository

January 13, 2026 ยท View on GitHub

#+TITLE: CLatter - A Common Lisp IRC Client #+AUTHOR: Glenn Thompson #+OPTIONS: toc:2

  • CLatter

A terminal-based IRC client written in Common Lisp using the [[https://codeberg.org/McParen/croatoan][croatoan]] ncurses library.

** Features

  • Multi-Network Support - Connect to multiple IRC networks simultaneously (e.g., Libera and OFTC)
  • TLS Support - Secure connections to IRC servers
  • SASL Authentication - PLAIN and EXTERNAL (client certificate) authentication
  • Client Certificate Auth - Authenticate using TLS client certificates
  • Auto-Reconnect - Automatic reconnection with exponential backoff
  • Connection Health Monitoring - Detects stale connections and reconnects
  • Nick Colorization - Each nick gets a consistent color based on hash
  • Nick Highlighting - Messages mentioning your nick are highlighted
  • Tab Completion - Press Tab to complete nicks in the current channel
  • Nick List Panel - Toggle channel member list with =Ctrl-O=
  • Input Scrolling - Long input lines scroll horizontally to keep cursor visible
  • Readline Keybindings - Emacs-style cursor movement (Ctrl-A/E/B/F)
  • Autojoin Management - Channels are auto-added to autojoin on /join
  • Multi-buffer Interface - Server, channel, and query buffers grouped by network
  • Command History - Up/Down arrows to navigate input history
  • Scrollback - Ctrl-U/D to scroll through message history
  • Split-Pane View - View two channels side-by-side with =Ctrl-W=
  • CTCP Support - Responds to VERSION, PING, TIME requests
  • DCC Support - Direct client-to-client chat and file transfers
  • Message Logging - Automatic logging to =~/.local/share/clatter/logs/=
  • Log Search - Search through message history with /log search
  • CrafterBin Integration - Upload files to pastebin with /crafterbin
  • IRCv3 Capabilities - server-time, away-notify, multi-prefix, account-notify, typing, batch, chathistory, labeled-response, MONITOR
  • Channel Modes Display - Shows channel modes and your status (@/+) in status bar
  • Ignore List - Hide messages from specific users with /ignore
  • Away Status - Set away status with /away
  • Secure Password Storage - Support for authinfo.gpg, systemd-creds, and pass(1)
  • Theming - Multiple built-in themes (dark, light, solarized, minimal, ascii, rounded) with /theme
  • Message Search - Search buffer history with /search
  • Message Filtering - Filter displayed messages with /filter
  • URL Detection - Automatically tracks URLs in chat, open with /url

** Requirements

  • SBCL (Steel Bank Common Lisp)
  • Quicklisp
  • ncurses development libraries
  • curl (for /crafterbin uploads)
  • One of the following for clipboard support (optional):
    • =xclip= (X11)
    • =xsel= (X11)
    • =wl-clipboard= (Wayland)

** Installation

#+begin_src bash

Clone the repository

git clone https://github.com/yourusername/CLatter.git cd CLatter

Build

make clean && make #+end_src

** Usage

#+begin_src bash ./clatter #+end_src

On first run, you'll be prompted for a nickname and connected to Libera.Chat.

*** Quick Start

  1. Launch CLatter: =./clatter=
  2. Join a channel: =/join #channel=
  3. Send messages: Just type and press Enter
  4. Switch buffers: =Ctrl-P= (previous) / =Ctrl-N= (next)
  5. Scroll history: =Ctrl-U= / =Ctrl-D=
  6. Tab-complete nicks: Start typing a nick and press =Tab=
  7. Quit: =/q= or =F10=

*** Tips

  • If the display looks corrupted, press =Ctrl-L= to refresh
  • Use =Ctrl-W= to toggle split-pane view for monitoring two channels
  • Messages mentioning your nick are highlighted
  • Logs are saved to =~/.local/share/clatter/logs/=

** Configuration

Configuration is stored in =~/.config/clatter/config.lisp=

Example: #+begin_src lisp (:clatter-config :version 1 :default-network nil :time-format "%H:%M:%S" :buflist-width 28 :networks ((:name "libera" :server "irc.libera.chat" :port 6697 :tls t :nick "yournick" :username nil :realname "Your Name" :password nil :nickserv-pw "your-password" :sasl :plain :autojoin ("#lisp" "#emacs") :autoconnect t))) #+end_src

*** UI Options

  • =:time-format= - Format string for timestamps (default: ="%H:%M"=)
  • =:buflist-width= - Width of the buffer list panel in characters (default: =28=). Reduce this for smaller terminal windows.

*** SASL Authentication

SASL authenticates you before your connection is visible, so your IP/hostname is cloaked from the start.

**** SASL PLAIN (password-based)

  1. You must have a registered nick with NickServ
  2. Add =:sasl :plain= to your network config
  3. Ensure =:nickserv-pw= contains your NickServ password (or use =:authinfo=)

**** SASL EXTERNAL (certificate-based) - UNTESTED

More secure - uses a client certificate instead of a password.

  1. Generate a certificate: #+begin_src bash openssl req -x509 -new -newkey rsa:4096 -sha256 -days 3650 -nodes
    -keyout ~/.config/clatter/clatter.key -out ~/.config/clatter/clatter.crt
    -subj "/CN=YourNick" cat ~/.config/clatter/clatter.crt ~/.config/clatter/clatter.key > ~/.config/clatter/clatter.pem #+end_src

  2. Register the certificate with NickServ (connect with password first): #+begin_example /msg NickServ CERT ADD #+end_example

  3. Update your config: #+begin_src lisp (:name "libera" :server "irc.libera.chat" :nick "yournick" :sasl :external :client-cert "/home/you/.config/clatter/clatter.pem" ...) #+end_src

  4. You can now remove =:nickserv-pw= - the certificate handles authentication

*** Password Storage Options

CLatter supports multiple methods for storing passwords securely. These options work for both =:nickserv-pw= (NickServ/SASL password) and =:password= (server password).

**** Plain Text (not recommended)

Store the password directly in the config file:

#+begin_src lisp :nickserv-pw "your-password" #+end_src

**** Authinfo (GPG encrypted)

Use =/.authinfo= or =/.authinfo.gpg= (encrypted with GPG):

#+begin_src lisp :nickserv-pw :authinfo #+end_src

Then add an entry to your =~/.authinfo.gpg= file: #+begin_example machine irc.libera.chat login yournick password your-secret-password #+end_example

CLatter will decrypt the file using GPG and look up the password by matching the server and nick.

**** systemd-creds (encrypted with TPM/host key)

Use =systemd-creds= to create a system credential to encrypt your password. This ties the credential to your machine and doesn't require GPG. This requires root privlages.

  1. Create the encrypted credential: #+begin_src bash mkdir -p ~/.config/clatter/creds read -s -p "Enter NickServ password: " pw && echo -n "$pw" |
    systemd-creds encrypt - ~/.config/clatter/creds/nickserv.cred &&
    echo -e "\nCredential saved" #+end_src

  2. Update your config: #+begin_src lisp :nickserv-pw (:systemd-cred "/home/you/.config/clatter/creds/nickserv.cred") #+end_src

CLatter will decrypt the credential file at startup using =systemd-creds decrypt=.

**** pass(1) (GPG encrypted) Use =pass(1)= the standard unix password manager, to store and encrypt your password. This works using GPG and the credential is portable.

  1. Install pass using your package manager of choice (see [[https://www.passwordstore.org/][website]] for supported platforms).

  2. Generate a password =pass generate=

  3. Update your config: #+begin_src lisp :nickserv-pw (:pass "password-name") ; where password-name is the name of the file in pass(1) #+end_src

**** Server Password

If your IRC server requires a connection password (separate from NickServ), use the =:password= field with any of the above methods:

#+begin_src lisp :password (:systemd-cred "/home/you/.config/clatter/creds/server.cred") #+end_src

Or with authinfo/plain text: #+begin_src lisp :password :authinfo :password "plain-text-password" #+end_src

** Commands

| Command | Description | |------------------------------+------------------------------------------| | /join #channel [key] | Join a channel (auto-adds to autojoin) | | /part [#channel] [msg] | Leave channel, remove from autojoin | | /leave [#channel] [msg] | Alias for /part | | /close | Close current buffer (use after /part) | | /autojoin | List autojoin channels | | /autojoin add #channel | Add channel to autojoin | | /autojoin remove #channel | Remove channel from autojoin | | /msg target text | Send private message | | /me action | Send action to current channel | | /nick newnick | Change nickname | | /quit or /q [message] | Disconnect and exit | | /ns command | Send to NickServ | | /cs command | Send to ChanServ | | /query nick | Open query with user | | /whois nick | Query user information | | /topic [text] | View or set channel topic | | /kick nick [reason] | Kick user from channel (requires op) | | /ban mask | Ban a hostmask from channel (requires op)| | /mode [+/-modes] [args] | Set channel or user modes | | /ctcp nick command | Send CTCP request (VERSION, PING, TIME) | | /log | View recent logs for current buffer | | /log search pattern | Search logs for pattern | | /log list | List all logged targets | | /log export [text/json/html] | Export logs to file | | /dcc chat nick | Initiate DCC chat with user | | /dcc send nick file | Send file via DCC | | /dcc accept [id] | Accept pending DCC offer | | /dcc reject [id] | Reject pending DCC offer | | /dcc list | List DCC connections | | /dcc close [id] | Close DCC connection | | /crafterbin file | Upload file to CrafterBin pastebin | | /ignore [nick] | List ignored or toggle ignore for nick | | /unignore nick | Remove nick from ignore list | | /away [message] | Set away status (no message = back) | | /back | Clear away status | | /history [count] | Request chat history (if server supports)| | /invite nick [#channel] | Invite user to channel | | /names [#channel] | Refresh channel member list | | /monitor + nick1,nick2 | Add nicks to monitor list | | /monitor - nick1,nick2 | Remove nicks from monitor list | | /monitor l | List monitored nicks | | /monitor s | Check status of monitored nicks | | /monitor c | Clear monitor list | | /list [pattern] | List channels on server | | /who target | Query user/channel info | | /raw line | Send raw IRC command | | /theme [name] | List themes or switch theme | | /search pattern | Search current buffer for messages | | /filter pattern | Show only messages matching pattern | | /unfilter | Clear message filter | | /url [N\vert{}list] | Open Nth recent URL or list URLs | | /help | Show help |

** Keybindings

| Key | Action | |-------------+---------------------------| | Tab | Nick completion | | Up/Down | Input history | | Ctrl-U/D | Scroll chat history | | Ctrl-P/N | Previous/Next buffer | | Ctrl-A | Move to start of line | | Ctrl-E | Move to end of line | | Ctrl-B | Move cursor back | | Ctrl-F | Move cursor forward | | Ctrl-L | Refresh/redraw screen | | Backspace | Delete character | | Enter | Send message/command | | Ctrl-W | Toggle split pane | | Ctrl-T | Toggle split orientation | | Ctrl-L | Force redraw | | Ctrl-R | Set right pane buffer | | Ctrl-X | Swap panes | | F10 | Quit |

** CrafterBin Integration

CLatter includes built-in support for uploading files to [[https://crafterbin.glennstack.dev][CrafterBin]], a simple pastebin service.

#+begin_src /crafterbin /path/to/file.txt #+end_src

This will:

  1. Upload the file to CrafterBin
  2. Copy the resulting URL to your clipboard (requires =xclip=, =xsel=, or =wl-copy=)
  3. Display the URL in the chat buffer

Useful for quickly sharing code snippets, logs, or configuration files in IRC channels.

** License

MIT

** Acknowledgments