+# beet modify quietly
+beetmq() {
+ local tmpf
+ tmpf="$(mktemp)"
+ # a bunch of effort to ignore output we dont care about...
+ sed 's/^format_item:.*/format_item: ignore_this/' ~/.config/beets/config.yaml >$tmpf
+ beet -c $tmpf modify -y "$@" > >(grep -vFx -e 'ignore_this' -e 'Modifying 1 items.' ||:)
+ rm "$tmpf"
+ beetag-nostatus 1
+}
+
+kill-bg-quiet() {
+ # https://stackoverflow.com/a/5722874
+ kill %% 2>/dev/null ||:; wait %% 2>/dev/null ||:
+}
+
+# debug variables
+dv() {
+ for arg; do
+ printf "%s=%s " "$arg" "${!arg}"
+ done
+ echo
+}
+
+# Must be called from beetag for variables to be setup
+beetag-help() {
+ local -i i j col_total row col button_total row_total remainder_cols remainder_term
+ col_total=4
+ button_total=${#button_map[@]}
+ row_total=$(( button_total / col_total ))
+ remainder_cols=$(( button_total % col_total ))
+ # for debugging
+ #dv button_total row_total remainder_cols
+ beetag-nostatus
+ # - 3 is just a constant that helps things work in practice.
+ if [[ $LINES ]] && (( LINES - 3 < scrolled )); then
+ hr
+ for (( i=0; i<button_total; i++)); do
+ row=$(( i / col_total ))
+ col=$(( i % col_total ))
+ remainder_term=$remainder_cols
+ if (( col < remainder_term )); then
+ remainder_term=$col
+ fi
+ j=$(( col * row_total + row + remainder_term ))
+ # avoid double newline when we have exactly row * col buttons
+ if (( i == button_total - 1 )); then
+ printf "%s %s" ${buttons[j]} ${button_map[j]}
+ elif (( i % col_total == col_total -1 )); then
+ printf "%s %s\n" ${buttons[j]} ${button_map[j]}
+ else
+ printf "%s %-15s" ${buttons[j]} ${button_map[j]}
+ fi
+ done
+ cat <<'EOF'
+
+
+y other genres z fg player ' = toggle play 1-5 rate
+; previous _ = delete up/down skip mpv vol,pause,seek
+EOF
+ hr
+ scrolled=10
+ fi
+}
+
+# Must be called from beetag for variables to be setup
+beetag-nostatus() {
+ if (( $# )); then
+ scrolled=$(( scrolled + $1 ))
+ fi
+ if $erasable_line; then
+ # https://stackoverflow.com/a/71286261
+ printf '\033[1A\033[K'
+ fi
+ erasable_line=false
+}
+# meant to be called from beetag
+beetag-status() {
+ if $erasable_line; then
+ # https://stackoverflow.com/a/71286261
+ printf '\033[1A\033[K'
+ fi
+ erasable_line=true
+}
+
+# meant to be called from beetag
+mpvrpc() {
+ if jobs -p | grep -q . &>/dev/null; then
+ printf "%s\n" "$*" | socat - /tmp/mpvsock >/dev/null ||:
+ fi
+}
+# meant to be called from beetag
+# o for get output
+mpvrpco() {
+ # note: testing for background jobs will output nothing if we are in a pipeline
+ printf "%s\n" "$*" | socat - /tmp/mpvsock ||:
+}
+
+# meant to be called from beetag
+mpvrpc-percent-pos() {
+ mpvrpco '{ "command": ["get_property", "percent-pos"] }' | jq .data | sed 's/\..*/%/' 2>/dev/null ||:
+}
+