push sheeet
Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s

This commit is contained in:
Dark Steveneq
2025-10-09 14:15:47 +02:00
commit 646b892680
49168 changed files with 5897842 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs._1password-gui;
in
{
imports = [
(lib.mkRemovedOptionModule [ "programs" "_1password-gui" "gid" ] ''
A preallocated GID will be used instead.
'')
];
options = {
programs._1password-gui = {
enable = lib.mkEnableOption "the 1Password GUI application";
polkitPolicyOwners = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = lib.literalExpression ''["user1" "user2" "user3"]'';
description = ''
A list of users who should be able to integrate 1Password with polkit-based authentication mechanisms.
'';
};
package = lib.mkPackageOption pkgs "1Password GUI" {
default = [ "_1password-gui" ];
};
};
};
config =
let
package = cfg.package.override {
polkitPolicyOwners = cfg.polkitPolicyOwners;
};
in
lib.mkIf cfg.enable {
environment.systemPackages = [ package ];
users.groups.onepassword.gid = config.ids.gids.onepassword;
security.wrappers = {
"1Password-BrowserSupport" = {
source = "${package}/share/1password/1Password-BrowserSupport";
owner = "root";
group = "onepassword";
setuid = false;
setgid = true;
};
};
};
}

View File

@@ -0,0 +1,44 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs._1password;
in
{
imports = [
(lib.mkRemovedOptionModule [ "programs" "_1password" "gid" ] ''
A preallocated GID will be used instead.
'')
];
options = {
programs._1password = {
enable = lib.mkEnableOption "the 1Password CLI tool";
package = lib.mkPackageOption pkgs "1Password CLI" {
default = [ "_1password-cli" ];
};
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
users.groups.onepassword-cli.gid = config.ids.gids.onepassword-cli;
security.wrappers = {
"op" = {
source = "${cfg.package}/bin/op";
owner = "root";
group = "onepassword-cli";
setuid = false;
setgid = true;
};
};
};
}

View File

@@ -0,0 +1,32 @@
{
config,
lib,
pkgs,
...
}:
{
meta.maintainers = [ lib.maintainers.mic92 ];
###### interface
options = {
programs.adb = {
enable = lib.mkOption {
default = false;
type = lib.types.bool;
description = ''
Whether to configure system to use Android Debug Bridge (adb).
To grant access to a user, it must be part of adbusers group:
`users.users.alice.extraGroups = ["adbusers"];`
'';
};
};
};
###### implementation
config = lib.mkIf config.programs.adb.enable {
services.udev.packages = [ pkgs.android-udev-rules ];
environment.systemPackages = [ pkgs.android-tools ];
users.groups.adbusers = { };
};
}

View File

@@ -0,0 +1,44 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.alvr;
in
{
options = {
programs.alvr = {
enable = lib.mkEnableOption "ALVR, the VR desktop streamer";
package = lib.mkPackageOption pkgs "alvr" { };
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to open the default ports in the firewall for the ALVR server.
'';
};
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
networking.firewall = lib.mkIf cfg.openFirewall {
allowedTCPPorts = [
9943
9944
];
allowedUDPPorts = [
9943
9944
];
};
};
meta.maintainers = with lib.maintainers; [ passivelemon ];
}

View File

@@ -0,0 +1,35 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.amnezia-vpn;
in
{
options.programs.amnezia-vpn = {
enable = lib.mkEnableOption "The AmneziaVPN client";
package = lib.mkPackageOption pkgs "amnezia-vpn" { };
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
services.dbus.packages = [ cfg.package ];
services.resolved.enable = true;
systemd = {
packages = [ cfg.package ];
services."AmneziaVPN" = {
wantedBy = [ "multi-user.target" ];
path = with pkgs; [
procps
iproute2
sudo
];
};
};
};
meta.maintainers = with lib.maintainers; [ sund3RRR ];
}

View File

@@ -0,0 +1,31 @@
{
config,
pkgs,
lib,
...
}:
{
options = {
programs.appgate-sdp = {
enable = lib.mkEnableOption "the AppGate SDP VPN client";
};
};
config = lib.mkIf config.programs.appgate-sdp.enable {
boot.kernelModules = [ "tun" ];
environment.systemPackages = [ pkgs.appgate-sdp ];
services.dbus.packages = [ pkgs.appgate-sdp ];
systemd = {
packages = [ pkgs.appgate-sdp ];
# https://github.com/NixOS/nixpkgs/issues/81138
services.appgatedriver.wantedBy = [ "multi-user.target" ];
services.appgate-dumb-resolver.path = [ pkgs.e2fsprogs ];
services.appgate-resolver.path = [
pkgs.procps
pkgs.e2fsprogs
];
services.appgatedriver.path = [ pkgs.e2fsprogs ];
};
};
}

View File

@@ -0,0 +1,53 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.programs.appimage;
in
{
options.programs.appimage = {
enable = lib.mkEnableOption "appimage-run wrapper script for executing appimages on NixOS";
binfmt = lib.mkEnableOption "binfmt registration to run appimages via appimage-run seamlessly";
package = lib.mkPackageOption pkgs "appimage-run" {
example = ''
pkgs.appimage-run.override {
extraPkgs = pkgs: [ pkgs.ffmpeg pkgs.imagemagick ];
}
'';
};
};
config = lib.mkIf cfg.enable {
boot.binfmt.registrations = lib.mkIf cfg.binfmt (
let
appimage_common = {
wrapInterpreterInShell = false;
interpreter = lib.getExe cfg.package;
recognitionType = "magic";
offset = 0;
mask = ''\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff'';
};
in
{
appimage_type_1 = appimage_common // {
magicOrExtension = ''\x7fELF....AI\x01'';
};
appimage_type_2 = appimage_common // {
magicOrExtension = ''\x7fELF....AI\x02'';
};
}
);
environment.systemPackages = [ cfg.package ];
};
meta.maintainers = with lib.maintainers; [
jopejoe1
atemu
aleksana
];
}

View File

@@ -0,0 +1,32 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.arp-scan;
in
{
options = {
programs.arp-scan = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to configure a setcap wrapper for arp-scan.
'';
};
};
};
config = lib.mkIf cfg.enable {
security.wrappers.arp-scan = {
owner = "root";
group = "root";
capabilities = "cap_net_raw+p";
source = lib.getExe pkgs.arp-scan;
};
};
}

View File

@@ -0,0 +1,186 @@
# Global configuration for atop.
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.atop;
in
{
###### interface
options = {
programs.atop = {
enable = lib.mkEnableOption "Atop, a tool for monitoring system resources";
package = lib.mkPackageOption pkgs "atop" { };
netatop = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to install and enable the netatop kernel module.
Note: this sets the kernel taint flag "O" for loading out-of-tree modules.
'';
};
package = lib.mkOption {
type = lib.types.package;
default = config.boot.kernelPackages.netatop;
defaultText = lib.literalExpression "config.boot.kernelPackages.netatop";
description = ''
Which package to use for netatop.
'';
};
};
atopgpu.enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to install and enable the atopgpud daemon to get information about
NVIDIA gpus.
'';
};
setuidWrapper.enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to install a setuid wrapper for Atop. This is required to use some of
the features as non-root user (e.g.: ipc information, netatop, atopgpu).
Atop tries to drop the root privileges shortly after starting.
'';
};
atopService.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to enable the atop service responsible for storing statistics for
long-term analysis.
'';
};
atopRotateTimer.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to enable the atop-rotate timer, which restarts the atop service
daily to make sure the data files are rotate.
'';
};
atopacctService.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to enable the atopacct service which manages process accounting.
This allows Atop to gather data about processes that disappeared in between
two refresh intervals.
'';
};
settings = lib.mkOption {
type = lib.types.attrs;
default = { };
example = {
flags = "a1f";
interval = 5;
};
description = ''
Parameters to be written to {file}`/etc/atoprc`.
'';
};
};
};
config = lib.mkIf cfg.enable (
let
atop = if cfg.atopgpu.enable then (cfg.package.override { withAtopgpu = true; }) else cfg.package;
in
{
environment.etc = lib.mkIf (cfg.settings != { }) {
atoprc.text = lib.concatStrings (
lib.mapAttrsToList (n: v: ''
${n} ${builtins.toString v}
'') cfg.settings
);
};
environment.systemPackages = [
atop
(lib.mkIf cfg.netatop.enable cfg.netatop.package)
];
boot.extraModulePackages = [ (lib.mkIf cfg.netatop.enable cfg.netatop.package) ];
systemd =
let
mkSystemd = type: name: restartTriggers: {
${name} = {
inherit restartTriggers;
wantedBy = [
(
if type == "services" then
"multi-user.target"
else if type == "timers" then
"timers.target"
else
null
)
];
};
};
mkService = mkSystemd "services";
mkTimer = mkSystemd "timers";
in
{
packages = [
atop
(lib.mkIf cfg.netatop.enable cfg.netatop.package)
];
services = lib.mkMerge [
(lib.mkIf cfg.atopService.enable (
lib.recursiveUpdate (mkService "atop" [ atop ]) {
# always convert logs to newer version first
# XXX might trigger TimeoutStart but restarting atop.service will
# convert remainings logs and start eventually
atop.preStart = ''
set -e -u
shopt -s nullglob
rm -f "$LOGPATH"/atop_*.new
for logfile in "$LOGPATH"/atop_*
do
${atop}/bin/atopconvert "$logfile" "$logfile".new
# only replace old file if version was upgraded to avoid
# false positives for atop-rotate.service
if ! ${pkgs.diffutils}/bin/cmp -s "$logfile" "$logfile".new
then
mv -v -f "$logfile".new "$logfile"
else
rm -f "$logfile".new
fi
done
'';
}
))
(lib.mkIf cfg.atopacctService.enable (mkService "atopacct" [ atop ]))
(lib.mkIf cfg.netatop.enable (mkService "netatop" [ cfg.netatop.package ]))
(lib.mkIf cfg.atopgpu.enable (mkService "atopgpu" [ atop ]))
];
timers = lib.mkIf cfg.atopRotateTimer.enable (mkTimer "atop-rotate" [ atop ]);
};
security.wrappers = lib.mkIf cfg.setuidWrapper.enable {
atop = {
setuid = true;
owner = "root";
group = "root";
source = "${atop}/bin/atop";
};
};
}
);
}

View File

@@ -0,0 +1,28 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.ausweisapp;
in
{
options.programs.ausweisapp = {
enable = lib.mkEnableOption "AusweisApp";
openFirewall = lib.mkOption {
description = ''
Whether to open the required firewall ports for the Smartphone as Card Reader (SaC) functionality of AusweisApp.
'';
default = false;
type = lib.types.bool;
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [ ausweisapp ];
networking.firewall.allowedUDPPorts = lib.optionals cfg.openFirewall [ 24727 ];
};
}

View File

@@ -0,0 +1,32 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.autoenv;
in
{
options = {
programs.autoenv = {
enable = lib.mkEnableOption "autoenv";
package = lib.mkPackageOption pkgs "autoenv" { };
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.autoenv ];
programs = {
zsh.interactiveShellInit = ''
source ${cfg.package}/share/autoenv/activate.sh
'';
bash.interactiveShellInit = ''
source ${cfg.package}/share/autoenv/activate.sh
'';
};
};
}

View File

@@ -0,0 +1,36 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.autojump;
prg = config.programs;
in
{
options = {
programs.autojump = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable autojump.
'';
};
};
};
###### implementation
config = lib.mkIf cfg.enable {
environment.pathsToLink = [ "/share/autojump" ];
environment.systemPackages = [ pkgs.autojump ];
programs.bash.interactiveShellInit = "source ${pkgs.autojump}/share/autojump/autojump.bash";
programs.zsh.interactiveShellInit = lib.mkIf prg.zsh.enable "source ${pkgs.autojump}/share/autojump/autojump.zsh";
programs.fish.interactiveShellInit = lib.mkIf prg.fish.enable "source ${pkgs.autojump}/share/autojump/autojump.fish";
};
}

View File

@@ -0,0 +1,36 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.bandwhich;
in
{
meta.maintainers = with lib.maintainers; [ Br1ght0ne ];
options = {
programs.bandwhich = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to add bandwhich to the global environment and configure a
setcap wrapper for it.
'';
};
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [ bandwhich ];
security.wrappers.bandwhich = {
owner = "root";
group = "root";
capabilities = "cap_sys_ptrace,cap_dac_read_search,cap_net_raw,cap_net_admin+ep";
source = "${pkgs.bandwhich}/bin/bandwhich";
};
};
}

View File

@@ -0,0 +1,28 @@
{
config,
pkgs,
lib,
...
}:
let
prg = config.programs;
cfg = prg.bash-my-aws;
initScript = ''
eval $(${pkgs.bash-my-aws}/bin/bma-init)
'';
in
{
options = {
programs.bash-my-aws = {
enable = lib.mkEnableOption "bash-my-aws";
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [ bash-my-aws ];
programs.bash.interactiveShellInit = initScript;
};
}

View File

@@ -0,0 +1,49 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.bash;
in
{
options.programs.bash.completion = {
enable = lib.mkEnableOption "Bash completion for all interactive bash shells" // {
default = true;
};
package = lib.mkPackageOption pkgs "bash-completion" { };
};
imports = [
(lib.mkRenamedOptionModule
[ "programs" "bash" "enableCompletion" ]
[ "programs" "bash" "completion" "enable" ]
)
];
config = lib.mkIf cfg.completion.enable {
programs.bash.promptPluginInit = ''
# Check whether we're running a version of Bash that has support for
# programmable completion. If we do, enable all modules installed in
# the system and user profile in obsolete /etc/bash_completion.d/
# directories. Bash loads completions in all
# $XDG_DATA_DIRS/bash-completion/completions/
# on demand, so they do not need to be sourced here.
if shopt -q progcomp &>/dev/null; then
. "${cfg.completion.package}/etc/profile.d/bash_completion.sh"
nullglobStatus=$(shopt -p nullglob)
shopt -s nullglob
for p in $NIX_PROFILES; do
for m in "$p/etc/bash_completion.d/"*; do
. "$m"
done
done
eval "$nullglobStatus"
unset nullglobStatus p m
fi
'';
};
}

View File

