···88with lib;
991010let
1111-1111+ cfg = config.programs.command-not-found;
1212 commandNotFound = pkgs.substituteAll {
1313 name = "command-not-found";
1414 dir = "bin";
1515 src = ./command-not-found.pl;
1616 isExecutable = true;
1717 inherit (pkgs) perl;
1818+ inherit (cfg) dbPath;
1819 perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ")
1920 [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]);
2021 };
···2223in
23242425{
2626+ options.programs.command-not-found = {
2727+2828+ enable = mkEnableOption "command-not-found hook for interactive shell";
25292626- programs.bash.interactiveShellInit =
2727- ''
2828- # This function is called whenever a command is not found.
2929- command_not_found_handle() {
3030- local p=/run/current-system/sw/bin/command-not-found
3131- if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then
3232- # Run the helper program.
3333- $p "$@"
3434- # Retry the command if we just installed it.
3535- if [ $? = 126 ]; then
3636- "$@"
3030+ dbPath = mkOption {
3131+ default = "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" ;
3232+ description = ''
3333+ Absolute path to programs.sqlite.
3434+3535+ By default this file will be provided by your channel
3636+ (nixexprs.tar.xz).
3737+ '';
3838+ type = types.path;
3939+ };
4040+ };
4141+4242+ config = mkIf cfg.enable {
4343+ programs.bash.interactiveShellInit =
4444+ ''
4545+ # This function is called whenever a command is not found.
4646+ command_not_found_handle() {
4747+ local p=${commandNotFound}
4848+ if [ -x $p -a -f ${cfg.dbPath} ]; then
4949+ # Run the helper program.
5050+ $p "$@"
5151+ # Retry the command if we just installed it.
5252+ if [ $? = 126 ]; then
5353+ "$@"
5454+ else
5555+ return 127
5656+ fi
3757 else
5858+ echo "$1: command not found" >&2
3859 return 127
3960 fi
4040- else
4141- echo "$1: command not found" >&2
4242- return 127
4343- fi
4444- }
4545- '';
6161+ }
6262+ '';
46634747- programs.zsh.interactiveShellInit =
4848- ''
4949- # This function is called whenever a command is not found.
5050- command_not_found_handler() {
5151- local p=/run/current-system/sw/bin/command-not-found
5252- if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then
5353- # Run the helper program.
5454- $p "$@"
6464+ programs.zsh.interactiveShellInit =
6565+ ''
6666+ # This function is called whenever a command is not found.
6767+ command_not_found_handler() {
6868+ local p=${commandNotFound}
6969+ if [ -x $p -a -f ${cfg.dbPath} ]; then
7070+ # Run the helper program.
7171+ $p "$@"
55725656- # Retry the command if we just installed it.
5757- if [ $? = 126 ]; then
5858- "$@"
7373+ # Retry the command if we just installed it.
7474+ if [ $? = 126 ]; then
7575+ "$@"
7676+ fi
7777+ else
7878+ # Indicate than there was an error so ZSH falls back to its default handler
7979+ echo "$1: command not found" >&2
8080+ return 127
5981 fi
6060- else
6161- # Indicate than there was an error so ZSH falls back to its default handler
6262- return 127
6363- fi
6464- }
6565- '';
8282+ }
8383+ '';
66846767- environment.systemPackages = [ commandNotFound ];
6868-6969- # TODO: tab completion for uninstalled commands! :-)
8585+ environment.systemPackages = [ commandNotFound ];
8686+ };
70877188}