about summary refs log tree commit diff stats
path: root/modules/home/conf/zsh/config/command_not_found.sh
blob: fb21b67691b8a9f28ba438bd45a8641dfd30f54a (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
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/usr/bin/env dash

# This was taken from the
# `${pkgs.nix-index}/etc/profile.d/command-not-found.sh` file on 2024-02-28

# for bash 4
# this will be called when a command is entered
# but not found in the user’s path + environment
command_not_found_handle() {
    # taken from http://www.linuxjournal.com/content/bash-command-not-found
    # - do not run when inside Midnight Commander or within a Pipe
    if [ -n "${MC_SID-}" ] || ! [ -t 1 ]; then
        >&2 echo "$1: command not found"
        return 127
    fi

    toplevel=nixpkgs # nixpkgs should always be available even in NixOS
    cmd="$1"
    attrs=$(nix-locate --minimal --no-group --type x --type s --top-level --whole-name --at-root "/bin/$cmd")
    len=$(if [ -n "$attrs" ]; then echo "$attrs" | wc -l; else echo 0; fi)

    case "$len" in
    0)
        eprintln "$cmd: command not found"
        ;;
    1)
        # If only one package provides this, then we can invoke it
        # without asking the user.

        # These will not return 127 if they worked correctly.

        >&2 cat <<EOF
The program '$cmd' is currently not installed. A shell will be opened
with it.
EOF
        if nix build "$toplevel#$attrs" --no-link; then
            nix shell "$toplevel#$attrs"
            return $?
        else
            >&2 cat <<EOF
Failed to build: '$toplevel#$attrs'
$cmd: command not found
EOF
        fi
        ;;
    *)
        >&2 cat <<EOF
The program '$cmd' is currently not installed. It is provided by
several packages. You can run it once with:
EOF
        awk --assign=toplevel="$toplevel" 'BEGIN{counter=0} {printf("%3s)", counter); printf("  nix shell %s#%s\n", toplevel, $1); counter+=1}' "$(ptmp "$attrs")"
        ;;
    esac

    return 127 # command not found should always exit with 127
}

# for zsh...
# we just pass it to the bash handler above
# apparently they work identically
command_not_found_handler() {
    command_not_found_handle "$@"
    return $?
}