about summary refs log tree commit diff stats
path: root/modules/by-name/zs/zsh/config/command_not_found.sh
diff options
context:
space:
mode:
Diffstat (limited to 'modules/by-name/zs/zsh/config/command_not_found.sh')
-rw-r--r--modules/by-name/zs/zsh/config/command_not_found.sh64
1 files changed, 64 insertions, 0 deletions
diff --git a/modules/by-name/zs/zsh/config/command_not_found.sh b/modules/by-name/zs/zsh/config/command_not_found.sh
new file mode 100644
index 00000000..fb21b676
--- /dev/null
+++ b/modules/by-name/zs/zsh/config/command_not_found.sh
@@ -0,0 +1,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 $?
+}