mirror of
https://github.com/Ahwxorg/nixos-config.git
synced 2025-12-04 15:00:13 +01:00
feat: adds back overlays and adds nix-search-fzf stolen from this file: https://github.com/IvarWithoutBones/dotfiles/blob/main/home-manager/modules/zsh.nix#L65
This commit is contained in:
parent
071540b706
commit
16fee58705
4 changed files with 285 additions and 1 deletions
|
|
@ -1,3 +1,3 @@
|
||||||
{
|
{
|
||||||
addition = final: _: import ../pkgs { pkgs = final; };
|
addition = final: _: import ../pkgs/default.nix { pkgs = final; };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
50
pkgs/nix-search-fzf/default.nix
Normal file
50
pkgs/nix-search-fzf/default.nix
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
{
|
||||||
|
createScript,
|
||||||
|
replaceVars,
|
||||||
|
gnused,
|
||||||
|
jq,
|
||||||
|
fzf,
|
||||||
|
nix,
|
||||||
|
coreutils,
|
||||||
|
bash,
|
||||||
|
nix-search-fzf,
|
||||||
|
writeShellScript,
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
previewText = createScript "fzf-preview" ./fzf-preview.sh { };
|
||||||
|
src = replaceVars ./nix-search-fzf.sh {
|
||||||
|
previewText = "${previewText}/bin/fzf-preview";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
createScript "nix-search-fzf" src {
|
||||||
|
dependencies = [
|
||||||
|
gnused
|
||||||
|
jq
|
||||||
|
fzf
|
||||||
|
nix
|
||||||
|
coreutils
|
||||||
|
bash
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enter a 'nix shell' with packages selected by this script
|
||||||
|
passthru.zsh-shell-widget = writeShellScript "nix-search-fzf-shell-widget" ''
|
||||||
|
nix-search-fzf-shell-widget() {
|
||||||
|
setopt localoptions pipefail no_aliases 2> /dev/null
|
||||||
|
local cmd="$(eval "${nix-search-fzf}/bin/nix-search-fzf -c")"
|
||||||
|
if [[ -z "$cmd" ]]; then
|
||||||
|
zle redisplay
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
zle push-line
|
||||||
|
BUFFER="''${cmd}"
|
||||||
|
zle accept-line
|
||||||
|
local ret=$?
|
||||||
|
unset cmd
|
||||||
|
zle reset-prompt
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta.description = "a wrapper around 'nix {run,shell,edit}' with autocomplete using fzf";
|
||||||
|
}
|
||||||
73
pkgs/nix-search-fzf/fzf-preview.sh
Normal file
73
pkgs/nix-search-fzf/fzf-preview.sh
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
#! /usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i bash -p
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PKG_NAME="$1"
|
||||||
|
FLAKE="$2"
|
||||||
|
FLAKE_PATH="${FLAKE}#${PKG_NAME}"
|
||||||
|
|
||||||
|
removeQuotes() {
|
||||||
|
local flag="$*"
|
||||||
|
flag="${flag%\"}"
|
||||||
|
echo "${flag#\"}"
|
||||||
|
}
|
||||||
|
|
||||||
|
newlinesToCommaSeperated() {
|
||||||
|
echo "$@" | sed ':a;N;$!ba;s/\n/, /g'
|
||||||
|
}
|
||||||
|
|
||||||
|
evalAttr() {
|
||||||
|
local attr data
|
||||||
|
attr="$1"
|
||||||
|
data="$(nix eval "$FLAKE_PATH"."$attr" 2>/dev/null)"
|
||||||
|
[[ $data != "null" && $data != "false" && -n $data ]] && removeQuotes "$data"
|
||||||
|
}
|
||||||
|
|
||||||
|
evalJsonAttr() {
|
||||||
|
local attr jqArgs data
|
||||||
|
attr="$1"
|
||||||
|
jqArgs="$2"
|
||||||
|
data="$(nix eval --json "$FLAKE_PATH"."$attr" 2>/dev/null | jq -r "$jqArgs")"
|
||||||
|
[[ $data != "null" && -n $data ]] && echo "$data"
|
||||||
|
}
|
||||||
|
|
||||||
|
evalNixpkgsLib() {
|
||||||
|
local function data
|
||||||
|
function="$1"
|
||||||
|
# Impure is needed to import the flake reference
|
||||||
|
data="$(nix eval --raw --impure --expr "let pkgs = (builtins.getFlake \"flake:$FLAKE\"); in pkgs.lib.$function pkgs.$PKG_NAME" 2>/dev/null)"
|
||||||
|
[[ $data != "null" && -n $data ]] && echo "$data"
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeEcho() {
|
||||||
|
local -r prefix="$1"
|
||||||
|
local flag="$2"
|
||||||
|
local -r commaSeperated="${3:-false}"
|
||||||
|
[[ $commaSeperated == "true" ]] && flag="$(newlinesToCommaSeperated "$flag")"
|
||||||
|
test -n "$flag" && echo "$prefix $flag"
|
||||||
|
}
|
||||||
|
|
||||||
|
test -n "$(evalAttr "meta.broken")" && echo "broken: true"
|
||||||
|
test -n "$(evalAttr "meta.insecure")" && echo "insecure: true"
|
||||||
|
|
||||||
|
version="$(evalAttr "version")"
|
||||||
|
# Derive the version from "name" using 'lib.getVersion' if it's not set
|
||||||
|
test -z "$version" && version="$(evalNixpkgsLib "getVersion")"
|
||||||
|
maybeEcho "version:" "$version"
|
||||||
|
|
||||||
|
homepage="$(evalAttr "meta.homepage")"
|
||||||
|
maybeEcho "homepage:" "$homepage"
|
||||||
|
|
||||||
|
description="$(evalAttr "meta.description")"
|
||||||
|
maybeEcho "description:" "$description"
|
||||||
|
|
||||||
|
license="$(evalJsonAttr "meta.license" 'if type=="array" then .[].fullName else .fullName end')"
|
||||||
|
maybeEcho "license:" "$license" true
|
||||||
|
|
||||||
|
maintainers="$(evalJsonAttr "meta.maintainers" '.[].github')"
|
||||||
|
maybeEcho "maintainers:" "$maintainers" true
|
||||||
|
|
||||||
|
platforms="$(evalJsonAttr "meta.platforms" 'if type=="array" then .[] else . end')"
|
||||||
|
maybeEcho "platforms:" "$platforms" true
|
||||||
161
pkgs/nix-search-fzf/nix-search-fzf.sh
Normal file
161
pkgs/nix-search-fzf/nix-search-fzf.sh
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# An fzf script with autocomplete from "nix search" which allows for interactive fuzzy searching of derivations.
|
||||||
|
# After the search a nix subcommand is executed on the selected derivation(s), e.g. "nix shell" or "nix run".
|
||||||
|
|
||||||
|
set -eou pipefail
|
||||||
|
|
||||||
|
FLAKE="nixpkgs" # The default flake to use. TODO: make this configurable
|
||||||
|
NIX_SUBCOMMAND="shell" # The default nix subcommand to execute
|
||||||
|
MULTIPLE_SELECTION=true # Whether to allow the user to select multiple derivations
|
||||||
|
PRINT_COMMAND=false # Only print the command that would be executed, don't execute it
|
||||||
|
|
||||||
|
if [ -n "${XDG_CACHE_HOME-}" ]; then
|
||||||
|
CACHE_PATH="$XDG_CACHE_HOME/nix-search-fzf/cache.txt"
|
||||||
|
else
|
||||||
|
CACHE_PATH="$HOME/.cache/nix-search-fzf/cache.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Because fzf executes commands from keybindings in a subprocess, we cannot directly change this scripts state.
|
||||||
|
# Instead we can use a temporary file as an IPC mechanism, to change which subcommand to execute.
|
||||||
|
TMP_FILE="$(mktemp --dry-run --suffix "-nix-search-fzf")"
|
||||||
|
trap 'rm -f "$TMP_FILE"' EXIT INT TERM
|
||||||
|
|
||||||
|
handleArguments() {
|
||||||
|
while (("$#" > 0)); do
|
||||||
|
case "$1" in
|
||||||
|
-s | shell | --shell)
|
||||||
|
NIX_SUBCOMMAND="shell"
|
||||||
|
;;
|
||||||
|
-b | build | --build)
|
||||||
|
NIX_SUBCOMMAND="build"
|
||||||
|
;;
|
||||||
|
-r | run | --run)
|
||||||
|
NIX_SUBCOMMAND="run"
|
||||||
|
MULTIPLE_SELECTION=false
|
||||||
|
;;
|
||||||
|
-e | edit | --edit)
|
||||||
|
NIX_SUBCOMMAND="edit"
|
||||||
|
MULTIPLE_SELECTION=false
|
||||||
|
;;
|
||||||
|
-c | command | --command)
|
||||||
|
PRINT_COMMAND=true
|
||||||
|
;;
|
||||||
|
-u | update | --update)
|
||||||
|
manageCache true
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
-h | help | --help)
|
||||||
|
echo "Usage: $(basename "$0") [--shell|--build|--run|--edit|--update]"
|
||||||
|
echo " --shell: enter a nix shell with the selected package(s). This is the default"
|
||||||
|
echo " --build: build the selected package(s) with nix build"
|
||||||
|
echo " --run: run the selected package with nix run"
|
||||||
|
echo " --edit: edit the selected package with nix edit"
|
||||||
|
echo " --command: only print the command that would be executed, don't execute it"
|
||||||
|
echo " --update: update the nix search cache, this is done automatically every 10 days"
|
||||||
|
echo " --help: show this help message"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option '$1'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
runColored() {
|
||||||
|
printf "\e[32m\$ %s\n\e[0m" "$1"
|
||||||
|
eval "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
manageCache() {
|
||||||
|
local doUpdate="${1:-false}"
|
||||||
|
mkdir -p "$(dirname "$CACHE_PATH")"
|
||||||
|
|
||||||
|
if [ ! -f "$CACHE_PATH" ] || [ ! -s "$CACHE_PATH" ]; then
|
||||||
|
doUpdate="true"
|
||||||
|
echo "attribute path cache does not exist, generating..." >&2
|
||||||
|
elif (($(date -r "$CACHE_PATH" +%s) < $(date -d "now - 10 days" +%s))); then
|
||||||
|
doUpdate="true"
|
||||||
|
echo "cache file is older than 10 days, updating..." >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$doUpdate" == "true" ]; then
|
||||||
|
echo "caching attribute paths..." >&2
|
||||||
|
# Create a list of all attribute paths with "legacyPackages.$arch" stripped
|
||||||
|
# In the future this could contain metadata as well, doing a "nix-eval" for each is not the fastest
|
||||||
|
nix search "$FLAKE" "^" --quiet --json | jq -r 'keys[]' | cut -d'.' -f3- >"$CACHE_PATH"
|
||||||
|
echo "successfully generated attribute path cache" >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
fzfBindingFlag() {
|
||||||
|
local tmpFile="$1"
|
||||||
|
local -A bindings=(
|
||||||
|
["shell"]="ctrl-s"
|
||||||
|
["build"]="ctrl-b"
|
||||||
|
["edit"]="ctrl-e"
|
||||||
|
["run"]="ctrl-r"
|
||||||
|
)
|
||||||
|
|
||||||
|
local result="--bind="
|
||||||
|
for subCommand in "${!bindings[@]}"; do
|
||||||
|
local binding="${bindings[$subCommand]}"
|
||||||
|
# When pressed, write the appropriate command to our temporary IPC file, and change the prompt accordingly
|
||||||
|
result+="$binding:execute-silent(echo $subCommand > $tmpFile)+change-prompt($subCommand > ),"
|
||||||
|
done
|
||||||
|
echo "${result%,}"
|
||||||
|
}
|
||||||
|
|
||||||
|
runFzf() {
|
||||||
|
local multi_flag
|
||||||
|
if [ "$MULTIPLE_SELECTION" == true ]; then
|
||||||
|
multi_flag="--multi"
|
||||||
|
else
|
||||||
|
multi_flag="--no-multi"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fzf "$multi_flag" \
|
||||||
|
--height 40% \
|
||||||
|
--preview-window right,70% \
|
||||||
|
--border rounded \
|
||||||
|
--prompt "$NIX_SUBCOMMAND > " \
|
||||||
|
--preview "bash -c \"@previewText@ {} $FLAKE\"" \
|
||||||
|
"$(fzfBindingFlag "$TMP_FILE")" <"$CACHE_PATH"
|
||||||
|
}
|
||||||
|
|
||||||
|
runNix() {
|
||||||
|
local packages selectedPkgs command
|
||||||
|
readarray -t selectedPkgs <<<"$@"
|
||||||
|
((${#selectedPkgs[@]} == 0)) && exit 0
|
||||||
|
|
||||||
|
if [ "$MULTIPLE_SELECTION" == true ] && ((${#selectedPkgs[@]} > 1)); then
|
||||||
|
# Build a brace expansion string
|
||||||
|
local pkg_list="{"
|
||||||
|
for pkg in "${selectedPkgs[@]}"; do
|
||||||
|
pkg_list+="$pkg,"
|
||||||
|
done
|
||||||
|
packages="${pkg_list%,}}"
|
||||||
|
else
|
||||||
|
packages="${selectedPkgs[0]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
((${#packages} == 0)) && exit 0
|
||||||
|
|
||||||
|
# Update what subcommand to execute, in case it was changed by a keybinding from fzf
|
||||||
|
[ -s "$TMP_FILE" ] && NIX_SUBCOMMAND="$(<"$TMP_FILE")"
|
||||||
|
|
||||||
|
command="NIXPKGS_ALLOW_UNFREE=1 nix $NIX_SUBCOMMAND $FLAKE#$packages --impure"
|
||||||
|
if [ "$PRINT_COMMAND" == true ]; then
|
||||||
|
echo "$command"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
runColored "$command"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
handleArguments "$@"
|
||||||
|
manageCache
|
||||||
|
runNix "$(runFzf)"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue