at 18.09-beta 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 (pkgs) perl; 18 inherit (cfg) dbPath; 19 perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ") 20 [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]); 21 }; 22 23in 24 25{ 26 options.programs.command-not-found = { 27 28 enable = mkOption { 29 type = types.bool; 30 default = true; 31 description = '' 32 Whether interactive shells should show which Nix package (if 33 any) provides a missing command. 34 ''; 35 }; 36 37 dbPath = mkOption { 38 default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ; 39 description = '' 40 Absolute path to programs.sqlite. 41 42 By default this file will be provided by your channel 43 (nixexprs.tar.xz). 44 ''; 45 type = types.path; 46 }; 47 }; 48 49 config = mkIf cfg.enable { 50 programs.bash.interactiveShellInit = 51 '' 52 # This function is called whenever a command is not found. 53 command_not_found_handle() { 54 local p=${commandNotFound}/bin/command-not-found 55 if [ -x $p -a -f ${cfg.dbPath} ]; then 56 # Run the helper program. 57 $p "$@" 58 # Retry the command if we just installed it. 59 if [ $? = 126 ]; then 60 "$@" 61 else 62 return 127 63 fi 64 else 65 echo "$1: command not found" >&2 66 return 127 67 fi 68 } 69 ''; 70 71 programs.zsh.interactiveShellInit = 72 '' 73 # This function is called whenever a command is not found. 74 command_not_found_handler() { 75 local p=${commandNotFound}/bin/command-not-found 76 if [ -x $p -a -f ${cfg.dbPath} ]; then 77 # Run the helper program. 78 $p "$@" 79 80 # Retry the command if we just installed it. 81 if [ $? = 126 ]; then 82 "$@" 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}