summary refs log tree commit diff
path: root/nixos/modules/programs/bash/command-not-found.nix
blob: 8c86d48b0808a2de54c70063f2929ed1bfec8eb9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# This module provides suggestions of packages to install if the user
# tries to run a missing command in Bash.  This is implemented using a
# SQLite database that maps program names to Nix package names (e.g.,
# "pdflatex" is mapped to "tetex").

{ config, lib, pkgs, ... }:

with lib;

let

  commandNotFound = pkgs.substituteAll {
    name = "command-not-found";
    dir = "bin";
    src = ./command-not-found.pl;
    isExecutable = true;
    inherit (pkgs) perl;
    perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ")
      [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite ]);
  };

in

{

  programs.bash.interactiveShellInit =
    ''
      # This function is called whenever a command is not found.
      command_not_found_handle() {
        local p=/run/current-system/sw/bin/command-not-found
        if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then
          # Run the helper program.
          $p "$1"
          # Retry the command if we just installed it.
          if [ $? = 126 ]; then
            "$@"
          else
            return 127
          fi
        else
          echo "$1: command not found" >&2
          return 127
        fi
      }
    '';

  environment.systemPackages = [ commandNotFound ];

  # TODO: tab completion for uninstalled commands! :-)

}