-
-
Save InternetUnexplorer/58e979642102d66f57188764bbf11701 to your computer and use it in GitHub Desktop.
| # 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 | |
| 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 ]; | |
| }; | |
| }; | |
| } |
Very cool idea, just inspired me to do some variation which may interest someone: if you use flakes to manage your system (in my case, with flake-utils-plus and its sharedOverlays option, but you can also use nixpkgs.overlays in normal flakes), it's very interesting to have the database tracked by flake.lock and saved in the nix store. Then, home-manager's home.file can be used to create a symlink in your home:
# flake.nix
{
inputs.nix-index-database.url = "github:Mic92/nix-index-database";
...
sharedOverlays = [
(final: prev: {
nix-index-database = final.runCommandLocal "nix-index-database" {} ''
mkdir -p $out
ln -s ${nix-index-database.legacyPackages.${prev.system}.database} $out/files
'';
})
];
}
# in your user's home-manager
{ pkgs, ... }: {
programs.nix-index.enable = true;
home.file.".cache/nix-index".source = pkgs.nix-index-database;
}With the above, your nix flake update will also update references of @Mic92's database, put it in a folder in store and deterministically link to it in your home-manager generation, instead of non-deterministically pulling it with wget. In my case, I didn't mind much the original nix-locate (although I admit yours is prettier), so I just used HM's default programs.nix-index module.
@andrevmatos I actually like your solution much more! nix-index-database didn't have a flake.nix when I made this, thanks for bringing it to my attention :)
Very cool idea, just inspired me to do some variation which may interest someone: if you use flakes to manage your system (in my case, with flake-utils-plus and its
sharedOverlaysoption, but you can also usenixpkgs.overlaysin normal flakes), it's very interesting to have the database tracked byflake.lockand saved in the nix store. Then,home-manager'shome.filecan be used to create a symlink in your home:# flake.nix { inputs.nix-index-database.url = "github:Mic92/nix-index-database"; ... sharedOverlays = [ (final: prev: { nix-index-database = final.runCommandLocal "nix-index-database" {} '' mkdir -p $out ln -s ${nix-index-database.legacyPackages.${prev.system}.database} $out/files ''; }) ]; } # in your user's home-manager { pkgs, ... }: { programs.nix-index.enable = true; home.file.".cache/nix-index".source = pkgs.nix-index-database; }With the above, your
nix flake updatewill also update references of @Mic92's database, put it in a folder in store and deterministically link to it in your home-manager generation, instead of non-deterministically pulling it withwget. In my case, I didn't mind much the originalnix-locate(although I admit yours is prettier), so I just used HM's defaultprograms.nix-indexmodule.
I am using this solution, but I discovered that the database is not getting updated though I updated the flake.lock
FYI: there now is a NixOS/home-manager module in the repo
Oh neat, I didn't know that, I assumed from the name that it didn't. Thanks for letting me know!