diff options
author | Andrew Cady <d@jerkface.net> | 2024-08-21 08:13:09 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2024-08-21 20:47:18 -0400 |
commit | 0f255a500235df5c9d59b735836f6106537cf452 (patch) | |
tree | a7983a2316134d80c34c4cb606b047182afa657a /src/twopane.bash | |
parent | cd1a4ac7692ec73a35cfdb86334a5e9655d9a609 (diff) |
separate write-tty command
Diffstat (limited to 'src/twopane.bash')
-rwxr-xr-x | src/twopane.bash | 154 |
1 files changed, 42 insertions, 112 deletions
diff --git a/src/twopane.bash b/src/twopane.bash index 7056053..de42ba9 100755 --- a/src/twopane.bash +++ b/src/twopane.bash | |||
@@ -15,9 +15,10 @@ if [ $# = 0 ] | |||
15 | then | 15 | then |
16 | TOP_CMD="$SHELL -i" | 16 | TOP_CMD="$SHELL -i" |
17 | BOT_CMD=foreground | 17 | BOT_CMD=foreground |
18 | TOP_EXIT=prompt | ||
19 | #BOT_CMD=start | 18 | #BOT_CMD=start |
20 | #TOP_EXIT=restart | 19 | #TOP_EXIT=quit |
20 | #TOP_EXIT=prompt | ||
21 | TOP_EXIT=restart | ||
21 | else | 22 | else |
22 | TOP_CMD=$* | 23 | TOP_CMD=$* |
23 | BOT_CMD=start | 24 | BOT_CMD=start |
@@ -31,7 +32,7 @@ trap 'rm -r "$TWOPANE"' EXIT | |||
31 | # STY=$(systemd-escape -p "$TWOPANE") | 32 | # STY=$(systemd-escape -p "$TWOPANE") |
32 | systemd_escape_path() | 33 | systemd_escape_path() |
33 | { | 34 | { |
34 | declare -g -n path="$1" result="$2" | 35 | declare -n path="$1" result="$2" |
35 | result=$(realpath "$path") | 36 | result=$(realpath "$path") |
36 | result=${result//-/--} | 37 | result=${result//-/--} |
37 | result=${result//\//-} | 38 | result=${result//\//-} |
@@ -89,10 +90,8 @@ kill_screen_pane() | |||
89 | 90 | ||
90 | start_screen_pane() | 91 | start_screen_pane() |
91 | { | 92 | { |
92 | # declare -g -a PANES | ||
93 | declare -i pane="${1:-1}" | 93 | declare -i pane="${1:-1}" |
94 | (( pane > 0 )) || return | 94 | (( pane > 0 )) || return |
95 | # PANES+=("$pane") | ||
96 | if check_screen_pane "$pane" | 95 | if check_screen_pane "$pane" |
97 | then | 96 | then |
98 | return | 97 | return |
@@ -119,9 +118,9 @@ connect_coproc() | |||
119 | { | 118 | { |
120 | declare -n coproc="$1" | 119 | declare -n coproc="$1" |
121 | shift | 120 | shift |
122 | declare -g -n std1="${!coproc}_STDOUT" | 121 | declare -n std1="${!coproc}_STDOUT" |
123 | declare -g -n std0="${!coproc}_STDIN" | 122 | declare -n std0="${!coproc}_STDIN" |
124 | declare -g -n opid="${!coproc}_PID" | 123 | declare -n opid="${!coproc}_PID" |
125 | 124 | ||
126 | if [ $# = 0 ] | 125 | if [ $# = 0 ] |
127 | then | 126 | then |
@@ -136,7 +135,6 @@ connect_coproc() | |||
136 | "$@" | 135 | "$@" |
137 | } 2>&$STDERR {STDERR}>&- | 136 | } 2>&$STDERR {STDERR}>&- |
138 | } {STDERR}>&2 2>/dev/null | 137 | } {STDERR}>&2 2>/dev/null |
139 | i "${!opid}=$opid" | ||
140 | x disown | 138 | x disown |
141 | fi | 139 | fi |
142 | # The copied file descriptors (unlike the original coprocess | 140 | # The copied file descriptors (unlike the original coprocess |
@@ -153,39 +151,48 @@ disconnect_coproc() | |||
153 | if [ $# = 1 ] | 151 | if [ $# = 1 ] |
154 | then | 152 | then |
155 | declare -n coproc="$1" | 153 | declare -n coproc="$1" |
156 | declare -g -n std1="${!coproc}_STDOUT" | 154 | declare -n std1="${!coproc}_STDOUT" |
157 | declare -g -n std0="${!coproc}_STDIN" | 155 | declare -n std0="${!coproc}_STDIN" |
158 | declare -g -n pid="${!coproc}_PID" | 156 | declare -n pid="${!coproc}_PID" |
159 | [ "$std0" -a "$std1" ] || return | 157 | if [ "$std0" -o "$std1" ] |
160 | exec {std0}<&- {std1}>&- | 158 | then |
161 | unset std0 std1 | 159 | exec {std0}<&- {std1}>&- |
162 | x kill "$pid" | 160 | fi |
163 | x wait -f "$pid" | 161 | if [ "$pid" ] |
162 | then | ||
163 | x kill "$pid" | ||
164 | x wait -f "$pid" | ||
165 | fi | ||
166 | unset std0 std1 coproc pid | ||
164 | fi | 167 | fi |
165 | } | 168 | } |
166 | 169 | ||
167 | connect() | 170 | connect() |
168 | { | 171 | { |
169 | connect_coproc SOCAT | 172 | x connect_coproc TOP_PANE |
170 | i "SOCAT_PID=$SOCAT_PID" | ||
171 | } | 173 | } |
172 | 174 | ||
173 | disconnect() | 175 | disconnect() |
174 | { | 176 | { |
175 | i "SOCAT_STDIN=$SOCAT_STDIN SOCAT_STDOUT=$SOCAT_STDOUT SOCAT_PID=$SOCAT_PID" | 177 | i "${TOP_PANE_STDIN@A} ${TOP_PANE_STDOUT@A} ${TOP_PANE_PID@A} ${TOP_PANE[@]@A}" |
176 | x disconnect_coproc SOCAT | 178 | x disconnect_coproc TOP_PANE |
179 | if [ "$ECHOSEND" ] | ||
180 | then | ||
181 | kill $ECHOSEND_PID | ||
182 | unset ECHOSEND ECHOSEND_PID | ||
183 | fi | ||
177 | } | 184 | } |
178 | 185 | ||
179 | sendc() | 186 | sendc() |
180 | { | 187 | { |
181 | [ "${SOCAT[0]}" ] || connect | 188 | [ "${TOP_PANE[0]}" ] || connect |
182 | printf '%s' "$*" >&${SOCAT[1]} | 189 | printf '%s' "$*" >&${TOP_PANE[1]} |
183 | } | 190 | } |
184 | 191 | ||
185 | send() | 192 | send() |
186 | { | 193 | { |
187 | [ "${SOCAT[0]}" ] || connect | 194 | [ "${TOP_PANE[0]}" ] || connect |
188 | printf '%s\n' "$*" >&${SOCAT[1]} | 195 | printf '%s\n' "$*" >&${TOP_PANE[1]} |
189 | } | 196 | } |
190 | 197 | ||
191 | restart() | 198 | restart() |
@@ -222,23 +229,24 @@ tty_forward() | |||
222 | { | 229 | { |
223 | declare -i pid="$1" | 230 | declare -i pid="$1" |
224 | read-tty | 231 | read-tty |
225 | x kill $pid | 232 | x kill "$pid" |
226 | } | 233 | } |
227 | 234 | ||
228 | SOCAT() | 235 | TOP_PANE() |
229 | { | 236 | { |
230 | (exec -a bottom-pane-tty-forward socat - UNIX-CONNECT:"$TWOPANE"/socket,forever) | 237 | (exec -a bottom-pane-tty-forward socat - UNIX-CONNECT:"$TWOPANE"/socket,forever) |
231 | case "$TOP_EXIT" in | 238 | case "$TOP_EXIT" in |
232 | restart ) | 239 | restart ) |
233 | start_screen_pane 1 "$@" | 240 | start_screen_pane 1 "$@" |
241 | kill -USR1 $$ | ||
234 | ;; | 242 | ;; |
235 | quit ) | 243 | quit ) |
236 | quit | 244 | quit |
237 | ;; | 245 | ;; |
238 | prompt | * ) | 246 | prompt | * ) |
247 | focus bottom | ||
239 | ;; | 248 | ;; |
240 | esac | 249 | esac |
241 | x screen -X quit | ||
242 | } | 250 | } |
243 | 251 | ||
244 | echosend() | 252 | echosend() |
@@ -247,11 +255,11 @@ echosend() | |||
247 | declare -n pid="${!fd}_PID" | 255 | declare -n pid="${!fd}_PID" |
248 | if ! [ "$fd" ] | 256 | if ! [ "$fd" ] |
249 | then | 257 | then |
250 | connect_coproc SOCAT | 258 | x connect |
251 | i "SOCAT_PID=$SOCAT_PID" | 259 | i "${TOP_PANE_STDIN@A} ${TOP_PANE_STDOUT@A} ${TOP_PANE_PID@A} ${TOP_PANE[@]@A}" |
252 | exec {fd}> >( | 260 | exec {fd}> >( |
253 | (exec -a echosend socat - fd:${SOCAT_STDIN?e}!!-) | | 261 | (exec -a echosend socat - fd:${TOP_PANE_STDIN?e}!!-) | |
254 | tee >(output_filter) >&${SOCAT_STDOUT?e} | 262 | tee >(write-tty) >&${TOP_PANE_STDOUT?e} |
255 | ) | 263 | ) |
256 | pid=$! | 264 | pid=$! |
257 | fi | 265 | fi |
@@ -269,7 +277,7 @@ background() | |||
269 | { | 277 | { |
270 | start_screen_pane 1 "$@" | 278 | start_screen_pane 1 "$@" |
271 | focus bottom | 279 | focus bottom |
272 | echosend ECHOSEND | 280 | x echosend ECHOSEND |
273 | { | 281 | { |
274 | eval "tty_forward $ECHOSEND_PID &" | 282 | eval "tty_forward $ECHOSEND_PID &" |
275 | } >&$ECHOSEND | 283 | } >&$ECHOSEND |
@@ -287,7 +295,6 @@ foreground() | |||
287 | check_tty_reader || background | 295 | check_tty_reader || background |
288 | focus top | 296 | focus top |
289 | fg %tty_forward >/dev/null | 297 | fg %tty_forward >/dev/null |
290 | #disconnect | ||
291 | focus bottom | 298 | focus bottom |
292 | } | 299 | } |
293 | 300 | ||
@@ -296,16 +303,13 @@ foreground_loop() | |||
296 | while true | 303 | while true |
297 | do | 304 | do |
298 | foreground | 305 | foreground |
299 | x kill %tty_forward 2>/dev/null | ||
300 | case "$TOP_EXIT" in | 306 | case "$TOP_EXIT" in |
301 | restart ) | 307 | restart ) |
302 | x kill -INT $TTY_READER_PID $ECHOSEND_PID | ||
303 | start_screen_pane "$@" | 308 | start_screen_pane "$@" |
304 | continue ;; | 309 | continue ;; |
305 | quit ) | 310 | quit ) |
306 | exit ;; | 311 | exit ;; |
307 | prompt | * ) | 312 | prompt | * ) |
308 | x kill -INT $TTY_READER_PID $ECHOSEND_PID | ||
309 | break | 313 | break |
310 | ;; | 314 | ;; |
311 | esac | 315 | esac |
@@ -327,79 +331,6 @@ focus() | |||
327 | screen -X focus "$@" | 331 | screen -X focus "$@" |
328 | } | 332 | } |
329 | 333 | ||
330 | output_filter() | ||
331 | { | ||
332 | tokenize | colorize | soft_cursor | ||
333 | } | ||
334 | |||
335 | chr() | ||
336 | { | ||
337 | declare -i n="$*" | ||
338 | printf "\\$(printf %o "$n")" | ||
339 | } | ||
340 | |||
341 | colorize() | ||
342 | { | ||
343 | while read -r | ||
344 | do | ||
345 | case "$REPLY" in | ||
346 | \\[0-7][0-7][0-7] ) ;; | ||
347 | * ) | ||
348 | printf '%s\n' "$REPLY" | ||
349 | continue | ||
350 | ;; | ||
351 | esac | ||
352 | declare -i c=8#"${REPLY#?}" | ||
353 | if (( c > 128 + 127 )) | ||
354 | then | ||
355 | : | ||
356 | elif (( c > 128 + 32 )) | ||
357 | then | ||
358 | printf -v REPLY "M-$(chr c - 128)" | ||
359 | elif (( c > 127 )) | ||
360 | then | ||
361 | printf -v REPLY "M-^$(chr c - 128 + 64)" | ||
362 | elif (( c < 32 )) | ||
363 | then | ||
364 | printf -v REPLY "^$(chr c + 64)" | ||
365 | fi | ||
366 | printf $'\e[106m%s\e[m\n' "$REPLY" | ||
367 | done | ||
368 | } | ||
369 | |||
370 | tokenize() | ||
371 | { | ||
372 | while read -r -N1 | ||
373 | do | ||
374 | if [[ "$REPLY" =~ [[:print:]] ]] | ||
375 | then | ||
376 | # Output one printable character per line. It may be a | ||
377 | # multibyte unicode character. | ||
378 | printf '%s\n' "$REPLY" | ||
379 | continue | ||
380 | else | ||
381 | # If it is a non-printable, then we output a | ||
382 | # multi-character line. In this case we colorize it | ||
383 | # later so that it won't be confused with multiple | ||
384 | # printable characters in the . | ||
385 | printf '\\%.3o\n' "'$REPLY" | ||
386 | continue | ||
387 | fi | ||
388 | done | ||
389 | } | ||
390 | |||
391 | soft_cursor() | ||
392 | { | ||
393 | FMT=$'%s \b\e[%sm \e[m\b' | ||
394 | REPLY= | ||
395 | color=101 | ||
396 | while printf "$FMT" "$REPLY" "$color" | ||
397 | do | ||
398 | read -r || break | ||
399 | let '++color <= 105' || color=101 | ||
400 | done | ||
401 | } | ||
402 | |||
403 | resize() | 334 | resize() |
404 | { | 335 | { |
405 | screen -X resize "$@" | 336 | screen -X resize "$@" |
@@ -411,8 +342,7 @@ our_bashrc_main() | |||
411 | set -f | 342 | set -f |
412 | set -o pipefail | 343 | set -o pipefail |
413 | #trap 'focus bottom; resize 90%; read -p "Exit> "; quit' EXIT | 344 | #trap 'focus bottom; resize 90%; read -p "Exit> "; quit' EXIT |
414 | #trap 'echo USR1 >&2; focus bottom; x kill -INT %tty_forward $TTY_READER_PID $ECHOSEND_PID' USR1 | 345 | trap 'disconnect; focus bottom;' USR1 |
415 | trap 'quit' USR1 | ||
416 | export PS1="$BOT_TITLE\\\$ " | 346 | export PS1="$BOT_TITLE\\\$ " |
417 | } | 347 | } |
418 | 348 | ||