aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/remembering.in128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/remembering.in b/src/remembering.in
new file mode 100755
index 0000000..c89beef
--- /dev/null
+++ b/src/remembering.in
@@ -0,0 +1,128 @@
+#!/bin/sh
+set -eu
+
+usage() {
+ printf 'Usage: %s -p PROFILE -c "COMMAND"\n' "$0"
+}
+
+help() {
+ echo '
+Options:
+ -p profile to be used for gathering and storing data
+ -c command to be run, reading from STDIN, writing to STDOUT
+ -h show this help
+ -V print program version
+
+See manpages for more information.'
+}
+
+missing() {
+ printf 'Missing option: %s\n' "$1" >&2
+}
+
+# shellcheck disable=2068
+for flag in $@; do
+ if [ "$flag" = '--help' ]; then
+ usage
+ help
+ exit 0
+ fi
+done
+
+COMMANDFLAG=
+PROFILEFLAG=
+while getopts 'hc:p:V' name; do
+ case "$name" in
+ c)
+ COMMANDFLAG="$OPTARG"
+ ;;
+ p)
+ PROFILEFLAG="$OPTARG"
+ ;;
+ h)
+ usage
+ help
+ exit
+ ;;
+ V)
+ echo 'remembering-@VERSION@ @DATE@'
+ exit
+ ;;
+ *)
+ echo "Ignoring unrecognized flag '$name'" >&2
+ ;;
+ esac
+done
+
+if [ -z "$COMMANDFLAG" ]; then
+ missing '-c "COMMAND"'
+ usage >&2
+ exit 2
+fi
+
+if [ -z "$PROFILEFLAG" ]; then
+ missing '-p PROFILE'
+ usage >&2
+ exit 2
+fi
+
+COMMAND="$COMMANDFLAG"
+PROFILE="${XDG_DATA_HOME:-$HOME/.local/share/remembering}/$PROFILEFLAG"
+
+if [ ! -e "$PROFILE" ]; then
+ mkdir -p "$(dirname "$PROFILE")"
+ touch "$PROFILE"
+fi
+
+MERGED="$(mktemp)"
+FILTERED="$(mktemp)"
+SORTED_STDIN="$(mktemp)"
+cat - > "$SORTED_STDIN"
+
+# sed line to reverse lines, replacing GNU/Linux's tac
+# Taken from:
+# https://unix.stackexchange.com/questions/280685/reverse-sequence-of-a-file-with-posix-tools/280686#comment601716_280686
+xargs -I{} printf '0:%s\n' "{}" < "$SORTED_STDIN" | \
+ sort -t: -k2,2 -m - "$PROFILE" | \
+ sed '1!x;H;1h;$!d;g' | \
+ sort -t: -k2,2 -u > "$MERGED"
+
+xargs -I{} printf 'filter_marker:%s\n' "{}" < "$SORTED_STDIN" | \
+ cat - "$PROFILE" | \
+ sort -t: -k2,2 | \
+ awk '{
+ split($0, l, ":")
+ rank = l[1]
+ entry = substr($0, length(rank) + 2)
+ if (rank != "filter_marker") {
+ prev_rank = rank
+ prev_entry = entry
+ } else {
+ if (prev_entry == entry) {
+ print prev_rank ":" entry
+ } else {
+ print "0:" entry
+ }
+ }
+ }' > "$FILTERED"
+
+CHOICE="$(sort -t: -k1nr,1 -k2,2 < "$FILTERED" | \
+ cut -d: -f2- | \
+ sh -c "$COMMAND")"
+
+if [ -n "$CHOICE" ]; then
+ NEW_PROFILE="$(mktemp)"
+ awk -v choice="$CHOICE" '{
+ split($0, l, ":")
+ rank = l[1]
+ entry = substr($0, length(rank) + 2)
+ if (entry == choice) {
+ # Naively increment ranking by one
+ print rank + 1 ":" entry
+ } else {
+ print rank ":" entry
+ }
+ }' "$MERGED" > "$NEW_PROFILE"
+ mv "$NEW_PROFILE" "$PROFILE"
+ echo "$CHOICE"
+fi