aboutsummaryrefslogtreecommitdiff
path: root/src/remembering.in
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2022-11-18 00:43:10 -0300
committerEuAndreh <eu@euandre.org>2022-11-25 23:14:05 -0300
commit694c2dbc6fa71ee6582bade3ecc82e7b6ace83bf (patch)
treec946b6a8b60a1a150b01b19ef699e38e4e7e96b4 /src/remembering.in
parentsrc/remembering.in: Use indented heredoc for usage() and help() (diff)
downloadremembering-694c2dbc6fa71ee6582bade3ecc82e7b6ace83bf.tar.gz
remembering-694c2dbc6fa71ee6582bade3ecc82e7b6ace83bf.tar.xz
Refactor: rewrite logic to make it simpler and faster
Diffstat (limited to 'src/remembering.in')
-rwxr-xr-xsrc/remembering.in163
1 files changed, 89 insertions, 74 deletions
diff --git a/src/remembering.in b/src/remembering.in
index 2ce8e9c..907ffe1 100755
--- a/src/remembering.in
+++ b/src/remembering.in
@@ -14,12 +14,25 @@ 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
+ -p PROFILE profile to be used for gathering and storing
+ data (default: create one based on $PWD)
+ -h, --help show this message
+ -V, --version print the version number
- See "man remembering" for more information.
+ COMMAND command to be ran, reading from
+ STDIN, writing to STDOUT
+
+
+ Explanation FIXME.
+
+ See "man @NAME@" for more information.
+
+
+ Examples:
+
+ FIXME:
+
+ $ FIXME
EOF
}
@@ -27,10 +40,24 @@ version() {
printf '%s %s %s\n' '@NAME@' '@VERSION@' '@DATE@'
}
-missing() {
- printf 'Missing option: %s\n' "$1"
+
+uuid() {
+ od -xN20 /dev/urandom |
+ head -n1 |
+ awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}'
+}
+
+tmpname() {
+ echo "${TMPDIR:-/tmp}/@NAME@.tmpfile.$(uuid)"
}
+mkstemp() {
+ name="$(tmpname)"
+ touch "$name"
+ echo "$name"
+}
+
+
for flag in "$@"; do
case "$flag" in
--)
@@ -50,15 +77,11 @@ for flag in "$@"; do
esac
done
-COMMANDFLAG=
-PROFILEFLAG=
-while getopts 'hc:p:V' name; do
- case "$name" in
- c)
- COMMANDFLAG="$OPTARG"
- ;;
+PROFILE_NAME="$(pwd | tr '/' '!')"
+while getopts 'p:hV' flag; do
+ case "$flag" in
p)
- PROFILEFLAG="$OPTARG"
+ PROFILE_NAME="$OPTARG"
;;
h)
usage
@@ -75,76 +98,68 @@ while getopts 'hc:p:V' name; do
;;
esac
done
+shift $((OPTIND - 1))
-if [ -z "$COMMANDFLAG" ]; then
- missing '-c COMMAND' >&2
- usage >&2
- exit 2
-fi
-if [ -z "$PROFILEFLAG" ]; then
- missing '-p PROFILE' >&2
+if [ $# = 0 ]; then
+ printf 'Missing "-- COMMAND"\n' >&2
usage >&2
exit 2
fi
-COMMAND="$COMMANDFLAG"
-PROFILE="${XDG_DATA_HOME:-$HOME/.local/share}/remembering/$PROFILEFLAG"
+NAME='@NAME@'
+PROFILE="${XDG_DATA_HOME:-$HOME/.local/share}"/$NAME/"$PROFILE_NAME"
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
- }
+NEXT_PROFILE="$PROFILE".tmp
+MERGED="$(mkstemp)"
+FILTERED="$(mkstemp)"
+trap 'rm -f "$NEXT_PROFILE" "$MERGED" "$FILTERED"' EXIT
+CHOICE="$(
+ cat - |
+ sed 's/^/0 stdin /' |
+ sort -k3 -k1nr - "$PROFILE" |
+ tee "$MERGED" |
+ awk '
+ { rest = substr($0, 3 + length($1) + length($2)) }
+ $2 == "profile" { seen[rest] += $1 }
+ $2 == "stdin" { printf "%s %s\n", seen[rest]+0, rest }
+ ' |
+ sort -k1nr |
+ cut -d' ' -f2- |
+ "$@"
+)"
+
+if [ -z "$CHOICE" ]; then
+ exit
+fi
+
+cat "$MERGED" |
+ cut -d' ' -f1,3- |
+ uniq -f1 |
+ awk -vCHOICE="$CHOICE" '
+ BEGIN { inc = 1 }
+
+ { rest = substr($0, 2 + length($1)) }
+
+ rest == CHOICE {
+ printf "%s profile %s\n", $1 + inc, rest
+ found = 1
+ next
}
- }' > "$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
+
+ { printf "%s profile %s\n", $1, rest }
+
+ END {
+ if (!found) {
+ printf "%s profile %s\n", 0 + inc, CHOICE
+ }
}
- }' "$MERGED" > "$NEW_PROFILE"
- mv "$NEW_PROFILE" "$PROFILE"
- printf '%s\n' "$CHOICE"
-fi
+ ' > "$NEXT_PROFILE"
+
+mv "$NEXT_PROFILE" "$PROFILE"
+printf '%s\n' "$CHOICE"