home-manager/modules/programs/bash.nix
Emily 9f9e277b60 treewide: remove now-redundant lib.mdDoc calls
These (and the `*MD` functions apart from `literalMD`) are now no-ops
in nixpkgs and serve no purpose other than to add additional noise and
potentially mislead people into thinking unmarked DocBook documentation
will still be accepted.

Note that if backporting changes including documentation to 23.05,
the `mdDoc` calls will need to be re-added.

To reproduce this commit, run:

    $ NIX_PATH=nixpkgs=flake:nixpkgs/e7e69199f0372364a6106a1e735f68604f4c5a25 \
      nix shell nixpkgs#coreutils \
      -c find . -name '*.nix' \
      -exec nix run -- github:emilazy/nix-doc-munge/98dadf1f77351c2ba5dcb709a2a171d655f15099 \
      --strip {} +
    $ ./format
2023-07-17 18:49:09 +01:00

238 lines
6.5 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.bash;
writeBashScript = name: text:
pkgs.writeTextFile {
inherit name text;
checkPhase = ''
${pkgs.stdenv.shellDryRun} "$target"
'';
};
in {
meta.maintainers = [ maintainers.rycee ];
imports = [
(mkRenamedOptionModule [ "programs" "bash" "enableAutojump" ] [
"programs"
"autojump"
"enable"
])
];
options = {
programs.bash = {
enable = mkEnableOption "GNU Bourne-Again SHell";
enableCompletion = mkOption {
type = types.bool;
default = true;
description = ''
Whether to enable Bash completion for all interactive Bash shells.
Note, if you use NixOS or nix-darwin and do not have Bash completion
enabled in the system configuration, then make sure to add
```nix
environment.pathsToLink = [ "/share/bash-completion" ];
```
to your system configuration to get completion for system packages.
Note, the legacy {file}`/etc/bash_completion.d` path is
not supported by Home Manager.
'';
};
historySize = mkOption {
type = types.int;
default = 10000;
description = "Number of history lines to keep in memory.";
};
historyFile = mkOption {
type = types.nullOr types.str;
default = null;
description = "Location of the bash history file.";
};
historyFileSize = mkOption {
type = types.int;
default = 100000;
description = "Number of history lines to keep on file.";
};
historyControl = mkOption {
type =
types.listOf (types.enum [ "erasedups" "ignoredups" "ignorespace" ]);
default = [ ];
description = "Controlling how commands are saved on the history list.";
};
historyIgnore = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "ls" "cd" "exit" ];
description =
"List of commands that should not be saved to the history list.";
};
shellOptions = mkOption {
type = types.listOf types.str;
default = [
# Append to history file rather than replacing it.
"histappend"
# check the window size after each command and, if
# necessary, update the values of LINES and COLUMNS.
"checkwinsize"
# Extended globbing.
"extglob"
"globstar"
# Warn if closing shell with running jobs.
"checkjobs"
];
example = [ "extglob" "-cdspell" ];
description = ''
Shell options to set. Prefix an option with
"`-`" to unset.
'';
};
sessionVariables = mkOption {
default = { };
type = types.attrs;
example = { MAILCHECK = 30; };
description = ''
Environment variables that will be set for the Bash session.
'';
};
shellAliases = mkOption {
default = { };
type = types.attrsOf types.str;
example = literalExpression ''
{
ll = "ls -l";
".." = "cd ..";
}
'';
description = ''
An attribute set that maps aliases (the top level attribute names in
this option) to command strings or directly to build outputs.
'';
};
profileExtra = mkOption {
default = "";
type = types.lines;
description = ''
Extra commands that should be run when initializing a login
shell.
'';
};
initExtra = mkOption {
default = "";
type = types.lines;
description = ''
Extra commands that should be run when initializing an
interactive shell.
'';
};
bashrcExtra = mkOption {
default = "";
type = types.lines;
description = ''
Extra commands that should be placed in {file}`~/.bashrc`.
Note that these commands will be run even in non-interactive shells.
'';
};
logoutExtra = mkOption {
default = "";
type = types.lines;
description = ''
Extra commands that should be run when logging out of an
interactive shell.
'';
};
};
};
config = let
aliasesStr = concatStringsSep "\n"
(mapAttrsToList (k: v: "alias ${k}=${escapeShellArg v}")
cfg.shellAliases);
shoptsStr = let switch = v: if hasPrefix "-" v then "-u" else "-s";
in concatStringsSep "\n"
(map (v: "shopt ${switch v} ${removePrefix "-" v}") cfg.shellOptions);
sessionVarsStr = config.lib.shell.exportAll cfg.sessionVariables;
historyControlStr = concatStringsSep "\n"
(mapAttrsToList (n: v: "${n}=${v}") ({
HISTFILESIZE = toString cfg.historyFileSize;
HISTSIZE = toString cfg.historySize;
} // optionalAttrs (cfg.historyFile != null) {
HISTFILE = ''"${cfg.historyFile}"'';
} // optionalAttrs (cfg.historyControl != [ ]) {
HISTCONTROL = concatStringsSep ":" cfg.historyControl;
} // optionalAttrs (cfg.historyIgnore != [ ]) {
HISTIGNORE = escapeShellArg (concatStringsSep ":" cfg.historyIgnore);
}));
in mkIf cfg.enable {
home.file.".bash_profile".source = writeBashScript "bash_profile" ''
# include .profile if it exists
[[ -f ~/.profile ]] && . ~/.profile
# include .bashrc if it exists
[[ -f ~/.bashrc ]] && . ~/.bashrc
'';
# If completion is enabled then make sure it is sourced very early. This
# is to avoid problems if any other initialization code attempts to set up
# completion.
programs.bash.initExtra = mkIf cfg.enableCompletion (mkOrder 100 ''
if [[ ! -v BASH_COMPLETION_VERSINFO ]]; then
. "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh"
fi
'');
home.file.".profile".source = writeBashScript "profile" ''
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
${sessionVarsStr}
${cfg.profileExtra}
'';
home.file.".bashrc".source = writeBashScript "bashrc" ''
${cfg.bashrcExtra}
# Commands that should be applied only for interactive shells.
[[ $- == *i* ]] || return
${historyControlStr}
${shoptsStr}
${aliasesStr}
${cfg.initExtra}
'';
home.file.".bash_logout" = mkIf (cfg.logoutExtra != "") {
source = writeBashScript "bash_logout" cfg.logoutExtra;
};
};
}