at 23.11-pre 2.6 kB view raw
1# This module provides suggestions of packages to install if the user 2# tries to run a missing command in Bash. This is implemented using a 3# SQLite database that maps program names to Nix package names (e.g., 4# "pdflatex" is mapped to "tetex"). 5 6{ config, lib, pkgs, ... }: 7 8with lib; 9 10let 11 cfg = config.programs.command-not-found; 12 commandNotFound = pkgs.substituteAll { 13 name = "command-not-found"; 14 dir = "bin"; 15 src = ./command-not-found.pl; 16 isExecutable = true; 17 inherit (cfg) dbPath; 18 perl = pkgs.perl.withPackages (p: [ p.DBDSQLite p.StringShellQuote ]); 19 }; 20 21in 22 23{ 24 options.programs.command-not-found = { 25 26 enable = mkOption { 27 type = types.bool; 28 default = true; 29 description = lib.mdDoc '' 30 Whether interactive shells should show which Nix package (if 31 any) provides a missing command. 32 ''; 33 }; 34 35 dbPath = mkOption { 36 default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ; 37 description = lib.mdDoc '' 38 Absolute path to programs.sqlite. 39 40 By default this file will be provided by your channel 41 (nixexprs.tar.xz). 42 ''; 43 type = types.path; 44 }; 45 }; 46 47 config = mkIf cfg.enable { 48 programs.bash.interactiveShellInit = 49 '' 50 # This function is called whenever a command is not found. 51 command_not_found_handle() { 52 local p='${commandNotFound}/bin/command-not-found' 53 if [ -x "$p" ] && [ -f '${cfg.dbPath}' ]; then 54 # Run the helper program. 55 "$p" "$@" 56 # Retry the command if we just installed it. 57 if [ $? = 126 ]; then 58 "$@" 59 else 60 return 127 61 fi 62 else 63 echo "$1: command not found" >&2 64 return 127 65 fi 66 } 67 ''; 68 69 programs.zsh.interactiveShellInit = 70 '' 71 # This function is called whenever a command is not found. 72 command_not_found_handler() { 73 local p='${commandNotFound}/bin/command-not-found' 74 if [ -x "$p" ] && [ -f '${cfg.dbPath}' ]; then 75 # Run the helper program. 76 "$p" "$@" 77 78 # Retry the command if we just installed it. 79 if [ $? = 126 ]; then 80 "$@" 81 else 82 return 127 83 fi 84 else 85 # Indicate than there was an error so ZSH falls back to its default handler 86 echo "$1: command not found" >&2 87 return 127 88 fi 89 } 90 ''; 91 92 environment.systemPackages = [ commandNotFound ]; 93 }; 94 95}