Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 55 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,40 +48,78 @@ $ nix-env -iA nixos.nix-index
```

## Usage
First, you need to generate an index by running `nix-index` (it takes around 5 minutes) . Then, you can use `nix-locate pattern`. For more information, see `nix-locate --help` and `nix-index --help`.

### Use pre-generated database
First, you need to generate an index by running `nix-index`, which takes around 10 minutes.
Then, you can use `nix-locate <pattern>`.
For more information, see `nix-locate --help` and `nix-index --help`.

[nix-index-database](https://github.com/Mic92/nix-index-database) provides pre-generated databases if you don't want to generate a database locally.
It also comes with nixos/home-manager modules to use those databases.
### As a replacement for `command-not-found`

### Usage as a command-not-found replacement
NixOS allows displaying suggestions for packages using [`command-not-found`](https://search.nixos.org/options?show=programs.command-not-found.enable).
`nix-index` provides a replacement for `command-not-found` with more elaborate suggestions.

Nix-index provides a "command-not-found" script that can print for you the attribute path of unfound commands in your shell. You can either source `${pkgs.nix-index}/etc/command-not-found.sh` in your own shell init files (works for ZSH and Bash for as far as we know) or you can use the following in home-manager / `/etc/nixos/configuration.nix`:
#### NixOS

```nix
programs.command-not-found.enable = false;
# for home-manager, use programs.bash.initExtra instead
programs.bash.interactiveShellInit = ''
source ${pkgs.nix-index}/etc/profile.d/command-not-found.sh
'';
{ ... }:
{
programs.command-not-found.enable = false;
programs.nix-index = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
enableFishIntegration = true;
};
}
```

Replace `bash` with `zsh` if you use `zsh`.
Refer to [`programs.nix-index`](https://search.nixos.org/options?query=nix-index) option documentation for details.

Example output:

```
$ blender
The program 'blender' is currently not installed. You can install it
by typing:
nix-env -iA nixpkgs.blender.out
The program 'blender' is currently not installed.
You can install it for all users by adding to your NixOS configuration:
environment.systemPackages = with pkgs; [ blender ];

Or run it once with:
nix-shell -p blender.out --run ...
nix-shell -p blender --run blender
```

A [`home-manager` module](https://nix-community.github.io/home-manager/options.html#opt-programs.nix-index.enable) is now available to integrate `nix-index` with `bash`, `zsh`, and `fish` using this script.
#### Home Manager

```nix
{ ... }:
{
programs.command-not-found.enable = false;
programs.nix-index = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
enableFishIntegration = true;
};
}
```

Refer to Home Manager option documentation on [`programs.nix-index`](https://nix-community.github.io/home-manager/options.xhtml#opt-programs.nix-index.enable) for details.

Example output:

```
$ blender
The program 'blender' is currently not installed.
You can install it for the current user '$USER' by adding to your Home Manager configuration:
home.packages = with pkgs; [ blender ];

Or run it once with:
nix-shell -p blender --run blender
```

### With a pre-generated database

[`nix-index-database`](https://github.com/Mic92/nix-index-database) provides pre-generated databases if you don't want to generate a database locally.
It also comes with modules for NixOS, Home Manager, and nix-darwin to use those databases.

## Contributing
If you find any missing features that you would like to implement, I'm very happy about any PRs! You can also create an issue first if the feature is more complex so we can discuss possible implementations.
Expand Down
89 changes: 59 additions & 30 deletions command-not-found.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ command_not_found_handle () {
>&2 echo "$cmd: command not found"
;;
1)
>&2 cat <<EOF
The program '$cmd' is currently not installed.
EOF
# if only 1 package provides this, then we can invoke it
# without asking the users if they have opted in with one
# of 2 environment variables
Expand All @@ -40,8 +43,7 @@ command_not_found_handle () {

if ! [ -z "${NIX_AUTO_INSTALL-}" ]; then
>&2 cat <<EOF
The program '$cmd' is currently not installed. It is provided by
the package '$toplevel.$attrs', which I will now install for you.
It is provided by the package '$toplevel.${attrs%.out}', which I will now install for you.
EOF
if [ -e "$HOME/.nix-profile/manifest.json" ]; then
nix profile install $toplevel#$attrs
Expand Down Expand Up @@ -71,55 +73,82 @@ $cmd: command not found
EOF
fi
else
# The Correct Way of checking we're running Home Manager
if [ -n "$__HM_SESS_VARS_SOURCED" ]; then
>&2 cat <<EOF
Install it for the current user '$USER' by adding to your Home Manager configuration:
home.packages = with pkgs; [ ${attrs%.out} ];

EOF
fi
# The Correct Way of checking we're running NixOS
if [ -e "/etc/NIXOS" ]; then
>&2 cat <<EOF
Install it for all users by adding to your NixOS configuration:
environment.systemPackages = with pkgs; [ ${attrs%.out} ];

EOF
fi
if [ -e "$HOME/.nix-profile/manifest.json" ]; then
>&2 cat <<EOF
The program '$cmd' is currently not installed. You can install it
by typing:
nix profile install $toplevel#$attrs
You can run it once with:
nix shell $toplevel#${attrs%.out} -c $cmd

Or run it once with:
nix shell $toplevel#$attrs -c $cmd ...
Or install it by typing:
nix profile install $toplevel#${attrs%.out}
EOF
else
>&2 cat <<EOF
The program '$cmd' is currently not installed. You can install it
by typing:
nix-env -iA $toplevel.$attrs

Or run it once with:
nix-shell -p $attrs --run '$cmd ...'
You can run it once with:
nix-shell -p ${attrs%.out} --run '$cmd'
EOF
fi
fi
;;
*)
>&2 cat <<EOF
The program '$cmd' is currently not installed. It is provided by
several packages. You can install it by typing one of the following:
The program '$cmd' is currently not installed. It is provided by several packages.
EOF

# ensure we get each element of attrs
# in a cross platform way
while read attr; do
if [ -e "$HOME/.nix-profile/manifest.json" ]; then
>&2 echo " nix profile install $toplevel#$attr"
else
>&2 echo " nix-env -iA $toplevel.$attr"
fi
done <<< "$attrs"

# ensure we get each element of attrs in a cross platform way
if [ -n "$__HM_SESS_VARS_SOURCED" ]; then
>&2 cat <<EOF
Install it for the current user '$USER' by adding to your Home Manager configuration one of:
EOF
while read attr; do
>&2 echo " home.packages = with pkgs; [ ${attr%.out} ];"
done <<< "$attrs"
echo \n
fi
if [ -e "/etc/NIXOS" ]; then
>&2 cat <<EOF
Install it for all users by adding to your NixOS configuration one of:
EOF
while read attr; do
>&2 echo " environment.systemPackages = with pkgs; [ ${attr%.out} ];"
done <<< "$attrs"
echo \n
fi
>&2 cat <<EOF

Or run it once with:
You can run it once with one of:
EOF

while read attr; do
if [ -e "$HOME/.nix-profile/manifest.json" ]; then
>&2 echo " nix shell $toplevel#$attr -c $cmd ..."
>&2 echo " nix shell $toplevel#${attr%.out} -c $cmd"
else
>&2 echo " nix-shell -p $attr --run '$cmd ...'"
>&2 echo " nix-shell -p ${attr%.out} --run '$cmd'"
fi
done <<< "$attrs"
if [ -e "$HOME/.nix-profile/manifest.json" ]; then
>&2 cat <<EOF

Or install it by typing one of:
EOF
while read attr; do
>&2 echo " nix profile install $toplevel#${attr%.out}"
done <<< "$attrs"
echo "\n"
fi
;;
esac

Expand Down