@@ -0,0 +1,243 @@
# This module defines global configuration for the Bash shell, in
# particular /etc/bashrc and /etc/profile.
{
config,
lib,
pkgs,
...
}:
let
cfge = config.environment;
cfg = config.programs.bash;
bashAliases = builtins.concatStringsSep "\n" (
lib.mapAttrsToList (k: v: "alias -- ${k}=${lib.escapeShellArg v}") (
lib.filterAttrs (k: v: v != null) cfg.shellAliases
)
);
in
{
options = {
programs.bash = {
enable = lib.mkOption {
default = true;
description = ''
Whenever to configure Bash as an interactive shell.
Note that this tries to make Bash the default
{option}`users.defaultUserShell`,
which in turn means that you might need to explicitly
set this variable if you have another shell configured
with NixOS.
'';
type = lib.types.bool;
};
shellAliases = lib.mkOption {
default = { };
description = ''
Set of aliases for bash shell, which overrides {option}`environment.shellAliases`.
See {option}`environment.shellAliases` for an option format description.
'';
type = with lib.types; attrsOf (nullOr (either str path));
};
shellInit = lib.mkOption {
default = "";
description = ''
Shell script code called during bash shell initialisation.
'';
type = lib.types.lines;
};
loginShellInit = lib.mkOption {
default = "";
description = ''
Shell script code called during login bash shell initialisation.
'';
type = lib.types.lines;
};
interactiveShellInit = lib.mkOption {
default = "";
description = ''
Shell script code called during interactive bash shell initialisation.
'';
type = lib.types.lines;
};
promptInit = lib.mkOption {
default = ''
# Provide a nice prompt if the terminal supports it.
if [ "$TERM" != "dumb" ] || [ -n "$INSIDE_EMACS" ]; then
PROMPT_COLOR="1;31m"
((UID)) && PROMPT_COLOR="1;32m"
if [ -n "$INSIDE_EMACS" ]; then
# Emacs term mode doesn't support xterm title escape sequence (\e]0;)
PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
else
PS1="\n\[\033[$PROMPT_COLOR\][\[\e]0;\u@\h: \w\a\]\u@\h:\w]\\$\[\033[0m\] "
fi
if test "$TERM" = "xterm"; then
PS1="\[\033]2;\h:\u:\w\007\]$PS1"
fi
fi
'';
description = ''
Shell script code used to initialise the bash prompt.
'';
type = lib.types.lines;
};
promptPluginInit = lib.mkOption {
default = "";
description = ''
Shell script code used to initialise bash prompt plugins.
'';
type = lib.types.lines;
internal = true;
};
logout = lib.mkOption {
# Reset the title bar when logging out. This protects against a remote
# NixOS system clobbering your local terminal's title bar when you SSH
# into the remote NixOS system and then log out.
#
# For more details, see: https://superuser.com/a/339946
default = ''
printf '\e]0;\a'
'';
description = ''
Shell script code called during login bash shell logout.
'';
type = lib.types.lines;
};
};
};
config = lib.mkIf cfg.enable {
programs.bash = {
shellAliases = builtins.mapAttrs (name: lib.mkDefault) cfge.shellAliases;
shellInit = ''
if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]; then
. ${config.system.build.setEnvironment}
fi
${cfge.shellInit}
'';
loginShellInit = cfge.loginShellInit;
interactiveShellInit = ''
# Check the window size after every command.
shopt -s checkwinsize
# Disable hashing (i.e. caching) of command lookups.
set +h
${cfg.promptInit}
${cfg.promptPluginInit}
${bashAliases}
${cfge.interactiveShellInit}
'';
};
environment.etc.profile.text = ''
# /etc/profile: DO NOT EDIT -- this file has been generated automatically.
# This file is read for login shells.
# Only execute this file once per shell.
if [ -n "$__ETC_PROFILE_SOURCED" ]; then return; fi
__ETC_PROFILE_SOURCED=1
# Prevent this file from being sourced by interactive non-login child shells.
export __ETC_PROFILE_DONE=1
${cfg.shellInit}
${cfg.loginShellInit}
# Read system-wide modifications.
if test -f /etc/profile.local; then
. /etc/profile.local
fi
if [ -n "''${BASH_VERSION:-}" ]; then
. /etc/bashrc
fi
'';
environment.etc.bashrc.text = ''
# /etc/bashrc: DO NOT EDIT -- this file has been generated automatically.
# Only execute this file once per shell.
if [ -n "$__ETC_BASHRC_SOURCED" ] || [ -n "$NOSYSBASHRC" ]; then return; fi
__ETC_BASHRC_SOURCED=1
# If the profile was not loaded in a parent process, source
# it. But otherwise don't do it because we don't want to
# clobber overridden values of $PATH, etc.
if [ -z "$__ETC_PROFILE_DONE" ]; then
. /etc/profile
fi
# We are not always an interactive shell.
if [ -n "$PS1" ]; then
${cfg.interactiveShellInit}
fi
# Read system-wide modifications.
if test -f /etc/bashrc.local; then
. /etc/bashrc.local
fi
'';
environment.etc.bash_logout.text = ''
# /etc/bash_logout: DO NOT EDIT -- this file has been generated automatically.
# Only execute this file once per shell.
if [ -n "$__ETC_BASHLOGOUT_SOURCED" ] || [ -n "$NOSYSBASHLOGOUT" ]; then return; fi
__ETC_BASHLOGOUT_SOURCED=1
${cfg.logout}
# Read system-wide modifications.
if test -f /etc/bash_logout.local; then
. /etc/bash_logout.local
fi
'';
# Configuration for readline in bash. We use "option default"
# priority to allow user override using both .text and .source.
environment.etc.inputrc.source = lib.mkOptionDefault ./inputrc;
users.defaultUserShell = lib.mkDefault pkgs.bashInteractive;
environment.pathsToLink = lib.optionals cfg.completion.enable [
"/etc/bash_completion.d"
"/share/bash-completion"
];
environment.shells = [
"/run/current-system/sw/bin/bash"
"/run/current-system/sw/bin/sh"
"${pkgs.bashInteractive}/bin/bash"
"${pkgs.bashInteractive}/bin/sh"
];
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.programs.bash.blesh;
in
{
options = {
programs.bash.blesh.enable = lib.mkEnableOption "blesh, a full-featured line editor written in pure Bash";
};
config = lib.mkIf cfg.enable {
programs.bash.interactiveShellInit = lib.mkBefore ''
source ${pkgs.blesh}/share/blesh/ble.sh
'';
};
meta.maintainers = with lib.maintainers; [ laalsaas ];
}

View File

@@ -0,0 +1,37 @@
# inputrc borrowed from CentOS (RHEL).
set bell-style none
set meta-flag on
set input-meta on
set convert-meta off
set output-meta on
set colored-stats on
#set mark-symlinked-directories on
$if mode=emacs
# for linux console and RH/Debian xterm
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert
"\e[5C": forward-word
"\e[5D": backward-word
"\e[1;5C": forward-word
"\e[1;5D": backward-word
# for rxvt
"\e[8~": end-of-line
# for non RH/Debian xterm, can't hurt for RH/DEbian xterm
"\eOH": beginning-of-line
"\eOF": end-of-line
# for freebsd console
"\e[H": beginning-of-line
"\e[F": end-of-line
$endif

View File

@@ -0,0 +1,31 @@
{
config,
lib,
pkgs,
...
}:
let
enable = config.programs.bash.enableLsColors;
in
{
options = {
programs.bash.enableLsColors = lib.mkEnableOption "extra colors in directory listings" // {
default = true;
};
programs.bash.lsColorsFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
example = lib.literalExpression "\${pkgs.dircolors-solarized}/ansi-dark";
description = "Alternative colorscheme for ls colors";
};
};
config = lib.mkIf enable {
programs.bash.promptPluginInit = ''
eval "$(${pkgs.coreutils}/bin/dircolors -b ${
lib.optionalString (config.programs.bash.lsColorsFile != null) config.programs.bash.lsColorsFile
})"
'';
};
}

View File

@@ -0,0 +1,39 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.bash.undistractMe;
in
{
options = {
programs.bash.undistractMe = {
enable = lib.mkEnableOption "notifications when long-running terminal commands complete";
playSound = lib.mkEnableOption "notification sounds when long-running terminal commands complete";
timeout = lib.mkOption {
default = 10;
description = ''
Number of seconds it would take for a command to be considered long-running.
'';
type = lib.types.int;
};
};
};
config = lib.mkIf cfg.enable {
programs.bash.promptPluginInit = ''
export LONG_RUNNING_COMMAND_TIMEOUT=${builtins.toString cfg.timeout}
export UDM_PLAY_SOUND=${if cfg.playSound then "1" else "0"}
. "${pkgs.undistract-me}/etc/profile.d/undistract-me.sh"
'';
};
meta = {
maintainers = with lib.maintainers; [ kira-bruneau ];
};
}

View File

@@ -0,0 +1,128 @@
{
pkgs,
config,
lib,
...
}:
let
inherit (builtins) isList elem;
inherit (lib)
getExe
literalExpression
maintainers
mapAttrs'
mkEnableOption
mkIf
mkOption
mkPackageOption
nameValuePair
optionalString
types
isBool
boolToString
;
inherit (types) listOf package;
cfg = config.programs.bat;
settingsFormat = pkgs.formats.keyValue { listsAsDuplicateKeys = true; };
inherit (settingsFormat) generate type;
recursiveToString =
value:
if isList value then
map recursiveToString value
else if isBool value then
boolToString value
else
toString value;
initScript =
{
program,
shell,
flags ? [ ],
}:
if (shell != "fish") then
''
eval "$(${getExe program} ${toString flags})"
''
else
''
${getExe program} ${toString flags} | source
'';
shellInit =
shell:
optionalString (elem pkgs.bat-extras.batpipe cfg.extraPackages) (initScript {
program = pkgs.bat-extras.batpipe;
inherit shell;
})
+ optionalString (elem pkgs.bat-extras.batman cfg.extraPackages) (initScript {
program = pkgs.bat-extras.batman;
inherit shell;
flags = [ "--export-env" ];
});
in
{
options.programs.bat = {
enable = mkEnableOption "`bat`, a {manpage}`cat(1)` clone with wings";
package = mkPackageOption pkgs "bat" { };
extraPackages = mkOption {
default = [ ];
example = literalExpression ''
with pkgs.bat-extras; [
batdiff
batman
prettybat
];
'';
description = ''
Extra `bat` scripts to be added to the system configuration.
'';
type = listOf package;
};
settings = mkOption {
default = { };
example = {
theme = "TwoDark";
italic-text = "always";
paging = "never";
pager = "less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse";
map-syntax = [
"*.ino:C++"
".ignore:Git Ignore"
];
};
description = ''
Parameters to be written to the system-wide `bat` configuration file.
'';
inherit type;
};
};
config = mkIf cfg.enable {
environment = {
systemPackages = [ cfg.package ] ++ cfg.extraPackages;
etc."bat/config".source = generate "bat-config" (
mapAttrs' (name: value: nameValuePair ("--" + name) (recursiveToString value)) cfg.settings
);
};
programs = {
bash = mkIf (!config.programs.fish.enable) {
interactiveShellInit = shellInit "bash";
};
fish = mkIf config.programs.fish.enable {
interactiveShellInit = shellInit "fish";
};
zsh = mkIf (!config.programs.fish.enable && config.programs.zsh.enable) {
interactiveShellInit = shellInit "zsh";
};
};
};
meta.maintainers = with maintainers; [ sigmasquadron ];
}

View File

