aboutsummaryrefslogtreecommitdiff
path: root/src/remembering.in
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2021-06-26 16:37:14 -0300
committerEuAndreh <eu@euandre.org>2021-06-26 16:37:14 -0300
commit2e62ef2f6c8a0dcd262376a7a874832c02fd35b2 (patch)
tree23dd8003ea85c9ef228bbd39b4b38f5399fe4411 /src/remembering.in
parentgit mv src/remembering.c src/remembering-c.c (diff)
downloadremembering-2e62ef2f6c8a0dcd262376a7a874832c02fd35b2.tar.gz
remembering-2e62ef2f6c8a0dcd262376a7a874832c02fd35b2.tar.xz
git mv src/remembering.sh src/remembering.in
Diffstat (limited to 'src/remembering.in')
-rwxr-xr-xsrc/remembering.in136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/remembering.in b/src/remembering.in
new file mode 100755
index 0000000..1576372
--- /dev/null
+++ b/src/remembering.in
@@ -0,0 +1,136 @@
+#!/bin/sh
+set -eu
+
+usage() {
+ printf 'Usage: %s -p PROFILE -c COMMAND\n' "$0"
+}
+
+help() {
+ cat <<EOF
+Options:
+ -p, PROFILE profile to be used for gathering and storing data
+ -c, COMMAND command to be run, reading from STDIN, writing to STDOUT
+ -h, --help show this help
+ -V, --version print the version number
+
+See manpages for more information.
+EOF
+}
+
+version() {
+ printf 'remembering-@VERSION@ @DATE@\n'
+}
+
+missing() {
+ printf 'Missing option: %s\n' "$1"
+}
+
+# shellcheck disable=2068
+for flag in $@; do
+ if [ "$flag" = '--help' ]; then
+ usage
+ help
+ exit
+ elif [ "$flag" = '--version' ]; then
+ version
+ exit
+ 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)
+ version
+ exit
+ ;;
+ *)
+ printf 'Ignoring unrecognized flag "%s"' "$name" >&2
+ ;;
+ esac
+done
+
+if [ -z "$COMMANDFLAG" ]; then
+ missing '-c COMMAND' >&2
+ usage >&2
+ exit 2
+fi
+
+if [ -z "$PROFILEFLAG" ]; then
+ missing '-p PROFILE' >&2
+ 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"
+ printf '%s\n' "$CHOICE"
+fi