https://github.com/3timeslazy/nix-search-tv
Fuzzy search for Nix packages.
https://github.com/3timeslazy/nix-search-tv
cli fzf nix nixos search television
Last synced: 7 months ago
JSON representation
Fuzzy search for Nix packages.
- Host: GitHub
- URL: https://github.com/3timeslazy/nix-search-tv
- Owner: 3timeslazy
- License: gpl-3.0
- Created: 2025-01-29T09:30:56.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-09-10T23:44:00.000Z (about 1 year ago)
- Last Synced: 2025-09-11T03:02:39.630Z (about 1 year ago)
- Topics: cli, fzf, nix, nixos, search, television
- Language: Go
- Homepage:
- Size: 10.3 MB
- Stars: 115
- Watchers: 1
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome - 3timeslazy/nix-search-tv
- best-of-nix - GitHub - 8% open · ⏱️ 12.10.2025) (Discovery)
- awesome-nix - nix-search-tv - CLI fuzzy finder for packages and options from Nixpkgs, Home Manager, and more. (Resources / Discovery)
README
# nix-search-tv
Fuzzy search for NixOS packages.
---
[](https://asciinema.org/a/afNYMXrhoEwwh3wzOK7FbsFtW)
## Installation
### Nix Package
```nix
environment.systemPackages = [ nix-search-tv ]
```
### Flake
There are many ways how one can install a package from a flake, below is one:
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nix-search-tv.url = "github:3timeslazy/nix-search-tv";
};
outputs = {
nixpkgs,
nix-search-tv,
...
}: {
nixosConfigurations.system = nixpkgs.lib.nixosSystem {
modules = [
{
environment.systemPackages = [
nix-search-tv.packages.x86_64-linux.default
];
}
];
};
};
}
```
## Usage
`nix-search-tv` does not do the search by itself, but rather integrates
with other general purpose fuzzy finders, such as [television](https://github.com/alexpasmantier/television) and [fzf](https://github.com/junegunn/fzf)
### Television
Add `nix.toml` file to your television cables directory with the content below:
```toml
[metadata]
name = "nix"
requirements = ["nix-search-tv"]
[source]
command = "nix-search-tv print"
[preview]
command = "nix-search-tv preview {}"
```
or use the Home Manager option:
```nix
programs.nix-search-tv.enableTelevisionIntegration = true;
```
### fzf
The most straightforward integration might look like:
```sh
alias ns="nix-search-tv print | fzf --preview 'nix-search-tv preview {}' --scheme history"
```
> [!NOTE]
> No matter how you use nix-search-tv with fzf, it's better to add `--scheme history`. That way, the options will be sorted, which makes the search experience better
More advanced integration might be found here in [nixpkgs.sh](./nixpkgs.sh). It is the same search but with the following shortcuts:
- Search only Nixpkgs or Home Manager
- Open package code declaration or homepage
- Search GitHub for snippets with the selected package/option
- And more
You can install it like:
```sh
let
ns = pkgs.writeShellScriptBin "ns" (builtins.readFile ./path/to/nixpkgs.sh);
in {
environment.systemPackages = [ ns ]
}
```
## Configuration
By default, the configuration file is looked at `$XDG_CONFIG_HOME/nix-search-tv/config.json`
```jsonc
{
// What indexes to search by default
//
// default:
// linux: [nixpkgs, "home-manager", "nur", "nixos"]
// darwin: [nixpkgs, "home-manager", "nur", "darwin"]
"indexes": ["nixpkgs", "home-manager", "nur"],
// How often to look for updates and run
// indexer again
//
// default: 1 week (168h)
"update_interval": "3h2m1s",
// Where to store the index files
//
// default: $XDG_CACHE_HOME/nix-search-tv
"cache_dir": "path/to/cache/dir",
// Whether to show the banner when waiting for
// the indexing
//
// default: true
"enable_waiting_message": true,
// More about experimental below
"experimental": {
"render_docs_indexes": {
"plasma": "https://nix-community.github.io/plasma-manager/options.xhtml",
},
"options_file": {
"agenix": "",
},
},
}
```
## Searchable package registries
### Builtin
- [Nixpkgs](https://search.nixos.org/packages?channel=unstable)
- [Home Manager](https://github.com/nix-community/home-manager)
- [NixOS](https://search.nixos.org/options)
- [Darwin](https://github.com/LnL7/nix-darwin)
- [NUR](https://github.com/nix-community/NUR)
### Custom
#### Parse HTML
`nix-search-tv` can parse a documentation HTML page and extract options from it. How to tell if a page can be parsed? To understand that, check the links in the example below and if the documentation page looks exactly like one of them, it probably can be parsed.
```jsonc
{
"render_docs_indexes": {
// https://github.com/nix-community/plasma-manager
"plasma": "https://nix-community.github.io/plasma-manager/options.xhtml",
},
}
```
#### Parse options.json file
The point of this setting is to generate the options file at nix build time and point `nix-search-tv` to them. Internally, the tool compares previous and the new path and only re-indexes it if the path has changes.
```jsonc
{
"options_file": {
// https://github.com/ryantm/agenix
"agenix": "",
// https://jovian-experiments.github.io/Jovian-NixOS/index.html
"jovian": "",
},
}
```
Here's one way to generate the options.json files for `agenix` and `nixvim` using [unf](https://git.atagen.co/atagen/unf) and home-manager:
```nix
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
agenix.url = "github:ryantm/agenix";
nixvim.url = "github:nix-community/nixvim";
unf = {
url = "git+https://git.atagen.co/atagen/unf";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
nixpkgs,
home-manager,
...
} @ inputs : let
# It's not required to use `unf`, but even though
# it brings some dependencies, I use it because its easy.
mkOpts = system: module:
inputs.unf.lib.json {
inherit self;
pkgs = nixpkgs.legacyPackages.${system};
# not all modules can be evaluated easily. If your module
# does not evaluate, try checking this NüschtOS file:
# https://github.com/NuschtOS/search.nuschtos.de/blob/main/flake.nix
modules = [module];
};
in {
nixosConfigurations.hostname = nixpkgs.lib.nixosSystem rec {
system = "x86_64-linux";
modules = [
home-manager.nixosModules.home-manager
{
# extraSpecialArgs is used here to pass the options files
# that depend on the flake inputs to home-manager modules,
# where configuration files are usually defined.
home-manager.extraSpecialArgs = {
inherit inputs;
agenixOptions = mkOpts system inputs.agenix.nixosModules.default;
# nixvim provides an options.json file already
nixvimOptions = inputs.nixvim.packages.${system}.options-json + /share/doc/nixos/options.json
};
}
];
};
};
}
# home.nix
{
pkgs,
lib,
...
} @ args : {
xdg.configFile."nix-search-tv/config.json".text = builtins.toJSON {
experimental = {
options_file = {
agenix = "${args.agenixOptions}";
nixvim = "${args.nixvimOptions}";
};
};
};
# or, with home-manager
programs.nix-search-tv = {
enable = true;
settings = {
experimental.options_file = {
agenix = "${args.agenixOptions}";
nixvim = "${args.nixvimOptions}";
};
};
};
}
```
## Credits
This project was inspired and wouldn't exist without work done by [nix-search](https://github.com/diamondburned/nix-search) contributors.