summaryrefslogtreecommitdiff
path: root/src/twopane.bash
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2024-08-21 17:42:07 -0400
committerAndrew Cady <d@jerkface.net>2024-08-21 20:47:18 -0400
commit98497a1a5e4eeba4d003c80e609ca2924148303f (patch)
treef6aee7399d81e3a7225712d79278fc82d55075a8 /src/twopane.bash
parent0f255a500235df5c9d59b735836f6106537cf452 (diff)
still working
Diffstat (limited to 'src/twopane.bash')
-rwxr-xr-xsrc/twopane.bash132
1 files changed, 79 insertions, 53 deletions
diff --git a/src/twopane.bash b/src/twopane.bash
index de42ba9..e2b12c9 100755
--- a/src/twopane.bash
+++ b/src/twopane.bash
@@ -17,8 +17,8 @@ then
17 BOT_CMD=foreground 17 BOT_CMD=foreground
18 #BOT_CMD=start 18 #BOT_CMD=start
19 #TOP_EXIT=quit 19 #TOP_EXIT=quit
20 #TOP_EXIT=prompt 20 TOP_EXIT=prompt
21 TOP_EXIT=restart 21 #TOP_EXIT=restart
22else 22else
23 TOP_CMD=$* 23 TOP_CMD=$*
24 BOT_CMD=start 24 BOT_CMD=start
@@ -105,7 +105,7 @@ start_screen_pane()
105 TOP_TITLE="Command: ${*@Q}" 105 TOP_TITLE="Command: ${*@Q}"
106 screen -X focus top 106 screen -X focus top
107 screen -X screen -ln -t "$TOP_TITLE" 1 "$@" 107 screen -X screen -ln -t "$TOP_TITLE" 1 "$@"
108 screen -p "$pane" -X exec .!. bash -c 'exec -a top-pane-tty-forward socat UNIX-LISTEN:"$TWOPANE"/socket STDIN,cfmakeraw!!STDOUT' 108 screen -p "$pane" -X exec .!. bash -c 'exec -a top-pane-tty-forward socat UNIX-LISTEN:"$TWOPANE"/socket STDIN,cfmakeraw,opost=1,onlcr=1!!STDOUT'
109} 109}
110 110
111restart_screen_pane() 111restart_screen_pane()
@@ -135,7 +135,7 @@ connect_coproc()
135 "$@" 135 "$@"
136 } 2>&$STDERR {STDERR}>&- 136 } 2>&$STDERR {STDERR}>&-
137 } {STDERR}>&2 2>/dev/null 137 } {STDERR}>&2 2>/dev/null
138 x disown 138 disown
139 fi 139 fi
140 # The copied file descriptors (unlike the original coprocess 140 # The copied file descriptors (unlike the original coprocess
141 # file descriptors, in ${coproc[0]} and ${coproc[1]}) can be 141 # file descriptors, in ${coproc[0]} and ${coproc[1]}) can be
@@ -148,37 +148,36 @@ connect_coproc()
148 148
149disconnect_coproc() 149disconnect_coproc()
150{ 150{
151 if [ $# = 1 ] 151 [ $# = 1 ] || return
152 declare -n coproc="$1"
153 declare -n std0="${!coproc}_STDIN"
154 declare -n std1="${!coproc}_STDOUT"
155 declare -n pid="${!coproc}_PID"
156 if [ "$std0" -o "$std1" ]
152 then 157 then
153 declare -n coproc="$1" 158 exec {std0}<&- {std1}>&-
154 declare -n std1="${!coproc}_STDOUT"
155 declare -n std0="${!coproc}_STDIN"
156 declare -n pid="${!coproc}_PID"
157 if [ "$std0" -o "$std1" ]
158 then
159 exec {std0}<&- {std1}>&-
160 fi
161 if [ "$pid" ]
162 then
163 x kill "$pid"
164 x wait -f "$pid"
165 fi
166 unset std0 std1 coproc pid
167 fi 159 fi
160 if [ "$pid" ]
161 then
162 kill "$pid" 2>/dev/null
163 wait -f "$pid" 2>/dev/null
164 fi
165 unset coproc std0 std1 pid
168} 166}
169 167
170connect() 168connect()
171{ 169{
172 x connect_coproc TOP_PANE 170 connect_coproc TOP_PANE
173} 171}
174 172
175disconnect() 173disconnect()
176{ 174{
177 i "${TOP_PANE_STDIN@A} ${TOP_PANE_STDOUT@A} ${TOP_PANE_PID@A} ${TOP_PANE[@]@A}" 175 : "${TOP_PANE_STDIN@A} ${TOP_PANE_STDOUT@A} ${TOP_PANE_PID@A} ${TOP_PANE[@]@A}"
178 x disconnect_coproc TOP_PANE 176 disconnect_coproc TOP_PANE
179 if [ "$ECHOSEND" ] 177 if [ "$ECHOSEND" ]
180 then 178 then
181 kill $ECHOSEND_PID 179 exec {ECHOSEND}>&-
180 kill $ECHOSEND_PID 2>/dev/null
182 unset ECHOSEND ECHOSEND_PID 181 unset ECHOSEND ECHOSEND_PID
183 fi 182 fi
184} 183}
@@ -207,9 +206,9 @@ start()
207 206
208check_tty_reader() 207check_tty_reader()
209{ 208{
210 [ "$TTY_READER_PID" ] || return 209 [ "$TTY_FORWARD_PID" ] || return
211 TTY_READER_JOBSPEC=$(jobs -sl | pid_to_jobspec "$TTY_READER_PID") 210 TTY_FORWARD_JOBSPEC=$(jobs -sl | pid_to_jobspec "$TTY_FORWARD_PID")
212 [ "$TTY_READER_JOBSPEC" ] 211 [ "$TTY_FORWARD_JOBSPEC" ]
213} 212}
214 213
215pid_to_jobspec() 214pid_to_jobspec()
@@ -227,20 +226,26 @@ pid_to_jobspec()
227 226
228tty_forward() 227tty_forward()
229{ 228{
230 declare -i pid="$1" 229 printf '%d\n' "$BASHPID" > "$TWOPANE"/tty_forward.pid
231 read-tty 230 read-tty
232 x kill "$pid" 231}
232
233kill_tty_forward()
234{
235 read pid < "$TWOPANE"/tty_forward.pid
236 /bin/kill -INT -- -$pid 2>/dev/null
233} 237}
234 238
235TOP_PANE() 239TOP_PANE()
236{ 240{
237 (exec -a bottom-pane-tty-forward socat - UNIX-CONNECT:"$TWOPANE"/socket,forever) 241 (exec -a bottom-pane-tty-forward socat - UNIX-CONNECT:"$TWOPANE"/socket,forever)
242 kill_tty_forward
238 case "$TOP_EXIT" in 243 case "$TOP_EXIT" in
239 restart ) 244 restart )
240 start_screen_pane 1 "$@"
241 kill -USR1 $$ 245 kill -USR1 $$
242 ;; 246 ;;
243 quit ) 247 quit )
248 kill -INT $$
244 quit 249 quit
245 ;; 250 ;;
246 prompt | * ) 251 prompt | * )
@@ -249,20 +254,24 @@ TOP_PANE()
249 esac 254 esac
250} 255}
251 256
252echosend() 257sink()
253{ 258{
254 declare -n fd="$1" 259 declare -n fd="$1"
255 declare -n pid="${!fd}_PID" 260 declare -n pid="${!fd}_PID"
256 if ! [ "$fd" ] 261 if [ "$fd" ]
257 then 262 then
258 x connect 263 exec {fd}>&-
259 i "${TOP_PANE_STDIN@A} ${TOP_PANE_STDOUT@A} ${TOP_PANE_PID@A} ${TOP_PANE[@]@A}" 264 kill $pid 2>/dev/null
260 exec {fd}> >( 265 unset fd pid
261 (exec -a echosend socat - fd:${TOP_PANE_STDIN?e}!!-) |
262 tee >(write-tty) >&${TOP_PANE_STDOUT?e}
263 )
264 pid=$!
265 fi 266 fi
267 exec {fd}> >("${@:2}")
268 pid=$!
269}
270
271echo_sender()
272{
273 (exec -a echo_sender socat - fd:${TOP_PANE_STDIN?$0: Internal error}!!-) |
274 tee >(write-tty) >&${TOP_PANE_STDOUT?$0: Internal error}
266} 275}
267 276
268quiet_bg() 277quiet_bg()
@@ -275,47 +284,59 @@ quiet_bg()
275 284
276background() 285background()
277{ 286{
287 disconnect
278 start_screen_pane 1 "$@" 288 start_screen_pane 1 "$@"
279 focus bottom 289 focus bottom
280 x echosend ECHOSEND 290 connect
281 { 291 sink ECHOSEND echo_sender
282 eval "tty_forward $ECHOSEND_PID &" 292 quiet_bg tty_forward >&$ECHOSEND
283 } >&$ECHOSEND 293 TTY_FORWARD_PID=$!
284 TTY_READER_PID=$! 294 printf '%d\n' "$TTY_FORWARD_PID" > "$TWOPANE"/tty_forward.pid
285 printf '%s\n' \ 295 printf '%s\n' \
286 "#!/bin/bash" \ 296 "#!/bin/bash" \
287 "kill -TSTP $TTY_READER_PID" \ 297 "kill -TSTP $TTY_FORWARD_PID" \
288 "screen -X focus bottom" \ 298 "screen -X focus bottom" \
289 > "$TWOPANE"/unforward 299 > "$TWOPANE"/unforward
290 chmod +x "$TWOPANE"/unforward 300 chmod +x "$TWOPANE"/unforward
291} 301}
292 302
293foreground() 303foreground_once()
294{ 304{
295 check_tty_reader || background 305 check_tty_reader || background "$@"
296 focus top 306 focus top
297 fg %tty_forward >/dev/null 307 while jobs %tty_forward >/dev/null 2>&1
298 focus bottom 308 do
309 fg %tty_forward >/dev/null
310 kill %tty_forward 2>/dev/null
311 done
299} 312}
300 313
301foreground_loop() 314foreground_loop()
302{ 315{
303 while true 316 while true
304 do 317 do
305 foreground 318 foreground_once "$@"
306 case "$TOP_EXIT" in 319 case "$TOP_EXIT" in
307 restart ) 320 restart )
308 start_screen_pane "$@" 321 start_screen_pane "$@"
309 continue ;; 322 continue
323 ;;
310 quit ) 324 quit )
311 exit ;; 325 quit
326 ;;
312 prompt | * ) 327 prompt | * )
313 break 328 kill -INT 0
329 break # unreached
314 ;; 330 ;;
315 esac 331 esac
316 done 332 done
317} 333}
318 334
335foreground()
336{
337 foreground_loop "$@"
338}
339
319twopane() 340twopane()
320{ 341{
321 start "$@" 342 start "$@"
@@ -336,13 +357,18 @@ resize()
336 screen -X resize "$@" 357 screen -X resize "$@"
337} 358}
338 359
360SIGUSR1()
361{
362 i "${BASH_COMMAND@A}"
363}
364
339our_bashrc_main() 365our_bashrc_main()
340{ 366{
341 set -m 367 set -m
342 set -f 368 set -f
343 set -o pipefail 369 set -o pipefail
344 #trap 'focus bottom; resize 90%; read -p "Exit> "; quit' EXIT 370 #trap 'focus bottom; resize 90%; read -p "Exit> "; quit' EXIT
345 trap 'disconnect; focus bottom;' USR1 371 trap 'SIGUSR1' USR1
346 export PS1="$BOT_TITLE\\\$ " 372 export PS1="$BOT_TITLE\\\$ "
347} 373}
348 374