commit 0aaa30346e0d9242471df1b742f8a1ed9d2a7be1 Author: h7x4 Date: Thu Nov 24 20:04:52 2022 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e2f5dd2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +result \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d4831a2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 h7x4 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3eb1e80 --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +# Nix Attr Search + +**NOTE: This is still in alpha** + +These are some tools i made for ease of searching for stuff while writing my nix configs. + +They are made with `fzf`, so they can easily be piped into other programs. + +Also, they all create a derivation containing all of the attributes. + +--- + +## Try it out! + +### Nix Packages + +TODO: + +### Nix Options + +TODO: + +### Homemanager + +``` +nix run github:h7x4/nix-attr-search#home-manager-search +``` + +Or a more advanced version: + +``` +nix run github:h7x4/nix-attr-search#home-manager-search -- --flake="github:nix-community/home-manager" --ref="release-22.05" +``` + +--- + +## Some piping ideas + +### Misc + +- Pipe the option into the clipboard +- Bind shortcut keys to open a terminal with the program, and paste the chosen option directly into the current program (probably a code editor of some sort, with your nix configs open). + +### Repiping values into `jq` +- Repipe the chosen value into `jq`, and choose either the default value, the example value. +- Repipe the chosen value into `jq`, choosing its referenced configs, pipe these into `fzf` once more to choose one referenced config, then pipe this relative file path into `rg` to (hopefully) find the specific location the value was set, and then open the file at its specific position in an editor. \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..cd5a696 --- /dev/null +++ b/flake.lock @@ -0,0 +1,64 @@ +{ + "nodes": { + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "utils": "utils" + }, + "locked": { + "lastModified": 1669071065, + "narHash": "sha256-KBpgj3JkvlPsJ3duOZqFJe6tgr+wc75t8sFmgRbBSbw=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "f7641a3ff398ccce952e19a199d775934e518c1d", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-22.11", + "repo": "home-manager", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1669196922, + "narHash": "sha256-J1fjyUsst3mXxgz2Z1cD7boh1Q5GmfeZjNfW1WVMsr8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e8016a90db25c48cfe2cb8ab48bbc94a4365dab9", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-22.11", + "type": "indirect" + } + }, + "root": { + "inputs": { + "home-manager": "home-manager", + "nixpkgs": "nixpkgs" + } + }, + "utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c154a24 --- /dev/null +++ b/flake.nix @@ -0,0 +1,38 @@ +{ + inputs = { + nixpkgs.url = "nixpkgs/nixos-22.11"; + home-manager = { + url = "github:nix-community/home-manager/release-22.11"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, home-manager }: + let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + in { + apps.${system} = let + toApp = _: pkg: { + type = "app"; + program = toString pkg; + }; + in builtins.mapAttrs toApp self.packages.${system}; + + hydraJobs = with pkgs.lib; + mapAttrs' (name: value: nameValuePair name { ${system} = value; }) + self.packages.${system}; + + packages.${system} = { + home-manager-search = + pkgs.callPackage ./home-manager-search.nix { inherit home-manager; }; + nix-option-search = pkgs.callPackage ./nix-option-search.nix { }; + nix-package-search = pkgs.callPackage ./nix-package-search.nix { }; + }; + + overlays.default = final: prev: prev // self.packages.${system}; + + devShells.${system}.default = + pkgs.mkShell { packages = with pkgs; [ nixfmt ]; }; + }; +} diff --git a/home-manager-search.nix b/home-manager-search.nix new file mode 100644 index 0000000..35a1479 --- /dev/null +++ b/home-manager-search.nix @@ -0,0 +1,159 @@ +{ pkgs, lib, home-manager, system, ... }: +let + + # TODO: Preprocess XML tags in description. + + # TODO: Make non-literal examples have better syntax highlighting + + # TODO: Colorize preview + + usage = pkgs.writeText "home-manager-search-usage" '' + Usage: + home-manager-search [ -j | -n ] [-f= [-r=]] + + Options: + -h | --help Display this message. + -j | --json Display raw data in json format. + -n | --no-preview Don't display a preview. + -f=* | --flake=* Use a flake url to an instance (e.g. a fork) of home-manager, + generate its options, and use those instead of the global ones. + -r=* | --ref=* If a flake url is specified, this option might be used to choose + a specific reference (branch, tag, commit, etc.) to use for + generating the docs. + + Example usage: + home-manager-search + home-manager-search -j + home-manager-search --flake="github:nix-community/home-manager" + home-manager-search --flake="github:nix-community/home-manager" --ref="release-22.05" + ''; + + inherit (pkgs.callPackage ./shared.nix { }) + jq fzf gomplate blinkred clear flatten; + + template = pkgs.writeText "preview-home-manager-attrs-template" (flatten '' + {{ with (ds "opt")}} + {{- $title := join .loc "." }} + {{- $title }} + {{ strings.Repeat (strings.RuneCount $title) "=" }} + + {{ if .readOnly }} + ${blinkred}READONLY${clear} + {{ end }} + + Type: {{ .type }} + + {{ if has . "description" }} + DESCRIPTION + {{ strings.Repeat 20 "=" }} + {{ .description }} + {{ end }} + + {{- if has . "example" }} + EXAMPLE + {{ strings.Repeat 20 "=" }} + {{ if and (has .example "_type") }} + {{ else }} + {{ data.ToJSONPretty " " .example }} + {{ end }} + {{ end }} + + {{- if has . "default" }} + DEFAULT + {{ strings.Repeat 20 "=" }} + {{ .default }} + {{ end }} + + CONFIGURED IN: + {{ strings.Repeat 20 "=" }} + {{ range .declarations }} + {{- .path }} + {{ end }} + + {{ else }} + ERROR: Could not find datasource + {{ end }} + ''); + + previewJson = pkgs.writers.writeBash "preview-home-manager-attrs-json" '' + OPTION_KEY=$1 + JSON_MANUAL_PATH=$2 + + ${jq} -C ".\"$OPTION_KEY\"" $JSON_MANUAL_PATH + ''; + + previewGomplate = + pkgs.writers.writeBash "preview-home-manager-attrs-gomplate" '' + OPTION_KEY=$1 + JSON_MANUAL_PATH=$2 + + ${jq} ".\"$OPTION_KEY\"" $JSON_MANUAL_PATH | ${gomplate} --datasource opt=stdin:?type=application/json --file ${template} + ''; + + defaultManualPath = "${ + home-manager.packages.${system}.docs-json + }/share/doc/home-manager/options.json"; + +in pkgs.writers.writeBash "search-home-manager-attrs" '' + JSON_MANUAL_PATH="${defaultManualPath}" + + for i in "$@"; do + case $i in + -h|--help) + cat ${usage} + exit 0 + ;; + -j|--json) + PRINT_JSON=1 + shift + ;; + -n|--no-preview) + NO_PREVIEW=1 + shift + ;; + -f=*|--flake=*) + FLAKE="''${i#*=}" + shift + ;; + -r=*|--ref=*) + REF="''${i#*=}" + shift + ;; + *|-*|--*) + echo "Unknown option $i" + cat ${usage} + exit 1 + ;; + esac + done + + if [ -v PRINT_JSON ] && [ -v NO_PREVIEW ]; then + echo "Cannot preview as json with no-preview enabled" + cat ${usage} + exit 1 + fi + + if [ -v FLAKE ]; then + FLAKE_URL="''${FLAKE}" + + if [ -v REF ]; then + FLAKE_URL="''${FLAKE_URL}?ref=$REF" + fi + + FLAKE_URL="''${FLAKE_URL}#docs-json" + echo "Building docs from $FLAKE_URL" + + OUT_PATH=$(${pkgs.nix}/bin/nix build "$FLAKE_URL" --no-link --print-out-paths --no-write-lock-file) + JSON_MANUAL_PATH="$OUT_PATH/share/doc/home-manager/options.json" + echo "Using docs located at $JSON_MANUAL_PATH" + fi + + if [ -v NO_PREVIEW ]; then + ${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} + elif [ -v PRINT_JSON ]; then + ${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} --preview "${previewJson} {} $JSON_MANUAL_PATH" + else + ${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} --preview "${previewGomplate} {} $JSON_MANUAL_PATH" + fi +'' + diff --git a/nix-option-search.nix b/nix-option-search.nix new file mode 100644 index 0000000..9fdaa7f --- /dev/null +++ b/nix-option-search.nix @@ -0,0 +1 @@ +{ pkgs, ... }: pkgs.emptyFile diff --git a/nix-package-search.nix b/nix-package-search.nix new file mode 100644 index 0000000..9fdaa7f --- /dev/null +++ b/nix-package-search.nix @@ -0,0 +1 @@ +{ pkgs, ... }: pkgs.emptyFile diff --git a/shared.nix b/shared.nix new file mode 100644 index 0000000..fc4e318 --- /dev/null +++ b/shared.nix @@ -0,0 +1,28 @@ +{ pkgs, lib, ... }: { + + # Executables + jq = "${pkgs.jq}/bin/jq"; + fzf = "${pkgs.fzf}/bin/fzf"; + gomplate = "${pkgs.gomplate}/bin/gomplate"; + + # ANSI Colors + blinkred = "\\033[31;5m"; + clear = "\\033[0m"; + + # Misc functionality + + # All empty lines, and all prefixed whitespace is removed. + flatten = with lib; + let + stripPrefixSpace = s: + if hasPrefix " " s then + stripPrefixSpace ((substring 1 (stringLength s)) s) + else + s; + in (flip pipe) [ + (splitString "\n") + (remove "") + (map stripPrefixSpace) + (concatStringsSep "\n") + ]; +}