Move all of NixOS to nixos/ in preparation of the repository merge
This commit is contained in:
217
nixos/modules/programs/bash/bash.nix
Normal file
217
nixos/modules/programs/bash/bash.nix
Normal file
@@ -0,0 +1,217 @@
|
||||
# This module defines global configuration for the Bash shell, in
|
||||
# particular /etc/bashrc and /etc/profile.
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfge = config.environment;
|
||||
|
||||
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).
|
||||
if shopt -q progcomp &>/dev/null; then
|
||||
. "${pkgs.bashCompletion}/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/"* "$p/share/bash-completion/completions/"*; do
|
||||
. $m
|
||||
done
|
||||
done
|
||||
eval "$nullglobStatus"
|
||||
unset nullglobStatus p m
|
||||
fi
|
||||
'';
|
||||
|
||||
bashAliases = concatStringsSep "\n" (
|
||||
mapAttrsFlatten (k: v: "alias ${k}='${v}'") cfg.shellAliases
|
||||
);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
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 = config.environment.shellAliases // { which = "type -P"; };
|
||||
description = ''
|
||||
Set of aliases for bash shell. See <option>environment.shellAliases</option>
|
||||
for an option format description.
|
||||
'';
|
||||
type = types.attrs; # types.attrsOf types.stringOrPath;
|
||||
};
|
||||
|
||||
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.
|
||||
PROMPT_COLOR="1;31m"
|
||||
let $UID && PROMPT_COLOR="1;32m"
|
||||
PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
|
||||
if test "$TERM" = "xterm"; then
|
||||
PS1="\[\033]2;\h:\u:\w\007\]$PS1"
|
||||
fi
|
||||
'';
|
||||
description = ''
|
||||
Shell script code used to initialise the bash prompt.
|
||||
'';
|
||||
type = types.lines;
|
||||
};
|
||||
|
||||
enableCompletion = mkOption {
|
||||
default = false;
|
||||
description = ''
|
||||
Enable Bash completion for all interactive bash shells.
|
||||
'';
|
||||
type = types.bool;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
programs.bash = {
|
||||
|
||||
shellInit = ''
|
||||
. ${config.system.build.setEnvironment}
|
||||
|
||||
${cfge.shellInit}
|
||||
'';
|
||||
|
||||
loginShellInit = cfge.loginShellInit;
|
||||
|
||||
interactiveShellInit = ''
|
||||
${cfge.interactiveShellInit}
|
||||
|
||||
# Check the window size after every command.
|
||||
shopt -s checkwinsize
|
||||
|
||||
# Disable hashing (i.e. caching) of command lookups.
|
||||
set +h
|
||||
|
||||
${cfg.promptInit}
|
||||
${bashCompletion}
|
||||
${bashAliases}
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
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" -o -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.
|
||||
environment.etc."inputrc".source = ./inputrc;
|
||||
|
||||
users.defaultUserShell = mkDefault "/run/current-system/sw/bin/bash";
|
||||
|
||||
environment.pathsToLink = optionals cfg.enableCompletion [
|
||||
"/etc/bash_completion.d"
|
||||
"/share/bash-completion"
|
||||
];
|
||||
|
||||
environment.shells =
|
||||
[ "/run/current-system/sw/bin/bash"
|
||||
"/var/run/current-system/sw/bin/bash"
|
||||
"/run/current-system/sw/bin/sh"
|
||||
"/var/run/current-system/sw/bin/sh"
|
||||
"${pkgs.bashInteractive}/bin/bash"
|
||||
"${pkgs.bashInteractive}/bin/sh"
|
||||
];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
51
nixos/modules/programs/bash/command-not-found.nix
Normal file
51
nixos/modules/programs/bash/command-not-found.nix
Normal file
@@ -0,0 +1,51 @@
|
||||
# This module provides suggestions of packages to install if the user
|
||||
# tries to run a missing command in Bash. This is implemented using a
|
||||
# SQLite database that maps program names to Nix package names (e.g.,
|
||||
# "pdflatex" is mapped to "tetex").
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
commandNotFound = pkgs.substituteAll {
|
||||
name = "command-not-found";
|
||||
dir = "bin";
|
||||
src = ./command-not-found.pl;
|
||||
isExecutable = true;
|
||||
inherit (pkgs) perl;
|
||||
perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ")
|
||||
[ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite ]);
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
programs.bash.interactiveShellInit =
|
||||
''
|
||||
# This function is called whenever a command is not found.
|
||||
command_not_found_handle() {
|
||||
local p=/run/current-system/sw/bin/command-not-found
|
||||
if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then
|
||||
# Run the helper program.
|
||||
$p "$1"
|
||||
# Retry the command if we just installed it.
|
||||
if [ $? = 126 ]; then
|
||||
"$@"
|
||||
else
|
||||
return 127
|
||||
fi
|
||||
else
|
||||
echo "$1: command not found" >&2
|
||||
return 127
|
||||
fi
|
||||
}
|
||||
'';
|
||||
|
||||
environment.systemPackages = [ commandNotFound ];
|
||||
|
||||
# TODO: tab completion for uninstalled commands! :-)
|
||||
|
||||
}
|
||||
48
nixos/modules/programs/bash/command-not-found.pl
Normal file
48
nixos/modules/programs/bash/command-not-found.pl
Normal file
@@ -0,0 +1,48 @@
|
||||
#! @perl@/bin/perl -w @perlFlags@
|
||||
|
||||
use strict;
|
||||
use DBI;
|
||||
use DBD::SQLite;
|
||||
use Config;
|
||||
|
||||
my $program = $ARGV[0];
|
||||
|
||||
my $dbPath = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite";
|
||||
|
||||
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "")
|
||||
or die "cannot open database `$dbPath'";
|
||||
$dbh->{RaiseError} = 0;
|
||||
$dbh->{PrintError} = 0;
|
||||
|
||||
my $system = $ENV{"NIX_SYSTEM"} // $Config{myarchname};
|
||||
|
||||
my $res = $dbh->selectall_arrayref(
|
||||
"select package from Programs where system = ? and name = ?",
|
||||
{ Slice => {} }, $system, $program);
|
||||
|
||||
if (!defined $res || scalar @$res == 0) {
|
||||
print STDERR "$program: command not found\n";
|
||||
} elsif (scalar @$res == 1) {
|
||||
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.
|
||||
EOF
|
||||
;
|
||||
exit 126 if system("nix-env", "-i", $package) == 0;
|
||||
} else {
|
||||
print STDERR <<EOF;
|
||||
The program ‘$program’ is currently not installed. You can install it by typing:
|
||||
nix-env -i $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:
|
||||
EOF
|
||||
print STDERR " nix-env -i $_->{package}\n" foreach @$res;
|
||||
}
|
||||
|
||||
exit 127;
|
||||
36
nixos/modules/programs/bash/inputrc
Normal file
36
nixos/modules/programs/bash/inputrc
Normal file
@@ -0,0 +1,36 @@
|
||||
# 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 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
|
||||
Reference in New Issue
Block a user