A dedicated, fully IRCv3-compliant IRC client for Emacs. Pure Elisp. No external dependencies beyond Emacs itself (GnuTLS required for TLS connections).
Spiritual successor to CLatter (the Common Lisp TUI client), redesigned from scratch for Emacs.
- Full IRC protocol (RFC 1459/2812)
- IRCv3 capability negotiation (CAP LS 302)
- SASL authentication (PLAIN, SCRAM-SHA-256, EXTERNAL/certificate)
- IRCv3 message tags (server-time, msgid, batch, etc.)
- Batch message handling (chathistory)
- Labeled responses
- Standard Replies (FAIL/WARN/NOTE) with formatted display
- Strict Transport Security (STS) - auto-upgrade plaintext to TLS
- MONITOR (online/offline tracking)
- Typing indicators (+typing)
- CTCP (VERSION, TIME, PING, ACTION, DCC)
- TLS/SSL with client certificate support
- mIRC color/formatting codes (bold, italic, underline, colors, reverse)
- BOT mode (draft/bot) - [bot] indicator on messages from bots
- WHOX (extended WHO) - bulk account name fetching on channel join
- Channel rename (draft/channel-rename) - auto-updates buffers
- STATUSMSG - prefix-targeted messages with [ops]/[voiced] indicator
- ISUPPORT (005) parameter parsing
- Thread/reply support (draft/reply) - inline reply context display
- Reactions (draft/react) - emoji reactions on messages via TAGMSG
- Buffer-per-channel (native Emacs buffers)
- Newest-at-top message layout (input prompt at top, messages below)
auth-sourceintegration for passwords (.authinfo.gpg, pass, etc.)- Multi-network support
- Configurable message suppression (JOIN, PART, QUIT, NICK, etc.)
- Buffer truncation (configurable
clatter-buffer-max-lines, default 10000) - Flyspell spell-checking in input area (built-in, toggle with
clatter-flyspell-enable) - Paste flood protection (warns before sending >3 lines, configurable threshold)
/closecommand to kill current buffer (PARTs from channels first)- Reconnect/disconnect status shown inline in channel buffers
- 40-color palette optimized for dark themes
- Hash-based stable colors (same nick = same color across sessions)
- In-text nick highlighting (nicks colorized in message body, not just prefix)
- Nick alias support for consistent colors across nick changes
- URL detection with clickable links (
RETor mouse click on any URL) clatter-hl-open-url-nearestopens nearest URL on current line (bind in init.el)M-x clatter-hl-browse-urlsto browse all URLs from the buffer (completing-read picker)M-x clatter-hl-copy-urlto copy a URL from the buffer to kill ring- Configurable skip-nicks and minimum length
/ignore NICK-OR-PATTERNto hide all messages from a user/unignore NICK-OR-PATTERNto remove from ignore list/ignorewith no args shows current ignore list- Glob wildcards (
*and?) supported, case-insensitive - Filtering is UI-only; ignored messages still appear in logs
- Toggle from action menu with
I
- Async URL title fetching (displays inline as system message)
- Cached titles to avoid re-fetching
- Excludes binary/media URLs (.png, .jpg, .mp4, etc.)
- Opt-in: set
clatter-url-preview-enabletot - Configurable max title length and timeout
- Automatic logging to
~/.emacs.d/clatter/logs/ - Daily rotated log files (
network/target-YYYY-MM-DD.log) - Buffered writes with configurable flush interval
- Logs PRIVMSG, ACTION, NOTICE, JOIN, PART, QUIT, NICK, TOPIC, KICK, MODE
M-x clatter-log-opento open log for current channelM-x clatter-log-open-directoryto browse all logs- Per-channel exclusion via
clatter-log-exclude-targets - Opt-in: set
clatter-log-enabletot
- Context-aware action menu on message at point (
C-c C-a) - Reply: insert nick at prompt
- Copy: message text, nick, or URL
- WHOIS: query sender info
- Query: open DM with sender
- Inspect: view raw message properties
- Ignore: toggle sender ignore (messages hidden)
- URL collection: list all URLs in buffer
- Global mode-line activity indicator
- Unread counts and mention detection per channel
- Priority sorting: mentions > DMs > regular activity
- Clickable mode-line entries (switch to buffer on click)
- Channel mute/unmute support
- Consult integration (narrow with
iinconsult-buffer) M-x clatter-track-switchto jump to most urgent activityM-x clatter-track-listto list all activity
- Mention, DM, and keyword-triggered notifications
- Uses notify-send (Linux) or terminal-notifier (macOS)
- Per-channel and per-nick muting
- Smart notification rules: per-channel levels (all/mentions/dms/none) with schedule
- DM priority override (always/rules/never)
- Schedule support with 24h ranges, wraps midnight (e.g. 22-8)
- Current-buffer suppression (no noise for what you already see)
- Rate limiting (configurable cooldown per source)
- Optional sound support
- Custom keyword watchlist
M-x clatter-notify-toggleto toggle,M-x clatter-notify-add-keywordto add keywordsM-x clatter-notify-testto verify setup
- Completion-at-point for nicks, /commands, and #channels
- Integrates with Corfu, Vertico, Orderless (standard Emacs CAPF)
- Nick annotations show channel prefix (@, +, etc.)
- /command annotations show descriptions
- Auto “: ” suffix when completing nick at start of input
- TAB triggers completion in input area
- Full raw IRC traffic inspector
- Color-coded incoming (<< green) and outgoing (>> blue)
- Optional parsed message structure display
- Filter by regex pattern
- Send raw IRC commands directly
- View CAP negotiation state
M-x clatter-rawlog-opento open rawlog
- Highlight custom words in message text (beyond nick mentions)
- Case-insensitive, word-boundary matching
- Configure with
clatter-hl-keywords(list of strings) - Distinct face (
clatter-hl-keyword) for easy visibility
- Search across all IRC log history with
grep - Two interfaces: dedicated results buffer and
completing-read - Filter by network, search current channel with
/searchhere - Jump directly to log file at matching line
- Commands:
/search,/searchhere,/grep,/find - Also available as
M-x clatter-search/M-x clatter-search-completing
- Incoming replies show context:
↳ sender: preview of original message /reply TEXTsends a threaded reply to the message at point- Uses IRCv3
+draft/replyandmsgidtags - Reply context is truncated to 60 chars for readability
/react EMOJIsends an emoji reaction to the message at point- Incoming reactions display as badges below the referenced message
- Multiple reactions aggregate with counts (e.g.
👍 3 🎉 1) - Uses IRCv3
+draft/reactvia TAGMSG
org-store-linksupport: store links to IRC messages (irc:network/channel#msgid)org-capturehelpers:%(clatter-org-capture-message)and%(clatter-org-capture-channel)- Log export:
M-x clatter-org-export-logconverts logs to org format grouped by date
- DCC SEND receive (XDCC pack downloads)
- Async binary download with 4-byte ack protocol
- Accept/reject prompt with file size display
- Progress reporting (speed, percentage, ETA)
- DCC RESUME/ACCEPT for interrupted transfers
- Auto-accept mode and configurable max file size
- Output path collision avoidance
- Configurable download directory (default
~/Downloads/) /dcc get BOT #PACKto request XDCC packs/dcc list,/dcc accept,/dcc cancelmanagement commands
/autojoin add #channelsaves channel to autojoin list/autojoin remove #channelremoves from autojoin list/autojoin listshows current autojoin for the network- Persists via
customize-save-variabletocustom-file
- Async inline image display for URLs in messages
- Opt-in: disabled by default (
clatter-image-enable) - GUI frames only, graceful no-op in terminal
- Configurable max width/height and file size cap
- Uses async curl subprocess (non-blocking)
- Interactive
/listcommand with tabulated display - Sorted by user count (descending)
- Filter by regex (
for/) - Join channel with
RET, refresh withg - Handles large networks efficiently
- MOTD displayed in server buffer on connect
- Formatted WHOIS output inline: nick, user@host, realname, account, server, channels, idle time, signon date, TLS, operator, away status
- Uses IRCv3 server-time tag for accurate timestamps
- Timestamps reflect when the message was sent, not received
- Essential for bouncer and chathistory accuracy
- Falls back to local time when server-time is unavailable
- IRCv3 CHATHISTORY extension support
- Auto-fetches backlog on channel join
- Fetches gap messages on reconnect
- Manual fetch commands for older messages
- Configurable message limit per request
- Works with soju, znc, and compliant servers
- Visual separator for batch-delivered history (chathistory, ZNC playback)
- Start/end markers with message count
- Messages render normally with timestamps between separators
- Works with any IRCv3 BATCH-based playback
- Eldoc integration: hover over
#channelnames to see topic and user count - Message info on hover: sender and message ID shown in echo area
- Automatic via
eldoc-modein clatter buffers
- IRCv3 read-marker (MARKREAD) protocol support
- Syncs read position across clients via server
- Visual marker line between read and unread messages
- Auto-sends MARKREAD on buffer focus
- Manual mark/query commands
- Emacs 29.1 or later
- GnuTLS (for TLS/SSL connections) - Emacs must be compiled with GnuTLS support
- On Debian/Ubuntu:
apt install gnutls-bin libgnutls28-dev - On Fedora/RHEL:
dnf install gnutls - On macOS (Homebrew):
brew install gnutls - On Arch:
pacman -S gnutls - Check with:
M-x describe-variable RET gnutls-available-p RET
- On Debian/Ubuntu:
Most modern Emacs builds include GnuTLS support by default.
Clone this repository and add to your load-path:
(add-to-list 'load-path "~/SourceCode/clatter.el")
(require 'clatter);; Connect to a network
(clatter-connect "libera"
:server "irc.libera.chat"
:port 6697
:tls t
:nick "yournick"
:autojoin '("#emacs" "#commonlisp"))Or configure via customize:
(setopt clatter-networks
'(("libera"
:server "irc.libera.chat"
:port 6697
:tls t
:nick "yournick"
:sasl scram-sha-256 ;; or 'plain or 'external
:autojoin ("#emacs" "#commonlisp"))))Or use M-x customize-group RET clatter RET for the full options UI.
clatter does not impose any global keybindings. All commands are available via M-x and /slash commands in the input prompt.
If you use Evil with a SPC leader (via general.el or similar), here is an example configuration:
(my-leader ;; replace with your leader definer
"i" '(:ignore t :wk "IRC")
"ii" '(clatter :wk "Connect to network")
"id" '(clatter-disconnect :wk "Disconnect")
"is" '(clatter-status :wk "Connection status")
"it" '(clatter-track-switch :wk "Jump to activity")
"il" '(clatter-track-list :wk "List activity")
"in" '(clatter-notify-toggle :wk "Toggle notifications")
"ik" '(clatter-notify-add-keyword :wk "Add notify keyword")
"ir" '(clatter-rawlog-open :wk "Raw protocol log")
"io" '(clatter-hl-browse-urls :wk "Browse URLs")
"iy" '(clatter-hl-copy-url :wk "Copy URL")
"ip" '(clatter-nicklist-toggle :wk "Toggle nick list"))With Evil, SPC only triggers the leader in normal state. When you press i to enter insert state at the prompt, SPC types a space character as expected.
(global-set-key (kbd "C-c i i") #'clatter)
(global-set-key (kbd "C-c i d") #'clatter-disconnect)
(global-set-key (kbd "C-c i t") #'clatter-track-switch)
(global-set-key (kbd "C-c i l") #'clatter-track-list)| File | Description |
|---|---|
clatter.el | Main entry point, autoloads |
clatter-protocol.el | IRC message parsing/formatting, IRCv3 tags |
clatter-connection.el | Network I/O, TLS, reconnection |
clatter-cap.el | CAP negotiation, SASL authentication |
clatter-handlers.el | IRC message dispatch and event handling |
clatter-model.el | Channel/nick/buffer state management |
clatter-ui.el | Buffer rendering, faces, mode-line, input |
clatter-commands.el | User commands (/join, /part, /msg, etc.) |
clatter-config.el | User configuration, defcustom, auth-source |
clatter-hl-nicks.el | Nick colorization, URL highlighting |
clatter-actions.el | Message actions at point |
clatter-track.el | Buffer activity tracking, mode-line indicator |
clatter-notify.el | Desktop notifications with IRC rules |
clatter-completion.el | Completion-at-point for nicks, commands, channels |
clatter-rawlog.el | Raw IRC protocol inspector/devtools |
clatter-chathistory.el | IRCv3 CHATHISTORY backlog fetching |
clatter-read-marker.el | IRCv3 read-marker sync |
clatter-nicklist.el | Channel member sidebar |
clatter-log.el | Channel logging to file with daily rotation |
clatter-url-preview.el | Async URL title preview |
clatter-format.el | mIRC color/formatting code parser |
clatter-sasl-scram.el | SASL SCRAM-SHA-256 (RFC 5802) |
clatter-sts.el | IRCv3 Strict Transport Security |
clatter-list.el | Interactive channel list browser |
clatter-image.el | Inline image preview (opt-in, GUI only) |
clatter-search.el | Full-text search across IRC log history |
clatter-org.el | Org-mode integration (links, capture, export) |
clatter-dcc.el | DCC file transfer (XDCC receive, resume) |
clatter.el requires curl at runtime for async URL/image fetching.
No Emacs Lisp dependencies beyond Emacs 29.1 itself.
Works well with:
- emojify - emoji rendering in messages (recommended)
- corfu / vertico - completion UI for nick/command/channel completion
- orderless - flexible completion matching
- consult -
consult-bufferintegration viaclatter-track
MIT
