From 528bd6611776713fb8fc42c143e72480cd8b4f08 Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Wed, 14 Aug 2024 16:31:49 -0400 Subject: implement pause/resume for input forwarding --- twopane.bash | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 6 deletions(-) diff --git a/twopane.bash b/twopane.bash index d4d6459..0398ed7 100755 --- a/twopane.bash +++ b/twopane.bash @@ -174,7 +174,7 @@ background() connect stdin stdout } -foreground() +foreground_loop() { while true do @@ -196,25 +196,92 @@ foreground() done } -forward() +forwarding() { - forward_input "$@" + [ "$FORWARD_PID" ] || return + FORWARD_JOBSPEC=$(jobs -sl | pid_to_jobspec "$FORWARD_PID") + [ "$FORWARD_JOBSPEC" ] } -forward_input() +forward() { + declare -g FORWARD_PID if ! check_top then echo "$0: Warning: Nothing to forward. Starting anew." >&2 background "$@" + elif forwarding + then + resume_forward + return fi + focus top - socat FD:100,cfmakeraw!!STDOUT - <&$stdin | - tee >(output_filter | soft_cursor >&101) >&$stdout + old_stty=$(stty -g) + # Lowercase $stdin/$stdout are the SOCAT coprocess connected to + # the other pane's terminal. Uppercase $STDIN/$STDOUT are the + # real stdin/stdout of this function, connected to the lower + # pane's terminal. Socat here merges inputs from both sources. + + # The input is put out raw back over the socket. The input is + # copied to stdout after being filtered (to display control + # characters with carrot-encoding like '^[' etc). + exec {STDIN}<&0 {STDOUT}>&1 {STDERR}>&2 + exec {TEE}> >(tee >(output_filter | soft_cursor >&$STDOUT) >&$stdout) + socat FD:$STDIN,cfmakeraw,opost=1,onlcr=1!!STDOUT - <&$stdin >&$TEE & + FORWARD_PID=$! + printf '%s\n' "#!/bin/bash" "kill $!" "screen -X focus bottom" > "$TWOPANE"/unforward + chmod +x "$TWOPANE"/unforward + fg stty "$old_stty" focus bottom } +cfmakeraw() +{ + cmd=(stty -ignbrk -brkint -parmrk -istrip -inlcr -igncr -icrnl + -ixon -opost -echo -echonl -icanon -isig -iexten -parenb cs8) + "${cmd[@]}" "$@" +} + +pid_to_jobspec() +{ + while read jspec pid status cmd + do + [ "$pid" = "$1" ] || continue + jspec=${jspec%]*} + jspec=%${jspec#[} + echo $jspec + return + done + false +} + +resume_forward() +{ + old_stty=$(stty -g) + cfmakeraw opost onlcr + focus top + fg "$FORWARD_JOBSPEC" + stty "$old_stty" + focus bottom +} + +foreground() +{ + if forwarding + then + resume_forward + else + foreground_loop "$@" + fi +} + +twopane() +{ + start "$@" +} + quit() { screen -X quit -- cgit v1.2.3