-
-
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 ]; | |
| }; | |
| }; | |
| } |
@izzues I think this is because import resolution happens before everything else, so I don't think you can use pkgs there. One way to get around this would be to use builtins.fetchTarball:
{ config, pkgs, ... }:
let
nixLocateAuto = builtins.fetchTarball {
url = "https://gist.github.com/InternetUnexplorer/58e979642102d66f57188764bbf11701/archive/3046ee564fed5b60cee5e5ef39b1837c04cc3aa2.tar.gz";
sha256 = "0hz4rpd0g1096sj1bl69kywv1gg14qaq1pk03jifvq9yhcq2i8pc";
};
in {
imports = [ "${nixLocateAuto}/default.nix" ];
# ...
}You could also use builtins.fetchGit of course. And if you're using flakes you could add this gist as an input (with flake = false), but that might be overkill. Hope that helps :)
Awesome, it worked! Thank you! I had no idea fetchTarball worked for more than just tarballs lol
I also didn't know I could use fetchGit for Gists! Does that mean if I use it with flakes I can then also get updates if you update this Gist without having to manually change the URL and SHA? I still don't know how to do that but I'm gonna do some research.
It does only work for tarballs; note the file extension :). GitHub allows downloading repositories as both .zip and .tar.gz (and each gist is a repository, which is why fetchGit would also work).
Huh, I didn't notice that, but I didn't actually change mine and it still works. Just to be sure, I also ran nix store delete /nix/store/67ix3q0s2ycar9lwpq6p780nhjk5jhvd-3046ee564fed5b60cee5e5ef39b1837c04cc3aa2.zip and then rebuilt again.
Apparently fetchTarball really does work with zips! From here:
Just for completion,
builtins.fetchTarballserves the same purpose asfetchzip– download an archive and then unpack it into store. Despite the name and docs, both support tarballs and zip files. (Nix uses libarchive, andfetchzipdepends onunzipand usesgnutarfromstdenv.)
Oh neat, I didn't know that, I assumed from the name that it didn't. Thanks for letting me know!
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
Hi, thanks for this!
I'm still a newbie, so I apologize for the dumb question, but how do I use this? I tried the following but got an "infinite recursion" error: