.sh

[sh] Multi-shell dotfiles manager
git clone https://git.torresjrjr.com/.sh.git
Log | Files | Refs | README | LICENSE

commit 1cf8cea074471577f784756fb1ca1f5ce9449432
parent 4fa5ed4c2dd8cd9c47add37725d99c74732867bc
Author: Byron Torres <b@torresjrjr.com>
Date:   Fri,  7 Apr 2023 17:13:12 +0100

gfa*: revamp, output new lines lazily

Diffstat:
Mbin/gfa | 74+++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 55 insertions(+), 19 deletions(-)

diff --git a/bin/gfa b/bin/gfa @@ -1,15 +1,26 @@ -#!/bin/sh -u +#!/bin/sh -eu # gfa -- fetch all git repos in cwd println() { - local line=$(( $1 + 1 )) column=$2 colour=$3 text=$4 - env printf '\r\e[%sB\e[%sC\e[%sm%s\e[m\r\e[%sA\e[%sC' \ - $line $column $colour "$text" $line $column + { flock 3 + line=$1 column=$2 colour=$3 text=$4 + lines=$( wc -l </tmp/gfa-lines ) + offset=$(( $lines - $line + 1)) + env printf '\r\e[%sA\e[%sC\e[%sm%s\e[m\r\e[%sB\r' \ + $offset $column \ + $colour "$text" \ + $offset + } 3</tmp/gfa-mutex } worker() { - local n=$1 - local dir="${2%/.git}" + local n="$( head -n1 /tmp/gfa-inits )" + local dir="${1%/.git}" + + { flock 3 + env printf '\n' | tee -a /tmp/gfa-lines + } 3</tmp/gfa-mutex + cd "$cwd" cd "$dir" println $n 0 0 "${dir#./}" @@ -28,15 +39,19 @@ worker() { case "$commits" in -1) - println $n $width 31 '?' + println "$n" $width 31 '?' ;; 0) - println $n $width 0 '.' + println "$n" $width 0 '.' ;; *) - println $n $width 32 "($commits)" + println "$n" $width 32 "($commits)" ;; esac + + env printf '\n' >/tmp/gfa-done + env printf '\n' >/tmp/gfa-finis + return } @@ -45,19 +60,40 @@ repos=$( find -maxdepth 3 -path '*/.git' -not -path '*/_*' | sort ) [ "$repos" ] || printf >&2 'No git repos here\n' -width="$(echo "$repos" | wc -L)" -total="$(echo "$repos" | wc -l)" +width="$(printf '%s\n' "$repos" | wc -L)" +total="$(printf '%s\n' "$repos" | wc -l)" + +touch /tmp/gfa-dummy +rm /tmp/gfa-* +touch /tmp/gfa-lines +touch /tmp/gfa-mutex +mkfifo /tmp/gfa-inits /tmp/gfa-finis /tmp/gfa-done -env printf '%s\r ~ \n' $(seq $(( total + 1 ))) -env printf '\e[%sA' $(( total + 1 )) -env printf '[fetching repos]\r' +winsz=32 +lines=0 + +env printf '[fetching %s repos]\n' "$total" -wg='' n=0 for dir in $repos do - worker $n "$dir" & wg="$wg $! " n=$(( n + 1 )) - sleep 0.05 + ( worker "$dir" )& done -wait $wg -env printf '\r\e[%sB' $(( total + 1 )) +worker_manager() { + for N in $(seq $total) + do + [ "$N" -gt $winsz ] && { + head -n1 /tmp/gfa-finis >/dev/null + } + + env printf '%s\n' "$N" + sleep 0.1 + done +} + +worker_manager >/tmp/gfa-inits & + +for N in $(seq $total) +do + head -n1 /tmp/gfa-done >/dev/null +done