From ffdb69ae17ce6d8d15a6397e998f1b535cc48d84 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Thu, 20 Apr 2023 14:45:06 -0400 Subject: [PATCH] Move p to file and add interactive selection --- home/bin/p | 85 +++++++++++++++++++++++++++++++++++++ home/lib/login_functions.sh | 70 ------------------------------ pkgs-void.list | 1 + 3 files changed, 86 insertions(+), 70 deletions(-) create mode 100755 home/bin/p diff --git a/home/bin/p b/home/bin/p new file mode 100755 index 0000000..b4a9cab --- /dev/null +++ b/home/bin/p @@ -0,0 +1,85 @@ +#! /bin/bash + +set -eo pipefail + +PROG=$0 + +find() { + local -r name="$1" + local -r file="$2" + + awk \ + -v _s="$name" \ + ' + BEGIN {_s = tolower(_s)} + + /^[a-zA-Z]/ && tolower($1) ~ _s && NF >= 2 { + n++ + s = $1 + p = $NF + if (NF == 2) { + e = "" + u = "" + } else if (NF == 3) { + e = $2 + u = "" + } else { + e = $2 + u = $3 + } # TODO What would NF > 4 mean? + + printf("%d [O] s:\"%s\", e:\"%s\", u:\"%s\"\n", n, s, e, u) > "/dev/stderr" + if (match(u, "@")) { + tmp = e + e = u + u = tmp + printf("%d [C] s:\"%s\", e:\"%s\", u:\"%s\"\n", n, s, e, u) > "/dev/stderr" + } + printf("%d s:\"%s\" e:\"%s\" u:\"%s\" %s\n", n, s, e, u, p) + } + ' \ + "$file" +} + +main() { + local -r default_file="$HOME"/._p/p + local -r usage="Usage: $PROG [FILE] NAME" + local name file records i meta data datum + + case "$#" in + 0) + echo "$usage" >&2 + return 1;; + 1) + file="$default_file" + name="$1";; + 2) + file="$1" + name="$2";; + *) + echo "$usage" >&2 + return 1;; + esac + + records=$(find "$name" "$file") + meta=$(echo "$records" | awk '{print($1, $2, $3, $4)}') + data=$(echo "$records" | awk '{print($1, $5)}') + + # XXX Even an empty result will count as one line after echo, so need to filter: + case "$(echo "$records" | grep -vc '^$')" in + 0) + echo '[ERROR] Found nothing.' >&2 + exit 1;; + 1) + datum="$data";; + *) + i=$(echo "$meta" | column -t | fzf | awk '{print $1}') + datum=$(echo "$data" | awk -v i="$i" 'NR == i');; + esac + + # XXX Intentionally avoiding newline: + echo "$datum" | awk '{printf "%s", $2}' | xsel -i -b -t 30000 + +} + +main "$@" diff --git a/home/lib/login_functions.sh b/home/lib/login_functions.sh index c393938..4f62b82 100644 --- a/home/lib/login_functions.sh +++ b/home/lib/login_functions.sh @@ -26,76 +26,6 @@ notify_done() { fi } -## p : string -> unit -p() { - local -r usage='Usage: p [FILE] NAME' - local name - local file - - case "$#" in - 0) - echo "$usage" >&2 - return 1;; - 1) - file=~/._p/p - name="$1";; - 2) - file="$1" - name="$2";; - *) - echo "$usage" >&2 - return 1;; - esac - - awk \ - -v _s="$name" \ - ' - BEGIN {_s = tolower(_s)} - - # TODO fzf/dmenu select instead of searching: - /^[a-zA-Z]/ && tolower($1) ~ _s && NF >= 2 { - n++ - s = $1 - p = $NF - if (NF == 2) { - e = "" - u = "" - } else if (NF == 3) { - e = $2 - u = "" - } else { - e = $2 - u = $3 - } # TODO What would NF > 4 mean? - - printf("%d [O] s:\"%s\", e:\"%s\", u:\"%s\"\n", n, s, e, u) > "/dev/stderr" - if (match(u, "@")) { - tmp = e - e = u - u = tmp - printf("%d [C] s:\"%s\", e:\"%s\", u:\"%s\"\n", n, s, e, u) > "/dev/stderr" - } - ps[n] = p - } - - END { - printf "%s", ps[n] # XXX Intentionally avoiding newline in the result. - if (n == 1) { - exit 0 - } else if (n == 0) { - printf "[ERROR] Found nothing.\n" > "/dev/stderr" - exit 1 - } else if (n > 1) { - # TODO fzf-select which of the records the user (ahem, me) wants. - printf "[WARNING] Found more than one record. Selecting the last one.\n" > "/dev/stderr" - exit 0 - } - } - ' \ - "$file" \ - | xsel -i -b -t 30000 -} - dl() { local -r timestamp="$(date --iso-8601=ns)" local -r dir="$HOME"/dl/adhoc/"$timestamp" diff --git a/pkgs-void.list b/pkgs-void.list index 19a2325..5464245 100644 --- a/pkgs-void.list +++ b/pkgs-void.list @@ -101,6 +101,7 @@ freetype-dbg fribidi-dbg fswatch fuse-dbg +fzf gcc gdb gdbm-dbg -- 2.20.1