From 27a6c5833e12d058ffc5592855fdd4edf33e5213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kier=C3=A1n=20Meinhardt?= Date: Thu, 15 Jul 2021 09:11:20 +0200 Subject: [PATCH] feat: use fzfmenu --- configs/default.nix | 6 ++- packages/scripts/fzfmenu.nix | 97 ++++++++++++++++++++++++++++++++++++ packages/scripts/fzfmenu.sh | 43 ---------------- 3 files changed, 102 insertions(+), 44 deletions(-) create mode 100755 packages/scripts/fzfmenu.nix delete mode 100755 packages/scripts/fzfmenu.sh diff --git a/configs/default.nix b/configs/default.nix index 733acf3..ab60a98 100644 --- a/configs/default.nix +++ b/configs/default.nix @@ -30,8 +30,12 @@ in { }; }; overlays = [ - (self: super: { + (self: super: rec { scripts = import { pkgs = super; lib = super.lib; }; + fzfmenu = import { pkgs = super; }; + dmenu = super.writers.writeDashBin "dmenu" '' + ${fzfmenu}/bin/fzfmenu "$@" + ''; }) (import ) (import ) diff --git a/packages/scripts/fzfmenu.nix b/packages/scripts/fzfmenu.nix new file mode 100755 index 0000000..b9fe2ee --- /dev/null +++ b/packages/scripts/fzfmenu.nix @@ -0,0 +1,97 @@ +with import ; +{ pkgs, ... }@args: + +let + # config cannot be declared in the input attribute set because that would + # cause callPackage to inject the wrong config. Instead, get it from ... + # via args. + config = args.config or {}; + + cfg = eval.config; + + eval = evalModules { + modules = singleton { + _file = toString ./profile.nix; + imports = singleton config; + options = { + appName = mkOption { + default = "fzfmenu"; + type = types.label; + }; + defaultPrompt = mkOption { + default = ">"; + type = types.str; + }; + printQuery = mkOption { + default = true; + type = types.bool; + }; + reverse = mkOption { + default = true; + type = types.bool; + }; + windowTitle = mkOption { + default = "fzfmenu"; + type = types.str; + }; + }; + }; + }; +in + +pkgs.writers.writeDashBin "fzfmenu" '' + set -efu + + # Spawn terminal if called without one, like e.g. from a window manager. + if [ -z ''${TERM+x} ]; then + exec 3<&0 + exec 4>&1 + export FZFMENU_INPUT_FD=3 + export FZFMENU_OUTPUT_FD=4 + exec ${pkgs.st}/bin/st \ + -n ${cfg.appName} \ + -t ${shell.escape cfg.windowTitle} \ + -e "$0" "$@" + else + exec 0<&''${FZFMENU_INPUT_FD-0} + exec 1>&''${FZFMENU_OUTPUT_FD-1} + fi + + PROMPT=${shell.escape cfg.defaultPrompt} + for i in "$@"; do + case $i in + -p) + PROMPT=$2 + shift 2 + break + ;; + -l) + # no reason to filter number of lines + LINES=$2 + shift 2 + break + ;; + -i) + # we do this anyway + shift + break + ;; + *) + echo "Unknown option $1" >&2 + shift + ;; + esac + done + + if test -n "''${FZFMENU_FZF_DEFAULT_OPTS-}"; then + FZF_DEFAULT_OPTS=''${FZFMENU_FZF_DEFAULT_OPTS-} + export FZF_DEFAULT_OPTS + fi + + ${pkgs.fzf}/bin/fzf \ + --history=/dev/null \ + --prompt="$PROMPT" \ + ${optionalString cfg.reverse "--reverse"} \ + ${optionalString cfg.printQuery "--print-query"} \ + ${optionalString cfg.printQuery "| ${pkgs.coreutils}/bin/tail -1"} +'' diff --git a/packages/scripts/fzfmenu.sh b/packages/scripts/fzfmenu.sh deleted file mode 100755 index 36ba08c..0000000 --- a/packages/scripts/fzfmenu.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash -# fzfmenu - fzf as dmenu replacement -# https://github.com/junegunn/fzf/wiki/Examples#fzf-as-dmenu-replacement -set -efu - -input=$(mktemp -u --suffix .fzfmenu.input) -output=$(mktemp -u --suffix .fzfmenu.output) -mkfifo "$input" -mkfifo "$output" -chmod 600 "$input" "$output" - -for i in "$@"; do - case $i in - -p) - PROMPT="$2" - shift - shift - break ;; - -l) - # no reason to filter number of lines - shift - shift - break ;; - -i) - # we do this anyway - shift - break ;; - *) - echo "Unknown option $1" >&2 - shift ;; - esac -done - -# it's better to use st here (starts a lot faster than pretty much everything else) -st -c fzfmenu -n fzfmenu -g 85x10 \ - -e dash \ - -c "cat $input | fzf --reverse --prompt='${PROMPT+> }' --print-query $* | tee $output" & disown - -# handle ctrl+c outside child terminal window -trap 'kill $! 2>/dev/null; rm -f $input $output' EXIT - -cat > "$input" -cat "$output"