diff options
-rwxr-xr-x | twopane.bash | 105 |
1 files changed, 71 insertions, 34 deletions
diff --git a/twopane.bash b/twopane.bash index bec96b9..39a6bfb 100755 --- a/twopane.bash +++ b/twopane.bash | |||
@@ -32,6 +32,7 @@ save_file() | |||
32 | { | 32 | { |
33 | cat > "$TWOPANE"/"${1:?$0: Error: filename cannot be empty string}" | 33 | cat > "$TWOPANE"/"${1:?$0: Error: filename cannot be empty string}" |
34 | } | 34 | } |
35 | |||
35 | save_screenrc() | 36 | save_screenrc() |
36 | { | 37 | { |
37 | save_file screenrc"${1:+.$1}" | 38 | save_file screenrc"${1:+.$1}" |
@@ -156,7 +157,7 @@ disconnect() | |||
156 | { | 157 | { |
157 | if [ $# = 2 ] | 158 | if [ $# = 2 ] |
158 | then | 159 | then |
159 | declare -n std0="$1" std1="$2" | 160 | declare -i -n std0="$1" std1="$2" |
160 | eval "exec $std0<&- $std1>&-" | 161 | eval "exec $std0<&- $std1>&-" |
161 | unset std0 std1 | 162 | unset std0 std1 |
162 | fi | 163 | fi |
@@ -228,12 +229,12 @@ forward() | |||
228 | # the other pane's terminal. Uppercase $STDIN/$STDOUT are the | 229 | # the other pane's terminal. Uppercase $STDIN/$STDOUT are the |
229 | # real stdin/stdout of this function, connected to the lower | 230 | # real stdin/stdout of this function, connected to the lower |
230 | # pane's terminal. Socat here merges inputs from both sources. | 231 | # pane's terminal. Socat here merges inputs from both sources. |
232 | exec {STDIN}<&0 {STDOUT}>&1 {STDERR}>&2 | ||
231 | 233 | ||
232 | # The input is put out raw back over the socket. The input is | 234 | # The input is put out raw back over the socket. The input is |
233 | # copied to stdout after being filtered (to display control | 235 | # copied to stdout after being filtered (to display control |
234 | # characters with carrot-encoding like '^[' etc). | 236 | # characters with carrot-encoding like '^[' etc). |
235 | exec {STDIN}<&0 {STDOUT}>&1 {STDERR}>&2 | 237 | exec {TEE}> >(tee >(output_filter >&$STDOUT) >&$stdout) |
236 | exec {TEE}> >(tee >(output_filter | soft_cursor >&$STDOUT) >&$stdout) | ||
237 | stty=cfmakeraw,opost=1,onlcr=1 | 238 | stty=cfmakeraw,opost=1,onlcr=1 |
238 | { | 239 | { |
239 | socat FD:$STDIN,$stty!!STDOUT - <&$stdin >&$TEE 2>&$STDERR & | 240 | socat FD:$STDIN,$stty!!STDOUT - <&$stdin >&$TEE 2>&$STDERR & |
@@ -304,34 +305,79 @@ focus() | |||
304 | 305 | ||
305 | output_filter() | 306 | output_filter() |
306 | { | 307 | { |
307 | exec {OUTPUT_FILTER}> >(exec cat -v) | 308 | tokenize | colorize | soft_cursor |
308 | while read -r -N1 | 309 | } |
310 | |||
311 | # if (show_nonprinting) { | ||
312 | # while (true) | ||
313 | # { | ||
314 | # if (ch >= 32) { | ||
315 | # if (ch < 127) *bpout++ = ch; | ||
316 | # else if (ch == 127) {*bpout++ = '^'; *bpout++ = '?';} | ||
317 | # else { | ||
318 | # *bpout++ = 'M'; | ||
319 | # *bpout++ = '-'; | ||
320 | # if (ch >= 128 + 32) { | ||
321 | # if (ch < 128 + 127) *bpout++ = ch - 128; | ||
322 | # else {*bpout++ = '^'; *bpout++ = '?';}} | ||
323 | # else {*bpout++ = '^'; *bpout++ = ch - 128 + 64;}}} | ||
324 | # else if (ch == '\t' && !show_tabs) *bpout++ = '\t'; | ||
325 | # else if (ch == '\n') {newlines = -1; break;} | ||
326 | # else {*bpout++ = '^'; *bpout++ = ch + 64;} | ||
327 | # ch = *bpin++;}} | ||
328 | |||
329 | chr() | ||
330 | { | ||
331 | declare -i n="$*" | ||
332 | printf "\\$(printf %o "$n")" | ||
333 | } | ||
334 | |||
335 | colorize() | ||
336 | { | ||
337 | while read -r | ||
309 | do | 338 | do |
310 | case "$REPLY" in | 339 | case "$REPLY" in |
311 | # Encode literal '^' as escape. This allows | 340 | \\[0-7][0-7][0-7] ) ;; |
312 | # a '^' in the output to be interpreted | 341 | * ) |
313 | # unambiguously as a control sequence later | 342 | printf '%s\n' "$REPLY" |
314 | # downstream, where it will be displayed in | ||
315 | # bold. | ||
316 | '^' ) | ||
317 | echo -n $'\e' | ||
318 | continue | ||
319 | ;; | ||
320 | $'\t' ) | ||
321 | echo -n '^I' | ||
322 | continue | 343 | continue |
323 | ;; | 344 | ;; |
324 | $'\n' ) | ||
325 | echo -n '^J' | ||
326 | continue | ||
327 | ;; | ||
328 | esac | 345 | esac |
329 | # Add unicode support to cat through bash primitives! | 346 | declare -i c=8#"${REPLY#?}" |
347 | if (( c > 128 + 127 )) | ||
348 | then | ||
349 | : | ||
350 | elif (( c > 128 + 32 )) | ||
351 | then | ||
352 | printf -v REPLY "M-$(chr c - 128)" | ||
353 | elif (( c > 127 )) | ||
354 | then | ||
355 | printf -v REPLY "M-^$(chr c - 128 + 64)" | ||
356 | elif (( c < 32 )) | ||
357 | then | ||
358 | printf -v REPLY "^$(chr c + 64)" | ||
359 | fi | ||
360 | printf $'\e[1m%s\e[m\n' "$REPLY" | ||
361 | done | ||
362 | } | ||
363 | |||
364 | tokenize() | ||
365 | { | ||
366 | while read -r -N1 | ||
367 | do | ||
330 | if [[ "$REPLY" =~ [[:print:]] ]] | 368 | if [[ "$REPLY" =~ [[:print:]] ]] |
331 | then | 369 | then |
332 | printf '%s' "$REPLY" | 370 | # Output one printable character per line. It may be a |
371 | # multibyte unicode character. | ||
372 | printf '%s\n' "$REPLY" | ||
373 | continue | ||
333 | else | 374 | else |
334 | printf '%s' "$REPLY" >&${OUTPUT_FILTER} | 375 | # If it is a non-printable, then we output a |
376 | # multi-character line. In this case we colorize it | ||
377 | # later so that it won't be confused with multiple | ||
378 | # printable characters. | ||
379 | printf '\\%.3o\n' "'$REPLY" | ||
380 | continue | ||
335 | fi | 381 | fi |
336 | done | 382 | done |
337 | } | 383 | } |
@@ -342,16 +388,7 @@ soft_cursor() | |||
342 | REPLY= | 388 | REPLY= |
343 | while printf "$FMT" "$REPLY" $(( 101 + RANDOM % 7 )) | 389 | while printf "$FMT" "$REPLY" $(( 101 + RANDOM % 7 )) |
344 | do | 390 | do |
345 | read -r -N1 || break | 391 | read -r || break |
346 | case "$REPLY" in | ||
347 | '^' ) | ||
348 | read -r -N1 || break | ||
349 | REPLY=$'\e[1m^'$REPLY$'\e[m' | ||
350 | ;; | ||
351 | $'\e' ) | ||
352 | REPLY='^' | ||
353 | ;; | ||
354 | esac | ||
355 | done | 392 | done |
356 | } | 393 | } |
357 | 394 | ||