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