at 17.09-beta 2.5 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 = mkEnableOption "command-not-found hook for interactive shell"; 29 30 dbPath = mkOption { 31 default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ; 32 description = '' 33 Absolute path to programs.sqlite. 34 35 By default this file will be provided by your channel 36 (nixexprs.tar.xz). 37 ''; 38 type = types.path; 39 }; 40 }; 41 42 config = mkIf cfg.enable { 43 programs.bash.interactiveShellInit = 44 '' 45 # This function is called whenever a command is not found. 46 command_not_found_handle() { 47 local p=${commandNotFound}/bin/command-not-found 48 if [ -x $p -a -f ${cfg.dbPath} ]; then 49 # Run the helper program. 50 $p "$@" 51 # Retry the command if we just installed it. 52 if [ $? = 126 ]; then 53 "$@" 54 else 55 return 127 56 fi 57 else 58 echo "$1: command not found" >&2 59 return 127 60 fi 61 } 62 ''; 63 64 programs.zsh.interactiveShellInit = 65 '' 66 # This function is called whenever a command is not found. 67 command_not_found_handler() { 68 local p=${commandNotFound}/bin/command-not-found 69 if [ -x $p -a -f ${cfg.dbPath} ]; then 70 # Run the helper program. 71 $p "$@" 72 73 # Retry the command if we just installed it. 74 if [ $? = 126 ]; then 75 "$@" 76 fi 77 else 78 # Indicate than there was an error so ZSH falls back to its default handler 79 echo "$1: command not found" >&2 80 return 127 81 fi 82 } 83 ''; 84 85 environment.systemPackages = [ commandNotFound ]; 86 }; 87 88}