Halloy

Halloy is an open-source IRC client written in Rust, with the iced GUI library. It aims to provide a simple and fast client for Mac, Windows, and Linux platforms.
- IRCv3.2 capabilities
- SASL support
- DCC Send
- Keyboard shortcuts
- Auto-completion for nicknames, commands, and channels
- Notifications support
- Multiple channels at the same time across servers
- Commandbar for for quick actions
- Custom themes
- Portable mode
Contributing
Halloy is free and open source. You can find the source code as well as report issues and feature requests on GitHub.
Installing Halloy
💡 To get the latest nightly version of Halloy, you can build from source.
Pre-built binaries
Download pre-built binaries from GitHub page.
Packaging status
macOS
The following third party repositories are available for macOS
Homebrew
brew install --cask halloy
MacPorts
sudo port install halloy
Linux
The following third party repositories are available for Linux
Flatpak
https://flathub.org/apps/org.squidowl.halloy
Snapcraft
Windows
Winget
winget install squidowl.halloy
Build from source
Clone the Halloy GitHub repository into a directory of your choice and build with cargo.
Requirements:
# Clone the repository
git clone https://github.com/squidowl/halloy.git
cd halloy
# Build and run
cargo build --release
cargo run --release
Getting started
To get started with Halloy, you need to connect to at least one IRC server. The template config file has been set up with the Libera server. However, there are many other servers available: OFTC, Undernet, EFnet, QuakeNet and many more. Halloy can connect to multiple servers at the same time.
Once connected to a server, you can join channels. This can be done automatically from the config file or manually using the join command: /join #channel
1. To find channels, you can either use the list command: /list
, or browse for channels online.
💡 Configuration in Halloy happens through a
config.toml
file. See Configuration.
Here are a few useful IRC commands for a new user2
Command | Example | Description |
---|---|---|
/join | /join #halloy | Join a new channel |
/part | /part #halloy | Part a channel |
/nick | /nick halloyisgreat | Change your nickname |
/whois nickname | /whois halloyisgreat | Displays information of nickname requested |
/list *keyword* | /list *linux* | List channels. Keyword is optional |
Channel names always start with a #
symbol and do not contain spaces.
Find more commands here.
Get in touch
Join #halloy
on libera.chat
(link) if you have questions, looking for help or just want to say hello.
For feature requests or reporting issues, please open a ticket on GitHub.
Maintainers
Connect with Soju
To connect with a soju bouncer, the configuration below can be used as a template. Simply change so it fits your credentials.
[servers.libera]
nickname = "casperstorm"
username = "<your-username>/irc.libera.chat@desktop"
server = "irc.squidowl.org"
port = 6697
password = "<your-password>"
chathistory = true
Connect with ZNC
To connect with a ZNC bouncer, the configuration below can be used as a template. Simply change so it fits your credentials.
[servers.libera]
nickname = "<znc-user>/<znc-network>"
server = "znc.example.com"
password = "<your-password>"
# Depending on your ZNC setup you may need to apply these extra settings:
# Does your znc use a self-signed or expired certificate? See:
# https://halloy.squidowl.org/configuration/servers.html#dangerously_accept_invalid_certs
# Does your znc listen on a different port? See:
# https://halloy.squidowl.org/configuration/servers.html#port
Portable mode
To enable portable mode for Halloy, simply place the config.toml
file in the same directory as the running executable.
.
├── Halloy.app
└── config.toml
Multiple servers
Creating multiple [servers]
sections lets you connect to multiple servers.
All configuration options can be found here.
[servers.liberachat]
nickname = "halloy-user"
server = "irc.libera.chat"
channels = ["#halloy"]
[servers.oftc]
nickname = "halloy-user"
server = "irc.oftc.net"
channels = ["#asahi-dev"]
Storing passwords in a File
If you need to commit your configuration file to a public repository, you can keep your passwords in a separate file for security. Below is an example of using a file for nickname password for NICKSERV.
💡 Avoid adding extra lines in the password file, as they will be treated as part of the password.
💡 Shell expansions (e.g.
"~/"
→"/home/user/"
) are not supported in path strings.
💡 Windows path strings should usually be specified as literal strings (e.g.
'C:\Users\Default\'
), otherwise directory separators will need to be escaped (e.g."C:\\Users\\Default\\"
).
[servers.liberachat]
nickname = "foobar"
nick_password_file = "/home/user/config/halloy/password"
server = "irc.libera.chat"
channels = ["#halloy"]
Text Formatting
Text can be formatted in Halloy by using the /format
(or /f
) command.
Attributes
Below is a table with the supported text attributes.
Action | Markdown | Token |
---|---|---|
Italics | _italic text_ | $iitalic text$i |
Bold | __bold text__ | $bbold text$b |
Italic and Bold | ___italic and bold___ | $b$iitalic and bold$i$b |
~~strikethrough~~ | $sstrikethrough$s | |
Underline | - | $uunderline$u |
Code | `code` | $mcode$m |
Spoiler | ||spoiler|| | - |
Example
/format __this is bold__ $iand this is italic$i
Will render the following:
this is bold and this is italic
Color
Action | Token |
---|---|
Text color (fg) | $c0 |
Text and background (fg & bg) | $c0,1 |
End color | $c |
The number next to the $c
token indicates the color. For a comprehensive list of all numbers, see the following ircdocs.horse documentation. Below, the first 00 to 15 colors are defined and have been assigned aliases for convenience.
Colors
- 00 - white
- 01 - black
- 02 - blue
- 03 - green
- 04 - red
- 05 - brown
- 06 - magenta
- 07 - orange
- 08 - yellow
- 09 - lightgreen
- 10 - cyan
- 11 - lightcyan
- 12 - lightblue
- 13 - pink
- 14 - grey
- 15 - lightgrey
Example
/format $cred,lightgreenfoobar$c
/format $c04,09foobar$c
Will both render the following:
foobarConfiguration
By default, Halloy will only format text when using the /format
command. This, however, can be changed with the auto_format
configuration option:
[buffer.text_input]
auto_format = "disabled" | "markdown" | "all"
Monitor users
Halloy has monitor support if the server has the IRCv3 Monitor extension.
💡 A protocol for notification of when clients become online/offline
To use the feature you need to add the user(s) you wish to monitor. This can be done in two ways:
- You can add a list of user directly to the configuration file. See configuration option.
- You can add users through
/monitor
directly in Halloy.
Examples with the /monitor
command:
/monitor + casperstorm # Add user to list being monitored
/monitor - casperstorm # Remove user from list being monitored
/monitor c # Clear the list of users being monitored
/monitor l # Get list of users being monitored
/monitor s # For each user in the list being monitored, get their current status
Migrating from YAML
Halloy switched configuration file format from YAML to TOML (PR-278)
This page will help you migrate your old config.yaml
to a new config.toml
file.
The basic structure of a TOML file consists of key-value pairs, where keys are strings. There are no nested indentations like YAML, which makes it easier to read and write. Consider the following old YAML config with of two servers in Halloy:
servers:
libera:
nickname: foobar
server: irc.libera.chat
quakenet:
nickname: barbaz
server: underworld2.no.quakenet.org
port: 6667
use_tls: true
This now looks the following in TOML
[servers.libera]
nickname = "foobar"
server = "irc.libera.chat"
[servers.quakenet]
nickname = "barbaz"
server = "underworld2.no.quakenet.org"
port = 6667
use_tls = true
💡 You can convert YAML to TOML using a converter tool like this one. Just note that a few keys and values have be renamed during the conversion process.
To migrate, and ensure everything is working, make sure to read through the Configuration section of this book. Here, every configuration option is documented using TOML.
Configuration
To edit configuration parameters, create a config.toml
file located in your configuration directory:
- Windows:
%AppData%\halloy
- Mac:
~/Library/Application Support/halloy
or$HOME/.config/halloy
- Linux:
$XDG_CONFIG_HOME/halloy
or$HOME/.config/halloy
💡 You can easily open the config file directory from command bar in Halloy
The specification for the configuration file format (TOML) can be found at https://toml.io/.
Example config for connecting to Libera:
[servers.liberachat]
nickname = "halloy-user"
server = "irc.libera.chat"
channels = ["#halloy"]
[buffer.channel.topic]
enabled = true
[buffer]
Buffer settings for Halloy.
- Away - Controls the appearance of away nicknames
- Channel - Channel specific settings
- Chathistory - IRCv3 Chat History extension settings
- Commands - Commands settings
- Date Separators - Customize how date separators are displayed within a buffer
- Emojis - Emojis settings
- Internal Messages - Internal messages are messages sent from Halloy itself
- Nickname - Customize how nicknames are displayed within a buffer
- Server Messages - Server messages are messages sent from a irc server.
- Status Message Prefix - Status message prefix settings
- Text Input - Customize the text input for in buffers
- Timestamp - Customize how timestamps are displayed within a buffer
[buffer.away]
Controls the appearance of away nicknames.
appearance
Controls the appearance of away nicknames in buffers.
# Type: string
# Values: "dimmed", "solid"
# Default: "dimmed"
[buffer.away]
appearance = "dimmed"
[buffer.channel]
Channel specific settings
[buffer.channel.message]
Message settings within a channel buffer.
nickname_color
Nickname colors in the message. "unique"
generates colors by randomizing the hue, while keeping the saturation and lightness from the theme's nickname color.
# Type: string
# Values: "solid", "unique"
# Default: "unique"
[buffer.channel.message]
nickname_color = "unique"
[buffer.channel.nicklist]
Nicklist settings within a channel buffer.
alignment
Horizontal alignment of nicknames.
# Type: string
# Values: "left", "right"
# Default: "left"
[buffer.channel.nicklist]
alignment = "left"
color
Nickname colors in the nicklist. "unique"
generates colors by randomizing the hue, while keeping the saturation and lightness from the theme's nickname color.
# Type: string
# Values: "solid", "unique"
# Default: "unique"
[buffer.channel.nicklist]
color = "unique"
enabled
Control if nicklist should be shown or not by default.
# Type: boolean
# Values: true, false
# Default: true
[buffer.channel.nicklist]
enabled = true
position
Nicklist position in the pane.
# Type: string
# Values: "left", "right"
# Default: "left"
[buffer.channel.nicklist]
position = "right"
show_access_levels
Show access levels in front of nicknames (@
, +
, ~
, etc.).
# Type: boolean
# Values: true, false
# Default: true
[buffer.channel.nicklist]
show_access_levels = true
width
Overwrite nicklist width in pixels.
# Type: integer
# Values: any positive integer
# Default: not set
[buffer.channel.nicklist]
width = 150
[buffer.channel.topic]
Topic settings within a channel buffer.
enabled
Control if topic should be shown or not by default.
# Type: boolean
# Values: true, false
# Default: true
[buffer.channel.topic]
enabled = true
max_lines
Amount of visible lines before you have to scroll in topic banner.
# Type: integer
# Values: any positive integer
# Default: 2z
[buffer.channel.topic]
max_lines = 2
[buffer.chathistory]
IRCv3 Chat History extension settings
infinite_scroll
Automatically request older history when scrolling to the top of a channel/query buffer
# Type: boolean
# Values: true, false
# Default: true
[buffer.chathistory]
infinite_scroll = true
[buffer.commands]
Commands settings.
[buffer.commands]
show_description = false
show_description
Show or hide the description for a command
# Type: boolean
# Values: true, false
# Default: true
[buffer.commands]
show_description = true
[buffer.date_separators]
Customize how date separators are displayed within a buffer
format
Controls the date format. The expected format is strftime.
NOTE: The application will panic if a invalid format is provided.
# Type: string
# Values: any valid strftime string
# Default: "%A, %B %-d"
[buffer.date_separators]
format = "%A, %B %-d"
show
Show date separators.
# Type: boolean
# Values: true, false
# Default: true
[buffer.date_separators]
show = true
[buffer.emojis]
Emojis settings.
[buffer.emojis]
show_picker = true
skin_tone = "default"
auto_replace = true
show_picker
Show the emoji picker when typing :shortcode:
in text input.
# Type: boolean
# Values: true, false
# Default: true
[buffer.emojis]
show_picker = true
skin_tone
Skin tone selected when picking an emoji.
# Type: string
# Values: "default", "light", "medium-light", "medium", "medium-dark", "dark"
# Default: "default"
[buffer.emojis]
skin_tone = "default"
auto_replace
Automatically replace :shortcode:
in text input with the corresponding emoji.
# Type: boolean
# Values: true, false
# Default: true
[buffer.emojis]
auto_replace = true
[buffer.internal_messages]
Internal messages are messages sent from Halloy itself.
[buffer.internal_messages.success]
A internal messages which is considered a "success" such as when a connection was restored, or when connected succesfully to a server.
enabled
Control if internal message type is enabled.
# Type: boolean
# Values: true, false
# Default: true
[buffer.internal_messages.success]
enabled = true
smart
Only show internal message if received within the given time duration (seconds).
# Type: integer
# Values: any positive integer
# Default: not set
[buffer.internal_messages.success]
smart = 180
[buffer.internal_messages.error]
A internal messages which is considered a "error" such as when a connection was lost, or when connection to server failed.
enabled
Control if internal message type is enabled.
# Type: boolean
# Values: true, false
# Default: true
[buffer.internal_messages.error]
enabled = true
smart
Only show internal message if received within the given time duration (seconds).
# Type: integer
# Values: any positive integer
# Default: not set
[buffer.internal_messages.error]
smart = 180
[buffer.nickname]
Customize how nicknames are displayed within a buffer.
alignment
Horizontal alignment of nicknames.
# Type: string
# Values: "left", "right", "top"
# Default: "left"
[buffer.nickname]
alignment = "right"
brackets
Brackets around nicknames.
# Type: string
# Values: { left = "<any string>", right = "<any string>" }
# Default: { left = "", right = "" }
[buffer.nickname]
brackets = { left = "<", right = ">" }
color
Nickname colors in a channel buffer. "unique"
generates colors by randomizing the hue, while keeping the saturation and lightness from the theme's nickname color.
# Type: string
# Values: "solid", "unique"
# Default: "unique"
[buffer.nickname]
color = "unique"
show_access_levels
Show access levels in front of nicknames (@
, +
, ~
, etc.).
# Type: boolean
# Values: true, false
# Default: true
[buffer.nickname]
show_access_levels = true
[buffer.server_messages]
Server messages are messages sent from a irc server.
- change_host - Message is sent when a user changes host
- join - Message is sent when a user joins a channel
- monitored_offline - Message is sent when a monitored user goes offline
- monitored_online - Message is sent when a monitored user goes online
- part - Message is sent when a user leaves a channel
- quit - Message is sent when a user closes the connection to a channel or server
- standard_reply_fail - Message is sent when a command/function fails or an error with the session
- standard_reply_note - Message is sent when there is information about a command/function or session
- standard_reply_warn - Message is sent when there is feedback about a command/function or session
- topic - Message is sent when a user changes channel topic
Example
# Hide all join messages except for `#halloy` channel:
[buffer.server_messages.join]
exclude = ["*"]
include = ["#halloy"]
# Disable all part messages
[buffer.server_messages.part]
enable = false
enabled
Control if internal message type is enabled.
# Type: boolean
# Values: true, false
# Default: true
[buffer.server_messages.<server_message>]
enabled = true
smart
Only show server message if the user has sent a message in the given time interval (seconds) prior to the server message.
# Type: integer
# Values: any positive integer
# Default: not set
[buffer.server_messages.<server_message>]
smart = 180
exclude
Exclude channels from receiving the server messag.
If you pass ["#halloy"]
, the channel #halloy
will not receive the server message. You can also exclude all channels by using a wildcard: ["*"]
.
# Type: array of strings
# Values: array of any strings
# Default: []
[buffer.server_messages.<server_message>]
exclude = ["*"]
include
Include channels to receive the server message.
If you pass ["#halloy"]
, the channel #halloy
will receive the server message. The include rule takes priority over exclude, so you can use both together. For example, you can exclude all channels with ["*"]
and then only include a few specific channels.
# Type: array of strings
# Values: array of any strings
# Default: []
[buffer.server_messages.<server_message>]
include = ["#halloy"]
username_format
Adjust the amount of information displayed for a username in server messages. If you choose "short"
, only the nickname will be shown. If you choose "full"
, the nickname, username, and hostname (if available) will be displayed.
Note: Not all server messages uses this setting.
# Type: string
# Values: "full", "short
# Default: "full"
[buffer.server_messages.<server_message>]
username_format = "full"
[buffer.status_message_prefix]
Status message prefix settings.
brackets
Brackets around status message prefix.
# Type: string
# Values: { left = "<any string>", right = "<any string>" }
# Default: { left = "", right = "" }
[buffer.status_message_prefix]
brackets = { left = "<", right = ">" }
[buffer.text_input]
Customize the text input for in buffers.
visibility
Text input visibility. When set to "focused"
it will only be visible when the buffer is focused.
# Type: string
# Values: "always", "focused"
# Default: "always"
[buffer.text_input]
visibility = "always"
auto_format
Control if the text input should auto format the input. By default text is only formatted when using the /format
command.
# Type: string
# Values: "disabled", "markdown", "all"
# Default: "disabled"
[buffer.text_input]
auto_format = "markdown"
💡 Read more about text formatting.
[buffer.text_input.autocomplete]
Customize autocomplete.
sort_direction
Sort direction when autocompleting.
# Type: string
# Values: "asc", "desc"
# Default: "asc"
[buffer.text_input.autocomplete]
sort_direction = "asc"
completion_suffixes
Sets what suffix is added after autocompleting. The first option is for when a nickname is autocompleted at the beginning of a sentence. The second is for when it's autocompleted in the middle of a sentence.
# Type: array of 2 strings
# Values: array of 2 strings
# Default: [": ", " "]
[buffer.text_input.autocomplete]
completion_suffixes = [": ", " "]
[buffer.timestamp]
Customize how timestamps are displayed within a buffer.
format
Controls the timestamp format. The expected format is strftime.
# Type: string
# Values: any valid strftime string
# Default: "%R"
[buffer.timestamp]
format = "%R"
brackets
Brackets around timestamps.
# Type: string
# Values: { left = "<any string>", right = "<any string>" }
# Default: { left = "", right = "" }
[buffer.timestamp]
brackets = { left = "[", right = "]" }
[file_transfer]
File transfer configuration options.
save_directory
Default directory to open when prompted to save a file.
# Type: string
# Values: any string
# Default: "$HOME/Downloads"
[file_transfer]
save_directory = "$HOME/Downloads"
passive
If true, act as the "client" for the transfer. Requires the remote user act as the server.
# Type: boolean
# Values: true, false
# Default: true
[file_transfer]
passive = true
timeout
Time (in seconds) to wait before timing out a transfer waiting to be accepted.
# Type: integer
# Values: any positive integer
# Default: 300
[file_transfer]
timeout = 300
[file_transfer.server]
This section is required if passive = false
. One side of the file transfer must
operate as the "server", who the other user connects with to establish a connection.
public_address
Address advertised to the remote user to connect to.
# Type: string
# Values: any string
# Default: not set
[file_transfer.server]
public_address = "<some ip>"
bind_address
Address to bind to when accepting connections.
# Type: string
# Values: any string
# Default: not set
[file_transfer.server]
bind_address = "<some ip>"
bind_port_first
First port in port range to bind to.
# Type: integer
# Values: any positive integer
# Default: not set
[file_transfer.server]
bind_port_first = "1024"
bind_port_last
Last port in port range to bind to.
# Type: integer
# Values: any positive integer
# Default: not set
[file_transfer.server]
bind_port_last = "5000"
[font]
Application wide font settings.
⚠️ Changes to font settings require an application restart to take effect.
family
Monospaced font family to use.
# Type: string
# Values: any string
# Default: not set
#
# Note: Iosevka Term is provided by the application, and used by default.
[font]
family = "Comic Mono"
size
Font size.
# Type: integer
# Values: any positive integer
# Default: 13
[font]
size = 13
[keyboard]
Customize keyboard shortcuts. Below is a list of all actions which can be mapped.
Example
[keyboard]
move_up = "alt+k"
move_down = "alt+j"
move_left = "alt+h"
move_right = "alt+l"
Key | Description | Default MacOS | Default Other |
---|---|---|---|
move_up | Moves focus up | ⌘ + ⌥ + ↑ | ctrl + alt + ↑ |
move_down | Moves focus down | ⌘ + ⌥ + ↓ | ctrl + alt + ↓ |
move_left | Moves focus left | ⌘ + ⌥ + ← | ctrl + alt + ← |
move_right | Moves focus right | ⌘ + ⌥ + → | ctrl + alt + → |
close_buffer | Close focused buffer | ⌘ + w | ctrl + w |
maximize_buffer | Maximize focused buffer | ⌘ + ↑ | ctrl + ↑ |
restore_buffer | Restore focused buffer | ⌘ + ↓ | ctrl + ↓ |
cycle_next_buffer | Cycle to next buffer | ctrl + tab | ctrl + tab |
cycle_previous_buffer | Cycle to previous buffer | ctrl + shift + tab | ctrl + shift + tab |
leave_buffer | Leave channel or close query | ⌘ + shift + w | ctrl + shift + w |
toggle_nick_list | Toggle nick list | ⌘ + ⌥ + m | ctrl + alt + m |
toggle_topic | Toggle topic | ⌘ + ⌥ + t | ctrl + alt + t |
toggle_sidebar | Toggle sidebar | ⌘ + ⌥ + b | ctrl + alt + b |
toggle_fullscreen | Toggle fullscreen | ctrl + ⌥ + f | ctrl + shift + f |
command_bar | Toggle command bar | ⌘ + k | ctrl + k |
reload_configuration | Refresh configuration file | ⌘ + r | ctrl + r |
file_transfers | Toggle File Transfers Buffer | ⌘ + j | ctrl + j |
logs | Toggle Logs Buffer | ⌘ + l | ctrl + l |
theme_editor | Toggle Theme Editor Window | ⌘ + t | ctrl + t |
[notifications]
Customize and enable notifications.
Example
[notifications]
direct_message = { sound = "peck", show_toast = true }
[notifications.highlight]
sound = "dong"
exclude = ["NickServ", "#halloy"]
Following notifications are available:
Name | Description |
---|---|
connected | Triggered when a server is connected |
direct_message | Triggered when a direct message is received |
disconnected | Triggered when a server disconnects |
file_transfer_request | Triggered when a file transfer request is received |
highlight | Triggered when you were highlighted in a buffer |
monitored_online | Triggered when a user you're monitoring is online |
monitored_offline | Triggered when a user you're monitoring is offline |
reconnected | Triggered when a server reconnects |
sound
Notification sound.
Supports both built-in sounds, and external sound files (mp3
, ogg
, flac
or wav
placed inside the sounds
folder within the configuration directory).
# Type: string
# Values: "dong", "peck", "ring", "squeak", "whistle", "bonk", "sing" or external sound.
# Default: not set
[notifications.<notification>]
sound = "dong"
show_toast
Notification should trigger a OS toast.
# Type: boolean
# Values: true, false
# Default: false
[notifications.<notification>]
show_toast = true
delay
Delay in milliseconds before triggering the next notification.
# Type: integer
# Values: any positive integer
# Default: 500
[notifications.<notification>]
delay = 250
exclude
Exclude notifications for nicks (and/or channels in highlight
's case).
Only available for direct_message
, highlight
and file_transfer_request
notifications.
You can also exclude all nicks/channels by using a wildcard: ["*"]
or ["all"]
.
# Type: array of strings
# Values: array of strings
# Default: []
[notifications.<direct_mesage|file_transfer_request>]
exclude = ["HalloyUser1"]
[notifications.highlight]
exclude = ["HalloyUser1", "#halloy"]
include
Include notifications for nicks (and/or channels in highlight
's case).
Only available for direct_message
, highlight
and file_transfer_request
notifications.
The include rule takes priority over exclude, so you can use both together.
For example, you can exclude all nicks with ["*"]
for direct_message
and
then only include a few specific nicks to receive direct_message
notifications
from.
# Type: array of strings
# Values: array of strings
# Default: []
[notifications.<direct_mesage|file_transfer_request>]
include = ["HalloyUser1"]
[notifications.highlight]
include = ["HalloyUser1", "#halloy"]
[proxy]
Proxy settings for Halloy.
[proxy.http]
Http proxy settings.
host
Proxy host to connect to.
# Type: string
# Values: any string
# Default: not set
# Required
[proxy.http]
host = "192.168.1.100"
port
Proxy port to connect on.
# Type: integer
# Values: any positive integer
# Default: not set
# Required
[proxy.http]
port = "1080"
username
Proxy username.
# Type: string
# Values: any string
# Default: not set
# Optional
[proxy.http]
username = "username"
password
Proxy password.
# Type: string
# Values: any string
# Default: not set
# Optional
[proxy.http]
password = "password"
Example
[proxy.http]
host = "192.168.1.100"
port = "1080"
username = "username"
password = "password"
[proxy.socks5]
Socks5 proxy settings.
host
Proxy host to connect to.
# Type: string
# Values: any string
# Default: not set
# Required
[proxy.socks5]
host = "192.168.1.100"
port
Proxy port to connect on.
# Type: integer
# Values: any positive integer
# Default: not set
# Required
[proxy.socks5]
port = "1080"
username
Proxy username.
# Type: string
# Values: any string
# Default: not set
# Optional
[proxy.socks5]
username = "username"
password
Proxy password.
# Type: string
# Values: any string
# Default: not set
# Optional
[proxy.socks5]
password = "password"
Example
[proxy.socks5]
host = "192.168.1.100"
port = "1080"
username = "username"
password = "password"
[proxy.tor]
Tor proxy settings. Utilizes the arti to integrate Tor natively. It accepts no further configuration.
Example
[proxy.tor]
[preview]
URL preview settings for Halloy.
enabled
Enable or disable previews globally
# Type: boolean
# Values: true, false
# Default: true
[preview]
enabled = true
request
Request settings for previews.
user_agent
Some servers will only send opengraph metadata to browser-like user agents. We default to WhatsApp/2
for wide compatability.
# Type: string
# Values: any string
# Default: "WhatsApp/2"
[preview.request]
user_agent = "WhatsApp/2"
timeout_ms
Request timeout in millisceonds. Defaults is 10s.
# Type: integer
# Values: any positive integer
# Default: 10000
[preview.request]
timeout_ms = 10000
max_image_size
Max image size in bytes. This prevents downloading responses that are too big. Default is 10mb.
# Type: integer
# Values: any positive integer
# Default: 10485760
[preview.request]
max_image_size = 10485760
max_scrape_size
Max bytes streamed when scraping for opengraph metadata before cancelling the request. This prevents downloading responses that are too big. Default is 500kb.
# Type: integer
# Values: any positive integer
# Default: 512000
[preview.request]
max_scrape_size = 512000
concurrency
Number of allowed concurrent requests for fetching previews. Reduce this to prevent rate-limiting.
# Type: integer
# Values: any positive integer
# Default: 4
[preview.request]
concurrency = 4
delay_ms
Numer of milliseconds to wait before requesting another preview when number of requested previews > concurrency
.
# Type: integer
# Values: any positive integer
# Default: 500
[preview.request]
delay_ms = 500
image
Specific image preview settings.
include
Include image previews from channels.
If you pass ["#halloy"]
, the channel #halloy
will show image previews. The include rule takes priority over exclude, so you can use both together. For example, you can exclude all channels with ["*"]
and then only include a few specific channels.
# Type: array of strings
# Values: array of any strings
# Default: []
[preview.image]
include = []
exclude
Exclude image previews from channels.
If you pass ["#halloy"]
, the channel #halloy
will not show image previews. You can also exclude all channels by using a wildcard: ["*"]
.
# Type: array of strings
# Values: array of any strings
# Default: []
[preview.image]
exclude = []
Example
[preview.image]
exclude = ["*"] # hide image previews in all channels
include = ["#halloy"] # show image previews in #halloy
card
Specific card preview settings.
show_image
Show image for card previews.
# Type: boolean
# Values: true, false
# Default: true
[preview.card]
show_image = true
include
Include card previews from channels.
If you pass ["#halloy"]
, the channel #halloy
will show image previews. The include rule takes priority over exclude, so you can use both together. For example, you can exclude all channels with ["*"]
and then only include a few specific channels.
# Type: array of strings
# Values: array of any strings
# Default: []
[preview.card]
include = []
exclude
Exclude card previews from channels.
If you pass ["#halloy"]
, the channel #halloy
will not show image previews. You can also exclude all channels by using a wildcard: ["*"]
.
# Type: array of strings
# Values: array of any strings
# Default: []
[preview.card]
exclude = []
Example
[preview.card]
exclude = ["*"] # hide card previews in all channels
include = ["#halloy"] # show card previews in #halloy
[scale_factor]
Application wide scale factor.
Note: scale_factor
is a root key, so it must be placed before any section.
# Type: float
# Values: 0.1 .. 3.0
# Default: 1.0
scale_factor = 1.0
[servers]
You can define multiple server sections in the configuration file. Each server section must have a unique name, which is used as the identifier in the [servers.<name>]
format.
Eg:
[servers.quakenet]
# ...
💡 For a multiple server example see here
nickname
The client's nickname.
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
nickname = ""
nick_password
The client's NICKSERV password.
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
nick_password = ""
nick_password_file
Read nick_password from the file at the given path.1 2
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
nick_password_file = ""
nick_password_command
Executes the command with sh
(or equivalent) and reads nick_password
as the output.
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
nick_password_command = ""
nick_identify_syntax
The server's NICKSERV IDENTIFY syntax.
# Type: string
# Values: "nick-password", "password-nick"
# Default: not set
[servers.<name>]
nick_identify_syntax = ""
alt_nicks
Alternative nicknames for the client, if the default is taken.
# Type: array of strings
# Values: array of any strings
# Default: not set
[servers.<name>]
alt_nicks = ["Foo", "Bar"]
username
The client's username.
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
username = ""
realname
The client's real name.
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
realname = ""
server
The server to connect to.
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
server = "irc.libera.chat"
port
The port to connect on.
# Type: integer
# Values: any positive integer
# Default: 6697
[servers.<name>]
port = 6697
password
The password to connect to the server.
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
password = ""
password_file
Read password from the file at the given path.1 2
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
password_file = ""
password_command
Executes the command with sh
(or equivalent) and reads password
as the output.
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
password_command = ""
channels
A list of channels to join on connection.
# Type: array of strings
# Values: array of any strings
# Default: not set
[servers.<name>]
channels = ["#foo", "#bar"]
channel_keys
A mapping of channel names to keys for join-on-connect.
# Type: map
# Values: map with string key value
# Default: {}
[servers.<name>]
channel_keys = { channel1 = "key1" }
ping_time
The amount of inactivity in seconds before the client will ping the server.
# Type: integer
# Values: any positive integer
# Default: 180
[servers.<name>]
ping_time = 180
ping_timeout
The amount of time in seconds for a client to reconnect due to no ping response.
# Type: integer
# Values: any positive integer
# Default: 20
[servers.<name>]
ping_timeout = 20
reconnect_delay
The amount of time in seconds before attempting to reconnect to the server when disconnected.
# Type: integer
# Values: any positive integer
# Default: 10
[servers.<name>]
reconnect_delay = 10
should_ghost
Whether the client should use NickServ GHOST to reclaim its primary nickname if it is in use.
# Type: boolean
# Values: true, false
# Default: false
[servers.<name>]
should_ghost = false
ghost_sequence
The command(s) that should be sent to NickServ to recover a nickname.
# Type: array of strings
# Values: array of any strings
# Default: ["REGAIN"]
[servers.<name>]
ghost_sequence = ["REGAIN"]
umodes
User modestring to set on connect.
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
umodes = "+RB-x"
use_tls
Whether or not to use TLS. Clients will automatically panic if this is enabled without TLS support.
# Type: boolean
# Values: true, false
# Default: false
[servers.<name>]
use_tls = false
dangerously_accept_invalid_certs
When true
, all certificate validations are skipped.
# Type: boolean
# Values: true, false
# Default: false
[servers.<name>]
dangerously_accept_invalid_certs = false
root_cert_path
The path to the root TLS certificate for this server in PEM format.1 2
# Type: string
# Values: any string
# Default: not set
[servers.<name>]
root_cert_path = ""
on_connect
Commands which are executed once connected.
# Type: array of string
# Values: array of any strings
# Default: not set
[servers.<name>]
on_connect = ["/msg NickServ IDENTIFY foo bar"]
who_poll_enabled
Whether or not to WHO polling is enabled.
# Type: boolean
# Values: true, false
# Default: true
[servers.<name>]
who_poll_enabled = true
who_poll_interval
WHO poll interval (in seconds) for servers without away-notify. Specifically, the time between individual WHO requests. Will be increased automatically if the server sends a rate-limiting message.
# Type: integer
# Values: 1 .. 3600
# Default: 2
[servers.<name>]
who_poll_interval = 2
monitor
A list of nicknames to monitor (if IRCv3 Monitor is supported by the server).
💡 Read more about monitoring users.
# Type: array of string
# Values: array of any strings
# Default: not set
[servers.<name>]
monitor = ["Foo", "Bar"]
chathistory
Whether or not to enable IRCv3 Chat History (if it is supported by the server).
# Type: boolean
# Values: true, false
# Default: true
[servers.<name>]
chathistory = true
sasl.plain
Plain SASL auth using a username and password
username
The account name used for authentication.
# Type: string
# Values: any string
# Default: not set
[servers.<name>.sasl.plain]
username = "username"
password
The password associated with the account used for authentication.
# Type: string
# Values: any string
# Default: not set
[servers.<name>.sasl.plain]
password = "password"
password_file
Read password
from the file at the given path.1 2
# Type: string
# Values: any string
# Default: not set
[servers.<name>.sasl.plain]
password_file = ""
password_command
Executes the command with sh
(or equivalent) and reads password
as the output.
# Type: string
# Values: any string
# Default: not set
[servers.<name>.sasl.plain]
password_command = ""
sasl.external
External SASL auth uses a PEM encoded X509 certificate. Reference.
cert
The path to PEM encoded X509 user certificate for external auth.1 2
# Type: string
# Values: any string
# Default: not set
[servers.<name>.sasl.external]
cert = "/path/to/your/certificate.pem"
key
The path to PEM encoded PKCS#8 private key for external auth (optional).1 2
# Type: string
# Values: any string
# Default: not set
[servers.<name>.sasl.external]
key = "/path/to/your/private_key.pem"
Shell expansions (e.g. "~/"
→ "/home/user/"
) are not supported in path strings.
Windows path strings should usually be specified as literal strings (e.g. 'C:\Users\Default\'
), otherwise directory separators will need to be escaped (e.g. "C:\\Users\\Default\\"
).
[sidebar]
Sidebar settings for Halloy.
buffer_action
Action when pressing buffers in the sidebar. "new-pane"
opens a new pane each time. "replace-pane"
replaces the focused pane with the pressed buffer. "new-window"
opens a new window each time.
# Type: string
# Values: "new-pane", "replace-pane", "new-window"
# Default: "new-pane"
[sidebar]
buffer_action = "replace-pane"
buffer_focused_action
Action when pressing a focused buffer in the sidebar. "close-pane"
will close the focused pane.
# Type: string
# Values: "close-pane"
# Default: not set
[sidebar]
buffer_focused_action = "close-pane"
unread_indicator
Unread buffer indicator style.
# Type: string
# Values: "dot", "title", "none"
# Default: "dot"
[sidebar]
unread_indicator = "dot"
position
Sidebar position within the application window.
# Type: string
# Values: "left", "top", "right", "bottom"
# Default: "left"
[sidebar]
position = "left"
width
Specify sidebar width in pixels. Only used if position
is "left"
or "right"
.
# Type: integer
# Values: any positive integer
# Default: 120
[sidebar]
width = 120
show_menu_button
Show or hide the user menu button in the sidemenu.
# Type: bool
# Values: true, false
# Default: true
[sidebar]
show_menu_button = true
Themes
Example
# Static
theme = "ferra"
# Dynamic
theme = { light = "ferra-light", dark = "ferra" }
Note: theme
is a root key, so it must be placed before any section.
theme
Specify the theme name(s) to use. The theme must correspond to a file located in the themes
folder, which can be found in the Halloy configuration directory. The default theme in Halloy is Ferra.
When a dynamic theme is used, Halloy will match the appearance of the OS.
- type: string or object
- values:
"<string>"
,{ light = "<string>", dark = "<string>" }
- default:
"ferra"
💡 See all community created themes here and base16 themes here.
Custom themes
To create a custom theme for Halloy, simply place a theme file (with a .toml
extension) inside the themes
folder within the configuration directory.
# Consider we have a theme called "foobar.toml" inside the themes folder.
# Theme is a root key, so it has to be placed before any sections in your config file.
theme = "foobar"
# .. rest of the configuration file.
💡 Halloy has a built in theme editor which makes theme creation easier
Each "<string>"
is expected to be a valid hex color. If invalid, or if the key is removed, the color will fallback to transparent. A custom theme is structured as follows:
[general]
background = "<string>"
border = "<string>"
horizontal_rule = "<string>"
unread_indicator = "<string>"
[text]
primary = "<string>"
secondary = "<string>"
tertiary = "<string>"
success = "<string>"
error = "<string>"
[buttons.primary]
background = "<string>"
background_hover = "<string>"
background_selected = "<string>"
background_selected_hover = "<string>"
[buttons.secondary]
background = "<string>"
background_hover = "<string>"
background_selected = "<string>"
background_selected_hover = "<string>"
[buffer]
action = "<string>"
background = "<string>"
background_text_input = "<string>"
background_title_bar = "<string>"
border = "<string>"
border_selected = "<string>"
code = "<string>"
highlight = "<string>"
nickname = "<string>"
selection = "<string>"
timestamp = "<string>"
topic = "<string>"
url = "<string>"
[buffer.server_messages]
# Set below if you want to have a unique color for each.
# Otherwise simply set `default` to use that for all server messages.
#
# change_host = "<string>"
# join = "<string>"
# part = "<string>"
# quit = "<string>"
# reply_topic = "<string>"
# monitored_online = "<string>"
# monitored_offline = "<string>"
# standard_reply_fail = "<string>"
# standard_reply_warn = "<string>"
# standard_reply_note = "<string>"
default = "<string>"
💡 The default Ferra theme toml file can be viewed here.
Community
This is a list of community created themes for Halloy.
💡 Have a great theme you want to share? Open a pull-request here.
Oxocarbon

Dracula

Gruvbox

Catppuccin Latte

Catppuccin Macchiato

Catppuccin Mocha

Ferra Light

Booberry

One Dark

IntelliJ Light

Macaw Light

Macaw Dark

Zenburn

Solarized Dark

Cyberpunk

Rose Pine

Rose Pine Moon

Rose Pine Dawn

Base16
The base16 color scheme framework
includes hundreds of colorschemes build using 16 colors. These colorschemes have
are compiled for Halloy in the
4e554c4c/base16-halloy
repository.
To use these themes, download themes.tar.gz
from the
latest release
and unpack it to the themes
folder in the Halloy configuration directory. Then
you can enable themes individually in config.toml
.
Example
# Static
theme = "base16-gruvbox-dark-hard"
[tooltips]
Control if tooltips are displayed or not.
Note: tooltips
is a root key, so it must be placed before any section.
# Type: boolean
# Values: true, false
# Default: true
tooltips = true
URL Schemes
Halloy is able to recongize different URL schemes.
IRC and IRCS
The IRC URL scheme is used to create a new connection to a server.
The format is based on the URI Syntax.
Format
<scheme>://<server>:<port>/[#channel[,#channel]]
Key | Description |
---|---|
scheme | Can be irc or ircs . TLS is enabled if is ircs . |
server | Address for the server. Eg: irc.libera.chat . |
port | Optional. Defaults to 6667 (if irc ) or 6697 (if ircs ). |
channel | Optional. List of channels, separated by a comma. |
Examples
Below is a few URL examples.
-
Connect to Libera:
ircs://irc.libera.chat -
Connect to Libera and join #halloy:
ircs://irc.libera.chat/#halloy -
Connect to OFTC on port 9999 and join #oftc and #asahi-dev:
ircs://irc.oftc.net:9999/#oftc,#asahi-dev
Halloy
The halloy://
scheme is used to import themes.
The syntax for that is halloy:///theme?e=base64EncodedThemeData
.
A list of community created themes can be found here.
Commands
Commands in Halloy are prefixed with /
.
Example
/me says halloy!
Halloy will first try to run below commands, and lastly send it directly to the server.
Command | Alias | Description |
---|---|---|
away | Mark yourself as away. If already away, the status is removed | |
join | j | Join channel(s) with optional key(s) |
me | describe | Send an action message to the channel |
mode | m | Set mode(s) on a channel or retrieve the current mode(s) set |
monitor | System to notify when users become online/offline | |
msg | Open a query with a nickname and send an optional message | |
nick | Change your nickname on the current server | |
part | leave | Leave channel(s) with an optional reason |
quit | Disconnect from the server with an optional reason | |
raw | Send data to the server without modifying it | |
topic | t | Retrieve the topic of a channel or set a new topic |
whois | Retrieve information about user(s) |