mirror of
https://github.com/nix-community/home-manager
synced 2024-12-23 10:19:48 +01:00
hexchat: add module
Review and contributions from Thiago Kenji Okada <thiagokokada@gmail.com>. Co-authored-by: Thiago Kenji Okada <thiagokokada@gmail.com> Co-authored-by: Nicolas Berbiche <nic.berbiche@gmail.com> Co-authored-by: Sumner Evans <me@sumnerevans.com>
This commit is contained in:
parent
8278c14f5f
commit
406eeec0b9
9 changed files with 477 additions and 0 deletions
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
|
@ -92,6 +92,9 @@
|
|||
|
||||
/modules/programs/go.nix @rvolosatovs
|
||||
|
||||
/modules/programs/hexchat.nix @superherointj @thiagokokada
|
||||
/tests/modules/programs/hexchat @thiagokokada
|
||||
|
||||
/modules/programs/himalaya.nix @ambroisie
|
||||
/tests/modules/programs/himalaya @ambroisie
|
||||
|
||||
|
|
|
@ -2225,6 +2225,14 @@ in
|
|||
you may need to do some changes.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
time = "2021-10-23T17:12:22+00:00";
|
||||
condition = hostPlatform.isLinux;
|
||||
message = ''
|
||||
A new module is available: 'programs.hexchat'.
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ let
|
|||
./programs/gnome-terminal.nix
|
||||
./programs/go.nix
|
||||
./programs/gpg.nix
|
||||
./programs/hexchat.nix
|
||||
./programs/himalaya.nix
|
||||
./programs/home-manager.nix
|
||||
./programs/htop.nix
|
||||
|
|
368
modules/programs/hexchat.nix
Normal file
368
modules/programs/hexchat.nix
Normal file
|
@ -0,0 +1,368 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.hexchat;
|
||||
|
||||
channelOptions = with types;
|
||||
submodule {
|
||||
options = {
|
||||
autoconnect = mkOption {
|
||||
type = nullOr bool;
|
||||
default = false;
|
||||
description = "Autoconnect to network.";
|
||||
};
|
||||
|
||||
connectToSelectedServerOnly = mkOption {
|
||||
type = nullOr bool;
|
||||
default = true;
|
||||
description = "Connect to selected server only.";
|
||||
};
|
||||
|
||||
bypassProxy = mkOption {
|
||||
type = nullOr bool;
|
||||
default = true;
|
||||
description = "Bypass proxy.";
|
||||
};
|
||||
|
||||
forceSSL = mkOption {
|
||||
type = nullOr bool;
|
||||
default = false;
|
||||
description = "Use SSL for all servers.";
|
||||
};
|
||||
|
||||
acceptInvalidSSLCertificates = mkOption {
|
||||
type = nullOr bool;
|
||||
default = false;
|
||||
description = "Accept invalid SSL certificates.";
|
||||
};
|
||||
|
||||
useGlobalUserInformation = mkOption {
|
||||
type = nullOr bool;
|
||||
default = false;
|
||||
description = "Use global user information.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
modChannelOption = with types;
|
||||
submodule {
|
||||
options = {
|
||||
autojoin = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
example = [ "#home-manager" "#linux" "#nix" ];
|
||||
description = "Channels list to autojoin on connecting to server.";
|
||||
};
|
||||
|
||||
charset = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
example = "UTF-8 (Unicode)";
|
||||
description = "Character set.";
|
||||
};
|
||||
|
||||
commands = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
example = literalExample ''[ "ECHO Greetings fellow Nixer! ]'';
|
||||
description = "Commands to be executed on connecting to server.";
|
||||
};
|
||||
|
||||
loginMethod = mkOption {
|
||||
type = nullOr (enum (attrNames loginMethodMap));
|
||||
default = null;
|
||||
description = ''
|
||||
The login method. The allowed options are:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><literal>null</literal></term>
|
||||
<listitem><para>Default</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>"nickServMsg"</literal></term>
|
||||
<listitem><para>NickServ (/MSG NickServ + password)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>"nickServ"</literal></term>
|
||||
<listitem><para>NickServ (/NICKSERV + password)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>"challengeAuth"</literal></term>
|
||||
<listitem><para>Challenge Auth (username + password)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>"sasl"</literal></term>
|
||||
<listitem><para>SASL (username + password)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>"serverPassword"</literal></term>
|
||||
<listitem><para>Server password (/PASS password)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>"saslExternal"</literal></term>
|
||||
<listitem><para>SASL EXTERNAL (cert)</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><literal>"customCommands"</literal></term>
|
||||
<listitem>
|
||||
<para>Use "commands" field for auth. For example
|
||||
<programlisting language="nix">
|
||||
commands = [ "/msg NickServ IDENTIFY my_password" ]
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
'';
|
||||
};
|
||||
|
||||
nickname = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = "Primary nickname.";
|
||||
};
|
||||
|
||||
nickname2 = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = "Secondary nickname.";
|
||||
};
|
||||
|
||||
options = mkOption {
|
||||
type = nullOr channelOptions;
|
||||
default = null;
|
||||
example = {
|
||||
autoconnect = true;
|
||||
useGlobalUserInformation = true;
|
||||
};
|
||||
description = "Channel options.";
|
||||
};
|
||||
|
||||
password = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Password to use. Note this password will be readable by all user's
|
||||
in the Nix store.
|
||||
'';
|
||||
};
|
||||
|
||||
realName = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
Real name. Is used to populate the real name field that appears when
|
||||
someone uses the <literal>WHOIS</literal> command on your nick.
|
||||
'';
|
||||
};
|
||||
|
||||
userName = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
User name. Part of your <literal>user@host</literal> hostmask that
|
||||
appears to other on IRC.
|
||||
'';
|
||||
};
|
||||
|
||||
servers = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
example = [ "chat.freenode.net" "irc.freenode.net" ];
|
||||
description = "IRC Server Address List.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
transformField = k: v: if (v != null) then "${k}=${v}" else null;
|
||||
|
||||
listChar = c: l:
|
||||
if l != [ ] then concatMapStringsSep "\n" (transformField c) l else null;
|
||||
|
||||
computeFieldsValue = channel:
|
||||
let
|
||||
ifTrue = p: n: if p then n else 0;
|
||||
result = with channel.options;
|
||||
foldl' (a: b: a + b) 0 [
|
||||
(ifTrue (!connectToSelectedServerOnly) 1)
|
||||
(ifTrue useGlobalUserInformation 2)
|
||||
(ifTrue forceSSL 4)
|
||||
(ifTrue autoconnect 8)
|
||||
(ifTrue (!bypassProxy) 16)
|
||||
(ifTrue acceptInvalidSSLCertificates 32)
|
||||
];
|
||||
in toString (if channel.options == null then 0 else result);
|
||||
|
||||
loginMethodMap = {
|
||||
nickServMsg = 1;
|
||||
nickServ = 2;
|
||||
challengeAuth = 4;
|
||||
sasl = 6;
|
||||
serverPassword = 7;
|
||||
customCommands = 9;
|
||||
saslExternal = 10;
|
||||
};
|
||||
|
||||
loginMethod = channel:
|
||||
transformField "L" (optionalString (channel.loginMethod != null)
|
||||
(toString loginMethodMap.${channel.loginMethod}));
|
||||
|
||||
# Note: Missing option `D=`.
|
||||
transformChannel = channelName:
|
||||
let channel = cfg.channels.${channelName};
|
||||
in concatStringsSep "\n" (filter (v: v != null) [
|
||||
"" # leave a space between one server and another
|
||||
(transformField "N" channelName)
|
||||
(loginMethod channel)
|
||||
(transformField "E" channel.charset)
|
||||
(transformField "F" (computeFieldsValue channel))
|
||||
(transformField "I" channel.nickname)
|
||||
(transformField "i" channel.nickname2)
|
||||
(transformField "R" channel.realName)
|
||||
(transformField "U" channel.userName)
|
||||
(transformField "P" channel.password)
|
||||
(listChar "S" channel.servers)
|
||||
(listChar "J" channel.autojoin)
|
||||
(listChar "C" channel.commands)
|
||||
]);
|
||||
|
||||
in {
|
||||
meta.maintainers = with maintainers; [ superherointj thiagokokada ];
|
||||
|
||||
options.programs.hexchat = with types; {
|
||||
enable = mkEnableOption "HexChat, a graphical IRC client";
|
||||
|
||||
channels = mkOption {
|
||||
type = attrsOf modChannelOption;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
freenode = {
|
||||
autojoin = [
|
||||
"#home-manager"
|
||||
"#linux"
|
||||
"#nixos"
|
||||
];
|
||||
charset = "UTF-8 (Unicode)";
|
||||
commands = [
|
||||
"ECHO Buzz Lightyear sent you a message: 'To Infinity... and Beyond!'"
|
||||
];
|
||||
loginMethod = sasl;
|
||||
nickname = "my_nickname";
|
||||
nickname2 = "my_secondchoice";
|
||||
options = {
|
||||
acceptInvalidSSLCertificates = false;
|
||||
autoconnect = true;
|
||||
bypassProxy = true;
|
||||
connectToSelectedServerOnly = true;
|
||||
useGlobalUserInformation = false;
|
||||
forceSSL = false;
|
||||
};
|
||||
password = "my_password";
|
||||
realName = "my_realname";
|
||||
servers = [
|
||||
"chat.freenode.net"
|
||||
"irc.freenode.net"
|
||||
];
|
||||
userName = "my_username";
|
||||
};
|
||||
}'';
|
||||
description = ''
|
||||
Configures <filename>~/.config/hexchat/servlist.conf</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
default = null;
|
||||
type = nullOr (attrsOf str);
|
||||
example = literalExample ''
|
||||
{
|
||||
irc_nick1 = "mynick";
|
||||
irc_username = "bob";
|
||||
irc_realname = "Bart Simpson";
|
||||
text_font = "Monospace 14";
|
||||
};
|
||||
'';
|
||||
description = ''
|
||||
Configuration for <filename>~/.config/hexchat/hexchat.conf</filename>, see
|
||||
<link xlink:href="https://hexchat.readthedocs.io/en/latest/settings.html#list-of-settings"/>
|
||||
for supported values.
|
||||
'';
|
||||
};
|
||||
|
||||
overwriteConfigFiles = mkOption {
|
||||
type = nullOr bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enables overwriting HexChat configuration files
|
||||
(<filename>hexchat.conf</filename>, <filename>servlist.conf</filename>).
|
||||
Any existing HexChat configuration will be lost. Certify to back-up any
|
||||
previous configuration before enabling this.
|
||||
</para><para>
|
||||
Enabling this setting is recommended, because everytime HexChat
|
||||
application is closed it overwrites Nix/Home Manager provided
|
||||
configuration files, causing:
|
||||
<orderedlist numeration="arabic">
|
||||
<listitem><para>
|
||||
Nix/Home Manager provided configuration to be out of sync with
|
||||
actual active HexChat configuration.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Blocking Nix/Home Manager updates until configuration files are
|
||||
manually removed.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
'';
|
||||
};
|
||||
|
||||
theme = mkOption {
|
||||
type = nullOr package;
|
||||
default = null;
|
||||
example = literalExample ''
|
||||
stdenv.mkDerivation rec {
|
||||
name = "hexchat-theme-MatriY";
|
||||
buildInputs = [ pkgs.unzip ];
|
||||
src = fetchurl {
|
||||
url = "https://dl.hexchat.net/themes/MatriY.hct";
|
||||
sha256 = "sha256-ffkFJvySfl0Hwja3y7XCiNJceUrGvlEoEm97eYNMTZc=";
|
||||
};
|
||||
unpackPhase = "unzip ''${src}";
|
||||
installPhase = "cp -r . $out";
|
||||
};
|
||||
'';
|
||||
description = ''
|
||||
Theme package for HexChat. Expects a derivation containing decompressed
|
||||
theme files. <literal>.hct</literal> file format requires unzip
|
||||
decompression, as seen in example.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
(hm.assertions.assertPlatform "programs.hexchat" pkgs platforms.linux)
|
||||
];
|
||||
|
||||
home.packages = [ pkgs.hexchat ];
|
||||
|
||||
xdg.configFile."hexchat" = mkIf (cfg.theme != null) {
|
||||
source = cfg.theme;
|
||||
recursive = true;
|
||||
};
|
||||
|
||||
xdg.configFile."hexchat/hexchat.conf" = mkIf (cfg.settings != null) {
|
||||
force = cfg.overwriteConfigFiles;
|
||||
text = concatMapStringsSep "\n" (x: x + " = " + cfg.settings.${x})
|
||||
(attrNames cfg.settings);
|
||||
};
|
||||
|
||||
xdg.configFile."hexchat/servlist.conf" = mkIf (cfg.channels != { }) {
|
||||
force = cfg.overwriteConfigFiles;
|
||||
# Final line breaks is required to avoid cropping last field value.
|
||||
text = concatMapStringsSep "\n" transformChannel (attrNames cfg.channels)
|
||||
+ "\n\n";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -110,6 +110,7 @@ import nmt {
|
|||
./modules/programs/foot
|
||||
./modules/programs/getmail
|
||||
./modules/programs/gnome-terminal
|
||||
./modules/programs/hexchat
|
||||
./modules/programs/i3status-rust
|
||||
./modules/programs/mangohud
|
||||
./modules/programs/ncmpcpp-linux
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
dcc_dir = /home/user/Downloads
|
||||
gui_quit_dialog = 0
|
||||
gui_slist_skip = 1
|
||||
irc_nick1 = user
|
||||
irc_nick2 = user_
|
||||
irc_nick3 = user__
|
||||
irc_real_name = real user
|
||||
irc_user_name = user
|
||||
text_font = Monospace 14
|
||||
text_font_main = Monospace 14
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
N=efnet
|
||||
L=
|
||||
F=4
|
||||
S=irc.choopa.net
|
||||
S=irc.colosolutions.net
|
||||
S=irc.mzima.net
|
||||
S=irc.prison.net
|
||||
J=#computers
|
||||
|
||||
N=freenode
|
||||
L=6
|
||||
E=UTF-8 (Unicode)
|
||||
F=12
|
||||
I=user
|
||||
i=user_
|
||||
R=real_user
|
||||
U=user
|
||||
P=password
|
||||
S=chat.freenode.net
|
||||
S=irc.freenode.net
|
||||
J=#home-manager
|
||||
J=#nixos
|
||||
|
61
tests/modules/programs/hexchat/basic-configuration.nix
Normal file
61
tests/modules/programs/hexchat/basic-configuration.nix
Normal file
|
@ -0,0 +1,61 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
config = {
|
||||
programs.hexchat = {
|
||||
enable = true;
|
||||
overwriteConfigFiles = true;
|
||||
channels = {
|
||||
freenode = {
|
||||
charset = "UTF-8 (Unicode)";
|
||||
userName = "user";
|
||||
password = "password";
|
||||
loginMethod = "sasl";
|
||||
nickname = "user";
|
||||
nickname2 = "user_";
|
||||
realName = "real_user";
|
||||
options = {
|
||||
autoconnect = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
servers = [ "chat.freenode.net" "irc.freenode.net" ];
|
||||
autojoin = [ "#home-manager" "#nixos" ];
|
||||
};
|
||||
efnet = {
|
||||
options = { forceSSL = true; };
|
||||
servers = [
|
||||
"irc.choopa.net"
|
||||
"irc.colosolutions.net"
|
||||
"irc.mzima.net"
|
||||
"irc.prison.net"
|
||||
];
|
||||
autojoin = [ "#computers" ];
|
||||
};
|
||||
};
|
||||
settings = {
|
||||
dcc_dir = "/home/user/Downloads";
|
||||
irc_nick1 = "user";
|
||||
irc_nick2 = "user_";
|
||||
irc_nick3 = "user__";
|
||||
irc_user_name = "user";
|
||||
irc_real_name = "real user";
|
||||
text_font = "Monospace 14";
|
||||
text_font_main = "Monospace 14";
|
||||
gui_slist_skip = "1"; # Skip network list on start-up
|
||||
gui_quit_dialog = "0";
|
||||
};
|
||||
};
|
||||
|
||||
test.stubs.hexchat = { };
|
||||
|
||||
nmt.script = ''
|
||||
assertFileContent \
|
||||
home-files/.config/hexchat/hexchat.conf \
|
||||
${./basic-configuration-expected-main-config}
|
||||
assertFileContent \
|
||||
home-files/.config/hexchat/servlist.conf \
|
||||
${./basic-configuration-expected-serverlist-config}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
1
tests/modules/programs/hexchat/default.nix
Normal file
1
tests/modules/programs/hexchat/default.nix
Normal file
|
@ -0,0 +1 @@
|
|||
{ hexchat-basic-configuration = ./basic-configuration.nix; }
|
Loading…
Reference in a new issue