@@ -0,0 +1,25 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.bazecor;
in
{
meta.maintainers = with lib.maintainers; [ amesgen ];
options = {
programs.bazecor = {
enable = lib.mkEnableOption "Bazecor, the graphical configurator for Dygma Products";
package = lib.mkPackageOption pkgs "bazecor" { };
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
services.udev.packages = [ cfg.package ];
};
}

View File

@@ -0,0 +1,14 @@
{
config,
pkgs,
lib,
...
}:
{
options.programs.bcc.enable = lib.mkEnableOption "bcc, tools for BPF-based Linux IO analysis, networking, monitoring, and more";
config = lib.mkIf config.programs.bcc.enable {
environment.systemPackages = [ pkgs.bcc ];
boot.extraModulePackages = [ pkgs.bcc ];
};
}

View File

@@ -0,0 +1,96 @@
{
lib,
pkgs,
config,
options,
...
}:
let
cfg = config.programs.benchexec;
opt = options.programs.benchexec;
filterUsers =
x:
if builtins.isString x then
config.users.users ? ${x}
else if builtins.isInt x then
x
else
throw "filterUsers expects string (username) or int (UID)";
uid =
x:
if builtins.isString x then
config.users.users.${x}.uid
else if builtins.isInt x then
x
else
throw "uid expects string (username) or int (UID)";
in
{
options.programs.benchexec = {
enable = lib.mkEnableOption "BenchExec";
package = lib.options.mkPackageOption pkgs "benchexec" { };
users = lib.options.mkOption {
type = with lib.types; listOf (either str int);
description = ''
Users that intend to use BenchExec.
Provide usernames of users that are configured via {option}`${options.users.users}` as string,
and UIDs of "mutable users" as integers.
Control group delegation will be configured via systemd.
For more information, see <https://github.com/sosy-lab/benchexec/blob/3.18/doc/INSTALL.md#setting-up-cgroups>.
'';
default = [ ];
example = lib.literalExpression ''
[
"alice" # username of a user configured via ${options.users.users}
1007 # UID of a mutable user
]
'';
};
};
config = lib.mkIf cfg.enable {
assertions =
(map (user: {
assertion = config.users.users ? ${user};
message = ''
The user '${user}' intends to use BenchExec (via `${opt.users}`), but is not configured via `${options.users.users}`.
'';
}) (builtins.filter builtins.isString cfg.users))
++ (map (id: {
assertion = config.users.mutableUsers;
message = ''
The user with UID '${id}' intends to use BenchExec (via `${opt.users}`), but mutable users are disabled via `${options.users.mutableUsers}`.
'';
}) (builtins.filter builtins.isInt cfg.users));
environment.systemPackages = [ cfg.package ];
# See <https://github.com/sosy-lab/benchexec/blob/3.18/doc/INSTALL.md#setting-up-cgroups>.
systemd.services = builtins.listToAttrs (
map (user: {
name = "user@${builtins.toString (uid user)}";
value = {
serviceConfig.Delegate = "yes";
overrideStrategy = "asDropin";
};
}) (builtins.filter filterUsers cfg.users)
);
# See <https://github.com/sosy-lab/benchexec/blob/3.18/doc/INSTALL.md#requirements>.
virtualisation.lxc.lxcfs.enable = lib.mkDefault true;
# See <https://github.com/sosy-lab/benchexec/blob/3.18/doc/INSTALL.md#requirements>.
programs = {
cpu-energy-meter.enable = lib.mkDefault true;
pqos-wrapper.enable = lib.mkDefault true;
};
# See <https://github.com/sosy-lab/benchexec/blob/3.18/doc/INSTALL.md#kernel-requirements>.
security.unprivilegedUsernsClone = true;
};
meta.maintainers = with lib.maintainers; [ lorenzleutgeb ];
}

View File

@@ -0,0 +1,37 @@
{
config,
lib,
pkgs,
...
}:
{
options.programs.browserpass.enable = lib.mkEnableOption "Browserpass native messaging host";
config = lib.mkIf config.programs.browserpass.enable {
environment.etc =
let
appId = "com.github.browserpass.native.json";
source = part: "${pkgs.browserpass}/lib/browserpass/${part}/${appId}";
in
{
# chromium
"chromium/native-messaging-hosts/${appId}".source = source "hosts/chromium";
"chromium/policies/managed/${appId}".source = source "policies/chromium";
# chrome
"opt/chrome/native-messaging-hosts/${appId}".source = source "hosts/chromium";
"opt/chrome/policies/managed/${appId}".source = source "policies/chromium";
# vivaldi
"opt/vivaldi/native-messaging-hosts/${appId}".source = source "hosts/chromium";
"opt/vivaldi/policies/managed/${appId}".source = source "policies/chromium";
# brave
"opt/brave/native-messaging-hosts/${appId}".source = source "hosts/chromium";
"opt/brave/policies/managed/${appId}".source = source "policies/chromium";
};
programs.firefox.nativeMessagingHosts.packages = [ pkgs.browserpass ];
};
}

View File

@@ -0,0 +1,31 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.calls;
in
{
options = {
programs.calls = {
enable = lib.mkEnableOption ''
GNOME calls: a phone dialer and call handler
'';
};
};
config = lib.mkIf cfg.enable {
programs.dconf.enable = true;
environment.systemPackages = [
pkgs.calls
];
services.dbus.packages = [
pkgs.callaudiod
];
};
}

View File

@@ -0,0 +1,166 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.captive-browser;
inherit (lib)
concatStringsSep
escapeShellArgs
optionalString
literalExpression
mkEnableOption
mkPackageOption
mkIf
mkOption
mkOptionDefault
types
;
requiresSetcapWrapper = config.boot.kernelPackages.kernelOlder "5.7" && cfg.bindInterface;
browserDefault =
chromium:
concatStringsSep " " [
''env XDG_CONFIG_HOME="$PREV_CONFIG_HOME"''
''${chromium}/bin/chromium''
''--user-data-dir=''${XDG_DATA_HOME:-$HOME/.local/share}/chromium-captive''
''--proxy-server="socks5://$PROXY"''
''--host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE localhost"''
''--no-first-run''
''--new-window''
''--incognito''
''-no-default-browser-check''
''http://cache.nixos.org/''
];
desktopItem = pkgs.makeDesktopItem {
name = "captive-browser";
desktopName = "Captive Portal Browser";
exec = "captive-browser";
icon = "nix-snowflake";
categories = [ "Network" ];
};
captive-browser-configured = pkgs.writeShellScriptBin "captive-browser" ''
export PREV_CONFIG_HOME="$XDG_CONFIG_HOME"
export XDG_CONFIG_HOME=${pkgs.writeTextDir "captive-browser.toml" ''
browser = """${cfg.browser}"""
dhcp-dns = """${cfg.dhcp-dns}"""
socks5-addr = """${cfg.socks5-addr}"""
${optionalString cfg.bindInterface ''
bind-device = """${cfg.interface}"""
''}
''}
exec ${cfg.package}/bin/captive-browser
'';
in
{
###### interface
options = {
programs.captive-browser = {
enable = mkEnableOption "captive browser, a dedicated Chrome instance to log into captive portals without messing with DNS settings";
package = mkPackageOption pkgs "captive-browser" { };
interface = mkOption {
type = types.str;
description = "your public network interface (wlp3s0, wlan0, eth0, ...)";
};
# the options below are the same as in "captive-browser.toml"
browser = mkOption {
type = types.str;
default = browserDefault pkgs.chromium;
defaultText = literalExpression (browserDefault "\${pkgs.chromium}");
description = ''
The shell (/bin/sh) command executed once the proxy starts.
When browser exits, the proxy exits. An extra env var PROXY is available.
Here, we use a separate Chrome instance in Incognito mode, so that
it can run (and be waited for) alongside the default one, and that
it maintains no state across runs. To configure this browser open a
normal window in it, settings will be preserved.
@volth: chromium is to open a plain HTTP (not HTTPS nor redirect to HTTPS!) website.
upstream uses http://example.com but I have seen captive portals whose DNS server resolves "example.com" to 127.0.0.1
'';
};
dhcp-dns = mkOption {
type = types.str;
description = ''
The shell (/bin/sh) command executed to obtain the DHCP
DNS server address. The first match of an IPv4 regex is used.
IPv4 only, because let's be real, it's a captive portal.
'';
};
socks5-addr = mkOption {
type = types.str;
default = "localhost:1666";
description = "the listen address for the SOCKS5 proxy server";
};
bindInterface = mkOption {
default = true;
type = types.bool;
description = ''
Binds `captive-browser` to the network interface declared in
`cfg.interface`. This can be used to avoid collisions
with private subnets.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
environment.systemPackages = [
(pkgs.runCommand "captive-browser-desktop-item" { } ''
install -Dm444 -t $out/share/applications ${desktopItem}/share/applications/*.desktop
'')
captive-browser-configured
];
programs.captive-browser.dhcp-dns =
let
iface =
prefixes: optionalString cfg.bindInterface (escapeShellArgs (prefixes ++ [ cfg.interface ]));
in
mkOptionDefault (
if config.networking.networkmanager.enable then
"${pkgs.networkmanager}/bin/nmcli dev show ${iface [ ]} | ${pkgs.gnugrep}/bin/fgrep IP4.DNS"
else if config.networking.dhcpcd.enable then
"${pkgs.dhcpcd}/bin/dhcpcd ${iface [ "-U" ]} | ${pkgs.gnugrep}/bin/fgrep domain_name_servers"
else if config.networking.useNetworkd then
"${cfg.package}/bin/systemd-networkd-dns ${iface [ ]}"
else
"${config.security.wrapperDir}/udhcpc --quit --now -f ${iface [ "-i" ]} -O dns --script ${pkgs.writeShellScript "udhcp-script" ''
if [ "$1" = bound ]; then
echo "$dns"
fi
''}"
);
security.wrappers.udhcpc = {
owner = "root";
group = "root";
capabilities = "cap_net_raw+p";
source = "${pkgs.busybox}/bin/udhcpc";
};
security.wrappers.captive-browser = mkIf requiresSetcapWrapper {
owner = "root";
group = "root";
capabilities = "cap_net_raw+p";
source = "${captive-browser-configured}/bin/captive-browser";
};
};
}

View File

@@ -0,0 +1,109 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.ccache;
in
{
options.programs.ccache = {
# host configuration
enable = lib.mkEnableOption "CCache, a compiler cache for fast recompilation of C/C++ code";
cacheDir = lib.mkOption {
type = lib.types.path;
description = "CCache directory";
default = "/var/cache/ccache";
};
# target configuration
packageNames = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Nix top-level packages to be compiled using CCache";
default = [ ];
example = [
"wxGTK32"
"ffmpeg"
"libav_all"
];
};
owner = lib.mkOption {
type = lib.types.str;
default = "root";
description = "Owner of CCache directory";
};
group = lib.mkOption {
type = lib.types.str;
default = "nixbld";
description = "Group owner of CCache directory";
};
};
config = lib.mkMerge [
# host configuration
(lib.mkIf cfg.enable {
systemd.tmpfiles.rules = [ "d ${cfg.cacheDir} 0770 ${cfg.owner} ${cfg.group} -" ];
# "nix-ccache --show-stats" and "nix-ccache --clear"
security.wrappers.nix-ccache = {
inherit (cfg) owner group;
setuid = false;
setgid = true;
source = pkgs.writeScript "nix-ccache.pl" ''
#!${pkgs.perl}/bin/perl
%ENV=( CCACHE_DIR => '${cfg.cacheDir}' );
sub untaint {
my $v = shift;
return '-C' if $v eq '-C' || $v eq '--clear';
return '-V' if $v eq '-V' || $v eq '--version';
return '-s' if $v eq '-s' || $v eq '--show-stats';
return '-z' if $v eq '-z' || $v eq '--zero-stats';
exec('${pkgs.ccache}/bin/ccache', '-h');
}
exec('${pkgs.ccache}/bin/ccache', map { untaint $_ } @ARGV);
'';
};
})
# target configuration
(lib.mkIf (cfg.packageNames != [ ]) {
nixpkgs.overlays = [
(
self: super:
lib.genAttrs cfg.packageNames (
pn: super.${pn}.override { stdenv = builtins.trace "with ccache: ${pn}" self.ccacheStdenv; }
)
)
(self: super: {
ccacheWrapper = super.ccacheWrapper.override {
extraConfig = ''
export CCACHE_COMPRESS=1
export CCACHE_SLOPPINESS=random_seed
export CCACHE_DIR="${cfg.cacheDir}"
export CCACHE_UMASK=007
if [ ! -d "$CCACHE_DIR" ]; then
echo "====="
echo "Directory '$CCACHE_DIR' does not exist"
echo "Please create it with:"
echo " sudo mkdir -m0770 '$CCACHE_DIR'"
echo " sudo chown ${cfg.owner}:${cfg.group} '$CCACHE_DIR'"
echo "====="
exit 1
fi
if [ ! -w "$CCACHE_DIR" ]; then
echo "====="
echo "Directory '$CCACHE_DIR' is not accessible for user $(whoami)"
echo "Please verify its access permissions"
echo "====="
exit 1
fi
'';
};
})
];
})
];
}

View File

@@ -0,0 +1,82 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.cdemu;
in
{
options = {
programs.cdemu = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
{command}`cdemu` for members of
{option}`programs.cdemu.group`.
'';
};
group = lib.mkOption {
type = lib.types.str;
default = "cdrom";
description = ''
Group that users must be in to use {command}`cdemu`.
'';
};
gui = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to install the {command}`cdemu` GUI (gCDEmu).
'';
};
image-analyzer = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to install the image analyzer.
'';
};
};
};
config = lib.mkIf cfg.enable {
boot = {
extraModulePackages = [ config.boot.kernelPackages.vhba ];
kernelModules = [ "vhba" ];
};
services = {
udev.extraRules = ''
KERNEL=="vhba_ctl", MODE="0660", OWNER="root", GROUP="${cfg.group}"
'';
dbus.packages = [ pkgs.cdemu-daemon ];
};
users.groups.${config.programs.cdemu.group} = { };
# Systemd User service
# manually adapted from example in source package:
# https://sourceforge.net/p/cdemu/code/ci/master/tree/cdemu-daemon/service-example/cdemu-daemon.service
systemd.user.services.cdemu-daemon.description = "CDEmu daemon";
systemd.user.services.cdemu-daemon.serviceConfig = {
Type = "dbus";
BusName = "net.sf.cdemu.CDEmuDaemon";
ExecStart = "${lib.getExe pkgs.cdemu-daemon} --config-file \"%h/.config/cdemu-daemon\"";
Restart = "no";
};
environment.systemPackages = [
pkgs.cdemu-daemon
pkgs.cdemu-client
]
++ lib.optional cfg.gui pkgs.gcdemu
++ lib.optional cfg.image-analyzer pkgs.image-analyzer;
};
}

View File

@@ -0,0 +1,37 @@
# CFS Zen Tweaks
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.cfs-zen-tweaks;
in
{
meta = {
maintainers = with lib.maintainers; [ mkg20001 ];
};
options = {
programs.cfs-zen-tweaks.enable = lib.mkEnableOption "CFS Zen Tweaks";
};
config = lib.mkIf cfg.enable {
systemd.packages = [ pkgs.cfs-zen-tweaks ];
systemd.services.set-cfs-tweaks.wantedBy = [
"multi-user.target"
"suspend.target"
"hibernate.target"
"hybrid-sleep.target"
"suspend-then-hibernate.target"
];
};
}

View File

@@ -0,0 +1,168 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.chromium;
defaultProfile = lib.filterAttrs (k: v: v != null) {
HomepageLocation = cfg.homepageLocation;
DefaultSearchProviderEnabled = cfg.defaultSearchProviderEnabled;
DefaultSearchProviderSearchURL = cfg.defaultSearchProviderSearchURL;
DefaultSearchProviderSuggestURL = cfg.defaultSearchProviderSuggestURL;
ExtensionInstallForcelist = cfg.extensions;
};
in
{
###### interface
options = {
programs.chromium = {
enable = lib.mkEnableOption "policies for chromium based browsers like Chromium, Google Chrome or Brave";
enablePlasmaBrowserIntegration = lib.mkEnableOption "Native Messaging Host for Plasma Browser Integration";
plasmaBrowserIntegrationPackage = lib.mkPackageOption pkgs [
"kdePackages"
"plasma-browser-integration"
] { };
extensions = lib.mkOption {
type = with lib.types; nullOr (listOf str);
description = ''
List of chromium extensions to install.
For list of plugins ids see id in url of extensions on
[chrome web store](https://chrome.google.com/webstore/category/extensions)
page. To install a chromium extension not included in the chrome web
store, append to the extension id a semicolon ";" followed by a URL
pointing to an Update Manifest XML file. See
[ExtensionInstallForcelist](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExtensionInstallForcelist)
for additional details.
'';
default = null;
example = lib.literalExpression ''
[
"chlffgpmiacpedhhbkiomidkjlcfhogd" # pushbullet
"mbniclmhobmnbdlbpiphghaielnnpgdp" # lightshot
"gcbommkclmclpchllfjekcdonpmejbdp" # https everywhere
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
]
'';
};
homepageLocation = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "Chromium default homepage";
default = null;
example = "https://nixos.org";
};
defaultSearchProviderEnabled = lib.mkOption {
type = lib.types.nullOr lib.types.bool;
description = "Enable the default search provider.";
default = null;
example = true;
};
defaultSearchProviderSearchURL = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "Chromium default search provider url.";
default = null;
example = "https://encrypted.google.com/search?q={searchTerms}&{google:RLZ}{google:originalQueryForSuggestion}{google:assistedQueryStats}{google:searchFieldtrialParameter}{google:searchClient}{google:sourceId}{google:instantExtendedEnabledParameter}ie={inputEncoding}";
};
defaultSearchProviderSuggestURL = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "Chromium default search provider url for suggestions.";
default = null;
example = "https://encrypted.google.com/complete/search?output=chrome&q={searchTerms}";
};
extraOpts = lib.mkOption {
type = lib.types.attrs;
description = ''
Extra chromium policy options. A list of available policies
can be found in the Chrome Enterprise documentation:
<https://cloud.google.com/docs/chrome-enterprise/policies/>
Make sure the selected policy is supported on Linux and your browser version.
'';
default = { };
example = lib.literalExpression ''
{
"BrowserSignin" = 0;
"SyncDisabled" = true;
"PasswordManagerEnabled" = false;
"SpellcheckEnabled" = true;
"SpellcheckLanguage" = [
"de"
"en-US"
];
}
'';
};
initialPrefs = lib.mkOption {
type = lib.types.attrs;
description = ''
Initial preferences are used to configure the browser for the first run.
Unlike {option}`programs.chromium.extraOpts`, initialPrefs can be changed by users in the browser settings.
More information can be found in the Chromium documentation:
<https://www.chromium.org/administrators/configuring-other-preferences/>
'';
default = { };
example = lib.literalExpression ''
{
"first_run_tabs" = [
"https://nixos.org/"
];
}
'';
};
};
};
###### implementation
config = {
environment.etc = lib.mkIf cfg.enable {
# for chromium
"chromium/native-messaging-hosts/org.kde.plasma.browser_integration.json" =
lib.mkIf cfg.enablePlasmaBrowserIntegration
{
source = "${cfg.plasmaBrowserIntegrationPackage}/etc/chromium/native-messaging-hosts/org.kde.plasma.browser_integration.json";
};
"chromium/policies/managed/default.json" = lib.mkIf (defaultProfile != { }) {
text = builtins.toJSON defaultProfile;
};
"chromium/policies/managed/extra.json" = lib.mkIf (cfg.extraOpts != { }) {
text = builtins.toJSON cfg.extraOpts;
};
"chromium/initial_preferences" = lib.mkIf (cfg.initialPrefs != { }) {
text = builtins.toJSON cfg.initialPrefs;
};
# for google-chrome https://www.chromium.org/administrators/linux-quick-start
"opt/chrome/native-messaging-hosts/org.kde.plasma.browser_integration.json" =
lib.mkIf cfg.enablePlasmaBrowserIntegration
{
source = "${cfg.plasmaBrowserIntegrationPackage}/etc/opt/chrome/native-messaging-hosts/org.kde.plasma.browser_integration.json";
};
"opt/chrome/policies/managed/default.json" = lib.mkIf (defaultProfile != { }) {
text = builtins.toJSON defaultProfile;
};
"opt/chrome/policies/managed/extra.json" = lib.mkIf (cfg.extraOpts != { }) {
text = builtins.toJSON cfg.extraOpts;
};
# for brave
"brave/policies/managed/default.json" = lib.mkIf (defaultProfile != { }) {
text = builtins.toJSON defaultProfile;
};
"brave/policies/managed/extra.json" = lib.mkIf (cfg.extraOpts != { }) {
text = builtins.toJSON cfg.extraOpts;
};
};
};
}

View File

@@ -0,0 +1,25 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.chrysalis;
in
{
options = {
programs.chrysalis = {
enable = lib.mkEnableOption "Chrysalis";
package = lib.mkPackageOption pkgs "Chrysalis" { default = "chrysalis"; };
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
services.udev.packages = [ cfg.package ];
};
meta.maintainers = with lib.maintainers; [ atalii ];
}

View File

@@ -0,0 +1,95 @@
{
config,
lib,
pkgs,
...
}:
{
imports = [
];
options.programs.clash-verge = {
enable = lib.mkEnableOption "Clash Verge";
package = lib.mkOption {
type = lib.types.package;
description = ''
The clash-verge package to use. Available options are
clash-verge-rev and clash-nyanpasu, both are forks of
the original clash-verge project.
'';
default = pkgs.clash-verge-rev;
defaultText = lib.literalExpression "pkgs.clash-verge-rev";
};
serviceMode = lib.mkEnableOption "Service Mode";
tunMode = lib.mkEnableOption "Setcap for TUN Mode. DNS settings won't work on this way";
autoStart = lib.mkEnableOption "Clash Verge auto launch";
};
config =
let
cfg = config.programs.clash-verge;
in
lib.mkIf cfg.enable {
environment.systemPackages = [
cfg.package
(lib.mkIf cfg.autoStart (
pkgs.makeAutostartItem {
name = "clash-verge";
package = cfg.package;
}
))
];
security.wrappers.clash-verge = lib.mkIf cfg.tunMode {
owner = "root";
group = "root";
capabilities = "cap_net_bind_service,cap_net_raw,cap_net_admin=+ep";
source = "${lib.getExe cfg.package}";
};
systemd.services.clash-verge = lib.mkIf cfg.serviceMode {
enable = true;
description = "Clash Verge Service Mode";
serviceConfig = {
ExecStart = "${cfg.package}/bin/clash-verge-service";
Restart = "on-failure";
ProtectSystem = "strict";
NoNewPrivileges = true;
ProtectHostname = true;
ProtectProc = "invisible";
ProcSubset = "pid";
SystemCallArchitectures = "native";
PrivateTmp = true;
PrivateMounts = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
LockPersonality = true;
RestrictRealtime = true;
RuntimeDirectory = "clash-verge-rev";
ProtectClock = true;
MemoryDenyWriteExecute = true;
RestrictSUIDSGID = true;
RestrictNamespaces = [ "~user cgroup mnt uts" ];
RestrictAddressFamilies = [
"AF_INET AF_INET6 AF_NETLINK AF_PACKET AF_UNIX"
];
CapabilityBoundingSet = [
"CAP_NET_ADMIN CAP_NET_RAW CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SETUID CAP_SETGID CAP_CHOWN CAP_MKNOD"
];
SystemCallFilter = [
"~@aio @chown @clock @cpu-emulation @debug @keyring @memlock @module @mount @obsolete @pkey @privileged @raw-io @reboot @sandbox @setuid @swap @timer"
];
SystemCallErrorNumber = "EPERM";
};
wantedBy = [ "multi-user.target" ];
};
};
meta.maintainers = with lib.maintainers; [
bot-wxt1221
Guanran928
];
}

View File

@@ -0,0 +1,26 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.cnping;
in
{
options = {
programs.cnping = {
enable = lib.mkEnableOption "a setcap wrapper for cnping";
};
};
config = lib.mkIf cfg.enable {
security.wrappers.cnping = {
owner = "root";
group = "root";
source = "${pkgs.cnping}/bin/cnping";
capabilities = "cap_net_raw+ep";
};
};
}

View File

@@ -0,0 +1,84 @@
# This module provides suggestions of packages to install if the user
# tries to run a missing command in Bash. This is implemented using a
# SQLite database that maps program names to Nix package names (e.g.,
# "pdflatex" is mapped to "tetex").
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.command-not-found;
commandNotFound = pkgs.replaceVarsWith {
name = "command-not-found";
dir = "bin";
src = ./command-not-found.pl;
isExecutable = true;
replacements = {
inherit (cfg) dbPath;
perl = pkgs.perl.withPackages (p: [
p.DBDSQLite
p.StringShellQuote
]);
};
};
in
{
options.programs.command-not-found = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether interactive shells should show which Nix package (if
any) provides a missing command.
Requires nix-channels to be set and downloaded (sudo nix-channels --update.)
See also nix-index and nix-index-database as an alternative for flakes-based systems.
Additionally, having the env var NIX_AUTO_RUN set will automatically run the matching package, and with NIX_AUTO_RUN_INTERACTIVE it will confirm the package before running.
'';
};
dbPath = lib.mkOption {
default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite";
description = ''
Absolute path to programs.sqlite.
By default this file will be provided by your channel
(nixexprs.tar.xz).
'';
type = lib.types.path;
};
};
config = lib.mkIf cfg.enable {
programs.bash.interactiveShellInit = ''
command_not_found_handle() {
'${commandNotFound}/bin/command-not-found' "$@"
}
'';
programs.zsh.interactiveShellInit = ''
command_not_found_handler() {
'${commandNotFound}/bin/command-not-found' "$@"
}
'';
# NOTE: Fish by itself checks for nixos command-not-found, let's instead makes it explicit.
programs.fish.interactiveShellInit = ''
function fish_command_not_found
"${commandNotFound}/bin/command-not-found" $argv
end
'';
environment.systemPackages = [ commandNotFound ];
};
}

View File

@@ -0,0 +1,95 @@
#! @perl@/bin/perl -w
use strict;
use DBI;
use DBD::SQLite;
use String::ShellQuote;
use Config;
my $program = $ARGV[0];
my $dbPath = "@dbPath@";
if (! -e $dbPath) {
print STDERR "$program: command not found\n";
print STDERR "\n";
print STDERR "command-not-found: Missing package database\n";
print STDERR "command-not-found is a tool for searching for missing packages.\n";
print STDERR "No database was found, this likely means the database hasn't been generated yet.\n";
print STDERR "This tool requires nix-channels to generate the database for the `nixos` channel.\n";
print STDERR "\n";
print STDERR "If you are using nix-channels you can run:\n";
print STDERR " sudo nix-channels --update\n";
print STDERR "\n";
print STDERR "If you are using flakes, see nix-index and nix-index-database.\n";
print STDERR "\n";
print STDERR "If you would like to disable this message you can set:\n";
print STDERR " programs.command-not-found.enable = false;\n";
exit 127;
}
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "")
or die "cannot open database `$dbPath'";
$dbh->{RaiseError} = 0;
$dbh->{PrintError} = 0;
my $system = $ENV{"NIX_SYSTEM"} // $Config{myarchname};
my $res = $dbh->selectall_arrayref(
"select package from Programs where system = ? and name = ?",
{ Slice => {} }, $system, $program);
my $len = !defined $res ? 0 : scalar @$res;
if ($len == 0) {
print STDERR "$program: command not found\n";
} elsif ($len == 1) {
my $package = @$res[0]->{package};
if ($ENV{"NIX_AUTO_RUN"} // "") {
if ($ENV{"NIX_AUTO_RUN_INTERACTIVE"} // "") {
while (1) {
print STDERR "'$program' from package '$package' will be run, confirm? [yn]: ";
chomp(my $comfirm = <STDIN>);
if (lc $comfirm eq "n") {
exit 0;
} elsif (lc $comfirm eq "y") {
last;
}
}
}
exec("nix-shell", "-p", $package, "--run", shell_quote("exec", @ARGV));
} else {
print STDERR <<EOF;
The program '$program' is not in your PATH. You can make it available in an
ephemeral shell by typing:
nix-shell -p $package
EOF
}
} else {
if ($ENV{"NIX_AUTO_RUN"} // "") {
print STDERR "Select a package that provides '$program':\n";
for my $i (0 .. $len - 1) {
print STDERR " [", $i + 1, "]: @$res[$i]->{package}\n";
}
my $choice = 0;
while (1) { # exec will break this loop
no warnings "numeric";
print STDERR "Your choice [1-${len}]: ";
# 0 can be invalid user input like non-number string
# so we start from 1
$choice = <STDIN> + 0;
if (1 <= $choice && $choice <= $len) {
exec("nix-shell", "-p", @$res[$choice - 1]->{package},
"--run", shell_quote("exec", @ARGV));
}
}
} else {
print STDERR <<EOF;
The program '$program' is not in your PATH. It is provided by several packages.
You can make it available in an ephemeral shell by typing one of the following:
EOF
print STDERR " nix-shell -p $_->{package}\n" foreach @$res;
}
}
exit 127;

View File

@@ -0,0 +1,69 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.coolercontrol;
in
{
##### interface
options = {
programs.coolercontrol = {
enable = lib.mkEnableOption "CoolerControl GUI & its background services";
nvidiaSupport = lib.mkOption {
type = lib.types.bool;
default = lib.elem "nvidia" config.services.xserver.videoDrivers;
defaultText = lib.literalExpression "lib.elem \"nvidia\" config.services.xserver.videoDrivers";
description = ''
Enable support for Nvidia GPUs.
'';
};
};
};
##### implementation
config = lib.mkIf cfg.enable (
lib.mkMerge [
# Common
{
environment.systemPackages = with pkgs.coolercontrol; [
coolercontrol-gui
];
systemd = {
packages = with pkgs.coolercontrol; [
coolercontrol-liqctld
coolercontrold
];
# https://github.com/NixOS/nixpkgs/issues/81138
services = {
coolercontrol-liqctld.wantedBy = [ "multi-user.target" ];
coolercontrold.wantedBy = [ "multi-user.target" ];
};
};
}
# Nvidia support
(lib.mkIf cfg.nvidiaSupport {
systemd.services.coolercontrold.path =
let
nvidiaPkg = config.hardware.nvidia.package;
in
[
nvidiaPkg # nvidia-smi
nvidiaPkg.settings # nvidia-settings
];
})
]
);
meta.maintainers = with lib.maintainers; [
OPNA2608
codifryed
];
}

View File

@@ -0,0 +1,42 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.corefreq;
kernelPackages = config.boot.kernelPackages;
in
{
options = {
programs.corefreq = {
enable = lib.mkEnableOption "Whether to enable the corefreq daemon and kernel module";
package = lib.mkOption {
type = lib.types.package;
default = kernelPackages.corefreq;
defaultText = lib.literalExpression "config.boot.kernelPackages.corefreq";
description = ''
The corefreq package to use.
'';
};
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
boot.extraModulePackages = [ cfg.package ];
boot.kernelModules = [ "corefreqk" ];
# Create a systemd service for the corefreq daemon
systemd.services.corefreq = {
description = "CoreFreq daemon";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = lib.getExe' cfg.package "corefreqd";
};
};
};
}

View File

@@ -0,0 +1,29 @@
{
config,
lib,
pkgs,
...
}:
{
options.programs.cpu-energy-meter = {
enable = lib.mkEnableOption "CPU Energy Meter";
package = lib.mkPackageOption pkgs "cpu-energy-meter" { };
};
config =
let
cfg = config.programs.cpu-energy-meter;
in
lib.mkIf cfg.enable {
hardware.cpu.x86.msr.enable = true;
security.wrappers.${cfg.package.meta.mainProgram} = {
owner = "nobody";
group = config.hardware.cpu.x86.msr.group;
source = lib.getExe cfg.package;
capabilities = "cap_sys_rawio=ep";
};
};
meta.maintainers = with lib.maintainers; [ lorenzleutgeb ];
}

View File

@@ -0,0 +1,32 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.criu;
in
{
options = {
programs.criu = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Install {command}`criu` along with necessary kernel options.
'';
};
};
};
config = lib.mkIf cfg.enable {
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "CHECKPOINT_RESTORE")
];
boot.kernel.features.criu = true;
environment.systemPackages = [ pkgs.criu ];
};
}

View File

@@ -0,0 +1,258 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.dconf;
# Compile keyfiles to dconf DB
compileDconfDb =
dir:
pkgs.runCommand "dconf-db" {
nativeBuildInputs = [ (lib.getBin pkgs.dconf) ];
} "dconf compile $out ${dir}";
# Check if dconf keyfiles are valid
checkDconfKeyfiles =
dir:
pkgs.runCommand "check-dconf-keyfiles"
{
nativeBuildInputs = [ (lib.getBin pkgs.dconf) ];
}
''
if [[ -f ${dir} ]]; then
echo "dconf keyfiles should be a directory but a file is provided: ${dir}"
exit 1
fi
dconf compile db ${dir} || (
echo "The dconf keyfiles are invalid: ${dir}"
exit 1
)
cp -R ${dir} $out
'';
mkAllLocks =
settings:
lib.flatten (lib.mapAttrsToList (k: v: lib.mapAttrsToList (k': _: "/${k}/${k'}") v) settings);
# Generate dconf DB from dconfDatabase and keyfiles
mkDconfDb =
val:
compileDconfDb (
pkgs.symlinkJoin {
name = "nixos-generated-dconf-keyfiles";
paths = [
(pkgs.writeTextDir "nixos-generated-dconf-keyfiles" (lib.generators.toDconfINI val.settings))
(pkgs.writeTextDir "locks/nixos-generated-dconf-locks" (
lib.concatStringsSep "\n" (if val.lockAll then mkAllLocks val.settings else val.locks)
))
]
++ (map checkDconfKeyfiles val.keyfiles);
}
);
# Check if a dconf DB file is valid. The dconf cli doesn't return 1 when it can't
# open the database file so we have to check if the output is empty.
checkDconfDb =
file:
pkgs.runCommand "check-dconf-db"
{
nativeBuildInputs = [ (lib.getBin pkgs.dconf) ];
}
''
if [[ -d ${file} ]]; then
echo "dconf DB should be a file but a directory is provided: ${file}"
exit 1
fi
echo "file-db:${file}" > profile
DCONF_PROFILE=$(pwd)/profile dconf dump / > output 2> error
if [[ ! -s output ]] && [[ -s error ]]; then
cat error
echo "The dconf DB file is invalid: ${file}"
exit 1
fi
cp ${file} $out
'';
# Generate dconf profile
mkDconfProfile =
name: value:
if lib.isDerivation value || lib.isPath value then
pkgs.runCommand "dconf-profile" { } ''
if [[ -d ${value} ]]; then
echo "Dconf profile should be a file but a directory is provided."
exit 1
fi
mkdir -p $out/etc/dconf/profile/
cp ${value} $out/etc/dconf/profile/${name}
''
else
pkgs.writeTextDir "etc/dconf/profile/${name}" (
lib.concatMapStrings (x: "${x}\n") (
(lib.optional value.enableUserDb "user-db:user")
++ (map (
value:
let
db = if lib.isAttrs value && !lib.isDerivation value then mkDconfDb value else checkDconfDb value;
in
"file-db:${db}"
) value.databases)
)
);
dconfDatabase =
with lib.types;
submodule {
options = {
keyfiles = lib.mkOption {
type = listOf (oneOf [
path
package
]);
default = [ ];
description = "A list of dconf keyfile directories.";
};
settings = lib.mkOption {
type = attrs;
default = { };
description = "An attrset used to generate dconf keyfile.";
example = literalExpression ''
with lib.gvariant;
{
"com/raggesilver/BlackBox" = {
scrollback-lines = mkUint32 10000;
theme-dark = "Tommorow Night";
};
}
'';
};
locks = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
description = ''
A list of dconf keys to be lockdown. This doesn't take effect if `lockAll`
is set.
'';
example = literalExpression ''
[ "/org/gnome/desktop/background/picture-uri" ]
'';
};
lockAll = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Lockdown all dconf keys in `settings`.";
};
};
};
dconfProfile =
with lib.types;
submodule {
options = {
enableUserDb = lib.mkOption {
type = bool;
default = true;
description = "Add `user-db:user` at the beginning of the profile.";
};
databases = lib.mkOption {
type =
with lib.types;
listOf (oneOf [
path
package
dconfDatabase
]);
default = [ ];
description = ''
List of data sources for the profile. An element can be an attrset,
or the path of an already compiled database. Each element is converted
to a file-db.
A key is searched from up to down and the first result takes the
priority. If a lock for a particular key is installed then the value from
the last database in the profile where the key is locked will be used.
This can be used to enforce mandatory settings.
'';
};
};
};
in
{
options = {
programs.dconf = {
enable = lib.mkEnableOption "dconf";
profiles = lib.mkOption {
type =
with lib.types;
attrsOf (oneOf [
path
package
dconfProfile
]);
default = { };
description = ''
Attrset of dconf profiles. By default the `user` profile is used which
ends up in `/etc/dconf/profile/user`.
'';
example = lib.literalExpression ''
{
# A "user" profile with a database
user.databases = [
{
settings = { };
}
];
# A "bar" profile from a package
bar = pkgs.bar-dconf-profile;
# A "foo" profile from a path
foo = ''${./foo}
};
'';
};
packages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
description = "A list of packages which provide dconf profiles and databases in {file}`/etc/dconf`.";
};
};
};
config = lib.mkIf (cfg.profiles != { } || cfg.enable) {
programs.dconf.packages = lib.mapAttrsToList mkDconfProfile cfg.profiles;
environment.etc.dconf = lib.mkIf (cfg.packages != [ ]) {
source = pkgs.symlinkJoin {
name = "dconf-system-config";
paths = map (x: "${x}/etc/dconf") cfg.packages;
nativeBuildInputs = [ (lib.getBin pkgs.dconf) ];
postBuild = ''
if test -d $out/db; then
dconf update $out/db
fi
'';
};
};
services.dbus.packages = [ pkgs.dconf ];
systemd.packages = [ pkgs.dconf ];
# For dconf executable
environment.systemPackages = [ pkgs.dconf ];
environment.sessionVariables = lib.mkIf cfg.enable {
# Needed for unwrapped applications
GIO_EXTRA_MODULES = [ "${pkgs.dconf.lib}/lib/gio/modules" ];
};
};
}

View File

@@ -0,0 +1,45 @@
# Digital Bitbox {#module-programs-digitalbitbox}
Digital Bitbox is a hardware wallet and second-factor authenticator.
The `digitalbitbox` programs module may be installed by setting
`programs.digitalbitbox` to `true` in a manner similar to
```nix
{ programs.digitalbitbox.enable = true; }
```
and bundles the `digitalbitbox` package (see [](#sec-digitalbitbox-package)),
which contains the `dbb-app` and `dbb-cli` binaries, along with the hardware
module (see [](#sec-digitalbitbox-hardware-module)) which sets up the necessary
udev rules to access the device.
Enabling the digitalbitbox module is pretty much the easiest way to get a
Digital Bitbox device working on your system.
For more information, see <https://digitalbitbox.com/start_linux>.
## Package {#sec-digitalbitbox-package}
The binaries, `dbb-app` (a GUI tool) and `dbb-cli` (a CLI tool), are available
through the `digitalbitbox` package which could be installed as follows:
```nix
{ environment.systemPackages = [ pkgs.digitalbitbox ]; }
```
## Hardware {#sec-digitalbitbox-hardware-module}
The digitalbitbox hardware package enables the udev rules for Digital Bitbox
devices and may be installed as follows:
```nix
{ hardware.digitalbitbox.enable = true; }
```
In order to alter the udev rules, one may provide different values for the
`udevRule51` and `udevRule52` attributes by means of overriding as follows:
```nix
{
programs.digitalbitbox = {
enable = true;
package = pkgs.digitalbitbox.override { udevRule51 = "something else"; };
};
}
```

View File

@@ -0,0 +1,41 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.digitalbitbox;
in
{
options.programs.digitalbitbox = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Installs the Digital Bitbox application and enables the complementary hardware module.
'';
};
package = lib.mkPackageOption pkgs "digitalbitbox" {
extraDescription = ''
This can be used to install a package with udev rules that differ from the defaults.
'';
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
hardware.digitalbitbox = {
enable = true;
package = cfg.package;
};
};
meta = {
doc = ./default.md;
maintainers = with lib.maintainers; [ vidbina ];
};
}

View File

@@ -0,0 +1,198 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.programs.direnv;
enabledOption =
x:
lib.mkEnableOption x
// {
default = true;
example = false;
};
format = pkgs.formats.toml { };
in
{
options.programs.direnv = {
enable = lib.mkEnableOption ''
direnv integration. Takes care of both installation and
setting up the sourcing of the shell. Additionally enables nix-direnv
integration. Note that you need to logout and login for this change to apply
'';
package = lib.mkPackageOption pkgs "direnv" { };
finalPackage = lib.mkOption {
type = lib.types.package;
readOnly = true;
description = "The wrapped direnv package.";
};
enableBashIntegration = enabledOption ''
Bash integration
'';
enableZshIntegration = enabledOption ''
Zsh integration
'';
enableFishIntegration = enabledOption ''
Fish integration
'';
enableXonshIntegration = enabledOption ''
Xonsh integration
'';
direnvrcExtra = lib.mkOption {
type = lib.types.lines;
default = "";
example = ''
export FOO="foo"
echo "loaded direnv!"
'';
description = ''
Extra lines to append to the sourced direnvrc
'';
};
silent = lib.mkEnableOption ''
the hiding of direnv logging
'';
loadInNixShell = enabledOption ''
loading direnv in `nix-shell` `nix shell` or `nix develop`
'';
nix-direnv = {
enable = enabledOption ''
a faster, persistent implementation of use_nix and use_flake, to replace the builtin one
'';
package = lib.mkOption {
default = pkgs.nix-direnv.override { nix = config.nix.package; };
defaultText = "pkgs.nix-direnv";
type = lib.types.package;
description = ''
The nix-direnv package to use
'';
};
};
settings = lib.mkOption {
inherit (format) type;
default = { };
example = lib.literalExpression ''
{
global = {
log_format = "-";
log_filter = "^$";
};
}
'';
description = ''
Direnv configuration. Refer to {manpage}`direnv.toml(1)`.
'';
};
};
config = lib.mkIf cfg.enable {
programs = {
direnv = {
finalPackage = pkgs.symlinkJoin {
inherit (cfg.package) name;
paths = [ cfg.package ];
# direnv has a fish library which automatically sources direnv for some reason
postBuild = ''
rm -rf "$out/share/fish"
'';
meta.mainProgram = "direnv";
};
settings = lib.mkIf cfg.silent {
global = {
log_format = lib.mkDefault "-";
log_filter = lib.mkDefault "^$";
};
};
};
zsh.interactiveShellInit = lib.mkIf cfg.enableZshIntegration ''
if ${lib.boolToString cfg.loadInNixShell} || printenv PATH | grep -vqc '/nix/store'; then
eval "$(${lib.getExe cfg.finalPackage} hook zsh)"
fi
'';
#$NIX_GCROOT for "nix develop" https://github.com/NixOS/nix/blob/6db66ebfc55769edd0c6bc70fcbd76246d4d26e0/src/nix/develop.cc#L530
#$IN_NIX_SHELL for "nix-shell"
bash.interactiveShellInit = lib.mkIf cfg.enableBashIntegration ''
if ${lib.boolToString cfg.loadInNixShell} || [ -z "$IN_NIX_SHELL$NIX_GCROOT$(printenv PATH | grep '/nix/store')" ] ; then
eval "$(${lib.getExe cfg.finalPackage} hook bash)"
fi
'';
fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration ''
if ${lib.boolToString cfg.loadInNixShell}; or printenv PATH | grep -vqc '/nix/store';
${lib.getExe cfg.finalPackage} hook fish | source
end
'';
xonsh = lib.mkIf cfg.enableXonshIntegration {
extraPackages = ps: [ ps.xonsh.xontribs.xonsh-direnv ];
config = ''
if ${
if cfg.loadInNixShell then
"True"
else
"not any(map(lambda s: s.startswith('/nix/store'), __xonsh__.env.get('PATH')))"
}:
xontrib load direnv
'';
};
};
environment = {
systemPackages = [
cfg.finalPackage
];
variables.DIRENV_CONFIG = "/etc/direnv";
etc = {
"direnv/direnv.toml" = lib.mkIf (cfg.settings != { }) {
source = format.generate "direnv.toml" cfg.settings;
};
"direnv/direnvrc".text = ''
${lib.optionalString cfg.nix-direnv.enable ''
#Load nix-direnv
source ${cfg.nix-direnv.package}/share/nix-direnv/direnvrc
''}
#Load direnvrcExtra
${cfg.direnvrcExtra}
#Load user-configuration if present (~/.direnvrc or ~/.config/direnv/direnvrc)
direnv_config_dir_home="''${DIRENV_CONFIG_HOME:-''${XDG_CONFIG_HOME:-$HOME/.config}/direnv}"
if [[ -f $direnv_config_dir_home/direnvrc ]]; then
source "$direnv_config_dir_home/direnvrc" >&2
elif [[ -f $HOME/.direnvrc ]]; then
source "$HOME/.direnvrc" >&2
fi
unset direnv_config_dir_home
'';
"direnv/lib/zz-user.sh".text = ''
direnv_config_dir_home="''${DIRENV_CONFIG_HOME:-''${XDG_CONFIG_HOME:-$HOME/.config}/direnv}"
for lib in "$direnv_config_dir_home/lib/"*.sh; do
source "$lib"
done
unset direnv_config_dir_home
'';
};
};
};
meta.maintainers = with lib.maintainers; [ gerg-l ];
}

View File

@@ -0,0 +1,37 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.dmrconfig;
in
{
meta.maintainers = [ ];
###### interface
options = {
programs.dmrconfig = {
enable = lib.mkOption {
default = false;
type = lib.types.bool;
description = ''
Whether to configure system to enable use of dmrconfig. This
enables the required udev rules and installs the program.
'';
relatedPackages = [ "dmrconfig" ];
};
package = lib.mkPackageOption pkgs "dmrconfig" { };
};
};
###### implementation
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
services.udev.packages = [ cfg.package ];
};
}

View File

@@ -0,0 +1,22 @@
{
lib,
pkgs,
config,
...
}:
{
options.programs.droidcam = {
enable = lib.mkEnableOption "DroidCam client";
};
config = lib.mkIf config.programs.droidcam.enable {
environment.systemPackages = [ pkgs.droidcam ];
boot.extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ];
boot.kernelModules = [
"v4l2loopback"
"snd-aloop"
];
};
}

View File

@@ -0,0 +1,33 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.dublin-traceroute;
in
{
meta.maintainers = pkgs.dublin-traceroute.meta.maintainers;
options = {
programs.dublin-traceroute = {
enable = lib.mkEnableOption "dublin-traceroute (including setcap wrapper)";
package = lib.mkPackageOption pkgs "dublin-traceroute" { };
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
security.wrappers.dublin-traceroute = {
owner = "root";
group = "root";
capabilities = "cap_net_raw+p";
source = lib.getExe cfg.package;
};
};
}

View File

@@ -0,0 +1,35 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.ecryptfs;
in
{
options.programs.ecryptfs = {
enable = lib.mkEnableOption "ecryptfs setuid mount wrappers";
};
config = lib.mkIf cfg.enable {
security.wrappers = {
"mount.ecryptfs_private" = {
setuid = true;
owner = "root";
group = "root";
source = "${lib.getBin pkgs.ecryptfs}/bin/mount.ecryptfs_private";
};
"umount.ecryptfs_private" = {
setuid = true;
owner = "root";
group = "root";
source = "${lib.getBin pkgs.ecryptfs}/bin/umount.ecryptfs_private";
};
};
};
}

View File

@@ -0,0 +1,68 @@
# This module defines a standard configuration for NixOS global environment.
# Most of the stuff here should probably be moved elsewhere sometime.
{ config, lib, ... }:
let
cfg = config.environment;
in
{
config = {
environment.variables = {
NIXPKGS_CONFIG = "/etc/nix/nixpkgs-config.nix";
# note: many programs exec() this directly, so default options for less must not
# be specified here; do so in the default value of programs.less.envVariables instead
PAGER = lib.mkDefault "less";
EDITOR = lib.mkDefault "nano";
};
# since we set PAGER to this above, make sure it's installed
programs.less.enable = true;
environment.profiles = lib.mkAfter [
"/nix/var/nix/profiles/default"
"/run/current-system/sw"
];
environment.sessionVariables = {
XDG_CONFIG_DIRS = [ "/etc/xdg" ]; # needs to be before profile-relative paths to allow changes through environment.etc
};
# TODO: move most of these elsewhere
environment.profileRelativeSessionVariables = {
PATH = [ "/bin" ];
INFOPATH = [
"/info"
"/share/info"
];
QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ];
GTK_PATH = [
"/lib/gtk-2.0"
"/lib/gtk-3.0"
"/lib/gtk-4.0"
];
XDG_CONFIG_DIRS = [ "/etc/xdg" ];
XDG_DATA_DIRS = [ "/share" ];
LIBEXEC_PATH = [ "/libexec" ];
};
environment.pathsToLink = [
"/lib/gtk-2.0"
"/lib/gtk-3.0"
"/lib/gtk-4.0"
];
environment.extraInit = ''
export NIX_USER_PROFILE_DIR="/nix/var/nix/profiles/per-user/$USER"
export NIX_PROFILES="${builtins.concatStringsSep " " (lib.reverseList cfg.profiles)}"
'';
};
}

View File

@@ -0,0 +1,51 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.envision;
in
{
options = {
programs.envision = {
enable = lib.mkEnableOption "envision";
package = lib.mkPackageOption pkgs "envision" { };
openFirewall = lib.mkEnableOption "the default ports in the firewall for the WiVRn server" // {
default = true;
};
};
};
config = lib.mkIf cfg.enable {
services.avahi = {
enable = true;
publish = {
enable = true;
userServices = true;
};
};
services.udev = {
enable = true;
packages = with pkgs; [
android-udev-rules
xr-hardware
];
};
environment.systemPackages = [ cfg.package ];
networking.firewall = lib.mkIf cfg.openFirewall {
allowedTCPPorts = [ 9757 ];
allowedUDPPorts = [ 9757 ];
};
};
meta.maintainers = pkgs.envision.meta.maintainers;
}

View File

@@ -0,0 +1,42 @@
# Evince.
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.evince;
in
{
###### interface
options = {
programs.evince = {
enable = lib.mkEnableOption "Evince, the GNOME document viewer";
package = lib.mkPackageOption pkgs "evince" { };
};
};
###### implementation
config = lib.mkIf config.programs.evince.enable {
environment.systemPackages = [ cfg.package ];
services.dbus.packages = [ cfg.package ];
systemd.packages = [ cfg.package ];
};
}

View File

@@ -0,0 +1,22 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.extra-container;
in
{
options = {
programs.extra-container.enable = lib.mkEnableOption ''
extra-container, a tool for running declarative NixOS containers
without host system rebuilds
'';
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.extra-container ];
boot.extraSystemdUnitPaths = [ "/etc/systemd-mutable/system" ];
};
}

View File

@@ -0,0 +1,33 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.fcast-receiver;
in
{
meta = {
maintainers = pkgs.fcast-receiver.meta.maintainers;
};
options.programs.fcast-receiver = {
enable = lib.mkEnableOption "FCast Receiver";
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Open ports needed for the functionality of the program.
'';
};
package = lib.mkPackageOption pkgs "fcast-receiver" { };
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
networking.firewall = lib.mkIf cfg.openFirewall {
allowedTCPPorts = [ 46899 ];
};
};
}

View File

@@ -0,0 +1,38 @@
{
pkgs,
lib,
config,
...
}:
let
cfg = config.programs.feedbackd;
in
{
options = {
programs.feedbackd = {
enable = lib.mkEnableOption ''
the feedbackd D-BUS service and udev rules.
Your user needs to be in the `feedbackd` group to trigger effects
'';
package = lib.mkPackageOption pkgs "feedbackd" { };
theme-package = lib.mkPackageOption pkgs "feedbackd-device-themes" {
nullable = true;
};
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [
cfg.package
]
++ (if cfg.theme-package != null then [ cfg.theme-package ] else [ ]);
services.dbus.packages = [ cfg.package ];
services.udev.packages = [ cfg.package ];
# TODO: also enable systemd unit fbd-alert-slider for OnePlus 6/6T devices, see release notes of feedbackd v0.5.0
users.groups.feedbackd = { };
};
}

View File

@@ -0,0 +1,40 @@
# File Roller.
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.file-roller;
in
{
###### interface
options = {
programs.file-roller = {
enable = lib.mkEnableOption "File Roller, an archive manager for GNOME";
package = lib.mkPackageOption pkgs "file-roller" { };
};
};
###### implementation
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
services.dbus.packages = [ cfg.package ];
};
}

View File

@@ -0,0 +1,362 @@
{
pkgs,
config,
lib,
...
}:
let
cfg = config.programs.firefox;
policyFormat = pkgs.formats.json { };
organisationInfo = ''
When this option is in use, Firefox will inform you that "your browser
is managed by your organisation". That message appears because NixOS
installs what you have declared here such that it cannot be overridden
through the user interface. It does not mean that someone else has been
given control of your browser, unless of course they also control your
NixOS configuration.
'';
# deprecated per-native-messaging-host options
nmhOptions = {
browserpass = {
name = "Browserpass";
package = pkgs.browserpass;
};
bukubrow = {
name = "Bukubrow";
package = pkgs.bukubrow;
};
euwebid = {
name = "Web eID";
package = pkgs.web-eid-app;
};
ff2mpv = {
name = "ff2mpv";
package = pkgs.ff2mpv;
};
fxCast = {
name = "fx_cast";
package = pkgs.fx-cast-bridge;
};
gsconnect = {
name = "GSConnect";
package = pkgs.gnomeExtensions.gsconnect;
};
jabref = {
name = "JabRef";
package = pkgs.jabref;
};
passff = {
name = "PassFF";
package = pkgs.passff-host;
};
tridactyl = {
name = "Tridactyl";
package = pkgs.tridactyl-native;
};
ugetIntegrator = {
name = "Uget Integrator";
package = pkgs.uget-integrator;
};
};
in
{
options.programs.firefox = {
enable = lib.mkEnableOption "the Firefox web browser";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.firefox;
description = "Firefox package to use.";
defaultText = lib.literalExpression "pkgs.firefox";
relatedPackages = [
"firefox"
"firefox-bin"
"firefox-esr"
];
};
wrapperConfig = lib.mkOption {
type = lib.types.attrs;
default = { };
description = "Arguments to pass to Firefox wrapper";
};
policies = lib.mkOption {
type = policyFormat.type;
default = { };
description = ''
Group policies to install.
See [Mozilla's documentation](https://mozilla.github.io/policy-templates/)
for a list of available options.
This can be used to install extensions declaratively! Check out the
documentation of the `ExtensionSettings` policy for details.
${organisationInfo}
'';
};
preferences = lib.mkOption {
type =
with lib.types;
attrsOf (oneOf [
bool
int
str
]);
default = { };
description = ''
Preferences to set from `about:config`.
Some of these might be able to be configured more ergonomically
using policies.
See [here](https://mozilla.github.io/policy-templates/#preferences) for allowed preferences.
${organisationInfo}
'';
example = lib.literalExpression ''
{
"browser.tabs.tabmanager.enabled" = false;
}
'';
};
preferencesStatus = lib.mkOption {
type = lib.types.enum [
"default"
"locked"
"user"
"clear"
];
default = "locked";
description = ''
The status of `firefox.preferences`.
`status` can assume the following values:
- `"default"`: Preferences appear as default.
- `"locked"`: Preferences appear as default and can't be changed.
- `"user"`: Preferences appear as changed.
- `"clear"`: Value has no effect. Resets to factory defaults on each startup.
'';
};
languagePacks = lib.mkOption {
# Available languages can be found in https://releases.mozilla.org/pub/firefox/releases/${cfg.package.version}/linux-x86_64/xpi/
type = lib.types.listOf (
lib.types.enum [
"ach"
"af"
"an"
"ar"
"ast"
"az"
"be"
"bg"
"bn"
"br"
"bs"
"ca-valencia"
"ca"
"cak"
"cs"
"cy"
"da"
"de"
"dsb"
"el"
"en-CA"
"en-GB"
"en-US"
"eo"
"es-AR"
"es-CL"
"es-ES"
"es-MX"
"et"
"eu"
"fa"
"ff"
"fi"
"fr"
"fur"
"fy-NL"
"ga-IE"
"gd"
"gl"
"gn"
"gu-IN"
"he"
"hi-IN"
"hr"
"hsb"
"hu"
"hy-AM"
"ia"
"id"
"is"
"it"
"ja"
"ka"
"kab"
"kk"
"km"
"kn"
"ko"
"lij"
"lt"
"lv"
"mk"
"mr"
"ms"
"my"
"nb-NO"
"ne-NP"
"nl"
"nn-NO"
"oc"
"pa-IN"
"pl"
"pt-BR"
"pt-PT"
"rm"
"ro"
"ru"
"sat"
"sc"
"sco"
"si"
"sk"
"skr"
"sl"
"son"
"sq"
"sr"
"sv-SE"
"szl"
"ta"
"te"
"tg"
"th"
"tl"
"tr"
"trs"
"uk"
"ur"
"uz"
"vi"
"xh"
"zh-CN"
"zh-TW"
]
);
default = [ ];
description = ''
The language packs to install.
'';
};
autoConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
AutoConfig files can be used to set and lock preferences that are not covered
by the policies.json for Mac and Linux. This method can be used to automatically
change user preferences or prevent the end user from modifiying specific
preferences by locking them. More info can be found in <https://support.mozilla.org/en-US/kb/customizing-firefox-using-autoconfig>.
'';
};
autoConfigFiles = lib.mkOption {
type = with lib.types; listOf path;
default = [ ];
description = ''
AutoConfig files can be used to set and lock preferences that are not covered
by the policies.json for Mac and Linux. This method can be used to automatically
change user preferences or prevent the end user from modifiying specific
preferences by locking them. More info can be found in <https://support.mozilla.org/en-US/kb/customizing-firefox-using-autoconfig>.
Files are concated and autoConfig is appended.
'';
};
nativeMessagingHosts = {
packages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
description = ''
Additional packages containing native messaging hosts that should be made available to Firefox extensions.
'';
};
}
// (builtins.mapAttrs (k: v: lib.mkEnableOption "${v.name} support") nmhOptions);
};
config =
let
forEachEnabledNmh =
fn:
lib.flatten (
lib.mapAttrsToList (k: v: lib.optional cfg.nativeMessagingHosts.${k} (fn k v)) nmhOptions
);
in
lib.mkIf cfg.enable {
warnings = forEachEnabledNmh (
k: v:
"The `programs.firefox.nativeMessagingHosts.${k}` option is deprecated, "
+ "please add `${v.package.pname}` to `programs.firefox.nativeMessagingHosts.packages` instead."
);
programs.firefox.nativeMessagingHosts.packages = forEachEnabledNmh (_: v: v.package);
environment.systemPackages = [
(cfg.package.override (old: {
extraPrefsFiles =
old.extraPrefsFiles or [ ]
++ cfg.autoConfigFiles
++ [ (pkgs.writeText "firefox-autoconfig.js" cfg.autoConfig) ];
nativeMessagingHosts = lib.unique (
old.nativeMessagingHosts or [ ] ++ cfg.nativeMessagingHosts.packages
);
cfg = (old.cfg or { }) // cfg.wrapperConfig;
}))
];
environment.etc =
let
policiesJSON = policyFormat.generate "firefox-policies.json" { inherit (cfg) policies; };
in
lib.mkIf (cfg.policies != { }) {
"firefox/policies/policies.json".source = "${policiesJSON}";
};
# Preferences are converted into a policy
programs.firefox.policies = {
DisableAppUpdate = true;
Preferences = (
builtins.mapAttrs (_: value: {
Value = value;
Status = cfg.preferencesStatus;
}) cfg.preferences
);
ExtensionSettings = builtins.listToAttrs (
builtins.map (
lang:
lib.attrsets.nameValuePair "langpack-${lang}@firefox.mozilla.org" {
installation_mode = "normal_installed";
install_url = "https://releases.mozilla.org/pub/firefox/releases/${cfg.package.version}/linux-x86_64/xpi/${lang}.xpi";
}
) cfg.languagePacks
);
};
};
meta.maintainers = with lib.maintainers; [
danth
linsui
];
}

View File

@@ -0,0 +1,125 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.firejail;
wrappedBins =
pkgs.runCommand "firejail-wrapped-binaries"
{
preferLocalBuild = true;
allowSubstitutes = false;
# take precedence over non-firejailed versions
meta.priority = -1;
}
''
mkdir -p $out/bin
mkdir -p $out/share/applications
${lib.concatStringsSep "\n" (
lib.mapAttrsToList (
command: value:
let
opts =
if builtins.isAttrs value then
value
else
{
executable = value;
desktop = null;
profile = null;
extraArgs = [ ];
};
args = lib.escapeShellArgs (
opts.extraArgs
++ (lib.optional (opts.profile != null) "--profile=${builtins.toString opts.profile}")
);
in
''
cat <<_EOF >$out/bin/${command}
#! ${pkgs.runtimeShell} -e
exec /run/wrappers/bin/firejail ${args} -- ${builtins.toString opts.executable} "\$@"
_EOF
chmod 0755 $out/bin/${command}
${lib.optionalString (opts.desktop != null) ''
substitute ${opts.desktop} $out/share/applications/$(basename ${opts.desktop}) \
--replace ${opts.executable} $out/bin/${command}
''}
''
) cfg.wrappedBinaries
)}
'';
in
{
options.programs.firejail = {
enable = lib.mkEnableOption "firejail, a sandboxing tool for Linux";
wrappedBinaries = lib.mkOption {
type = lib.types.attrsOf (
lib.types.either lib.types.path (
lib.types.submodule {
options = {
executable = lib.mkOption {
type = lib.types.path;
description = "Executable to run sandboxed";
example = lib.literalExpression ''"''${lib.getBin pkgs.firefox}/bin/firefox"'';
};
desktop = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ".desktop file to modify. Only necessary if it uses the absolute path to the executable.";
example = lib.literalExpression ''"''${pkgs.firefox}/share/applications/firefox.desktop"'';
};
profile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "Profile to use";
example = lib.literalExpression ''"''${pkgs.firejail}/etc/firejail/firefox.profile"'';
};
extraArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Extra arguments to pass to firejail";
example = [ "--private=~/.firejail_home" ];
};
};
}
)
);
default = { };
example = lib.literalExpression ''
{
firefox = {
executable = "''${lib.getBin pkgs.firefox}/bin/firefox";
profile = "''${pkgs.firejail}/etc/firejail/firefox.profile";
};
mpv = {
executable = "''${lib.getBin pkgs.mpv}/bin/mpv";
profile = "''${pkgs.firejail}/etc/firejail/mpv.profile";
};
}
'';
description = ''
Wrap the binaries in firejail and place them in the global path.
'';
};
};
config = lib.mkIf cfg.enable {
security.wrappers.firejail = {
setuid = true;
owner = "root";
group = "root";
source = "${lib.getBin pkgs.firejail}/bin/firejail";
};
environment.systemPackages = [ pkgs.firejail ] ++ [ wrappedBins ];
};
meta.maintainers = with lib.maintainers; [ peterhoeg ];
}

View File

@@ -0,0 +1,346 @@
{
config,
lib,
pkgs,
...
}:
let
cfge = config.environment;
cfg = config.programs.fish;
fishAbbrs = lib.concatStringsSep "\n" (
lib.mapAttrsToList (k: v: "abbr -a ${k} -- ${lib.escapeShellArg v}") cfg.shellAbbrs
);
fishAliases = lib.concatStringsSep "\n" (
lib.mapAttrsToList (k: v: "alias ${k} ${lib.escapeShellArg v}") (
lib.filterAttrs (k: v: v != null) cfg.shellAliases
)
);
envShellInit = pkgs.writeText "shellInit" cfge.shellInit;
envLoginShellInit = pkgs.writeText "loginShellInit" cfge.loginShellInit;
envInteractiveShellInit = pkgs.writeText "interactiveShellInit" cfge.interactiveShellInit;
sourceEnv =
file:
if cfg.useBabelfish then
"source /etc/fish/${file}.fish"
else
''
set fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d $fish_function_path
fenv source /etc/fish/foreign-env/${file} > /dev/null
set -e fish_function_path[1]
'';
babelfishTranslate =
path: name:
pkgs.runCommand "${name}.fish" {
preferLocalBuild = true;
nativeBuildInputs = [ pkgs.babelfish ];
} "babelfish < ${path} > $out;";
in
{
options = {
programs.fish = {
enable = lib.mkOption {
default = false;
description = ''
Whether to configure fish as an interactive shell.
'';
type = lib.types.bool;
};
package = lib.mkPackageOption pkgs "fish" { };
useBabelfish = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
If enabled, the configured environment will be translated to native fish using [babelfish](https://github.com/bouk/babelfish).
Otherwise, [foreign-env](https://github.com/oh-my-fish/plugin-foreign-env) will be used.
'';
};
generateCompletions = lib.mkEnableOption "generating completion files from man pages" // {
default = true;
example = false;
};
vendor.config.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether fish should source configuration snippets provided by other packages.
'';
};
vendor.completions.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether fish should use completion files provided by other packages.
'';
};
vendor.functions.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether fish should autoload fish functions provided by other packages.
'';
};
shellAbbrs = lib.mkOption {
default = { };
example = {
gco = "git checkout";
npu = "nix-prefetch-url";
};
description = ''
Set of fish abbreviations.
'';
type = with lib.types; attrsOf str;
};
shellAliases = lib.mkOption {
default = { };
description = ''
Set of aliases for fish shell, which overrides {option}`environment.shellAliases`.
See {option}`environment.shellAliases` for an option format description.
'';
type = with lib.types; attrsOf (nullOr (either str path));
};
shellInit = lib.mkOption {
default = "";
description = ''
Shell script code called during fish shell initialisation.
'';
type = lib.types.lines;
};
loginShellInit = lib.mkOption {
default = "";
description = ''
Shell script code called during fish login shell initialisation.
'';
type = lib.types.lines;
};
interactiveShellInit = lib.mkOption {
default = "";
description = ''
Shell script code called during interactive fish shell initialisation.
'';
type = lib.types.lines;
};
promptInit = lib.mkOption {
default = "";
description = ''
Shell script code used to initialise fish prompt.
'';
type = lib.types.lines;
};
};
};
config = lib.mkIf cfg.enable {
programs.fish.shellAliases = lib.mapAttrs (name: lib.mkDefault) cfge.shellAliases;
# Required for man completions
documentation.man.generateCaches = lib.mkDefault true;
environment = lib.mkMerge [
(lib.mkIf cfg.useBabelfish {
etc."fish/setEnvironment.fish".source =
babelfishTranslate config.system.build.setEnvironment "setEnvironment";
etc."fish/shellInit.fish".source = babelfishTranslate envShellInit "shellInit";
etc."fish/loginShellInit.fish".source = babelfishTranslate envLoginShellInit "loginShellInit";
etc."fish/interactiveShellInit.fish".source =
babelfishTranslate envInteractiveShellInit "interactiveShellInit";
})
(lib.mkIf (!cfg.useBabelfish) {
etc."fish/foreign-env/shellInit".source = envShellInit;
etc."fish/foreign-env/loginShellInit".source = envLoginShellInit;
etc."fish/foreign-env/interactiveShellInit".source = envInteractiveShellInit;
})
{
etc."fish/nixos-env-preinit.fish".text =
if cfg.useBabelfish then
''
# source the NixOS environment config
if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]
source /etc/fish/setEnvironment.fish
end
''
else
''
# This happens before $__fish_datadir/config.fish sets fish_function_path, so it is currently
# unset. We set it and then completely erase it, leaving its configuration to $__fish_datadir/config.fish
set fish_function_path ${pkgs.fishPlugins.foreign-env}/share/fish/vendor_functions.d $__fish_datadir/functions
# source the NixOS environment config
if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]
fenv source ${config.system.build.setEnvironment}
end
# clear fish_function_path so that it will be correctly set when we return to $__fish_datadir/config.fish
set -e fish_function_path
'';
}
{
etc."fish/config.fish".text = ''
# /etc/fish/config.fish: DO NOT EDIT -- this file has been generated automatically.
# if we haven't sourced the general config, do it
if not set -q __fish_nixos_general_config_sourced
${sourceEnv "shellInit"}
${cfg.shellInit}
# and leave a note so we don't source this config section again from
# this very shell (children will source the general config anew)
set -g __fish_nixos_general_config_sourced 1
end
# if we haven't sourced the login config, do it
status is-login; and not set -q __fish_nixos_login_config_sourced
and begin
${sourceEnv "loginShellInit"}
${cfg.loginShellInit}
# and leave a note so we don't source this config section again from
# this very shell (children will source the general config anew)
set -g __fish_nixos_login_config_sourced 1
end
# if we haven't sourced the interactive config, do it
status is-interactive; and not set -q __fish_nixos_interactive_config_sourced
and begin
${fishAbbrs}
${fishAliases}
${sourceEnv "interactiveShellInit"}
${cfg.promptInit}
${cfg.interactiveShellInit}
# and leave a note so we don't source this config section again from
# this very shell (children will source the general config anew,
# allowing configuration changes in, e.g, aliases, to propagate)
set -g __fish_nixos_interactive_config_sourced 1
end
'';
}
(lib.mkIf cfg.generateCompletions {
etc."fish/generated_completions".source =
let
patchedGenerator = pkgs.stdenv.mkDerivation {
name = "fish_patched-completion-generator";
srcs = [
"${cfg.package}/share/fish/tools/create_manpage_completions.py"
"${cfg.package}/share/fish/tools/deroff.py"
];
unpackCmd = "cp $curSrc $(basename $curSrc)";
sourceRoot = ".";
patches = [ ./fish_completion-generator.patch ]; # to prevent collisions of identical completion files
dontBuild = true;
installPhase = ''
mkdir -p $out
cp * $out/
'';
preferLocalBuild = true;
allowSubstitutes = false;
};
generateCompletions =
package:
pkgs.runCommand
(
with lib.strings;
let
storeLength = stringLength storeDir + 34; # Nix' StorePath::HashLen + 2 for the separating slash and dash
pathName = substring storeLength (stringLength package - storeLength) package;
in
(package.name or pathName) + "_fish-completions"
)
(
{
inherit package;
preferLocalBuild = true;
}
// lib.optionalAttrs (package ? meta.priority) { meta.priority = package.meta.priority; }
)
''
mkdir -p $out
if [ -d $package/share/man ]; then
find -L $package/share/man -type f | xargs ${pkgs.python3.pythonOnBuildForHost.interpreter} ${patchedGenerator}/create_manpage_completions.py --directory $out >/dev/null
fi
'';
in
pkgs.buildEnv {
name = "system_fish-completions";
ignoreCollisions = true;
paths = builtins.map generateCompletions config.environment.systemPackages;
};
})
# include programs that bring their own completions
{
pathsToLink =
[ ]
++ lib.optional cfg.vendor.config.enable "/share/fish/vendor_conf.d"
++ lib.optional cfg.vendor.completions.enable "/share/fish/vendor_completions.d"
++ lib.optional cfg.vendor.functions.enable "/share/fish/vendor_functions.d";
}
{ systemPackages = [ cfg.package ]; }
{
shells = [
"/run/current-system/sw/bin/fish"
(lib.getExe cfg.package)
];
}
];
programs.fish.interactiveShellInit =
lib.optionalString cfg.generateCompletions ''
# add completions generated by NixOS to $fish_complete_path
begin
# joins with null byte to accommodate all characters in paths, then respectively gets all paths before (exclusive) / after (inclusive) the first one including "generated_completions",
# splits by null byte, and then removes all empty lines produced by using 'string'
set -l prev (string join0 $fish_complete_path | string match --regex "^.*?(?=\x00[^\x00]*generated_completions.*)" | string split0 | string match -er ".")
set -l post (string join0 $fish_complete_path | string match --regex "[^\x00]*generated_completions.*" | string split0 | string match -er ".")
set fish_complete_path $prev "/etc/fish/generated_completions" $post
end
''
+ ''
# prevent fish from generating completions on first run
if not test -d $__fish_user_data_dir/generated_completions
${pkgs.coreutils}/bin/mkdir $__fish_user_data_dir/generated_completions
end
'';
};
meta.maintainers = with lib.maintainers; [ sigmasquadron ];
}

View File

@@ -0,0 +1,14 @@
--- a/create_manpage_completions.py
+++ b/create_manpage_completions.py
@@ -879,10 +879,6 @@ def parse_manpage_at_path(manpage_path, output_directory):
)
return False
- # Output the magic word Autogenerated so we can tell if we can overwrite this
- built_command_output.insert(
- 0, "# " + CMDNAME + "\n# Autogenerated from man page " + manpage_path
- )
# built_command_output.insert(2, "# using " + parser.__class__.__name__) # XXX MISATTRIBUTES THE CULPABLE PARSER! Was really using Type2 but reporting TypeDeroffManParser
for line in built_command_output:

View File

@@ -0,0 +1,28 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.flashprog;
in
{
options.programs.flashprog = {
enable = lib.mkEnableOption ''
configuring flashprog udev rules and
installing flashprog as system package
'';
package = lib.mkPackageOption pkgs "flashprog" { };
};
config = lib.mkIf cfg.enable {
services.udev.packages = [ cfg.package ];
environment.systemPackages = [ cfg.package ];
hardware.libjaylink.enable = true;
hardware.libftdi.enable = true;
};
meta.maintainers = with lib.maintainers; [ felixsinger ];
}

View File

@@ -0,0 +1,29 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.flashrom;
in
{
options.programs.flashrom = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Installs flashrom and configures udev rules for programmers
used by flashrom. Grants access to users in the "flashrom"
group.
'';
};
package = lib.mkPackageOption pkgs "flashrom" { };
};
config = lib.mkIf cfg.enable {
services.udev.packages = [ cfg.package ];
environment.systemPackages = [ cfg.package ];
};
}

View File

@@ -0,0 +1,24 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.flexoptix-app;
in
{
options = {
programs.flexoptix-app = {
enable = lib.mkEnableOption "FLEXOPTIX app + udev rules";
package = lib.mkPackageOption pkgs "flexoptix-app" { };
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
services.udev.packages = [ cfg.package ];
};
}

View File

@@ -0,0 +1,27 @@
osc7_cwd() {
local strlen=${#PWD}
local encoded=""
local pos c o
for (( pos=0; pos<strlen; pos++ )); do
c=${PWD:$pos:1}
case "$c" in
[-/:_.!\'\(\)~[:alnum:]] ) o="${c}" ;;
* ) printf -v o '%%%02X' "'${c}" ;;
esac
encoded+="${o}"
done
printf '\e]7;file://%s%s\e\\' "${HOSTNAME}" "${encoded}"
}
PROMPT_COMMAND=${PROMPT_COMMAND:+${PROMPT_COMMAND%;}; }osc7_cwd
prompt_marker() {
printf '\e]133;A\e\\'
}
PROMPT_COMMAND=${PROMPT_COMMAND:+${PROMPT_COMMAND%;}; }prompt_marker
PS0+='\e]133;C\e\\'
command_done() {
printf '\e]133;D\e\\'
}
PROMPT_COMMAND=${PROMPT_COMMAND:+${PROMPT_COMMAND%;}; }command_done

View File

@@ -0,0 +1,20 @@
function update_cwd_osc --on-variable PWD --description 'Notify terminals when $PWD changes'
if status --is-command-substitution || set -q INSIDE_EMACS
return
end
printf \e\]7\;file://%s%s\e\\ $hostname (string escape --style=url $PWD)
end
update_cwd_osc # Run once since we might have inherited PWD from a parent shell
function mark_prompt_start --on-event fish_prompt
echo -en "\e]133;A\e\\"
end
function foot_cmd_start --on-event fish_preexec
echo -en "\e]133;C\e\\"
end
function foot_cmd_end --on-event fish_postexec
echo -en "\e]133;D\e\\"
end

View File

@@ -0,0 +1,92 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.foot;
settingsFormat = pkgs.formats.ini {
listsAsDuplicateKeys = true;
mkKeyValue =
with lib.generators;
mkKeyValueDefault {
mkValueString =
v:
mkValueStringDefault { } (
if v == true then
"yes"
else if v == false then
"no"
else if v == null then
"none"
else
v
);
} "=";
};
in
{
options.programs.foot = {
enable = lib.mkEnableOption "foot terminal emulator";
package = lib.mkPackageOption pkgs "foot" { };
settings = lib.mkOption {
inherit (settingsFormat) type;
default = { };
description = ''
Configuration for foot terminal emulator. Further information can be found in {command}`man 5 foot.ini`.
Global configuration has to be written under the [main] section.
'';
example = {
main.font = "FreeMono:size=12";
scrollback.lines = 100000;
};
};
theme = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Theme name. Check <https://codeberg.org/dnkl/foot/src/branch/master/themes> for available themes.
'';
example = "aeroroot";
};
enableBashIntegration = lib.mkEnableOption "foot bash integration" // {
default = true;
};
enableFishIntegration = lib.mkEnableOption "foot fish integration" // {
default = true;
};
enableZshIntegration = lib.mkEnableOption "foot zsh integration" // {
default = true;
};
};
config = lib.mkIf cfg.enable {
environment = {
systemPackages = [ cfg.package ];
etc."xdg/foot/foot.ini".source = settingsFormat.generate "foot.ini" cfg.settings;
};
programs = {
foot.settings.main.include = lib.optionals (cfg.theme != null) [
"${pkgs.foot.themes}/share/foot/themes/${cfg.theme}"
];
# https://codeberg.org/dnkl/foot/wiki#user-content-shell-integration
bash.interactiveShellInit = lib.mkIf cfg.enableBashIntegration ". ${./bashrc} # enable shell integration for foot terminal";
fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration "source ${./config.fish} # enable shell integration for foot terminal";
zsh.interactiveShellInit = lib.mkIf cfg.enableZshIntegration ". ${./zshrc} # enable shell integration for foot terminal";
};
};
meta = {
maintainers = with lib.maintainers; [ linsui ];
};
}

View File

@@ -0,0 +1,27 @@
function osc7-pwd() {
emulate -L zsh # also sets localoptions for us
setopt extendedglob
local LC_ALL=C
printf '\e]7;file://%s%s\e\' $HOST ${PWD//(#m)([^@-Za-z&-;_~])/%${(l:2::0:)$(([##16]#MATCH))}}
}
function chpwd-osc7-pwd() {
(( ZSH_SUBSHELL )) || osc7-pwd
}
precmd() {
print -Pn "\e]133;A\e\\"
}
function precmd {
if ! builtin zle; then
print -n "\e]133;D\e\\"
fi
}
function preexec {
print -n "\e]133;C\e\\"
}
autoload -U add-zsh-hook
add-zsh-hook -Uz chpwd chpwd-osc7-pwd

View File

@@ -0,0 +1,65 @@
# Global configuration for freetds environment.
{
config,
lib,
pkgs,
...
}:
let
cfg = config.environment.freetds;
in
{
###### interface
options = {
environment.freetds = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
default = { };
example = lib.literalExpression ''
{ MYDATABASE = '''
host = 10.0.2.100
port = 1433
tds version = 7.2
''';
}
'';
description = ''
Configure freetds database entries. Each attribute denotes
a section within freetds.conf, and the value (a string) is the config
content for that section. When at least one entry is configured
the global environment variables FREETDSCONF, FREETDS and SYBASE
will be configured to allow the programs that use freetds to find the
library and config.
'';
};
};
###### implementation
config = lib.mkIf (builtins.length (builtins.attrNames cfg) > 0) {
environment.variables.FREETDSCONF = "/etc/freetds.conf";
environment.variables.FREETDS = "/etc/freetds.conf";
environment.variables.SYBASE = "${pkgs.freetds}";
environment.etc."freetds.conf" = {
text = (
lib.concatStrings (
lib.mapAttrsToList (name: value: ''
[${name}]
${value}
'') cfg
)
);
};
};
}

View File

@@ -0,0 +1,65 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.fuse;
in
{
meta.maintainers = [ ];
options.programs.fuse = {
enable = lib.mkEnableOption "fuse" // {
default = true;
};
mountMax = lib.mkOption {
# In the C code it's an "int" (i.e. signed and at least 16 bit), but
# negative numbers obviously make no sense:
type = lib.types.ints.between 0 32767; # 2^15 - 1
default = 1000;
description = ''
Set the maximum number of FUSE mounts allowed to non-root users.
'';
};
userAllowOther = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Allow non-root users to specify the allow_other or allow_root mount
options, see mount.fuse3(8).
'';
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [
pkgs.fuse
pkgs.fuse3
];
security.wrappers =
let
mkSetuidRoot = source: {
setuid = true;
owner = "root";
group = "root";
inherit source;
};
in
{
fusermount = mkSetuidRoot "${lib.getBin pkgs.fuse}/bin/fusermount";
fusermount3 = mkSetuidRoot "${lib.getBin pkgs.fuse3}/bin/fusermount3";
};
environment.etc."fuse.conf".text = ''
${lib.optionalString (!cfg.userAllowOther) "#"}user_allow_other
mount_max = ${builtins.toString cfg.mountMax}
'';
};
}

View File

@@ -0,0 +1,53 @@
{
pkgs,
config,
lib,
...
}:
let
cfg = config.programs.fzf;
in
{
options = {
programs.fzf = {
fuzzyCompletion = lib.mkEnableOption "fuzzy completion with fzf";
keybindings = lib.mkEnableOption "fzf keybindings";
};
};
config = lib.mkIf (cfg.keybindings || cfg.fuzzyCompletion) {
environment.systemPackages = [ pkgs.fzf ];
programs = {
# load after programs.bash.completion.enable
bash.promptPluginInit = lib.mkAfter (
lib.optionalString cfg.fuzzyCompletion ''
source ${pkgs.fzf}/share/fzf/completion.bash
''
+ lib.optionalString cfg.keybindings ''
source ${pkgs.fzf}/share/fzf/key-bindings.bash
''
);
zsh = {
interactiveShellInit = lib.optionalString (!config.programs.zsh.ohMyZsh.enable) (
lib.optionalString cfg.fuzzyCompletion ''
source ${pkgs.fzf}/share/fzf/completion.zsh
''
+ lib.optionalString cfg.keybindings ''
source ${pkgs.fzf}/share/fzf/key-bindings.zsh
''
);
ohMyZsh.plugins = lib.mkIf config.programs.zsh.ohMyZsh.enable [ "fzf" ];
};
fish.interactiveShellInit = lib.optionalString cfg.keybindings ''
source ${pkgs.fzf}/share/fzf/key-bindings.fish && fzf_key_bindings
'';
};
};
meta.maintainers = with lib.maintainers; [ laalsaas ];
}

View File

@@ -0,0 +1,107 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.gamemode;
settingsFormat = pkgs.formats.ini { listsAsDuplicateKeys = true; };
configFile = settingsFormat.generate "gamemode.ini" cfg.settings;
in
{
options = {
programs.gamemode = {
enable = lib.mkEnableOption "GameMode to optimise system performance on demand";
enableRenice =
lib.mkEnableOption "CAP_SYS_NICE on gamemoded to support lowering process niceness"
// {
default = true;
};
settings = lib.mkOption {
type = settingsFormat.type;
default = { };
description = ''
System-wide configuration for GameMode (/etc/gamemode.ini).
See {manpage}`gamemoded(8)` man page for available settings.
'';
example = lib.literalExpression ''
{
general = {
renice = 10;
};
# Warning: GPU optimisations have the potential to damage hardware
gpu = {
apply_gpu_optimisations = "accept-responsibility";
gpu_device = 0;
amd_performance_level = "high";
};
custom = {
start = "''${pkgs.libnotify}/bin/notify-send 'GameMode started'";
end = "''${pkgs.libnotify}/bin/notify-send 'GameMode ended'";
};
}
'';
};
};
};
config = lib.mkIf cfg.enable {
environment = {
systemPackages = [ pkgs.gamemode ];
etc."gamemode.ini".source = configFile;
};
security = {
polkit.enable = true;
wrappers = lib.mkIf cfg.enableRenice {
gamemoded = {
owner = "root";
group = "root";
source = "${pkgs.gamemode}/bin/gamemoded";
capabilities = "cap_sys_nice+ep";
};
};
};
systemd = {
packages = [ pkgs.gamemode ];
user.services.gamemoded = {
# The upstream service already defines this, but doesn't get applied.
# See https://github.com/NixOS/nixpkgs/issues/81138
wantedBy = [ "default.target" ];
# Use pkexec from the security wrappers to allow users to
# run libexec/cpugovctl & libexec/gpuclockctl as root with
# the the actions defined in share/polkit-1/actions.
#
# This uses a link farm to make sure other wrapped executables
# aren't included in PATH.
environment.PATH = lib.mkForce (
pkgs.linkFarm "pkexec" [
{
name = "pkexec";
path = "${config.security.wrapperDir}/pkexec";
}
]
);
serviceConfig.ExecStart = lib.mkIf cfg.enableRenice [
"" # Tell systemd to clear the existing ExecStart list, to prevent appending to it.
"${config.security.wrapperDir}/gamemoded"
];
};
};
users.groups.gamemode = { };
};
meta = {
maintainers = with lib.maintainers; [ kira-bruneau ];
};
}

View File

@@ -0,0 +1,82 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.gamescope;
gamescope =
let
wrapperArgs =
lib.optional (cfg.args != [ ]) ''--add-flags "${builtins.toString cfg.args}"''
++ builtins.attrValues (builtins.mapAttrs (var: val: "--set-default ${var} ${val}") cfg.env);
in
pkgs.runCommand "gamescope" { nativeBuildInputs = [ pkgs.makeBinaryWrapper ]; } ''
mkdir -p $out/bin
makeWrapper ${cfg.package}/bin/gamescope $out/bin/gamescope --inherit-argv0 \
${builtins.toString wrapperArgs}
ln -s ${cfg.package}/bin/gamescopectl $out/bin/gamescopectl
'';
in
{
options.programs.gamescope = {
enable = lib.mkEnableOption "gamescope, the SteamOS session compositing window manager";
package = lib.mkPackageOption pkgs "gamescope" { };
capSysNice = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Add cap_sys_nice capability to the GameScope
binary so that it may renice itself.
'';
};
args = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [
"--rt"
"--prefer-vk-device 8086:9bc4"
];
description = ''
Arguments passed to GameScope on startup.
'';
};
env = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
default = { };
example = lib.literalExpression ''
# for Prime render offload on Nvidia laptops.
# Also requires `hardware.nvidia.prime.offload.enable`.
{
__NV_PRIME_RENDER_OFFLOAD = "1";
__VK_LAYER_NV_optimus = "NVIDIA_only";
__GLX_VENDOR_LIBRARY_NAME = "nvidia";
}
'';
description = ''
Default environment variables available to the GameScope process, overridable at runtime.
'';
};
};
config = lib.mkIf cfg.enable {
security.wrappers = lib.mkIf cfg.capSysNice {
gamescope = {
owner = "root";
group = "root";
source = "${gamescope}/bin/gamescope";
capabilities = "cap_sys_nice+pie";
};
};
environment.systemPackages = lib.mkIf (!cfg.capSysNice) [ gamescope ];
};
meta.maintainers = [ ];
}

View File

@@ -0,0 +1,37 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.gdk-pixbuf;
loadersCache = pkgs.gnome._gdkPixbufCacheBuilder_DO_NOT_USE {
extraLoaders = lib.unique cfg.modulePackages;
};
in
{
imports = [
(lib.mkRenamedOptionModule [ "services" "xserver" "gdk-pixbuf" ] [ "programs" "gdk-pixbuf" ])
];
options = {
programs.gdk-pixbuf.modulePackages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
description = "Packages providing GDK-Pixbuf modules, for cache generation.";
};
};
# If there is any package configured in modulePackages, we generate the
# loaders.cache based on that and set the environment variable
# GDK_PIXBUF_MODULE_FILE to point to it.
config = lib.mkIf (cfg.modulePackages != [ ]) {
environment.sessionVariables = {
GDK_PIXBUF_MODULE_FILE = loadersCache;
};
};
}

View File

@@ -0,0 +1,27 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.geary;
in
{
meta = {
maintainers = lib.teams.gnome.members;
};
options = {
programs.geary.enable = lib.mkEnableOption "Geary, a Mail client for GNOME";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.geary ];
programs.dconf.enable = true;
services.gnome.gnome-keyring.enable = true;
services.gnome.gnome-online-accounts.enable = true;
};
}

View File

@@ -0,0 +1,47 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.ghidra;
in
{
options.programs.ghidra = {
enable = lib.mkEnableOption "Ghidra, a software reverse engineering (SRE) suite of tools";
gdb = lib.mkOption {
default = true;
type = lib.types.bool;
description = ''
Whether to add to gdbinit the python modules required to make Ghidra's debugger work.
'';
};
package = lib.mkPackageOption pkgs "ghidra" { example = "ghidra-bin"; };
};
config = lib.mkIf cfg.enable {
environment = {
systemPackages = [ cfg.package ];
etc = lib.mkIf cfg.gdb {
"gdb/gdbinit.d/ghidra-modules.gdb".text = with pkgs.python3.pkgs; ''
python
import sys
[sys.path.append(p) for p in "${
(makePythonPath [
psutil
protobuf
])
}".split(":")]
end
'';
};
};
};
meta.maintainers = with lib.maintainers; [ govanify ];
}

View File

@@ -0,0 +1,41 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.git-worktree-switcher;
initScript =
shell:
if (shell == "fish") then
''
${lib.getExe cfg.package} init ${shell} | source
''
else
''
eval "$(${lib.getExe cfg.package} init ${shell})"
'';
in
{
options = {
programs.git-worktree-switcher = {
enable = lib.mkEnableOption "git-worktree-switcher, switch between git worktrees with speed.";
package = lib.mkPackageOption pkgs "git-worktree-switcher" { };
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [ git-worktree-switcher ];
programs.bash.interactiveShellInit = initScript "bash";
programs.zsh.interactiveShellInit = lib.optionalString config.programs.zsh.enable (
initScript "zsh"
);
programs.fish.interactiveShellInit = lib.optionalString config.programs.fish.enable (
initScript "fish"
);
};
}

View File

@@ -0,0 +1,119 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.git;
in
{
options = {
programs.git = {
enable = lib.mkEnableOption "git, a distributed version control system";
package = lib.mkPackageOption pkgs "git" {
example = "gitFull";
};
config = lib.mkOption {
type =
with lib.types;
let
gitini = attrsOf (attrsOf anything);
in
either gitini (listOf gitini)
// {
merge =
loc: defs:
let
config =
builtins.foldl'
(
acc:
{ value, ... }@x:
acc
// (
if builtins.isList value then
{
ordered = acc.ordered ++ value;
}
else
{
unordered = acc.unordered ++ [ x ];
}
)
)
{
ordered = [ ];
unordered = [ ];
}
defs;
in
[ (gitini.merge loc config.unordered) ] ++ config.ordered;
};
default = [ ];
example = {
init.defaultBranch = "main";
url."https://github.com/".insteadOf = [
"gh:"
"github:"
];
};
description = ''
Configuration to write to /etc/gitconfig. A list can also be
specified to keep the configuration in order. For example, setting
`config` to `[ { foo.x = 42; } { bar.y = 42; }]` will put the `foo`
section before the `bar` section unlike the default alphabetical
order, which can be helpful for sections such as `include` and
`includeIf`. See the CONFIGURATION FILE section of {manpage}`git-config(1)` for
more information.
'';
};
prompt = {
enable = lib.mkEnableOption "automatically sourcing git-prompt.sh. This does not change $PS1; it simply provides relevant utility functions";
};
lfs = {
enable = lib.mkEnableOption "git-lfs (Large File Storage)";
package = lib.mkPackageOption pkgs "git-lfs" { };
enablePureSSHTransfer = lib.mkEnableOption "Enable pure SSH transfer in server side by adding git-lfs-transfer to environment.systemPackages";
};
};
};
config = lib.mkMerge [
(lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
environment.etc.gitconfig = lib.mkIf (cfg.config != [ ]) {
text = lib.concatMapStringsSep "\n" lib.generators.toGitINI cfg.config;
};
})
(lib.mkIf (cfg.enable && cfg.lfs.enable) {
environment.systemPackages = lib.mkMerge [
[ cfg.lfs.package ]
(lib.mkIf cfg.lfs.enablePureSSHTransfer [ pkgs.git-lfs-transfer ])
];
programs.git.config = {
filter.lfs = {
clean = "git-lfs clean -- %f";
smudge = "git-lfs smudge -- %f";
process = "git-lfs filter-process";
required = true;
};
};
})
(lib.mkIf (cfg.enable && cfg.prompt.enable) {
environment.interactiveShellInit = ''
source ${cfg.package}/share/bash-completion/completions/git-prompt.sh
'';
})
];
meta.maintainers = with lib.maintainers; [ figsoda ];
}

View File

@@ -0,0 +1,45 @@
# GNOME Disks.
{
config,
pkgs,
lib,
...
}:
{
meta = {
maintainers = lib.teams.gnome.members;
};
###### interface
options = {
programs.gnome-disks = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable GNOME Disks daemon, a program designed to
be a UDisks2 graphical front-end.
'';
};
};
};
###### implementation
config = lib.mkIf config.programs.gnome-disks.enable {
environment.systemPackages = [ pkgs.gnome-disk-utility ];
services.dbus.packages = [ pkgs.gnome-disk-utility ];
};
}

View File

@@ -0,0 +1,34 @@
# GNOME Terminal.
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.gnome-terminal;
in
{
meta = {
maintainers = lib.teams.gnome.members;
};
options = {
programs.gnome-terminal.enable = lib.mkEnableOption "GNOME Terminal";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.gnome-terminal ];
services.dbus.packages = [ pkgs.gnome-terminal ];
systemd.packages = [ pkgs.gnome-terminal ];
programs.bash.vteIntegration = true;
programs.zsh.vteIntegration = true;
};
}

View File

@@ -0,0 +1,242 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
mkRemovedOptionModule
mkOption
mkPackageOption
types
mkIf
optionalString
;
cfg = config.programs.gnupg;
agentSettingsFormat = pkgs.formats.keyValue {
mkKeyValue = lib.generators.mkKeyValueDefault { } " ";
};
in
{
imports = [
(mkRemovedOptionModule [
"programs"
"gnupg"
"agent"
"pinentryFlavor"
] "Use programs.gnupg.agent.pinentryPackage instead")
];
options.programs.gnupg = {
package = mkPackageOption pkgs "gnupg" { };
agent.enable = mkOption {
type = types.bool;
default = false;
description = ''
Enables GnuPG agent with socket-activation for every user session.
'';
};
agent.enableSSHSupport = mkOption {
type = types.bool;
default = false;
description = ''
Enable SSH agent support in GnuPG agent. Also sets SSH_AUTH_SOCK
environment variable correctly. This will disable socket-activation
and thus always start a GnuPG agent per user session.
'';
};
agent.enableExtraSocket = mkOption {
type = types.bool;
default = false;
description = ''
Enable extra socket for GnuPG agent.
'';
};
agent.enableBrowserSocket = mkOption {
type = types.bool;
default = false;
description = ''
Enable browser socket for GnuPG agent.
'';
};
agent.pinentryPackage = mkOption {
type = types.nullOr types.package;
example = lib.literalMD "pkgs.pinentry-gnome3";
default = pkgs.pinentry-curses;
defaultText = lib.literalMD "matching the configured desktop environment or `pkgs.pinentry-curses`";
description = ''
Which pinentry package to use. The path to the mainProgram as defined in
the package's meta attributes will be set in /etc/gnupg/gpg-agent.conf.
If not set by the user, it'll pick an appropriate flavor depending on the
system configuration (qt flavor for lxqt and plasma, gtk2 for xfce,
gnome3 on all other systems with X enabled, curses otherwise).
'';
};
agent.settings = mkOption {
type = agentSettingsFormat.type;
default = { };
example = {
default-cache-ttl = 600;
};
description = ''
Configuration for /etc/gnupg/gpg-agent.conf.
See {manpage}`gpg-agent(1)` for supported options.
'';
};
dirmngr.enable = mkOption {
type = types.bool;
default = false;
description = ''
Enables GnuPG network certificate management daemon with socket-activation for every user session.
'';
};
};
config = mkIf cfg.agent.enable {
programs.gnupg.agent.settings = mkIf (cfg.agent.pinentryPackage != null) {
pinentry-program = lib.getExe cfg.agent.pinentryPackage;
};
environment.etc."gnupg/gpg-agent.conf".source =
agentSettingsFormat.generate "gpg-agent.conf" cfg.agent.settings;
# This overrides the systemd user unit shipped with the gnupg package
systemd.user.services.gpg-agent = {
unitConfig = {
Description = "GnuPG cryptographic agent and passphrase cache";
Documentation = "man:gpg-agent(1)";
Requires = [ "sockets.target" ];
};
serviceConfig = {
ExecStart = "${cfg.package}/bin/gpg-agent --supervised";
ExecReload = "${cfg.package}/bin/gpgconf --reload gpg-agent";
};
};
systemd.user.sockets.gpg-agent = {
unitConfig = {
Description = "GnuPG cryptographic agent and passphrase cache";
Documentation = "man:gpg-agent(1)";
};
socketConfig = {
ListenStream = "%t/gnupg/S.gpg-agent";
FileDescriptorName = "std";
SocketMode = "0600";
DirectoryMode = "0700";
};
wantedBy = [ "sockets.target" ];
};
systemd.user.sockets.gpg-agent-ssh = mkIf cfg.agent.enableSSHSupport {
unitConfig = {
Description = "GnuPG cryptographic agent (ssh-agent emulation)";
Documentation = "man:gpg-agent(1) man:ssh-add(1) man:ssh-agent(1) man:ssh(1)";
};
socketConfig = {
ListenStream = "%t/gnupg/S.gpg-agent.ssh";
FileDescriptorName = "ssh";
Service = "gpg-agent.service";
SocketMode = "0600";
DirectoryMode = "0700";
};
wantedBy = [ "sockets.target" ];
};
systemd.user.sockets.gpg-agent-extra = mkIf cfg.agent.enableExtraSocket {
unitConfig = {
Description = "GnuPG cryptographic agent and passphrase cache (restricted)";
Documentation = "man:gpg-agent(1)";
};
socketConfig = {
ListenStream = "%t/gnupg/S.gpg-agent.extra";
FileDescriptorName = "extra";
Service = "gpg-agent.service";
SocketMode = "0600";
DirectoryMode = "0700";
};
wantedBy = [ "sockets.target" ];
};
systemd.user.sockets.gpg-agent-browser = mkIf cfg.agent.enableBrowserSocket {
unitConfig = {
Description = "GnuPG cryptographic agent and passphrase cache (access for web browsers)";
Documentation = "man:gpg-agent(1)";
};
socketConfig = {
ListenStream = "%t/gnupg/S.gpg-agent.browser";
FileDescriptorName = "browser";
Service = "gpg-agent.service";
SocketMode = "0600";
DirectoryMode = "0700";
};
wantedBy = [ "sockets.target" ];
};
systemd.user.services.dirmngr = mkIf cfg.dirmngr.enable {
unitConfig = {
Description = "GnuPG network certificate management daemon";
Documentation = "man:dirmngr(8)";
Requires = "dirmngr.socket";
};
serviceConfig = {
ExecStart = "${cfg.package}/bin/dirmngr --supervised";
ExecReload = "${cfg.package}/bin/gpgconf --reload dirmngr";
};
};
systemd.user.sockets.dirmngr = mkIf cfg.dirmngr.enable {
unitConfig = {
Description = "GnuPG network certificate management daemon";
Documentation = "man:dirmngr(8)";
};
socketConfig = {
ListenStream = "%t/gnupg/S.dirmngr";
SocketMode = "0600";
DirectoryMode = "0700";
};
wantedBy = [ "sockets.target" ];
};
services.dbus.packages = mkIf (lib.elem "gnome3" (cfg.agent.pinentryPackage.flavors or [ ])) [
pkgs.gcr
];
environment.systemPackages = [ cfg.package ];
environment.interactiveShellInit = ''
# Bind gpg-agent to this TTY if gpg commands are used.
export GPG_TTY=$(tty)
'';
programs.ssh.extraConfig = optionalString cfg.agent.enableSSHSupport ''
# The SSH agent protocol doesn't have support for changing TTYs; however we
# can simulate this with the `exec` feature of openssh (see ssh_config(5))
# that hooks a command to the shell currently running the ssh program.
Match host * exec "${pkgs.runtimeShell} -c '${cfg.package}/bin/gpg-connect-agent --quiet updatestartuptty /bye >/dev/null 2>&1'"
'';
environment.extraInit = mkIf cfg.agent.enableSSHSupport ''
if [ -z "$SSH_AUTH_SOCK" ]; then
export SSH_AUTH_SOCK=$(${cfg.package}/bin/gpgconf --list-dirs agent-ssh-socket)
fi
'';
assertions = [
{
assertion = cfg.agent.enableSSHSupport -> !config.programs.ssh.startAgent;
message = "You can't use ssh-agent and GnuPG agent with SSH support enabled at the same time!";
}
];
};
}

View File

@@ -0,0 +1,34 @@
# GPaste.
{
config,
lib,
pkgs,
...
}:
{
###### interface
options = {
programs.gpaste = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable GPaste, a clipboard manager.
'';
};
};
};
###### implementation
config = lib.mkIf config.programs.gpaste.enable {
environment.systemPackages = [ pkgs.gpaste ];
services.dbus.packages = [ pkgs.gpaste ];
systemd.packages = [ pkgs.gpaste ];
# gnome-control-center crashes in Keyboard Shortcuts pane without the GSettings schemas.
services.desktopManager.gnome.sessionPath = [ pkgs.gpaste ];
# gpaste-reloaded applet doesn't work without the typelib
services.xserver.desktopManager.cinnamon.sessionPath = [ pkgs.gpaste ];
};
}

View File

@@ -0,0 +1,33 @@
{
config,
lib,
pkgs,
...
}:
{
meta.maintainers = [ lib.maintainers.league ];
###### interface
options = {
programs.gphoto2 = {
enable = lib.mkOption {
default = false;
type = lib.types.bool;
description = ''
Whether to configure system to use gphoto2.
To grant digital camera access to a user, the user must
be part of the camera group:
`users.users.alice.extraGroups = ["camera"];`
'';
};
};
};
###### implementation
config = lib.mkIf config.programs.gphoto2.enable {
services.udev.packages = [ pkgs.libgphoto2 ];
environment.systemPackages = [ pkgs.gphoto2 ];
users.groups.camera = { };
};
}

View File

@@ -0,0 +1,40 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.gpu-screen-recorder;
package = cfg.package.override {
inherit (config.security) wrapperDir;
};
in
{
options = {
programs.gpu-screen-recorder = {
package = lib.mkPackageOption pkgs "gpu-screen-recorder" { };
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to install gpu-screen-recorder and generate setcap
wrappers for promptless recording.
'';
};
};
};
config = lib.mkIf cfg.enable {
security.wrappers."gsr-kms-server" = {
owner = "root";
group = "root";
capabilities = "cap_sys_admin+ep";
source = lib.getExe' package "gsr-kms-server";
};
};
meta.maintainers = with lib.maintainers; [ timschumi ];
}

View File

@@ -0,0 +1,18 @@
{
lib,
pkgs,
config,
...
}:
{
options.programs.haguichi = {
enable = lib.mkEnableOption "Haguichi, a Linux GUI frontend to the proprietary LogMeIn Hamachi";
};
config = lib.mkIf config.programs.haguichi.enable {
environment.systemPackages = with pkgs; [ haguichi ];
services.logmein-hamachi.enable = true;
};
}

View File

@@ -0,0 +1,17 @@
{
config,
lib,
pkgs,
...
}:
{
meta.maintainers = pkgs.hamster.meta.maintainers;
options.programs.hamster.enable = lib.mkEnableOption "hamster, a time tracking program";
config = lib.mkIf config.programs.hamster.enable {
environment.systemPackages = [ pkgs.hamster ];
services.dbus.packages = [ pkgs.hamster ];
};
}

View File

@@ -0,0 +1,75 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.htop;
fmt =
value:
if builtins.isList value then
builtins.concatStringsSep " " (builtins.map fmt value)
else if builtins.isString value then
value
else if builtins.isBool value then
if value then "1" else "0"
else if builtins.isInt value then
builtins.toString value
else
throw "Unrecognized type ${builtins.typeOf value} in htop settings";
in
{
options.programs.htop = {
package = lib.mkPackageOption pkgs "htop" { };
enable = lib.mkEnableOption "htop process monitor";
settings = lib.mkOption {
type =
with lib.types;
attrsOf (oneOf [
str
int
bool
(listOf (oneOf [
str
int
bool
]))
]);
default = { };
example = {
hide_kernel_threads = true;
hide_userland_threads = true;
};
description = ''
Extra global default configuration for htop
which is read on first startup only.
Htop subsequently uses ~/.config/htop/htoprc
as configuration source.
'';
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [
cfg.package
];
environment.etc."htoprc".text = ''
# Global htop configuration
# To change set: programs.htop.settings.KEY = VALUE;
''
+ builtins.concatStringsSep "\n" (
lib.mapAttrsToList (key: value: "${key}=${fmt value}") cfg.settings
);
};
}

View File

@@ -0,0 +1,58 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.i3lock;
in
{
###### interface
options = {
programs.i3lock = {
enable = lib.mkEnableOption "i3lock";
package = lib.mkPackageOption pkgs "i3lock" {
example = "i3lock-color";
extraDescription = ''
::: {.note}
The i3lock package must include a i3lock file or link in its out directory in order for the u2fSupport option to work correctly.
:::
'';
};
u2fSupport = lib.mkOption {
type = lib.types.bool;
default = false;
example = true;
description = ''
Whether to enable U2F support in the i3lock program.
U2F enables authentication using a hardware device, such as a security key.
When U2F support is enabled, the i3lock program will set the setuid bit on the i3lock binary and enable the pam u2fAuth service,
'';
};
};
};
###### implementation
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
security.wrappers.i3lock = lib.mkIf cfg.u2fSupport {
setuid = true;
owner = "root";
group = "root";
source = "${cfg.package.out}/bin/i3lock";
};
security.pam.services.i3lock.u2fAuth = cfg.u2fSupport;
};
}

View File

@@ -0,0 +1,50 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.iay;
inherit (lib)
mkEnableOption
mkIf
mkOption
mkPackageOption
optionalString
types
;
in
{
options.programs.iay = {
enable = mkEnableOption "iay, a minimalistic shell prompt";
package = mkPackageOption pkgs "iay" { };
minimalPrompt = mkOption {
type = types.bool;
default = false;
description = "Use minimal one-liner prompt.";
};
};
config = mkIf cfg.enable {
programs.bash.promptInit = ''
if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then
PS1='$(iay ${optionalString cfg.minimalPrompt "-m"})'
fi
'';
programs.zsh.promptInit = ''
if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then
autoload -Uz add-zsh-hook
_iay_prompt() {
PROMPT="$(iay -z ${optionalString cfg.minimalPrompt "-m"})"
}
add-zsh-hook precmd _iay_prompt
fi
'';
};
meta.maintainers = pkgs.iay.meta.maintainers;
}

View File

@@ -0,0 +1,24 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.iftop;
in
{
options = {
programs.iftop.enable = lib.mkEnableOption "iftop and setcap wrapper for it";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.iftop ];
security.wrappers.iftop = {
owner = "root";
group = "root";
capabilities = "cap_net_raw+p";
source = lib.getExe pkgs.iftop;
};
};
}

View File

@@ -0,0 +1,24 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.iio-hyprland;
in
{
options = {
programs.iio-hyprland = {
enable = lib.mkEnableOption "iio-hyprland and iio-sensor-proxy";
package = lib.mkPackageOption pkgs "iio-hyprland" { };
};
};
config = lib.mkIf cfg.enable {
hardware.sensor.iio.enable = lib.mkDefault true;
environment.systemPackages = [ cfg.package ];
};
meta.maintainers = with lib.maintainers; [ yusuf-duran ];
}

View File

@@ -0,0 +1,49 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.immersed;
in
{
imports = [
(lib.mkRenamedOptionModule
[
"programs"
"immersed-vr"
]
[
"programs"
"immersed"
]
)
];
options = {
programs.immersed = {
enable = lib.mkEnableOption "immersed";
package = lib.mkPackageOption pkgs "immersed" { };
};
};
config = lib.mkIf cfg.enable {
boot = {
kernelModules = [
"v4l2loopback"
"snd-aloop"
];
extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ];
extraModprobeConfig = ''
options v4l2loopback exclusive_caps=1 card_label="v4l2loopback Virtual Camera"
'';
};
environment.systemPackages = [ cfg.package ];
};
meta.maintainers = pkgs.immersed.meta.maintainers;
}

View File

@@ -0,0 +1,26 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.iotop;
in
{
options = {
programs.iotop = {
enable = lib.mkEnableOption "iotop + setcap wrapper";
package = lib.mkPackageOption pkgs "iotop" { example = "iotop-c"; };
};
};
config = lib.mkIf cfg.enable {
security.wrappers.iotop = {
owner = "root";
group = "root";
capabilities = "cap_net_admin+p";
source = lib.getExe cfg.package;
};
};
}

View File

@@ -0,0 +1,75 @@
# This module provides JAVA_HOME, with a different way to install java
# system-wide.
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.java;
in
{
options = {
programs.java = {
enable = lib.mkEnableOption "java" // {
description = ''
Install and setup the Java development kit.
::: {.note}
This adds JAVA_HOME to the global environment, by sourcing the
jdk's setup-hook on shell init. It is equivalent to starting a shell
through 'nix-shell -p jdk', or roughly the following system-wide
configuration:
environment.variables.JAVA_HOME = ''${pkgs.jdk.home}/lib/openjdk;
environment.systemPackages = [ pkgs.jdk ];
:::
'';
};
package = lib.mkPackageOption pkgs "jdk" { example = "jre"; };
binfmt = lib.mkEnableOption "binfmt to execute java jar's and classes";
};
};
config = lib.mkIf cfg.enable {
boot.binfmt.registrations = lib.mkIf cfg.binfmt {
java-class = {
recognitionType = "extension";
magicOrExtension = "class";
interpreter = pkgs.writeShellScript "java-class-wrapper" ''
test -e ${cfg.package}/nix-support/setup-hook && source ${cfg.package}/nix-support/setup-hook
classpath=$(dirname "$1")
class=$(basename "''${1%%.class}")
$JAVA_HOME/bin/java -classpath "$classpath" "$class" "''${@:2}"
'';
};
java-jar = {
recognitionType = "extension";
magicOrExtension = "jar";
interpreter = pkgs.writeShellScript "java-jar-wrapper" ''
test -e ${cfg.package}/nix-support/setup-hook && source ${cfg.package}/nix-support/setup-hook
$JAVA_HOME/bin/java -jar "$@"
'';
};
};
environment.systemPackages = [ cfg.package ];
environment.shellInit = ''
test -e ${cfg.package}/nix-support/setup-hook && . ${cfg.package}/nix-support/setup-hook
'';
};
}

View File

@@ -0,0 +1,21 @@
{
lib,
pkgs,
config,
...
}:
{
options.programs.joycond-cemuhook = {
enable = lib.mkEnableOption "joycond-cemuhook, a program to enable support for cemuhook's UDP protocol for joycond devices";
};
config = lib.mkIf config.programs.joycond-cemuhook.enable {
assertions = [
{
assertion = config.services.joycond.enable;
message = "joycond must be enabled through `services.joycond.enable`";
}
];
environment.systemPackages = [ pkgs.joycond-cemuhook ];
};
}

View File

@@ -0,0 +1,53 @@
{
config,
pkgs,
lib,
...
}:
{
options.programs.k3b = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable k3b, the KDE disk burning application.
Additionally to installing `k3b` enabling this will
add `setuid` wrappers in `/run/wrappers/bin`
for both `cdrdao` and `cdrecord`. On first
run you must manually configure the path of `cdrdae` and
`cdrecord` to correspond to the appropriate paths under
`/run/wrappers/bin` in the "Setup External Programs" menu.
'';
};
};
config = lib.mkIf config.programs.k3b.enable {
environment.systemPackages = with pkgs; [
kdePackages.k3b
dvdplusrwtools
cdrdao
cdrtools
];
security.wrappers = {
cdrdao = {
setuid = true;
owner = "root";
group = "cdrom";
permissions = "u+wrx,g+x";
source = "${pkgs.cdrdao}/bin/cdrdao";
};
cdrecord = {
setuid = true;
owner = "root";
group = "cdrom";
permissions = "u+wrx,g+x";
source = "${pkgs.cdrtools}/bin/cdrecord";
};
};
};
}

View File

@@ -0,0 +1,35 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.k40-whisperer;
pkg = cfg.package.override {
udevGroup = cfg.group;
};
in
{
options.programs.k40-whisperer = {
enable = lib.mkEnableOption "K40-Whisperer";
group = lib.mkOption {
type = lib.types.str;
description = ''
Group assigned to the device when connected.
'';
default = "k40";
};
package = lib.mkPackageOption pkgs "k40-whisperer" { };
};
config = lib.mkIf cfg.enable {
users.groups.${cfg.group} = { };
environment.systemPackages = [ pkg ];
services.udev.packages = [ pkg ];
};
}

View File

@@ -0,0 +1,24 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.kbdlight;
in
{
options.programs.kbdlight.enable = lib.mkEnableOption "kbdlight";
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.kbdlight ];
security.wrappers.kbdlight = {
setuid = true;
owner = "root";
group = "root";
source = "${pkgs.kbdlight.out}/bin/kbdlight";
};
};
}

View File

@@ -0,0 +1,20 @@
{
lib,
pkgs,
config,
...
}:
let
cfg = config.programs.kclock;
kclockPkg = pkgs.libsForQt5.kclock;
in
{
options.programs.kclock = {
enable = lib.mkEnableOption "KClock";
};
config = lib.mkIf cfg.enable {
services.dbus.packages = [ kclockPkg ];
environment.systemPackages = [ kclockPkg ];
};
}

View File

@@ -0,0 +1,46 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.kde-pim;
in
{
options.programs.kde-pim = {
enable = lib.mkEnableOption "KDE PIM base packages";
kmail = lib.mkEnableOption "KMail";
kontact = lib.mkEnableOption "Kontact";
merkuro = lib.mkEnableOption "Merkuro";
};
config = lib.mkIf cfg.enable {
environment.systemPackages =
with pkgs.kdePackages;
[
# core packages
akonadi
kdepim-runtime
]
++ lib.optionals cfg.kmail [
akonadiconsole
akonadi-search
kmail
kmail-account-wizard
]
++ lib.optionals cfg.kontact [
kontact
]
++ lib.optionals cfg.merkuro (
[
merkuro
]
# Only needed when using the Merkuro Contacts widget in Plasma.
++ lib.optionals config.services.desktopManager.plasma6.enable [
kcontacts
]
);
};
}

View File

@@ -0,0 +1,40 @@
{
config,
pkgs,
lib,
...
}:
{
options.programs.kdeconnect = {
enable = lib.mkEnableOption ''
kdeconnect.
Note that it will open the TCP and UDP port from
1714 to 1764 as they are needed for it to function properly.
You can use the {option}`package` to use
`gnomeExtensions.gsconnect` as an alternative
implementation if you use Gnome
'';
package = lib.mkPackageOption pkgs [ "kdePackages" "kdeconnect-kde" ] {
example = "gnomeExtensions.gsconnect";
};
};
config =
let
cfg = config.programs.kdeconnect;
in
lib.mkIf cfg.enable {
environment.systemPackages = [
cfg.package
];
networking.firewall = rec {
allowedTCPPortRanges = [
{
from = 1714;
to = 1764;
}
];
allowedUDPPortRanges = allowedTCPPortRanges;
};
};
}

View File

@@ -0,0 +1,47 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.kubeswitch;
in
{
options = {
programs.kubeswitch = {
enable = lib.mkEnableOption "kubeswitch";
commandName = lib.mkOption {
type = lib.types.str;
default = "kswitch";
description = "The name of the command to use";
};
package = lib.mkPackageOption pkgs "kubeswitch" { };
};
};
config =
let
shell_files = pkgs.runCommand "kubeswitch-shell-files" { } ''
mkdir -p $out/share
for shell in bash zsh; do
${cfg.package}/bin/switcher init $shell | sed 's/switch(/${cfg.commandName}(/' > $out/share/${cfg.commandName}_init.$shell
${cfg.package}/bin/switcher --cmd ${cfg.commandName} completion $shell > $out/share/${cfg.commandName}_completion.$shell
done
'';
in
lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
programs.bash.interactiveShellInit = ''
source ${shell_files}/share/${cfg.commandName}_init.bash
source ${shell_files}/share/${cfg.commandName}_completion.bash
'';
programs.zsh.interactiveShellInit = ''
source ${shell_files}/share/${cfg.commandName}_init.zsh
source ${shell_files}/share/${cfg.commandName}_completion.zsh
'';
};
}

Some files were not shown because too many files have changed in this diff Show More