commit 20fe3f0e9197bd4c4fcedb03f710d72cd4f098d2
parent cebc7201350dfc11ecb3c8ec8c02698debd12cb8
Author: Jacob R. Edwards <n/a>
Date: Tue, 29 Nov 2022 11:13:17 -0600
Add buf, a buffer manager
This (ugly) script provides a more-or-less common interface to X
and tmux buffers (dubbed "external") aswell as it's own internal
ones. Additional external buffers may be added too, see the script
for details.
A caveat to external buffers is that they cannot be dynamic. For
example, tmux maintains multiple buffers, yet only the default one
can reasonably be used with this script. This may be changed in the
future.
There is currently no way of removing buffers (since I would only
implement it for internal buffers, I'm not sure I want to add the
feature).
Diffstat:
4 files changed, 117 insertions(+), 0 deletions(-)
diff --git a/local/Makefile b/local/Makefile
@@ -3,6 +3,7 @@ dest = ${HOME}
mods =\
awk\
bin\
+ buf\
dillo\
git\
ksh\
diff --git a/local/bin/bin/buf b/local/bin/bin/buf
@@ -0,0 +1,109 @@
+#!/bin/sh
+# Copyright 2022 Jacob R. Edwards
+# buf -- Buffer manager
+#
+# This (ugly) script provides a more-or-less common interface to
+# X and tmux buffers (dubbed "external") aswell as it's own internal
+# ones. Additional external buffers may be added in the external
+# config ($XDG_CONFIG_HOME/bufs/external), the format is like this:
+#
+# name (get|set) sh(1) command to get or set
+#
+# A caveat to external buffers is that they cannot be dynamic. For
+# example, tmux maintains multiple buffers, yet only the default
+# one can reasonably be used with this script. This COULD and MAY
+# be changed in the future.
+# If no buffer is specified, $XDG_CONFIG_HOME/bufs/default is
+# read to determine the default buffer to use.
+# There is currently no way of removing buffers (since I would
+# only implement it for internal buffers, I'm not sure I want to
+# add the feature).
+
+bufs=/tmp/bufs/$(id -u)
+config="${XDG_CONFIG_HOME:-"$HOME"/.config}"/buf
+
+buffers() (
+ {
+ test -f "$config"/external &&
+ awk '$2 == "get" { print $1 }' < "$config"/external
+ (cd "$bufs" &&
+ find . -type f | cut -c3-)
+ } | sort -u | egrep -e "${1:-.}"
+)
+
+external() {
+ awk -vtype="$1" -vname="$2" '
+ BEGIN {
+ if (!name)
+ exit 1;
+ }
+ $1 == name && $2 == type {
+ sub("^[^ ]+[ +]+(get|set)[ ]+", "", $0);
+ p=$0;
+ exit
+ }
+ END {
+ if (!p) {
+ if (name)
+ printf "%s not found\n", name > "/dev/stderr";
+ exit 1
+ }
+ print p
+ }' < "$config"/external
+}
+
+getbuf() {
+ cat "$bufs/$1" 2>/dev/null ||
+ sh -c "$(external get "$1")"
+}
+
+setbuf() {
+ if set="$(external set "$1" 2>/dev/null)"
+ then
+ sh -c "$set"
+ else
+ cat > "$bufs/$1"
+ fi
+}
+
+swap() {
+ swap="$(mktemp "$bufs"/swapXXXXXX)"
+ swapname="$(basename "$swap")"
+ trap 'rm -f "$swap"; exit 1' TERM INT
+ getbuf "$1" | setbuf "$swapname"
+ getbuf "$2" | setbuf "$1"
+ getbuf "$swapname" | setbuf "$2"
+ rm -f "$swap"
+ trap '' TERM INT
+}
+
+default() cat "$config"/default
+
+set -eu
+
+mkdir -p "$bufs"
+com="$1"
+shift
+case "$#$com" in
+([01]list)
+ buffers "$@" ;;
+([01]brief|[01]show)
+ for buf in $(buffers "$@")
+ do
+ echo "$buf" = "$(getbuf "$buf" | sed -n '1h; 2{ g; s/$/ [...]/p; q; }')"
+ done
+ ;;
+([01]get)
+ getbuf "${1:-"$(default)"}" ;;
+([01]set)
+ setbuf "${1:-"$(default)"}" ;;
+([12]swap)
+ swap "$1" "${2:-"$(default)"}" ;;
+(*)
+ echo 'usage: buf list [regex]
+ buf show [regex]
+ buf get [buf]
+ buf set [buf]
+ buf swap buf1 [buf2]' 1>&2
+ exit 1
+esac
diff --git a/local/buf/config/buf/default b/local/buf/config/buf/default
@@ -0,0 +1 @@
+x/clipboard
diff --git a/local/buf/config/buf/external b/local/buf/config/buf/external
@@ -0,0 +1,6 @@
+tmux get tmux show-buffer
+tmux set tmux set-buffer "$(cat)"
+x/clipboard get xclip -selection clipboard -out
+x/clipboard set xclip -r -selection clipboard
+x/primary get xclip -out
+x/primary set xclip -r