diff options
Diffstat (limited to 'nixos/modules/programs')
58 files changed, 1750 insertions, 630 deletions
diff --git a/nixos/modules/programs/appgate-sdp.nix b/nixos/modules/programs/appgate-sdp.nix new file mode 100644 index 00000000000..12cb542f4d0 --- /dev/null +++ b/nixos/modules/programs/appgate-sdp.nix @@ -0,0 +1,25 @@ +{ config, pkgs, lib, ... }: + +with lib; + +{ + options = { + programs.appgate-sdp = { + enable = mkEnableOption "AppGate SDP VPN client"; + }; + }; + + config = 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 ]; + }; + }; +} diff --git a/nixos/modules/programs/atop.nix b/nixos/modules/programs/atop.nix index 7ef8d687ca1..b45eb16e3ea 100644 --- a/nixos/modules/programs/atop.nix +++ b/nixos/modules/programs/atop.nix @@ -1,6 +1,6 @@ # Global configuration for atop. -{ config, lib, ... }: +{ config, lib, pkgs, ... }: with lib; @@ -12,11 +12,85 @@ in options = { - programs.atop = { + programs.atop = rec { + enable = mkEnableOption "Atop"; + + package = mkOption { + type = types.package; + default = pkgs.atop; + defaultText = "pkgs.atop"; + description = '' + Which package to use for Atop. + ''; + }; + + netatop = { + enable = mkOption { + type = 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 = mkOption { + type = types.package; + default = config.boot.kernelPackages.netatop; + defaultText = "config.boot.kernelPackages.netatop"; + description = '' + Which package to use for netatop. + ''; + }; + }; + + atopgpu.enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to install and enable the atopgpud daemon to get information about + NVIDIA gpus. + ''; + }; + + setuidWrapper.enable = mkOption { + type = 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 = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable the atop service responsible for storing statistics for + long-term analysis. + ''; + }; + atopRotateTimer.enable = mkOption { + type = 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 = mkOption { + type = 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 = mkOption { type = types.attrs; - default = {}; + default = { }; example = { flags = "a1f"; interval = 5; @@ -25,12 +99,50 @@ in Parameters to be written to <filename>/etc/atoprc</filename>. ''; }; - }; }; - config = mkIf (cfg.settings != {}) { - environment.etc.atoprc.text = - concatStrings (mapAttrsToList (n: v: "${n} ${toString v}\n") cfg.settings); - }; + config = mkIf cfg.enable ( + let + atop = + if cfg.atopgpu.enable then + (cfg.package.override { withAtopgpu = true; }) + else + cfg.package; + in + { + environment.etc = mkIf (cfg.settings != { }) { + atoprc.text = concatStrings + (mapAttrsToList + (n: v: '' + ${n} ${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: cond: name: restartTriggers: { + ${name} = lib.mkIf cond { + 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 = + mkService cfg.atopService.enable "atop" [ atop ] + // mkService cfg.atopacctService.enable "atopacct" [ atop ] + // mkService cfg.netatop.enable "netatop" [ cfg.netatop.package ] + // mkService cfg.atopgpu.enable "atopgpu" [ atop ]; + timers = mkTimer cfg.atopRotateTimer.enable "atop-rotate" [ atop ]; + }; + security.wrappers = + lib.mkIf cfg.setuidWrapper.enable { atop = { source = "${atop}/bin/atop"; }; }; + } + ); } diff --git a/nixos/modules/programs/bandwhich.nix b/nixos/modules/programs/bandwhich.nix index 5413044f461..1cffb5fa276 100644 --- a/nixos/modules/programs/bandwhich.nix +++ b/nixos/modules/programs/bandwhich.nix @@ -4,7 +4,7 @@ with lib; let cfg = config.programs.bandwhich; in { - meta.maintainers = with maintainers; [ filalex77 ]; + meta.maintainers = with maintainers; [ Br1ght0ne ]; options = { programs.bandwhich = { diff --git a/nixos/modules/programs/bash/bash-completion.nix b/nixos/modules/programs/bash/bash-completion.nix new file mode 100644 index 00000000000..f07b1b636ef --- /dev/null +++ b/nixos/modules/programs/bash/bash-completion.nix @@ -0,0 +1,37 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + enable = config.programs.bash.enableCompletion; +in +{ + options = { + programs.bash.enableCompletion = mkEnableOption "Bash completion for all interactive bash shells" // { + default = true; + }; + }; + + config = mkIf 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 + . "${pkgs.bash-completion}/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 + ''; + }; +} diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix index 1b3254b54a5..908ab34b08d 100644 --- a/nixos/modules/programs/bash/bash.nix +++ b/nixos/modules/programs/bash/bash.nix @@ -11,31 +11,6 @@ let cfg = config.programs.bash; - bashCompletion = optionalString cfg.enableCompletion '' - # 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 - . "${pkgs.bash-completion}/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 - ''; - - lsColors = optionalString cfg.enableLsColors '' - eval "$(${pkgs.coreutils}/bin/dircolors -b)" - ''; - bashAliases = concatStringsSep "\n" ( mapAttrsFlatten (k: v: "alias ${k}=${escapeShellArg v}") (filterAttrs (k: v: v != null) cfg.shellAliases) @@ -123,20 +98,13 @@ in type = types.lines; }; - enableCompletion = mkOption { - default = true; - description = '' - Enable Bash completion for all interactive bash shells. - ''; - type = types.bool; - }; - - enableLsColors = mkOption { - default = true; + promptPluginInit = mkOption { + default = ""; description = '' - Enable extra colors in directory listings. + Shell script code used to initialise bash prompt plugins. ''; - type = types.bool; + type = types.lines; + internal = true; }; }; @@ -167,8 +135,7 @@ in set +h ${cfg.promptInit} - ${bashCompletion} - ${lsColors} + ${cfg.promptPluginInit} ${bashAliases} ${cfge.interactiveShellInit} diff --git a/nixos/modules/programs/bash/ls-colors.nix b/nixos/modules/programs/bash/ls-colors.nix new file mode 100644 index 00000000000..254ee14c477 --- /dev/null +++ b/nixos/modules/programs/bash/ls-colors.nix @@ -0,0 +1,20 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + enable = config.programs.bash.enableLsColors; +in +{ + options = { + programs.bash.enableLsColors = mkEnableOption "extra colors in directory listings" // { + default = true; + }; + }; + + config = mkIf enable { + programs.bash.promptPluginInit = '' + eval "$(${pkgs.coreutils}/bin/dircolors -b)" + ''; + }; +} diff --git a/nixos/modules/programs/bash/undistract-me.nix b/nixos/modules/programs/bash/undistract-me.nix new file mode 100644 index 00000000000..0e6465e048a --- /dev/null +++ b/nixos/modules/programs/bash/undistract-me.nix @@ -0,0 +1,36 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.bash.undistractMe; +in +{ + options = { + programs.bash.undistractMe = { + enable = mkEnableOption "notifications when long-running terminal commands complete"; + + playSound = mkEnableOption "notification sounds when long-running terminal commands complete"; + + timeout = mkOption { + default = 10; + description = '' + Number of seconds it would take for a command to be considered long-running. + ''; + type = types.int; + }; + }; + }; + + config = mkIf cfg.enable { + programs.bash.promptPluginInit = '' + export LONG_RUNNING_COMMAND_TIMEOUT=${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 maintainers; [ kira-bruneau ]; + }; +} diff --git a/nixos/modules/programs/captive-browser.nix b/nixos/modules/programs/captive-browser.nix index 26db1675072..1f223e2475c 100644 --- a/nixos/modules/programs/captive-browser.nix +++ b/nixos/modules/programs/captive-browser.nix @@ -1,7 +1,6 @@ { config, lib, pkgs, ... }: with lib; - let cfg = config.programs.captive-browser; in @@ -27,15 +26,17 @@ in # the options below are the same as in "captive-browser.toml" browser = mkOption { type = types.str; - default = concatStringsSep " " [ ''${pkgs.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'' - ''http://cache.nixos.org/'' - ]; + default = concatStringsSep " " [ + ''${pkgs.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/'' + ]; description = '' The shell (/bin/sh) command executed once the proxy starts. When browser exits, the proxy exits. An extra env var PROXY is available. @@ -62,7 +63,7 @@ in socks5-addr = mkOption { type = types.str; default = "localhost:1666"; - description = ''the listen address for the SOCKS5 proxy server''; + description = "the listen address for the SOCKS5 proxy server"; }; bindInterface = mkOption { @@ -81,42 +82,45 @@ in config = mkIf cfg.enable { - programs.captive-browser.dhcp-dns = mkOptionDefault ( - if config.networking.networkmanager.enable then - "${pkgs.networkmanager}/bin/nmcli dev show ${escapeShellArg cfg.interface} | ${pkgs.gnugrep}/bin/fgrep IP4.DNS" - else if config.networking.dhcpcd.enable then - "${pkgs.dhcpcd}/bin/dhcpcd -U ${escapeShellArg cfg.interface} | ${pkgs.gnugrep}/bin/fgrep domain_name_servers" - else if config.networking.useNetworkd then - "${cfg.package}/bin/systemd-networkd-dns ${escapeShellArg cfg.interface}" - else - "${config.security.wrapperDir}/udhcpc --quit --now -f -i ${escapeShellArg cfg.interface} -O dns --script ${ - pkgs.writeScript "udhcp-script" '' - #!/bin/sh - if [ "$1" = bound ]; then - echo "$dns" - fi - ''}" - ); + programs.captive-browser.dhcp-dns = + let + iface = prefix: + optionalString cfg.bindInterface (concatStringsSep " " (map escapeShellArg [ prefix 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 = { - capabilities = "cap_net_raw+p"; - source = "${pkgs.busybox}/bin/udhcpc"; + capabilities = "cap_net_raw+p"; + source = "${pkgs.busybox}/bin/udhcpc"; }; security.wrappers.captive-browser = { - capabilities = "cap_net_raw+p"; - source = pkgs.writeScript "captive-browser" '' - #!${pkgs.bash}/bin/bash - 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 - ''; + capabilities = "cap_net_raw+p"; + source = pkgs.writeShellScript "captive-browser" '' + 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 + ''; }; }; } diff --git a/nixos/modules/programs/ccache.nix b/nixos/modules/programs/ccache.nix index 3c9e64932f1..d672e1da017 100644 --- a/nixos/modules/programs/ccache.nix +++ b/nixos/modules/programs/ccache.nix @@ -17,7 +17,7 @@ in { type = types.listOf types.str; description = "Nix top-level packages to be compiled using CCache"; default = []; - example = [ "wxGTK30" "qt48" "ffmpeg_3_3" "libav_all" ]; + example = [ "wxGTK30" "ffmpeg" "libav_all" ]; }; }; diff --git a/nixos/modules/programs/cdemu.nix b/nixos/modules/programs/cdemu.nix index a59cd93cadf..142e2934240 100644 --- a/nixos/modules/programs/cdemu.nix +++ b/nixos/modules/programs/cdemu.nix @@ -16,18 +16,21 @@ in { ''; }; group = mkOption { + type = types.str; default = "cdrom"; description = '' Group that users must be in to use <command>cdemu</command>. ''; }; gui = mkOption { + type = types.bool; default = true; description = '' Whether to install the <command>cdemu</command> GUI (gCDEmu). ''; }; image-analyzer = mkOption { + type = types.bool; default = true; description = '' Whether to install the image analyzer. diff --git a/nixos/modules/programs/chromium.nix b/nixos/modules/programs/chromium.nix index 3f042913619..b727f850a94 100644 --- a/nixos/modules/programs/chromium.nix +++ b/nixos/modules/programs/chromium.nix @@ -29,7 +29,7 @@ in 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 - <link xlink:href="https://www.chromium.org/administrators/policy-list-3#ExtensionInstallForcelist">ExtensionInstallForcelist</link> + <link xlink:href="https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExtensionInstallForcelist">ExtensionInstallForcelist</link> for additional details. ''; default = []; diff --git a/nixos/modules/programs/command-not-found/command-not-found.nix b/nixos/modules/programs/command-not-found/command-not-found.nix index 656c255fcb1..79786584c66 100644 --- a/nixos/modules/programs/command-not-found/command-not-found.nix +++ b/nixos/modules/programs/command-not-found/command-not-found.nix @@ -14,10 +14,8 @@ let dir = "bin"; src = ./command-not-found.pl; isExecutable = true; - inherit (pkgs) perl; inherit (cfg) dbPath; - perlFlags = concatStrings (map (path: "-I ${path}/${pkgs.perl.libPrefix} ") - [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]); + perl = pkgs.perl.withPackages (p: [ p.DBDSQLite p.StringShellQuote ]); }; in @@ -80,6 +78,8 @@ in # Retry the command if we just installed it. if [ $? = 126 ]; then "$@" + else + return 127 fi else # Indicate than there was an error so ZSH falls back to its default handler diff --git a/nixos/modules/programs/command-not-found/command-not-found.pl b/nixos/modules/programs/command-not-found/command-not-found.pl index ab7aa204653..6e275bcc8be 100644 --- a/nixos/modules/programs/command-not-found/command-not-found.pl +++ b/nixos/modules/programs/command-not-found/command-not-found.pl @@ -1,4 +1,4 @@ -#! @perl@/bin/perl -w @perlFlags@ +#! @perl@/bin/perl -w use strict; use DBI; @@ -27,8 +27,8 @@ if (!defined $res || scalar @$res == 0) { my $package = @$res[0]->{package}; if ($ENV{"NIX_AUTO_INSTALL"} // "") { print STDERR <<EOF; -The program ‘$program’ is currently not installed. It is provided by -the package ‘$package’, which I will now install for you. +The program '$program' is currently not installed. It is provided by +the package '$package', which I will now install for you. EOF ; exit 126 if system("nix-env", "-iA", "nixos.$package") == 0; @@ -36,16 +36,17 @@ EOF exec("nix-shell", "-p", $package, "--run", shell_quote("exec", @ARGV)); } else { print STDERR <<EOF; -The program ‘$program’ is currently not installed. You can install it by typing: - nix-env -iA nixos.$package +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 { print STDERR <<EOF; -The program ‘$program’ is currently not installed. It is provided by -several packages. You can install it by typing one of the following: +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-env -iA nixos.$_->{package}\n" foreach @$res; + print STDERR " nix-shell -p $_->{package}\n" foreach @$res; } exit 127; diff --git a/nixos/modules/programs/dconf.nix b/nixos/modules/programs/dconf.nix index ec85cb9d18c..298abac8afa 100644 --- a/nixos/modules/programs/dconf.nix +++ b/nixos/modules/programs/dconf.nix @@ -54,6 +54,8 @@ in services.dbus.packages = [ pkgs.dconf ]; + systemd.packages = [ pkgs.dconf ]; + # For dconf executable environment.systemPackages = [ pkgs.dconf ]; diff --git a/nixos/modules/programs/droidcam.nix b/nixos/modules/programs/droidcam.nix new file mode 100644 index 00000000000..9843a1f5be2 --- /dev/null +++ b/nixos/modules/programs/droidcam.nix @@ -0,0 +1,16 @@ +{ lib, pkgs, config, ... }: + +with lib; + +{ + options.programs.droidcam = { + enable = 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" ]; + }; +} diff --git a/nixos/modules/programs/environment.nix b/nixos/modules/programs/environment.nix index 38bdabb4fa8..8877356360a 100644 --- a/nixos/modules/programs/environment.nix +++ b/nixos/modules/programs/environment.nix @@ -33,7 +33,6 @@ in { PATH = [ "/bin" ]; INFOPATH = [ "/info" "/share/info" ]; KDEDIRS = [ "" ]; - STRIGI_PLUGIN_PATH = [ "/lib/strigi/" ]; QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ]; QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ]; GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ]; diff --git a/nixos/modules/programs/feedbackd.nix b/nixos/modules/programs/feedbackd.nix new file mode 100644 index 00000000000..bb14489a6f4 --- /dev/null +++ b/nixos/modules/programs/feedbackd.nix @@ -0,0 +1,32 @@ +{ pkgs, lib, config, ... }: + +with lib; + +let + cfg = config.programs.feedbackd; +in { + options = { + programs.feedbackd = { + enable = mkEnableOption '' + Whether to enable the feedbackd D-BUS service and udev rules. + + Your user needs to be in the `feedbackd` group to trigger effects. + ''; + package = mkOption { + description = '' + Which feedbackd package to use. + ''; + type = types.package; + default = pkgs.feedbackd; + }; + }; + }; + config = mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + services.dbus.packages = [ cfg.package ]; + services.udev.packages = [ cfg.package ]; + + users.groups.feedbackd = {}; + }; +} diff --git a/nixos/modules/programs/file-roller.nix b/nixos/modules/programs/file-roller.nix index 64f6a94e764..b939d59909c 100644 --- a/nixos/modules/programs/file-roller.nix +++ b/nixos/modules/programs/file-roller.nix @@ -30,9 +30,9 @@ with lib; config = mkIf config.programs.file-roller.enable { - environment.systemPackages = [ pkgs.gnome3.file-roller ]; + environment.systemPackages = [ pkgs.gnome.file-roller ]; - services.dbus.packages = [ pkgs.gnome3.file-roller ]; + services.dbus.packages = [ pkgs.gnome.file-roller ]; }; diff --git a/nixos/modules/programs/firejail.nix b/nixos/modules/programs/firejail.nix index 484f9eb4440..ad4ef1a3945 100644 --- a/nixos/modules/programs/firejail.nix +++ b/nixos/modules/programs/firejail.nix @@ -11,10 +11,20 @@ let } '' mkdir -p $out/bin - ${lib.concatStringsSep "\n" (lib.mapAttrsToList (command: binary: '' + ${lib.concatStringsSep "\n" (lib.mapAttrsToList (command: value: + let + opts = if builtins.isAttrs value + then value + else { executable = value; profile = null; extraArgs = []; }; + args = lib.escapeShellArgs ( + (optional (opts.profile != null) "--profile=${toString opts.profile}") + ++ opts.extraArgs + ); + in + '' cat <<_EOF >$out/bin/${command} #! ${pkgs.runtimeShell} -e - exec /run/wrappers/bin/firejail ${binary} "\$@" + exec /run/wrappers/bin/firejail ${args} -- ${toString opts.executable} "\$@" _EOF chmod 0755 $out/bin/${command} '') cfg.wrappedBinaries)} @@ -25,12 +35,38 @@ in { enable = mkEnableOption "firejail"; wrappedBinaries = mkOption { - type = types.attrsOf types.path; + type = types.attrsOf (types.either types.path (types.submodule { + options = { + executable = mkOption { + type = types.path; + description = "Executable to run sandboxed"; + example = literalExample "''${lib.getBin pkgs.firefox}/bin/firefox"; + }; + profile = mkOption { + type = types.nullOr types.path; + default = null; + description = "Profile to use"; + example = literalExample "''${pkgs.firejail}/etc/firejail/firefox.profile"; + }; + extraArgs = mkOption { + type = types.listOf types.str; + default = []; + description = "Extra arguments to pass to firejail"; + example = [ "--private=~/.firejail_home" ]; + }; + }; + })); default = {}; example = literalExample '' { - firefox = "''${lib.getBin pkgs.firefox}/bin/firefox"; - mpv = "''${lib.getBin pkgs.mpv}/bin/mpv"; + 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 = '' diff --git a/nixos/modules/programs/fish.nix b/nixos/modules/programs/fish.nix index 39b92edf2ac..8dd7101947f 100644 --- a/nixos/modules/programs/fish.nix +++ b/nixos/modules/programs/fish.nix @@ -8,11 +8,37 @@ let cfg = config.programs.fish; + fishAbbrs = concatStringsSep "\n" ( + mapAttrsFlatten (k: v: "abbr -ag ${k} ${escapeShellArg v}") + cfg.shellAbbrs + ); + fishAliases = concatStringsSep "\n" ( mapAttrsFlatten (k: v: "alias ${k} ${escapeShellArg v}") (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" { + nativeBuildInputs = [ pkgs.babelfish ]; + } "${pkgs.babelfish}/bin/babelfish < ${path} > $out;"; + in { @@ -29,6 +55,15 @@ in type = types.bool; }; + useBabelfish = mkOption { + type = types.bool; + default = false; + description = '' + If enabled, the configured environment will be translated to native fish using <link xlink:href="https://github.com/bouk/babelfish">babelfish</link>. + Otherwise, <link xlink:href="https://github.com/oh-my-fish/plugin-foreign-env">foreign-env</link> will be used. + ''; + }; + vendor.config.enable = mkOption { type = types.bool; default = true; @@ -53,6 +88,18 @@ in ''; }; + shellAbbrs = mkOption { + default = {}; + example = { + gco = "git checkout"; + npu = "nix-prefetch-url"; + }; + description = '' + Set of fish abbreviations. + ''; + type = with types; attrsOf str; + }; + shellAliases = mkOption { default = {}; description = '' @@ -103,74 +150,155 @@ in programs.fish.shellAliases = mapAttrs (name: mkDefault) cfge.shellAliases; # Required for man completions - documentation.man.generateCaches = true; - - environment.etc."fish/foreign-env/shellInit".text = cfge.shellInit; - environment.etc."fish/foreign-env/loginShellInit".text = cfge.loginShellInit; - environment.etc."fish/foreign-env/interactiveShellInit".text = cfge.interactiveShellInit; - - environment.etc."fish/nixos-env-preinit.fish".text = '' - # 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.fish-foreign-env}/share/fish-foreign-env/functions $__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 - ''; - - environment.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 - set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path - fenv source /etc/fish/foreign-env/shellInit > /dev/null - set -e fish_function_path[1] - - ${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 - set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path - fenv source /etc/fish/foreign-env/loginShellInit > /dev/null - set -e fish_function_path[1] - - ${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 - ${fishAliases} - - set fish_function_path ${pkgs.fish-foreign-env}/share/fish-foreign-env/functions $fish_function_path - fenv source /etc/fish/foreign-env/interactiveShellInit > /dev/null - set -e fish_function_path[1] - - ${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 - ''; + documentation.man.generateCaches = lib.mkDefault true; + + environment = mkMerge [ + (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"; + }) + + (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 + ''; + } + + { + etc."fish/generated_completions".source = + let + patchedGenerator = pkgs.stdenv.mkDerivation { + name = "fish_patched-completion-generator"; + srcs = [ + "${pkgs.fish}/share/fish/tools/create_manpage_completions.py" + "${pkgs.fish}/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 + "${package.name}_fish-completions" + ( + { + inherit package; + preferLocalBuild = true; + allowSubstitutes = false; + } + // optionalAttrs (package ? meta.priority) { meta.priority = package.meta.priority; } + ) + '' + mkdir -p $out + if [ -d $package/share/man ]; then + find $package/share/man -type f | xargs ${pkgs.python3.interpreter} ${patchedGenerator}/create_manpage_completions.py --directory $out >/dev/null + fi + ''; + in + pkgs.buildEnv { + name = "system_fish-completions"; + ignoreCollisions = true; + paths = map generateCompletions config.environment.systemPackages; + }; + } + + # include programs that bring their own completions + { + pathsToLink = [] + ++ optional cfg.vendor.config.enable "/share/fish/vendor_conf.d" + ++ optional cfg.vendor.completions.enable "/share/fish/vendor_completions.d" + ++ optional cfg.vendor.functions.enable "/share/fish/vendor_functions.d"; + } + + { systemPackages = [ pkgs.fish ]; } + + { + shells = [ + "/run/current-system/sw/bin/fish" + "${pkgs.fish}/bin/fish" + ]; + } + ]; programs.fish.interactiveShellInit = '' # add completions generated by NixOS to $fish_complete_path @@ -187,61 +315,6 @@ in end ''; - environment.etc."fish/generated_completions".source = - let - patchedGenerator = pkgs.stdenv.mkDerivation { - name = "fish_patched-completion-generator"; - srcs = [ - "${pkgs.fish}/share/fish/tools/create_manpage_completions.py" - "${pkgs.fish}/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 - "${package.name}_fish-completions" - ( - { - inherit package; - preferLocalBuild = true; - allowSubstitutes = false; - } - // optionalAttrs (package ? meta.priority) { meta.priority = package.meta.priority; } - ) - '' - mkdir -p $out - if [ -d $package/share/man ]; then - find $package/share/man -type f | xargs ${pkgs.python3.interpreter} ${patchedGenerator}/create_manpage_completions.py --directory $out >/dev/null - fi - ''; - in - pkgs.buildEnv { - name = "system_fish-completions"; - ignoreCollisions = true; - paths = map generateCompletions config.environment.systemPackages; - }; - - # include programs that bring their own completions - environment.pathsToLink = [] - ++ optional cfg.vendor.config.enable "/share/fish/vendor_conf.d" - ++ optional cfg.vendor.completions.enable "/share/fish/vendor_completions.d" - ++ optional cfg.vendor.functions.enable "/share/fish/vendor_functions.d"; - - environment.systemPackages = [ pkgs.fish ]; - - environment.shells = [ - "/run/current-system/sw/bin/fish" - "${pkgs.fish}/bin/fish" - ]; - }; } diff --git a/nixos/modules/programs/fish_completion-generator.patch b/nixos/modules/programs/fish_completion-generator.patch index 997f38c5066..fa207e484c9 100644 --- a/nixos/modules/programs/fish_completion-generator.patch +++ b/nixos/modules/programs/fish_completion-generator.patch @@ -1,13 +1,14 @@ --- a/create_manpage_completions.py +++ b/create_manpage_completions.py -@@ -844,10 +844,6 @@ def parse_manpage_at_path(manpage_path, output_directory): +@@ -879,10 +879,6 @@ def parse_manpage_at_path(manpage_path, output_directory): + ) + return False - built_command_output.insert(0, "# " + CMDNAME) +- # 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 -- # Output the magic word Autogenerated so we can tell if we can overwrite this -- built_command_output.insert( -- 1, "# Autogenerated from man page " + manpage_path -- ) - # built_command_output.insert(2, "# using " + parser.__class__.__name__) # XXX MISATTRIBUTES THE CULPABILE PARSER! Was really using Type2 but reporting TypeDeroffManParser - - for line in built_command_output: + for line in built_command_output: + diff --git a/nixos/modules/programs/flashrom.nix b/nixos/modules/programs/flashrom.nix new file mode 100644 index 00000000000..f026c2e31cd --- /dev/null +++ b/nixos/modules/programs/flashrom.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.flashrom; +in +{ + options.programs.flashrom = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Installs flashrom and configures udev rules for programmers + used by flashrom. Grants access to users in the "flashrom" + group. + ''; + }; + }; + + config = mkIf cfg.enable { + services.udev.packages = [ pkgs.flashrom ]; + environment.systemPackages = [ pkgs.flashrom ]; + users.groups.flashrom = { }; + }; +} diff --git a/nixos/modules/programs/flexoptix-app.nix b/nixos/modules/programs/flexoptix-app.nix new file mode 100644 index 00000000000..93dcdfeb514 --- /dev/null +++ b/nixos/modules/programs/flexoptix-app.nix @@ -0,0 +1,25 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.programs.flexoptix-app; +in { + options = { + programs.flexoptix-app = { + enable = mkEnableOption "FLEXOPTIX app + udev rules"; + + package = mkOption { + description = "FLEXOPTIX app package to use"; + type = types.package; + default = pkgs.flexoptix-app; + defaultText = "\${pkgs.flexoptix-app}"; + }; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + services.udev.packages = [ cfg.package ]; + }; +} diff --git a/nixos/modules/programs/gamemode.nix b/nixos/modules/programs/gamemode.nix new file mode 100644 index 00000000000..03949bf98df --- /dev/null +++ b/nixos/modules/programs/gamemode.nix @@ -0,0 +1,96 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.gamemode; + settingsFormat = pkgs.formats.ini { }; + configFile = settingsFormat.generate "gamemode.ini" cfg.settings; +in +{ + options = { + programs.gamemode = { + enable = mkEnableOption "GameMode to optimise system performance on demand"; + + enableRenice = mkEnableOption "CAP_SYS_NICE on gamemoded to support lowering process niceness" // { + default = true; + }; + + settings = mkOption { + type = settingsFormat.type; + default = {}; + description = '' + System-wide configuration for GameMode (/etc/gamemode.ini). + See gamemoded(8) man page for available settings. + ''; + example = literalExample '' + { + 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 = mkIf cfg.enable { + environment = { + systemPackages = [ pkgs.gamemode ]; + etc."gamemode.ini".source = configFile; + }; + + security = { + polkit.enable = true; + wrappers = mkIf cfg.enableRenice { + gamemoded = { + 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 = mkForce (pkgs.linkFarm "pkexec" [ + { + name = "pkexec"; + path = "${config.security.wrapperDir}/pkexec"; + } + ]); + + serviceConfig.ExecStart = mkIf cfg.enableRenice [ + "" # Tell systemd to clear the existing ExecStart list, to prevent appending to it. + "${config.security.wrapperDir}/gamemoded" + ]; + }; + }; + }; + + meta = { + maintainers = with maintainers; [ kira-bruneau ]; + }; +} diff --git a/nixos/modules/programs/geary.nix b/nixos/modules/programs/geary.nix index 5e441a75cb6..407680c30dc 100644 --- a/nixos/modules/programs/geary.nix +++ b/nixos/modules/programs/geary.nix @@ -15,10 +15,10 @@ in { }; config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.gnome3.geary ]; + environment.systemPackages = [ pkgs.gnome.geary ]; programs.dconf.enable = true; - services.gnome3.gnome-keyring.enable = true; - services.gnome3.gnome-online-accounts.enable = true; + services.gnome.gnome-keyring.enable = true; + services.gnome.gnome-online-accounts.enable = true; }; } diff --git a/nixos/modules/programs/gnome-disks.nix b/nixos/modules/programs/gnome-disks.nix index 80dc2983ea5..4b128b47126 100644 --- a/nixos/modules/programs/gnome-disks.nix +++ b/nixos/modules/programs/gnome-disks.nix @@ -41,9 +41,9 @@ with lib; config = mkIf config.programs.gnome-disks.enable { - environment.systemPackages = [ pkgs.gnome3.gnome-disk-utility ]; + environment.systemPackages = [ pkgs.gnome.gnome-disk-utility ]; - services.dbus.packages = [ pkgs.gnome3.gnome-disk-utility ]; + services.dbus.packages = [ pkgs.gnome.gnome-disk-utility ]; }; diff --git a/nixos/modules/programs/gnome-documents.nix b/nixos/modules/programs/gnome-documents.nix index 9dd53483055..43ad3163efd 100644 --- a/nixos/modules/programs/gnome-documents.nix +++ b/nixos/modules/programs/gnome-documents.nix @@ -13,7 +13,7 @@ with lib; # Added 2019-08-09 imports = [ (mkRenamedOptionModule - [ "services" "gnome3" "gnome-documents" "enable" ] + [ "services" "gnome" "gnome-documents" "enable" ] [ "programs" "gnome-documents" "enable" ]) ]; @@ -41,13 +41,13 @@ with lib; config = mkIf config.programs.gnome-documents.enable { - environment.systemPackages = [ pkgs.gnome3.gnome-documents ]; + environment.systemPackages = [ pkgs.gnome.gnome-documents ]; - services.dbus.packages = [ pkgs.gnome3.gnome-documents ]; + services.dbus.packages = [ pkgs.gnome.gnome-documents ]; - services.gnome3.gnome-online-accounts.enable = true; + services.gnome.gnome-online-accounts.enable = true; - services.gnome3.gnome-online-miners.enable = true; + services.gnome.gnome-online-miners.enable = true; }; diff --git a/nixos/modules/programs/gnome-terminal.nix b/nixos/modules/programs/gnome-terminal.nix index f2617e5bc03..71a6b217880 100644 --- a/nixos/modules/programs/gnome-terminal.nix +++ b/nixos/modules/programs/gnome-terminal.nix @@ -28,9 +28,9 @@ in }; config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.gnome3.gnome-terminal ]; - services.dbus.packages = [ pkgs.gnome3.gnome-terminal ]; - systemd.packages = [ pkgs.gnome3.gnome-terminal ]; + environment.systemPackages = [ pkgs.gnome.gnome-terminal ]; + services.dbus.packages = [ pkgs.gnome.gnome-terminal ]; + systemd.packages = [ pkgs.gnome.gnome-terminal ]; programs.bash.vteIntegration = true; programs.zsh.vteIntegration = true; diff --git a/nixos/modules/programs/gpaste.nix b/nixos/modules/programs/gpaste.nix index 4f6deb77e5e..cff2fb8d003 100644 --- a/nixos/modules/programs/gpaste.nix +++ b/nixos/modules/programs/gpaste.nix @@ -27,8 +27,10 @@ with lib; ###### implementation config = mkIf config.programs.gpaste.enable { - environment.systemPackages = [ pkgs.gnome3.gpaste ]; - services.dbus.packages = [ pkgs.gnome3.gpaste ]; - systemd.packages = [ pkgs.gnome3.gpaste ]; + environment.systemPackages = [ pkgs.gnome.gpaste ]; + services.dbus.packages = [ pkgs.gnome.gpaste ]; + systemd.packages = [ pkgs.gnome.gpaste ]; + # gnome-control-center crashes in Keyboard Shortcuts pane without the GSettings schemas. + services.xserver.desktopManager.gnome.sessionPath = [ pkgs.gnome.gpaste ]; }; } diff --git a/nixos/modules/programs/hamster.nix b/nixos/modules/programs/hamster.nix index b2f4a82b260..0bb56ad7ff3 100644 --- a/nixos/modules/programs/hamster.nix +++ b/nixos/modules/programs/hamster.nix @@ -6,7 +6,7 @@ with lib; meta.maintainers = pkgs.hamster.meta.maintainers; options.programs.hamster.enable = - mkEnableOption "Whether to enable hamster time tracking."; + mkEnableOption "hamster, a time tracking program"; config = lib.mkIf config.programs.hamster.enable { environment.systemPackages = [ pkgs.hamster ]; diff --git a/nixos/modules/programs/kdeconnect.nix b/nixos/modules/programs/kdeconnect.nix new file mode 100644 index 00000000000..673449b9f63 --- /dev/null +++ b/nixos/modules/programs/kdeconnect.nix @@ -0,0 +1,35 @@ +{ config, pkgs, lib, ... }: +with lib; +{ + options.programs.kdeconnect = { + enable = 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</option> to use + <code>gnomeExtensions.gsconnect</code> as an alternative + implementation if you use Gnome. + ''; + package = mkOption { + default = pkgs.kdeconnect; + defaultText = "pkgs.kdeconnect"; + type = types.package; + example = literalExample "pkgs.gnomeExtensions.gsconnect"; + description = '' + The package providing the implementation for kdeconnect. + ''; + }; + }; + config = + let + cfg = config.programs.kdeconnect; + in + mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + networking.firewall = rec { + allowedTCPPortRanges = [ { from = 1714; to = 1764; } ]; + allowedUDPPortRanges = allowedTCPPortRanges; + }; + }; +} diff --git a/nixos/modules/programs/less.nix b/nixos/modules/programs/less.nix index 75b3e707d57..09cb6030e66 100644 --- a/nixos/modules/programs/less.nix +++ b/nixos/modules/programs/less.nix @@ -40,7 +40,7 @@ in configFile = mkOption { type = types.nullOr types.path; default = null; - example = literalExample "$${pkgs.my-configs}/lesskey"; + example = literalExample "\${pkgs.my-configs}/lesskey"; description = '' Path to lesskey configuration file. diff --git a/nixos/modules/programs/mininet.nix b/nixos/modules/programs/mininet.nix index ecc924325e6..6e90e7669ac 100644 --- a/nixos/modules/programs/mininet.nix +++ b/nixos/modules/programs/mininet.nix @@ -8,7 +8,7 @@ let cfg = config.programs.mininet; generatedPath = with pkgs; makeSearchPath "bin" [ - iperf ethtool iproute socat + iperf ethtool iproute2 socat ]; pyEnv = pkgs.python.withPackages(ps: [ ps.mininet-python ]); diff --git a/nixos/modules/programs/msmtp.nix b/nixos/modules/programs/msmtp.nix new file mode 100644 index 00000000000..217060e6b3b --- /dev/null +++ b/nixos/modules/programs/msmtp.nix @@ -0,0 +1,104 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.msmtp; + +in { + meta.maintainers = with maintainers; [ pacien ]; + + options = { + programs.msmtp = { + enable = mkEnableOption "msmtp - an SMTP client"; + + setSendmail = mkOption { + type = types.bool; + default = true; + description = '' + Whether to set the system sendmail to msmtp's. + ''; + }; + + defaults = mkOption { + type = types.attrs; + default = {}; + example = { + aliases = "/etc/aliases"; + port = 587; + tls = true; + }; + description = '' + Default values applied to all accounts. + See msmtp(1) for the available options. + ''; + }; + + accounts = mkOption { + type = with types; attrsOf attrs; + default = {}; + example = { + "default" = { + host = "smtp.example"; + auth = true; + user = "someone"; + passwordeval = "cat /secrets/password.txt"; + }; + }; + description = '' + Named accounts and their respective configurations. + The special name "default" allows a default account to be defined. + See msmtp(1) for the available options. + + Use `programs.msmtp.extraConfig` instead of this attribute set-based + option if ordered account inheritance is needed. + + It is advised to use the `passwordeval` setting to read the password + from a secret file to avoid having it written in the world-readable + nix store. The password file must end with a newline (`\n`). + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra lines to add to the msmtp configuration verbatim. + See msmtp(1) for the syntax and available options. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.msmtp ]; + + services.mail.sendmailSetuidWrapper = mkIf cfg.setSendmail { + program = "sendmail"; + source = "${pkgs.msmtp}/bin/sendmail"; + setuid = false; + setgid = false; + }; + + environment.etc."msmtprc".text = let + mkValueString = v: + if v == true then "on" + else if v == false then "off" + else generators.mkValueStringDefault {} v; + mkKeyValueString = k: v: "${k} ${mkValueString v}"; + mkInnerSectionString = + attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValueString attrs); + mkAccountString = name: attrs: '' + account ${name} + ${mkInnerSectionString attrs} + ''; + in '' + defaults + ${mkInnerSectionString cfg.defaults} + + ${concatStringsSep "\n" (mapAttrsToList mkAccountString cfg.accounts)} + + ${cfg.extraConfig} + ''; + }; +} diff --git a/nixos/modules/programs/neovim.nix b/nixos/modules/programs/neovim.nix new file mode 100644 index 00000000000..0a1a2ac2b75 --- /dev/null +++ b/nixos/modules/programs/neovim.nix @@ -0,0 +1,165 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.neovim; + + runtime' = filter (f: f.enable) (attrValues cfg.runtime); + + # taken from the etc module + runtime = pkgs.stdenvNoCC.mkDerivation { + name = "runtime"; + + builder = ../system/etc/make-etc.sh; + + preferLocalBuild = true; + allowSubstitutes = false; + + sources = map (x: x.source) runtime'; + targets = map (x: x.target) runtime'; + }; + +in { + options.programs.neovim = { + enable = mkEnableOption "Neovim"; + + defaultEditor = mkOption { + type = types.bool; + default = false; + description = '' + When enabled, installs neovim and configures neovim to be the default editor + using the EDITOR environment variable. + ''; + }; + + viAlias = mkOption { + type = types.bool; + default = false; + description = '' + Symlink <command>vi</command> to <command>nvim</command> binary. + ''; + }; + + vimAlias = mkOption { + type = types.bool; + default = false; + description = '' + Symlink <command>vim</command> to <command>nvim</command> binary. + ''; + }; + + withRuby = mkOption { + type = types.bool; + default = true; + description = "Enable ruby provider."; + }; + + configure = mkOption { + type = types.attrs; + default = {}; + example = literalExample '' + configure = { + customRC = $'''' + " here your custom configuration goes! + $''''; + packages.myVimPackage = with pkgs.vimPlugins; { + # loaded on launch + start = [ fugitive ]; + # manually loadable by calling `:packadd $plugin-name` + opt = [ ]; + }; + }; + ''; + description = '' + Generate your init file from your list of plugins and custom commands. + Neovim will then be wrapped to load <command>nvim -u /nix/store/<replaceable>hash</replaceable>-vimrc</command> + ''; + }; + + package = mkOption { + type = types.package; + default = pkgs.neovim-unwrapped; + defaultText = literalExample "pkgs.neovim-unwrapped"; + description = "The package to use for the neovim binary."; + }; + + finalPackage = mkOption { + type = types.package; + visible = false; + readOnly = true; + description = "Resulting customized neovim package."; + }; + + runtime = mkOption { + default = {}; + example = literalExample '' + runtime."ftplugin/c.vim".text = "setlocal omnifunc=v:lua.vim.lsp.omnifunc"; + ''; + description = '' + Set of files that have to be linked in <filename>runtime</filename>. + ''; + + type = with types; attrsOf (submodule ( + { name, config, ... }: + { options = { + + enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether this /etc file should be generated. This + option allows specific /etc files to be disabled. + ''; + }; + + target = mkOption { + type = types.str; + description = '' + Name of symlink. Defaults to the attribute + name. + ''; + }; + + text = mkOption { + default = null; + type = types.nullOr types.lines; + description = "Text of the file."; + }; + + source = mkOption { + type = types.path; + description = "Path of the source file."; + }; + + }; + + config = { + target = mkDefault name; + source = mkIf (config.text != null) ( + let name' = "neovim-runtime" + baseNameOf name; + in mkDefault (pkgs.writeText name' config.text)); + }; + + })); + + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ + cfg.finalPackage + ]; + environment.variables = { EDITOR = mkOverride 900 "nvim"; }; + + programs.neovim.finalPackage = pkgs.wrapNeovim cfg.package { + inherit (cfg) viAlias vimAlias; + configure = cfg.configure // { + + customRC = (cfg.configure.customRC or "") + '' + set runtimepath^=${runtime}/etc + ''; + }; + }; + }; +} diff --git a/nixos/modules/programs/nm-applet.nix b/nixos/modules/programs/nm-applet.nix index 273a6dec59a..5bcee30125b 100644 --- a/nixos/modules/programs/nm-applet.nix +++ b/nixos/modules/programs/nm-applet.nix @@ -5,14 +5,25 @@ maintainers = lib.teams.freedesktop.members; }; - options.programs.nm-applet.enable = lib.mkEnableOption "nm-applet"; + options.programs.nm-applet = { + enable = lib.mkEnableOption "nm-applet"; + + indicator = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Whether to use indicator instead of status icon. + It is needed for Appindicator environments, like Enlightenment. + ''; + }; + }; config = lib.mkIf config.programs.nm-applet.enable { systemd.user.services.nm-applet = { description = "Network manager applet"; wantedBy = [ "graphical-session.target" ]; partOf = [ "graphical-session.target" ]; - serviceConfig.ExecStart = "${pkgs.networkmanagerapplet}/bin/nm-applet"; + serviceConfig.ExecStart = "${pkgs.networkmanagerapplet}/bin/nm-applet ${lib.optionalString config.programs.nm-applet.indicator "--indicator"}"; }; services.dbus.packages = [ pkgs.gcr ]; diff --git a/nixos/modules/programs/noisetorch.nix b/nixos/modules/programs/noisetorch.nix new file mode 100644 index 00000000000..5f3b0c8f5d1 --- /dev/null +++ b/nixos/modules/programs/noisetorch.nix @@ -0,0 +1,25 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let cfg = config.programs.noisetorch; +in { + options.programs.noisetorch = { + enable = mkEnableOption "noisetorch + setcap wrapper"; + + package = mkOption { + type = types.package; + default = pkgs.noisetorch; + description = '' + The noisetorch package to use. + ''; + }; + }; + + config = mkIf cfg.enable { + security.wrappers.noisetorch = { + source = "${cfg.package}/bin/noisetorch"; + capabilities = "cap_sys_resource=+ep"; + }; + }; +} diff --git a/nixos/modules/programs/partition-manager.nix b/nixos/modules/programs/partition-manager.nix new file mode 100644 index 00000000000..1be2f0a69a1 --- /dev/null +++ b/nixos/modules/programs/partition-manager.nix @@ -0,0 +1,19 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + meta.maintainers = [ maintainers.oxalica ]; + + ###### interface + options = { + programs.partition-manager.enable = mkEnableOption "KDE Partition Manager"; + }; + + ###### implementation + config = mkIf config.programs.partition-manager.enable { + services.dbus.packages = [ pkgs.libsForQt5.kpmcore ]; + # `kpmcore` need to be installed to pull in polkit actions. + environment.systemPackages = [ pkgs.libsForQt5.kpmcore pkgs.partition-manager ]; + }; +} diff --git a/nixos/modules/programs/phosh.nix b/nixos/modules/programs/phosh.nix new file mode 100644 index 00000000000..cba3f73768e --- /dev/null +++ b/nixos/modules/programs/phosh.nix @@ -0,0 +1,163 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.phosh; + + # Based on https://source.puri.sm/Librem5/librem5-base/-/blob/4596c1056dd75ac7f043aede07887990fd46f572/default/sm.puri.OSK0.desktop + oskItem = pkgs.makeDesktopItem { + name = "sm.puri.OSK0"; + type = "Application"; + desktopName = "On-screen keyboard"; + exec = "${pkgs.squeekboard}/bin/squeekboard"; + categories = "GNOME;Core;"; + extraEntries = '' + OnlyShowIn=GNOME; + NoDisplay=true + X-GNOME-Autostart-Phase=Panel + X-GNOME-Provides=inputmethod + X-GNOME-Autostart-Notify=true + X-GNOME-AutoRestart=true + ''; + }; + + phocConfigType = types.submodule { + options = { + xwayland = mkOption { + description = '' + Whether to enable XWayland support. + + To start XWayland immediately, use `immediate`. + ''; + type = types.enum [ "true" "false" "immediate" ]; + default = "false"; + }; + cursorTheme = mkOption { + description = '' + Cursor theme to use in Phosh. + ''; + type = types.str; + default = "default"; + }; + outputs = mkOption { + description = '' + Output configurations. + ''; + type = types.attrsOf phocOutputType; + default = { + DSI-1 = { + scale = 2; + }; + }; + }; + }; + }; + + phocOutputType = types.submodule { + options = { + modeline = mkOption { + description = '' + One or more modelines. + ''; + type = types.either types.str (types.listOf types.str); + default = []; + example = [ + "87.25 720 776 848 976 1440 1443 1453 1493 -hsync +vsync" + "65.13 768 816 896 1024 1024 1025 1028 1060 -HSync +VSync" + ]; + }; + mode = mkOption { + description = '' + Default video mode. + ''; + type = types.nullOr types.str; + default = null; + example = "768x1024"; + }; + scale = mkOption { + description = '' + Display scaling factor. + ''; + type = types.nullOr types.ints.unsigned; + default = null; + example = 2; + }; + rotate = mkOption { + description = '' + Screen transformation. + ''; + type = types.enum [ + "90" "180" "270" "flipped" "flipped-90" "flipped-180" "flipped-270" null + ]; + default = null; + }; + }; + }; + + optionalKV = k: v: if v == null then "" else "${k} = ${builtins.toString v}"; + + renderPhocOutput = name: output: let + modelines = if builtins.isList output.modeline + then output.modeline + else [ output.modeline ]; + renderModeline = l: "modeline = ${l}"; + in '' + [output:${name}] + ${concatStringsSep "\n" (map renderModeline modelines)} + ${optionalKV "mode" output.mode} + ${optionalKV "scale" output.scale} + ${optionalKV "rotate" output.rotate} + ''; + + renderPhocConfig = phoc: let + outputs = mapAttrsToList renderPhocOutput phoc.outputs; + in '' + [core] + xwayland = ${phoc.xwayland} + ${concatStringsSep "\n" outputs} + [cursor] + theme = ${phoc.cursorTheme} + ''; +in { + options = { + programs.phosh = { + enable = mkEnableOption '' + Whether to enable, Phosh, related packages and default configurations. + ''; + phocConfig = mkOption { + description = '' + Configurations for the Phoc compositor. + ''; + type = types.oneOf [ types.lines types.path phocConfigType ]; + default = {}; + }; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ + pkgs.phoc + pkgs.phosh + pkgs.squeekboard + oskItem + ]; + + systemd.packages = [ pkgs.phosh ]; + + programs.feedbackd.enable = true; + + security.pam.services.phosh = {}; + + hardware.opengl.enable = mkDefault true; + + services.gnome.core-shell.enable = true; + services.gnome.core-os-services.enable = true; + services.xserver.displayManager.sessionPackages = [ pkgs.phosh ]; + + environment.etc."phosh/phoc.ini".source = + if builtins.isPath cfg.phocConfig then cfg.phocConfig + else if builtins.isString cfg.phocConfig then pkgs.writeText "phoc.ini" cfg.phocConfig + else pkgs.writeText "phoc.ini" (renderPhocConfig cfg.phocConfig); + }; +} diff --git a/nixos/modules/programs/proxychains.nix b/nixos/modules/programs/proxychains.nix new file mode 100644 index 00000000000..7743f79c1c0 --- /dev/null +++ b/nixos/modules/programs/proxychains.nix @@ -0,0 +1,165 @@ +{ config, lib, pkgs, ... }: +with lib; +let + + cfg = config.programs.proxychains; + + configFile = '' + ${cfg.chain.type}_chain + ${optionalString (cfg.chain.type == "random") + "chain_len = ${builtins.toString cfg.chain.length}"} + ${optionalString cfg.proxyDNS "proxy_dns"} + ${optionalString cfg.quietMode "quiet_mode"} + remote_dns_subnet ${builtins.toString cfg.remoteDNSSubnet} + tcp_read_time_out ${builtins.toString cfg.tcpReadTimeOut} + tcp_connect_time_out ${builtins.toString cfg.tcpConnectTimeOut} + localnet ${cfg.localnet} + [ProxyList] + ${builtins.concatStringsSep "\n" + (lib.mapAttrsToList (k: v: "${v.type} ${v.host} ${builtins.toString v.port}") + (lib.filterAttrs (k: v: v.enable) cfg.proxies))} + ''; + + proxyOptions = { + options = { + enable = mkEnableOption "this proxy"; + + type = mkOption { + type = types.enum [ "http" "socks4" "socks5" ]; + description = "Proxy type."; + }; + + host = mkOption { + type = types.str; + description = "Proxy host or IP address."; + }; + + port = mkOption { + type = types.port; + description = "Proxy port"; + }; + }; + }; + +in { + + ###### interface + + options = { + + programs.proxychains = { + + enable = mkEnableOption "installing proxychains configuration"; + + chain = { + type = mkOption { + type = types.enum [ "dynamic" "strict" "random" ]; + default = "strict"; + description = '' + <literal>dynamic</literal> - Each connection will be done via chained proxies + all proxies chained in the order as they appear in the list + at least one proxy must be online to play in chain + (dead proxies are skipped) + otherwise <literal>EINTR</literal> is returned to the app. + + <literal>strict</literal> - Each connection will be done via chained proxies + all proxies chained in the order as they appear in the list + all proxies must be online to play in chain + otherwise <literal>EINTR</literal> is returned to the app. + + <literal>random</literal> - Each connection will be done via random proxy + (or proxy chain, see <option>programs.proxychains.chain.length</option>) from the list. + ''; + }; + length = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Chain length for random chain. + ''; + }; + }; + + proxyDNS = mkOption { + type = types.bool; + default = true; + description = "Proxy DNS requests - no leak for DNS data."; + }; + + quietMode = mkEnableOption "Quiet mode (no output from the library)."; + + remoteDNSSubnet = mkOption { + type = types.enum [ 10 127 224 ]; + default = 224; + description = '' + Set the class A subnet number to use for the internal remote DNS mapping, uses the reserved 224.x.x.x range by default. + ''; + }; + + tcpReadTimeOut = mkOption { + type = types.int; + default = 15000; + description = "Connection read time-out in milliseconds."; + }; + + tcpConnectTimeOut = mkOption { + type = types.int; + default = 8000; + description = "Connection time-out in milliseconds."; + }; + + localnet = mkOption { + type = types.str; + default = "127.0.0.0/255.0.0.0"; + description = "By default enable localnet for loopback address ranges."; + }; + + proxies = mkOption { + type = types.attrsOf (types.submodule proxyOptions); + description = '' + Proxies to be used by proxychains. + ''; + + example = literalExample '' + { myproxy = + { type = "socks4"; + host = "127.0.0.1"; + port = 1337; + }; + } + ''; + }; + + }; + + }; + + ###### implementation + + meta.maintainers = with maintainers; [ sorki ]; + + config = mkIf cfg.enable { + + assertions = singleton { + assertion = cfg.chain.type != "random" && cfg.chain.length == null; + message = '' + Option `programs.proxychains.chain.length` + only makes sense with `programs.proxychains.chain.type` = "random". + ''; + }; + + programs.proxychains.proxies = mkIf config.services.tor.client.enable + { + torproxy = mkDefault { + enable = true; + type = "socks4"; + host = "127.0.0.1"; + port = 9050; + }; + }; + + environment.etc."proxychains.conf".text = configFile; + environment.systemPackages = [ pkgs.proxychains ]; + }; + +} diff --git a/nixos/modules/programs/qt5ct.nix b/nixos/modules/programs/qt5ct.nix index aeb7fc50849..3f2bcf62283 100644 --- a/nixos/modules/programs/qt5ct.nix +++ b/nixos/modules/programs/qt5ct.nix @@ -26,6 +26,6 @@ with lib; ###### implementation config = mkIf config.programs.qt5ct.enable { environment.variables.QT_QPA_PLATFORMTHEME = "qt5ct"; - environment.systemPackages = with pkgs; [ qt5ct libsForQt5.qtstyleplugins ]; + environment.systemPackages = with pkgs; [ qt5ct ]; }; } diff --git a/nixos/modules/programs/seahorse.nix b/nixos/modules/programs/seahorse.nix index b229d2a2c0d..c0a356bff57 100644 --- a/nixos/modules/programs/seahorse.nix +++ b/nixos/modules/programs/seahorse.nix @@ -31,14 +31,14 @@ with lib; config = mkIf config.programs.seahorse.enable { - programs.ssh.askPassword = mkDefault "${pkgs.gnome3.seahorse}/libexec/seahorse/ssh-askpass"; + programs.ssh.askPassword = mkDefault "${pkgs.gnome.seahorse}/libexec/seahorse/ssh-askpass"; environment.systemPackages = [ - pkgs.gnome3.seahorse + pkgs.gnome.seahorse ]; services.dbus.packages = [ - pkgs.gnome3.seahorse + pkgs.gnome.seahorse ]; }; diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix index a983ffa4b89..d4a7769bbd6 100644 --- a/nixos/modules/programs/ssh.nix +++ b/nixos/modules/programs/ssh.nix @@ -36,7 +36,7 @@ in askPassword = mkOption { type = types.str; default = "${pkgs.x11_ssh_askpass}/libexec/x11-ssh-askpass"; - description = ''Program used by SSH to ask for passwords.''; + description = "Program used by SSH to ask for passwords."; }; forwardX11 = mkOption { @@ -131,7 +131,7 @@ in knownHosts = mkOption { default = {}; - type = types.loaOf (types.submodule ({ name, ... }: { + type = types.attrsOf (types.submodule ({ name, ... }: { options = { certAuthority = mkOption { type = types.bool; diff --git a/nixos/modules/programs/ssmtp.nix b/nixos/modules/programs/ssmtp.nix index 15d2750c193..8b500f0383f 100644 --- a/nixos/modules/programs/ssmtp.nix +++ b/nixos/modules/programs/ssmtp.nix @@ -1,6 +1,6 @@ # Configuration for `ssmtp', a trivial mail transfer agent that can # replace sendmail/postfix on simple systems. It delivers email -# directly to an SMTP server defined in its configuration file, wihout +# directly to an SMTP server defined in its configuration file, without # queueing mail locally. { config, lib, pkgs, ... }: @@ -124,7 +124,8 @@ in example = "/run/keys/ssmtp-authpass"; description = '' Path to a file that contains the password used for SMTP auth. The file - should not contain a trailing newline, if the password does not contain one. + should not contain a trailing newline, if the password does not contain one + (e.g. use <command>echo -n "password" > file</command>). This file should be readable by the users that need to execute ssmtp. ''; }; @@ -142,6 +143,13 @@ in config = mkIf cfg.enable { + assertions = [ + { + assertion = cfg.useSTARTTLS -> cfg.useTLS; + message = "services.ssmtp.useSTARTTLS has no effect without services.ssmtp.useTLS"; + } + ]; + services.ssmtp.settings = mkMerge [ ({ MailHub = cfg.hostName; @@ -155,15 +163,16 @@ in (mkIf (cfg.authPassFile != null) { AuthPassFile = cfg.authPassFile; }) ]; - environment.etc."ssmtp/ssmtp.conf".source = - let - toStr = value: + # careful here: ssmtp REQUIRES all config lines to end with a newline char! + environment.etc."ssmtp/ssmtp.conf".text = with generators; toKeyValue { + mkKeyValue = mkKeyValueDefault { + mkValueString = value: if value == true then "YES" else if value == false then "NO" - else builtins.toString value + else mkValueStringDefault {} value ; - in - pkgs.writeText "ssmtp.conf" (concatStringsSep "\n" (mapAttrsToList (key: value: "${key}=${toStr value}") cfg.settings)); + } "="; + } cfg.settings; environment.systemPackages = [pkgs.ssmtp]; diff --git a/nixos/modules/programs/steam.nix b/nixos/modules/programs/steam.nix index 3c919c47a0c..ff4deba2bf0 100644 --- a/nixos/modules/programs/steam.nix +++ b/nixos/modules/programs/steam.nix @@ -4,12 +4,38 @@ with lib; let cfg = config.programs.steam; + + steam = pkgs.steam.override { + extraLibraries = pkgs: with config.hardware.opengl; + if pkgs.hostPlatform.is64bit + then [ package ] ++ extraPackages + else [ package32 ] ++ extraPackages32; + }; in { - options.programs.steam.enable = mkEnableOption "steam"; + options.programs.steam = { + enable = mkEnableOption "steam"; + + remotePlay.openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open ports in the firewall for Steam Remote Play. + ''; + }; + + dedicatedServer.openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open ports in the firewall for Source Dedicated Server. + ''; + }; + }; config = mkIf cfg.enable { hardware.opengl = { # this fixes the "glXChooseVisual failed" bug, context: https://github.com/NixOS/nixpkgs/issues/47932 enable = true; + driSupport = true; driSupport32Bit = true; }; @@ -18,7 +44,19 @@ in { hardware.steam-hardware.enable = true; - environment.systemPackages = [ pkgs.steam ]; + environment.systemPackages = [ steam steam.run ]; + + networking.firewall = lib.mkMerge [ + (mkIf cfg.remotePlay.openFirewall { + allowedTCPPorts = [ 27036 ]; + allowedUDPPortRanges = [ { from = 27031; to = 27036; } ]; + }) + + (mkIf cfg.dedicatedServer.openFirewall { + allowedTCPPorts = [ 27015 ]; # SRCDS Rcon port + allowedUDPPorts = [ 27015 ]; # Gameplay traffic + }) + ]; }; meta.maintainers = with maintainers; [ mkg20001 ]; diff --git a/nixos/modules/programs/sway.nix b/nixos/modules/programs/sway.nix index 364debddb0f..d5819a08e8f 100644 --- a/nixos/modules/programs/sway.nix +++ b/nixos/modules/programs/sway.nix @@ -31,6 +31,7 @@ let extraOptions = cfg.extraOptions; withBaseWrapper = cfg.wrapperFeatures.base; withGtkWrapper = cfg.wrapperFeatures.gtk; + isNixOS = true; }; in { options.programs.sway = { @@ -38,9 +39,8 @@ in { Sway, the i3-compatible tiling Wayland compositor. You can manually launch Sway by executing "exec sway" on a TTY. Copy /etc/sway/config to ~/.config/sway/config to modify the default configuration. See - https://github.com/swaywm/sway/wiki and "man 5 sway" for more information. - Please have a look at the "extraSessionCommands" example for running - programs natively under Wayland''; + <link xlink:href="https://github.com/swaywm/sway/wiki" /> and + "man 5 sway" for more information''; wrapperFeatures = mkOption { type = wrapperOptions; @@ -55,16 +55,20 @@ in { type = types.lines; default = ""; example = '' + # SDL: export SDL_VIDEODRIVER=wayland - # needs qt5.qtwayland in systemPackages - export QT_QPA_PLATFORM=wayland + # QT (needs qt5.qtwayland in systemPackages): + export QT_QPA_PLATFORM=wayland-egl export QT_WAYLAND_DISABLE_WINDOWDECORATION="1" # Fix for some Java AWT applications (e.g. Android Studio), # use this if they aren't displayed properly: export _JAVA_AWT_WM_NONREPARENTING=1 ''; description = '' - Shell commands executed just before Sway is started. + Shell commands executed just before Sway is started. See + <link xlink:href="https://github.com/swaywm/sway/wiki/Running-programs-natively-under-wayland" /> + and <link xlink:href="https://github.com/swaywm/wlroots/blob/master/docs/env_vars.md" /> + for some useful environment variables. ''; }; @@ -86,24 +90,25 @@ in { extraPackages = mkOption { type = with types; listOf package; default = with pkgs; [ - swaylock swayidle - xwayland alacritty dmenu - rxvt-unicode # For backward compatibility (old default terminal) + swaylock swayidle alacritty dmenu ]; defaultText = literalExample '' - with pkgs; [ swaylock swayidle xwayland rxvt-unicode dmenu ]; + with pkgs; [ swaylock swayidle alacritty dmenu ]; ''; example = literalExample '' with pkgs; [ - xwayland i3status i3status-rust termite rofi light ] ''; description = '' - Extra packages to be installed system wide. + Extra packages to be installed system wide. See + <link xlink:href="https://github.com/swaywm/sway/wiki/Useful-add-ons-for-sway" /> and + <link xlink:href="https://github.com/swaywm/sway/wiki/i3-Migration-Guide#common-x11-apps-used-on-i3-with-wayland-alternatives" /> + for a list of useful software. ''; }; + }; config = mkIf cfg.enable { @@ -120,8 +125,11 @@ in { systemPackages = [ swayPackage ] ++ cfg.extraPackages; etc = { "sway/config".source = mkOptionDefault "${swayPackage}/etc/sway/config"; - #"sway/security.d".source = mkOptionDefault "${swayPackage}/etc/sway/security.d/"; - #"sway/config.d".source = mkOptionDefault "${swayPackage}/etc/sway/config.d/"; + "sway/config.d/nixos.conf".source = pkgs.writeText "nixos.conf" '' + # Import the most important environment variables into the D-Bus and systemd + # user environments (e.g. required for screen sharing and Pinentry prompts): + exec dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP + ''; }; }; security.pam.services.swaylock = {}; @@ -130,7 +138,10 @@ in { programs.dconf.enable = mkDefault true; # To make a Sway session available if a display manager like SDDM is enabled: services.xserver.displayManager.sessionPackages = [ swayPackage ]; + programs.xwayland.enable = mkDefault true; + # For screen sharing (this option only has an effect with xdg.portal.enable): + xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-wlr ]; }; - meta.maintainers = with lib.maintainers; [ gnidorah primeos colemickens ]; + meta.maintainers = with lib.maintainers; [ primeos colemickens ]; } diff --git a/nixos/modules/programs/tilp2.nix b/nixos/modules/programs/tilp2.nix new file mode 100644 index 00000000000..da9e32e3e6c --- /dev/null +++ b/nixos/modules/programs/tilp2.nix @@ -0,0 +1,28 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.programs.tilp2; + +in { + options.programs.tilp2 = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable tilp2 and udev rules for supported calculators. + ''; + }; + }; + + config = mkIf cfg.enable { + services.udev.packages = [ + pkgs.libticables2 + ]; + + environment.systemPackages = [ + pkgs.tilp2 + ]; + }; +} diff --git a/nixos/modules/programs/tsm-client.nix b/nixos/modules/programs/tsm-client.nix index eb6f1247528..7ac4086d5f0 100644 --- a/nixos/modules/programs/tsm-client.nix +++ b/nixos/modules/programs/tsm-client.nix @@ -7,7 +7,7 @@ let inherit (lib.modules) mkDefault mkIf; inherit (lib.options) literalExample mkEnableOption mkOption; inherit (lib.strings) concatStringsSep optionalString toLower; - inherit (lib.types) addCheck attrsOf lines loaOf nullOr package path port str strMatching submodule; + inherit (lib.types) addCheck attrsOf lines nullOr package path port str strMatching submodule; # Checks if given list of strings contains unique # elements when compared without considering case. @@ -178,7 +178,7 @@ let client system-options file "dsm.sys" ''; servers = mkOption { - type = loaOf (submodule [ serverOptions ]); + type = attrsOf (submodule [ serverOptions ]); default = {}; example.mainTsmServer = { server = "tsmserver.company.com"; diff --git a/nixos/modules/programs/turbovnc.nix b/nixos/modules/programs/turbovnc.nix new file mode 100644 index 00000000000..e6f8836aa36 --- /dev/null +++ b/nixos/modules/programs/turbovnc.nix @@ -0,0 +1,54 @@ +# Global configuration for the SSH client. + +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.turbovnc; +in +{ + options = { + + programs.turbovnc = { + + ensureHeadlessSoftwareOpenGL = mkOption { + type = types.bool; + default = false; + description = '' + Whether to set up NixOS such that TurboVNC's built-in software OpenGL + implementation works. + + This will enable <option>hardware.opengl.enable</option> so that OpenGL + programs can find Mesa's llvmpipe drivers. + + Setting this option to <code>false</code> does not mean that software + OpenGL won't work; it may still work depending on your system + configuration. + + This option is also intended to generate warnings if you are using some + configuration that's incompatible with using headless software OpenGL + in TurboVNC. + ''; + }; + + }; + + }; + + config = mkIf cfg.ensureHeadlessSoftwareOpenGL { + + # TurboVNC has builtin support for Mesa llvmpipe's `swrast` + # software rendering to implemnt GLX (OpenGL on Xorg). + # However, just building TurboVNC with support for that is not enough + # (it only takes care of the X server side part of OpenGL); + # the indiviudual applications (e.g. `glxgears`) also need to directly load + # the OpenGL libs. + # Thus, this creates `/run/opengl-driver` populated by Mesa so that the applications + # can find the llvmpipe `swrast.so` software rendering DRI lib via `libglvnd`. + # This comment exists to explain why `hardware.` is involved, + # even though 100% software rendering is used. + hardware.opengl.enable = true; + + }; +} diff --git a/nixos/modules/programs/udevil.nix b/nixos/modules/programs/udevil.nix index ba5670f9dfe..25975d88ec8 100644 --- a/nixos/modules/programs/udevil.nix +++ b/nixos/modules/programs/udevil.nix @@ -10,5 +10,8 @@ in { config = mkIf cfg.enable { security.wrappers.udevil.source = "${lib.getBin pkgs.udevil}/bin/udevil"; + + systemd.packages = [ pkgs.udevil ]; + systemd.services."devmon@".wantedBy = [ "multi-user.target" ]; }; } diff --git a/nixos/modules/programs/venus.nix b/nixos/modules/programs/venus.nix deleted file mode 100644 index 58faf38777d..00000000000 --- a/nixos/modules/programs/venus.nix +++ /dev/null @@ -1,173 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; -let - cfg = config.services.venus; - - configFile = pkgs.writeText "venus.ini" - '' - [Planet] - name = ${cfg.name} - link = ${cfg.link} - owner_name = ${cfg.ownerName} - owner_email = ${cfg.ownerEmail} - output_theme = ${cfg.cacheDirectory}/theme - output_dir = ${cfg.outputDirectory} - cache_directory = ${cfg.cacheDirectory} - items_per_page = ${toString cfg.itemsPerPage} - ${(concatStringsSep "\n\n" - (map ({ name, feedUrl, homepageUrl }: - '' - [${feedUrl}] - name = ${name} - link = ${homepageUrl} - '') cfg.feeds))} - ''; - -in -{ - - options = { - services.venus = { - enable = mkOption { - default = false; - type = types.bool; - description = '' - Planet Venus is an awesome ‘river of news’ feed reader. It downloads - news feeds published by web sites and aggregates their content - together into a single combined feed, latest news first. - ''; - }; - - dates = mkOption { - default = "*:0/15"; - type = types.str; - description = '' - Specification (in the format described by - <citerefentry><refentrytitle>systemd.time</refentrytitle> - <manvolnum>7</manvolnum></citerefentry>) of the time at - which the Venus will collect feeds. - ''; - }; - - user = mkOption { - default = "root"; - type = types.str; - description = '' - User for running venus script. - ''; - }; - - group = mkOption { - default = "root"; - type = types.str; - description = '' - Group for running venus script. - ''; - }; - - name = mkOption { - default = "NixOS Planet"; - type = types.str; - description = '' - Your planet's name. - ''; - }; - - link = mkOption { - default = "https://planet.nixos.org"; - type = types.str; - description = '' - Link to the main page. - ''; - }; - - ownerName = mkOption { - default = "Rok Garbas"; - type = types.str; - description = '' - Your name. - ''; - }; - - ownerEmail = mkOption { - default = "some@example.com"; - type = types.str; - description = '' - Your e-mail address. - ''; - }; - - outputTheme = mkOption { - default = "${pkgs.venus}/themes/classic_fancy"; - type = types.path; - description = '' - Directory containing a config.ini file which is merged with this one. - This is typically used to specify templating and bill of material - information. - ''; - }; - - outputDirectory = mkOption { - type = types.path; - description = '' - Directory to place output files. - ''; - }; - - cacheDirectory = mkOption { - default = "/var/cache/venus"; - type = types.path; - description = '' - Where cached feeds are stored. - ''; - }; - - itemsPerPage = mkOption { - default = 15; - type = types.int; - description = '' - How many items to put on each page. - ''; - }; - - feeds = mkOption { - default = []; - example = [ - { - name = "Rok Garbas"; - feedUrl= "http://url/to/rss/feed.xml"; - homepageUrl = "http://garbas.si"; - } - ]; - description = '' - List of feeds. - ''; - }; - - }; - }; - - config = mkIf cfg.enable { - - system.activationScripts.venus = - '' - mkdir -p ${cfg.outputDirectory} - chown ${cfg.user}:${cfg.group} ${cfg.outputDirectory} -R - rm -rf ${cfg.cacheDirectory}/theme - mkdir -p ${cfg.cacheDirectory}/theme - cp -R ${cfg.outputTheme}/* ${cfg.cacheDirectory}/theme - chown ${cfg.user}:${cfg.group} ${cfg.cacheDirectory} -R - ''; - - systemd.services.venus = - { description = "Planet Venus Feed Reader"; - path = [ pkgs.venus ]; - script = "exec venus-planet ${configFile}"; - serviceConfig.User = "${cfg.user}"; - serviceConfig.Group = "${cfg.group}"; - startAt = cfg.dates; - }; - - }; -} diff --git a/nixos/modules/programs/vim.nix b/nixos/modules/programs/vim.nix index fe0e7f2c6d6..9f46dff2a29 100644 --- a/nixos/modules/programs/vim.nix +++ b/nixos/modules/programs/vim.nix @@ -14,10 +14,20 @@ in { using the EDITOR environment variable. ''; }; + + package = mkOption { + type = types.package; + default = pkgs.vim; + defaultText = "pkgs.vim"; + example = "pkgs.vimHugeX"; + description = '' + vim package to use. + ''; + }; }; config = mkIf cfg.defaultEditor { - environment.systemPackages = [ pkgs.vim ]; - environment.variables = { EDITOR = mkOverride 900 "vim"; }; + environment.systemPackages = [ cfg.package ]; + environment.variables = { EDITOR = mkOverride 900 "vim"; }; }; } diff --git a/nixos/modules/programs/wshowkeys.nix b/nixos/modules/programs/wshowkeys.nix new file mode 100644 index 00000000000..09b008af1d5 --- /dev/null +++ b/nixos/modules/programs/wshowkeys.nix @@ -0,0 +1,22 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.wshowkeys; +in { + meta.maintainers = with maintainers; [ primeos ]; + + options = { + programs.wshowkeys = { + enable = mkEnableOption '' + wshowkeys (displays keypresses on screen on supported Wayland + compositors). It requires root permissions to read input events, but + these permissions are dropped after startup''; + }; + }; + + config = mkIf cfg.enable { + security.wrappers.wshowkeys.source = "${pkgs.wshowkeys}/bin/wshowkeys"; + }; +} diff --git a/nixos/modules/programs/x2goserver.nix b/nixos/modules/programs/x2goserver.nix deleted file mode 100644 index 7d74231e956..00000000000 --- a/nixos/modules/programs/x2goserver.nix +++ /dev/null @@ -1,149 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - cfg = config.programs.x2goserver; - - defaults = { - superenicer = { enable = cfg.superenicer.enable; }; - }; - confText = generators.toINI {} (recursiveUpdate defaults cfg.settings); - x2goServerConf = pkgs.writeText "x2goserver.conf" confText; - - x2goAgentOptions = pkgs.writeText "x2goagent.options" '' - X2GO_NXOPTIONS="" - X2GO_NXAGENT_DEFAULT_OPTIONS="${concatStringsSep " " cfg.nxagentDefaultOptions}" - ''; - -in { - options.programs.x2goserver = { - enable = mkEnableOption "x2goserver" // { - description = '' - Enables the x2goserver module. - NOTE: This will create a good amount of symlinks in `/usr/local/bin` - ''; - }; - - superenicer = { - enable = mkEnableOption "superenicer" // { - description = '' - Enables the SupeReNicer code in x2gocleansessions, this will renice - suspended sessions to nice level 19 and renice them to level 0 if the - session becomes marked as running again - ''; - }; - }; - - nxagentDefaultOptions = mkOption { - type = types.listOf types.str; - default = [ "-extension GLX" "-nolisten tcp" ]; - example = [ "-extension GLX" "-nolisten tcp" ]; - description = '' - List of default nx agent options. - ''; - }; - - settings = mkOption { - type = types.attrsOf types.attrs; - default = {}; - description = '' - x2goserver.conf ini configuration as nix attributes. See - `x2goserver.conf(5)` for details - ''; - example = literalExample '' - superenicer = { - "enable" = "yes"; - "idle-nice-level" = 19; - }; - telekinesis = { "enable" = "no"; }; - ''; - }; - }; - - config = mkIf cfg.enable { - - environment.systemPackages = [ pkgs.x2goserver ]; - - users.groups.x2go = {}; - users.users.x2go = { - home = "/var/lib/x2go/db"; - group = "x2go"; - isSystemUser = true; - }; - - security.wrappers.x2gosqliteWrapper = { - source = "${pkgs.x2goserver}/lib/x2go/libx2go-server-db-sqlite3-wrapper.pl"; - owner = "x2go"; - group = "x2go"; - setgid = true; - }; - security.wrappers.x2goprintWrapper = { - source = "${pkgs.x2goserver}/bin/x2goprint"; - owner = "x2go"; - group = "x2go"; - setgid = true; - }; - - systemd.tmpfiles.rules = with pkgs; [ - "d /var/lib/x2go/ - x2go x2go - -" - "d /var/lib/x2go/db - x2go x2go - -" - "d /var/lib/x2go/conf - x2go x2go - -" - "d /run/x2go 0755 x2go x2go - -" - ] ++ - # x2goclient sends SSH commands with preset PATH set to - # "/usr/local/bin;/usr/bin;/bin". Since we cannot filter arbitrary ssh - # commands, we have to make the following executables available. - map (f: "L+ /usr/local/bin/${f} - - - - ${x2goserver}/bin/${f}") [ - "x2goagent" "x2gobasepath" "x2gocleansessions" "x2gocmdexitmessage" - "x2godbadmin" "x2gofeature" "x2gofeaturelist" "x2gofm" "x2gogetapps" - "x2gogetservers" "x2golistdesktops" "x2golistmounts" "x2golistsessions" - "x2golistsessions_root" "x2golistshadowsessions" "x2gomountdirs" - "x2gopath" "x2goprint" "x2goresume-desktopsharing" "x2goresume-session" - "x2goruncommand" "x2goserver-run-extensions" "x2gosessionlimit" - "x2gosetkeyboard" "x2goshowblocks" "x2gostartagent" - "x2gosuspend-desktopsharing" "x2gosuspend-session" - "x2goterminate-desktopsharing" "x2goterminate-session" - "x2goumount-session" "x2goversion" - ] ++ [ - "L+ /usr/local/bin/awk - - - - ${gawk}/bin/awk" - "L+ /usr/local/bin/chmod - - - - ${coreutils}/bin/chmod" - "L+ /usr/local/bin/cp - - - - ${coreutils}/bin/cp" - "L+ /usr/local/bin/sed - - - - ${gnused}/bin/sed" - "L+ /usr/local/bin/setsid - - - - ${utillinux}/bin/setsid" - "L+ /usr/local/bin/xrandr - - - - ${xorg.xrandr}/bin/xrandr" - "L+ /usr/local/bin/xmodmap - - - - ${xorg.xmodmap}/bin/xmodmap" - ]; - - systemd.services.x2goserver = { - description = "X2Go Server Daemon"; - wantedBy = [ "multi-user.target" ]; - unitConfig.Documentation = "man:x2goserver.conf(5)"; - serviceConfig = { - Type = "forking"; - ExecStart = "${pkgs.x2goserver}/bin/x2gocleansessions"; - PIDFile = "/run/x2go/x2goserver.pid"; - User = "x2go"; - Group = "x2go"; - RuntimeDirectory = "x2go"; - StateDirectory = "x2go"; - }; - preStart = '' - if [ ! -e /var/lib/x2go/setup_ran ] - then - mkdir -p /var/lib/x2go/conf - cp -r ${pkgs.x2goserver}/etc/x2go/* /var/lib/x2go/conf/ - ln -sf ${x2goServerConf} /var/lib/x2go/conf/x2goserver.conf - ln -sf ${x2goAgentOptions} /var/lib/x2go/conf/x2goagent.options - ${pkgs.x2goserver}/bin/x2godbadmin --createdb - touch /var/lib/x2go/setup_ran - fi - ''; - }; - - # https://bugs.x2go.org/cgi-bin/bugreport.cgi?bug=276 - security.sudo.extraConfig = '' - Defaults env_keep+=QT_GRAPHICSSYSTEM - ''; - }; -} diff --git a/nixos/modules/programs/xss-lock.nix b/nixos/modules/programs/xss-lock.nix index a7ad9b89db4..ceb7259b3d7 100644 --- a/nixos/modules/programs/xss-lock.nix +++ b/nixos/modules/programs/xss-lock.nix @@ -11,7 +11,7 @@ in lockerCommand = mkOption { default = "${pkgs.i3lock}/bin/i3lock"; - example = literalExample ''''${pkgs.i3lock-fancy}/bin/i3lock-fancy''; + example = literalExample "\${pkgs.i3lock-fancy}/bin/i3lock-fancy"; type = types.separatedString " "; description = "Locker to be used with xsslock"; }; @@ -34,7 +34,7 @@ in partOf = [ "graphical-session.target" ]; serviceConfig.ExecStart = with lib; strings.concatStringsSep " " ([ - "${pkgs.xss-lock}/bin/xss-lock" + "${pkgs.xss-lock}/bin/xss-lock" "--session \${XDG_SESSION_ID}" ] ++ (map escapeShellArg cfg.extraOptions) ++ [ "--" cfg.lockerCommand diff --git a/nixos/modules/programs/xwayland.nix b/nixos/modules/programs/xwayland.nix new file mode 100644 index 00000000000..cb3c9c5b156 --- /dev/null +++ b/nixos/modules/programs/xwayland.nix @@ -0,0 +1,51 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.xwayland; + +in + +{ + options.programs.xwayland = { + + enable = mkEnableOption "Xwayland (an X server for interfacing X11 apps with the Wayland protocol)"; + + defaultFontPath = mkOption { + type = types.str; + default = optionalString config.fonts.fontDir.enable + "/run/current-system/sw/share/X11/fonts"; + defaultText = literalExample '' + optionalString config.fonts.fontDir.enable + "/run/current-system/sw/share/X11/fonts"; + ''; + description = '' + Default font path. Setting this option causes Xwayland to be rebuilt. + ''; + }; + + package = mkOption { + type = types.path; + default = pkgs.xwayland.override (oldArgs: { + inherit (cfg) defaultFontPath; + }); + defaultText = literalExample '' + pkgs.xwayland.override (oldArgs: { + inherit (config.programs.xwayland) defaultFontPath; + }); + ''; + description = "The Xwayland package to use."; + }; + + }; + + config = mkIf cfg.enable { + + # Needed by some applications for fonts and default settings + environment.pathsToLink = [ "/share/X11" ]; + + environment.systemPackages = [ cfg.package ]; + + }; +} diff --git a/nixos/modules/programs/zsh/oh-my-zsh.xml b/nixos/modules/programs/zsh/oh-my-zsh.xml index 568c2de6557..14a7228ad9b 100644 --- a/nixos/modules/programs/zsh/oh-my-zsh.xml +++ b/nixos/modules/programs/zsh/oh-my-zsh.xml @@ -73,7 +73,7 @@ <programlisting> { pkgs, ... }: { - programs.zsh.ohMyZsh.customPkgs = with pkgs; [ + programs.zsh.ohMyZsh.customPkgs = [ pkgs.nix-zsh-completions # and even more... ]; diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix index 049a315c762..6c824a692b7 100644 --- a/nixos/modules/programs/zsh/zsh.nix +++ b/nixos/modules/programs/zsh/zsh.nix @@ -53,7 +53,7 @@ in }; shellAliases = mkOption { - default = {}; + default = { }; description = '' Set of aliases for zsh shell, which overrides <option>environment.shellAliases</option>. See <option>environment.shellAliases</option> for an option format description. @@ -91,7 +91,7 @@ in # before setting your PS1 and etc. Otherwise this will likely to interact with # your ~/.zshrc configuration in unexpected ways as the default prompt sets # a lot of different prompt variables. - autoload -U promptinit && promptinit && prompt walters && setopt prompt_sp + autoload -U promptinit && promptinit && prompt suse && setopt prompt_sp ''; description = '' Shell script code used to initialise the zsh prompt. @@ -118,7 +118,9 @@ in setOptions = mkOption { type = types.listOf types.str; default = [ - "HIST_IGNORE_DUPS" "SHARE_HISTORY" "HIST_FCNTL_LOCK" + "HIST_IGNORE_DUPS" + "SHARE_HISTORY" + "HIST_FCNTL_LOCK" ]; example = [ "EXTENDED_HISTORY" "RM_STAR_WAIT" ]; description = '' @@ -278,15 +280,29 @@ in environment.etc.zinputrc.source = ./zinputrc; - environment.systemPackages = [ pkgs.zsh ] - ++ optional cfg.enableCompletion pkgs.nix-zsh-completions; + environment.systemPackages = + let + completions = + if lib.versionAtLeast (lib.getVersion config.nix.package) "2.4pre" + then + pkgs.nix-zsh-completions.overrideAttrs + (_: { + postInstall = '' + rm $out/share/zsh/site-functions/_nix + ''; + }) + else pkgs.nix-zsh-completions; + in + [ pkgs.zsh ] + ++ optional cfg.enableCompletion completions; environment.pathsToLink = optional cfg.enableCompletion "/share/zsh"; #users.defaultUserShell = mkDefault "/run/current-system/sw/bin/zsh"; environment.shells = - [ "/run/current-system/sw/bin/zsh" + [ + "/run/current-system/sw/bin/zsh" "${pkgs.zsh}/bin/zsh" ]; |