diff options
Diffstat (limited to 'nixos/modules/programs/command-not-found/command-not-found.nix')
-rw-r--r-- | nixos/modules/programs/command-not-found/command-not-found.nix | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/nixos/modules/programs/command-not-found/command-not-found.nix b/nixos/modules/programs/command-not-found/command-not-found.nix new file mode 100644 index 00000000000..4d2a89b5158 --- /dev/null +++ b/nixos/modules/programs/command-not-found/command-not-found.nix @@ -0,0 +1,95 @@ +# This module provides suggestions of packages to install if the user +# tries to run a missing command in Bash. This is implemented using a +# SQLite database that maps program names to Nix package names (e.g., +# "pdflatex" is mapped to "tetex"). + +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.command-not-found; + commandNotFound = pkgs.substituteAll { + name = "command-not-found"; + dir = "bin"; + src = ./command-not-found.pl; + isExecutable = true; + inherit (cfg) dbPath; + perl = pkgs.perl.withPackages (p: [ p.DBDSQLite p.StringShellQuote ]); + }; + +in + +{ + options.programs.command-not-found = { + + enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether interactive shells should show which Nix package (if + any) provides a missing command. + ''; + }; + + dbPath = mkOption { + default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ; + description = '' + Absolute path to programs.sqlite. + + By default this file will be provided by your channel + (nixexprs.tar.xz). + ''; + type = types.path; + }; + }; + + config = mkIf cfg.enable { + programs.bash.interactiveShellInit = + '' + # This function is called whenever a command is not found. + command_not_found_handle() { + local p='${commandNotFound}/bin/command-not-found' + if [ -x "$p" ] && [ -f '${cfg.dbPath}' ]; then + # Run the helper program. + "$p" "$@" + # 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 + } + ''; + + programs.zsh.interactiveShellInit = + '' + # This function is called whenever a command is not found. + command_not_found_handler() { + local p='${commandNotFound}/bin/command-not-found' + if [ -x "$p" ] && [ -f '${cfg.dbPath}' ]; then + # Run the helper program. + "$p" "$@" + + # 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 + echo "$1: command not found" >&2 + return 127 + fi + } + ''; + + environment.systemPackages = [ commandNotFound ]; + }; + +} |