From 9b99f2b4061aecca469014ab214949d8283dc25e Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Sun, 25 Aug 2024 10:55:14 -0400 Subject: too many changes gotta commit em all!! --- src/hijack-prompt.bash | 167 ++++++++++++++++++++++++++++++++++++++----------- src/twopane.bash | 32 ++++++++-- src/write-tty | 46 +++++++++----- 3 files changed, 186 insertions(+), 59 deletions(-) diff --git a/src/hijack-prompt.bash b/src/hijack-prompt.bash index f41dd17..6da5888 100755 --- a/src/hijack-prompt.bash +++ b/src/hijack-prompt.bash @@ -1,49 +1,38 @@ #!/bin/bash +PS4=$'+ L\t$LINENO:\t' case $- in *i* ) - set -m + ;; + *x* ) + exec bash --init-file "$0" -i -x -s "$@" ;; * ) - exec bash --init-file "$0" -i "$@" + exec bash --init-file "$0" -i -s "$@" ;; esac -unhijack() -{ - case $# in - 0 ) - exec \ - 0<&$HIJACK_0 \ - 1>&$HIJACK_1 \ - 2>&$HIJACK_2 \ - {HIJACK_0}<&- \ - {HIJACK_1}>&- \ - {HIJACK_2}>&- - ;; - * ) - echo "history -d -1; unhijack; ${*@Q}" - ;; - esac -} +set -mx -finally() -{ - exec \ - {HIJACK_0}<&0 \ - {HIJACK_1}>&1 \ - {HIJACK_2}>&2 \ - 0< <(unhijack eval "$1") \ - &> /dev/null - { - "${@:2}" - } <&$HIJACK_0 >&$HIJACK_1 2>&$HIJACK_2 -} +source ./src/finally.bash burld_read() { - sleep 1 - read -p '[hullo? burld?]> ' - echo "Burly ${REPLY:-Burld!}" + while r=0; POSIXLY_CORRECT=y read -N1 -p '[hullo? burld?]> ' || r=$? + do + if (( r > 128 )) + then + sleep .25 + continue + elif [[ -n $REPLY ]] + then + echo "Burly ${REPLY:-Burld!}" + return 0 + else + echo "read returned $r" >&2 + return $r + fi + done + return 1 } quiet_fg() @@ -55,20 +44,124 @@ quiet_bg() { local STDERR { - eval "$(printf '%q ' "$@") 2>&\$STDERR {STDERR}>&- &" + eval "$(printf '%q ' "$@") 2>&$STDERR $STDERR>&- &" } {STDERR}>&2 2>/dev/null } ring0() { - PS1="Burly boo\\\$ " + PS1="Burly ${SIGNAL:=bee}\\\$ " +} + +lifetime() +{ + [[ $$ != $BASHPID ]] && trap 'exit 0' INT + sleep "$1" & + if wait -f $! + then + kill "${@:2}" 2>/dev/null + true + else + return $? + fi +} + +h() +{ + quiet_bg sleep 5 + jobs -x quiet_bg lifetime 3 -INT %% + finally 'ring0' \ + quiet_fg %sleep +} + +# Does this work? +g() +{ + # lifetime 1 -INT $$ & + { burld_read; kill -INT $$; : reached ; } & + lifetime 3 -STOP $! & + PROMPT_COMMAND='pcmd fg' + fg +} + +# Does this work? +g() +{ + # lifetime 1 $$ & + { burld_read; kill -INT $$; : reached ; } & + lifetime 3 -INT $$ & disown + finally 'fg' eval 'sleep 3m & wait -f $!' +} + +gn() +{ + { burld_read; kill -INT $$; : reached ; } & + lifetime 3 -TSTP $! & disown + finally 'fg' fg +} + +gp() +{ + { burld_read; kill -INT $$; : reached ; } & + trap "finally fg :" SIGINT + lifetime 3 -INT $$ & disown +# finally 'fg' fg } +# Interrupting read that works f() { quiet_bg burld_read + jobs -x quiet_bg lifetime 3 -INT %% finally 'ring0' \ - quiet_fg burld_read + quiet_fg %burld_read +} + +pcmd() +{ + if [ "$PROMPT_COMMAND" ] + then + PROMPT_COMMAND= + "$@" + else + PROMPT_COMMAND="pcmd ${*@Q}" + fi +} + +ff() +{ + quiet_bg burld_read + jobs -x quiet_bg lifetime 3 -INT %% + pcmd ring0 + quiet_fg %burld_read +} + +ring0gg() +{ + kill -INT "$1" 2>/dev/null + PS1="Burly ${SIGNAL:=bee}\\\$ " } +gg() +{ + quiet_bg burld_read + jobs -x quiet_bg lifetime 3 -INT %% + finally "ring0gg $!" \ + quiet_fg %burld_read +} + +DEBUG=y + +trap 'SIGNAL=INT; : SIGINT' INT + PS1="[type 'f']\\\$ " + +case "$1" in + '' ) ;; + ff ) + "$1" + ;; + * ) + "$1" + ;; +esac diff --git a/src/twopane.bash b/src/twopane.bash index 59077fe..327d246 100755 --- a/src/twopane.bash +++ b/src/twopane.bash @@ -22,8 +22,8 @@ then TOP_CMD="$SHELL -i" BOT_CMD=start #TOP_EXIT=quit - TOP_EXIT=prompt - #TOP_EXIT=restart + #TOP_EXIT=prompt + TOP_EXIT=restart elif [ "$TWOPANE" -a "$*" = detach ] then kill_tty_forward -TSTP @@ -245,18 +245,19 @@ start() tty_forward() { printf '%d\n' "$BASHPID" > "$TWOPANE"/tty_forward.pid + trap 'kill -INT $$' INT read-tty } TOP_PANE() { (exec -a bottom-pane-tty-forward socat - UNIX-CONNECT:"$TWOPANE"/socket,forever) - x kill_tty_forward + x kill_tty_forward -STOP case "$TOP_EXIT" in restart ) # x kill -USR1 $$ x kill -INT $$ - with_screen_pane 1 start_screen_pane "$@" + # with_screen_pane 1 start_screen_pane "$@" ;; quit ) kill -INT $$ @@ -313,7 +314,7 @@ background() disconnect_sink ECHOSEND connect connect_sink ECHOSEND echo_sender - kill %tty_forward + kill %tty_forward 2>/dev/null %tty_forward & disown %tty_forward i 'starting tty_forward' @@ -379,6 +380,26 @@ SIGCHLD() i "SIGCHILD: ${BASH_COMMAND@A}" } +prompt_command() +{ + set -- 'unset PROMPT_COMMAND; restart' + + exec {FINALLY_0}<&0 {FINALLY_1}>&1 {FINALLY_2}>&2 + if ! [ "$DEBUG" ] + then + exec &>/dev/null + fi + cmd="history -d -1; exec <&$FINALLY_0 >&$FINALLY_1 >&$FINALLY_2; $*" + exec <<< "$cmd" +} + +SIGINT() +{ + i INT "${BASH_COMMAND@A}" + kill $TOP_PANE_PID $ECHOSEND_PID 2>/dev/null + PROMPT_COMMAND=prompt_command +} + our_bashrc_main() { BASH_ARGV0=twopane @@ -388,6 +409,7 @@ our_bashrc_main() set -o pipefail trap 'SIGUSR1' USR1 # trap 'SIGCHLD' CHLD + trap 'SIGINT' INT trap '! [ "$DEBUG" ] || read -p "Exit> "; quit' EXIT export PS1="$BOT_TITLE\\\$ " } diff --git a/src/write-tty b/src/write-tty index fbe62ea..8fdb78f 100644 --- a/src/write-tty +++ b/src/write-tty @@ -10,7 +10,7 @@ output_filter() chr() { declare -i n="$*" - printf "\\$(printf %o "$n")" + printf "$(printf '\%o' "$n")" } colorize() @@ -20,25 +20,29 @@ colorize() while read -r do case "$REPLY" in - \\[0-7][0-7][0-7] ) ;; + \\[0-7][0-7][0-7] ) + declare -i c=8#"${REPLY#?}" + ;; + \\U[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] ) + declare -i c=16#"${REPLY#??}" + ;; * ) printf '%s\n' "$REPLY" continue ;; esac - declare -i c=8#"${REPLY#?}" if (( c > 128 + 127 )) then : elif (( c > 128 + 32 )) then - printf -v REPLY "M-$(chr c - 128)" + REPLY=M-$(chr c - 128) elif (( c > 127 )) then - printf -v REPLY "M-^$(chr c - 128 + 64)" + REPLY=M-^$(chr c - 128 + 64) elif (( c < 32 )) then - printf -v REPLY "^$(chr c + 64)" + REPLY=^$(chr c + 64) fi printf $'\e[106m%s\e[m\n' "$REPLY" done @@ -48,7 +52,7 @@ tokenize() { BASH_ARGV0=tokenize echo -n "$0" >/proc/$BASHPID/comm - while read -r -N1 + while read -r -n1 -d '' do if [[ "$REPLY" =~ [[:print:]] ]] then @@ -56,13 +60,26 @@ tokenize() # multibyte unicode character. printf '%s\n' "$REPLY" continue - else + elif [ "$REPLY" ] + then # If it is a non-printable, then we output a # multi-character line. In this case we colorize it # later so that it won't be confused with multiple - # printable characters in the . - printf '\\%.3o\n' "'$REPLY" - continue + # printable characters. + bytelen=$(LC_ALL=C; echo ${#REPLY}) + if (( bytelen == 1 )) + then + printf '\\%.3o\n' "'$REPLY" + else + hexdigits=$(LC_ALL=C; for ((i=0; i<$bytelen; ++i)) + do + printf '%.2x' "'${REPLY:$i:1}" + printf '%.2x\n' "'${REPLY:$i:1}" >&2 + done) + printf '%s%.8x\n' '\U' 0x"$hexdigits" + fi + else + printf '\\%.3o\n' 0 fi done } @@ -81,9 +98,4 @@ soft_cursor() done } -if [ -t 1 ] -then - output_filter -else - exec -a write-tty-raw socat - - -fi +output_filter -- cgit v1.2.3