Skip to content

Instantly share code, notes, and snippets.

@nebez
Forked from InternetUnexplorer/command-not-found.sh
Last active May 15, 2023 15:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nebez/47fa8522e5d52bddc36548b7ded27883 to your computer and use it in GitHub Desktop.
Save nebez/47fa8522e5d52bddc36548b7ded27883 to your computer and use it in GitHub Desktop.
Improved home-manager nix-locate configuration, with an auto-updated index and a better command-not-found handler
# Adapted from https://github.com/bennofs/nix-index/blob/master/command-not-found.sh
command_not_found_handle () {
if [ -n "${MC_SID-}" ] || ! [ -t 1 ]; then
>&2 echo "$1: command not found"
return 127
fi
echo -n "searching nix-index..."
ATTRS=$(@nix-locate@ --minimal --no-group --type x --type s --top-level --whole-name --at-root "/bin/$1")
case `echo -n "$ATTRS" | grep -c "^"` in
0)
>&2 echo -ne "$(@tput@ el1)\r"
>&2 echo "$1: command not found"
;;
*)
>&2 echo -ne "$(@tput@ el1)\r"
>&2 echo "The program ‘$(@tput@ setaf 4)$1$(@tput@ sgr0)’ is currently not installed."
>&2 echo "It is provided by the following derivation(s):"
while read ATTR; do
ATTR=$(echo "$ATTR" | sed 's|\.out$||') # Strip trailing '.out'
>&2 echo " $(@tput@ setaf 12)nixpkgs#$(@tput@ setaf 4)$ATTR$(@tput@ sgr0)"
done <<< "$ATTRS"
esac
return 127
}
command_not_found_handler () {
command_not_found_handle $@
return $?
}
{ config, pkgs, lib, ... }:
let
# Automatically download the latest index from Mic92's nix-index-database.
nix-locate = pkgs.writeShellScriptBin "nix-locate" ''
set -euo pipefail
mkdir -p ~/.cache/nix-index && cd ~/.cache/nix-index
# Check for updates at most once a day
if [ ! -f last-check ] || [ $(find last-check -mtime +1) ]; then
filename="index-x86_64-$(uname | tr A-Z a-z)"
# Prevent partial downloads
[ -f files ] || rm -f $filename
rm -f files
${pkgs.wget}/bin/wget -q -N --show-progress \
https://github.com/Mic92/nix-index-database/releases/latest/download/$filename
ln -sf $filename files
touch last-check
fi
exec ${pkgs.nix-index}/bin/nix-locate "$@"
'';
# Modified version of command-not-found.sh that uses our wrapped version of
# nix-locate, makes the output a bit less noisy, and adds color!
command-not-found = pkgs.runCommandLocal "command-not-found.sh" { } ''
mkdir -p $out/etc/profile.d
substitute ${./command-not-found.sh} \
$out/etc/profile.d/command-not-found.sh \
--replace @nix-locate@ ${nix-locate}/bin/nix-locate \
--replace @tput@ ${pkgs.ncurses}/bin/tput
'';
in {
programs.nix-index = {
enable = true;
package = pkgs.symlinkJoin {
name = "nix-index";
# Don't provide 'bin/nix-index', since the index is updated automatically
# and it is easy to forget that. It can always be run manually with
# 'nix run nixpkgs#nix-index' if necessary.
paths = [ nix-locate command-not-found ];
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment