summary refs log tree commit diff
path: root/nixos/modules/programs/bash
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/programs/bash')
-rw-r--r--nixos/modules/programs/bash/bash-completion.nix37
-rw-r--r--nixos/modules/programs/bash/bash.nix217
-rw-r--r--nixos/modules/programs/bash/inputrc37
-rw-r--r--nixos/modules/programs/bash/ls-colors.nix20
-rw-r--r--nixos/modules/programs/bash/undistract-me.nix36
5 files changed, 347 insertions, 0 deletions
diff --git a/nixos/modules/programs/bash/bash-completion.nix b/nixos/modules/programs/bash/bash-completion.nix
new file mode 100644
index 00000000000..b8e5b1bfa33
--- /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
new file mode 100644
index 00000000000..7281126979e
--- /dev/null
+++ b/nixos/modules/programs/bash/bash.nix
@@ -0,0 +1,217 @@
+# This module defines global configuration for the Bash shell, in
+# particular /etc/bashrc and /etc/profile.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfge = config.environment;
+
+  cfg = config.programs.bash;
+
+  bashAliases = concatStringsSep "\n" (
+    mapAttrsFlatten (k: v: "alias ${k}=${escapeShellArg v}")
+      (filterAttrs (k: v: v != null) cfg.shellAliases)
+  );
+
+in
+
+{
+  imports = [
+    (mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
+  ];
+
+  options = {
+
+    programs.bash = {
+
+      /*
+      enable = mkOption {
+        default = true;
+        description = ''
+          Whenever to configure Bash as an interactive shell.
+          Note that this tries to make Bash the default
+          <option>users.defaultUserShell</option>,
+          which in turn means that you might need to explicitly
+          set this variable if you have another shell configured
+          with NixOS.
+        '';
+        type = types.bool;
+      };
+      */
+
+      shellAliases = mkOption {
+        default = {};
+        description = ''
+          Set of aliases for bash shell, which overrides <option>environment.shellAliases</option>.
+          See <option>environment.shellAliases</option> for an option format description.
+        '';
+        type = with types; attrsOf (nullOr (either str path));
+      };
+
+      shellInit = mkOption {
+        default = "";
+        description = ''
+          Shell script code called during bash shell initialisation.
+        '';
+        type = types.lines;
+      };
+
+      loginShellInit = mkOption {
+        default = "";
+        description = ''
+          Shell script code called during login bash shell initialisation.
+        '';
+        type = types.lines;
+      };
+
+      interactiveShellInit = mkOption {
+        default = "";
+        description = ''
+          Shell script code called during interactive bash shell initialisation.
+        '';
+        type = types.lines;
+      };
+
+      promptInit = 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" ] || [ "$TERM" = "eterm" ] || [ "$TERM" = "eterm-color" ]; 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 = types.lines;
+      };
+
+      promptPluginInit = mkOption {
+        default = "";
+        description = ''
+          Shell script code used to initialise bash prompt plugins.
+        '';
+        type = types.lines;
+        internal = true;
+      };
+
+    };
+
+  };
+
+  config = /* mkIf cfg.enable */ {
+
+    programs.bash = {
+
+      shellAliases = mapAttrs (name: 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
+      '';
+
+    # Configuration for readline in bash. We use "option default"
+    # priority to allow user override using both .text and .source.
+    environment.etc.inputrc.source = mkOptionDefault ./inputrc;
+
+    users.defaultUserShell = mkDefault pkgs.bashInteractive;
+
+    environment.pathsToLink = optionals cfg.enableCompletion [
+      "/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"
+      ];
+
+  };
+
+}
diff --git a/nixos/modules/programs/bash/inputrc b/nixos/modules/programs/bash/inputrc
new file mode 100644
index 00000000000..f339eb649ed
--- /dev/null
+++ b/nixos/modules/programs/bash/inputrc
@@ -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
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 ];
+  };
+}