mirror of
https://github.com/nix-community/home-manager
synced 2024-11-30 06:59:45 +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/go.nix @rvolosatovs
|
||||||
|
|
||||||
|
/modules/programs/hexchat.nix @superherointj @thiagokokada
|
||||||
|
/tests/modules/programs/hexchat @thiagokokada
|
||||||
|
|
||||||
/modules/programs/himalaya.nix @ambroisie
|
/modules/programs/himalaya.nix @ambroisie
|
||||||
/tests/modules/programs/himalaya @ambroisie
|
/tests/modules/programs/himalaya @ambroisie
|
||||||
|
|
||||||
|
|
|
@ -2225,6 +2225,14 @@ in
|
||||||
you may need to do some changes.
|
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/gnome-terminal.nix
|
||||||
./programs/go.nix
|
./programs/go.nix
|
||||||
./programs/gpg.nix
|
./programs/gpg.nix
|
||||||
|
./programs/hexchat.nix
|
||||||
./programs/himalaya.nix
|
./programs/himalaya.nix
|
||||||
./programs/home-manager.nix
|
./programs/home-manager.nix
|
||||||
./programs/htop.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/foot
|
||||||
./modules/programs/getmail
|
./modules/programs/getmail
|
||||||
./modules/programs/gnome-terminal
|
./modules/programs/gnome-terminal
|
||||||
|
./modules/programs/hexchat
|
||||||
./modules/programs/i3status-rust
|
./modules/programs/i3status-rust
|
||||||
./modules/programs/mangohud
|
./modules/programs/mangohud
|
||||||
./modules/programs/ncmpcpp-linux
|
./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