summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/hijack-prompt.bash167
-rwxr-xr-xsrc/twopane.bash32
-rw-r--r--src/write-tty46
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 @@
1#!/bin/bash 1#!/bin/bash
2PS4=$'+ L\t$LINENO:\t'
2case $- in 3case $- in
3 *i* ) 4 *i* )
4 set -m 5 ;;
6 *x* )
7 exec bash --init-file "$0" -i -x -s "$@"
5 ;; 8 ;;
6 * ) 9 * )
7 exec bash --init-file "$0" -i "$@" 10 exec bash --init-file "$0" -i -s "$@"
8 ;; 11 ;;
9esac 12esac
10 13
11unhijack() 14set -mx
12{
13 case $# in
14 0 )
15 exec \
16 0<&$HIJACK_0 \
17 1>&$HIJACK_1 \
18 2>&$HIJACK_2 \
19 {HIJACK_0}<&- \
20 {HIJACK_1}>&- \
21 {HIJACK_2}>&-
22 ;;
23 * )
24 echo "history -d -1; unhijack; ${*@Q}"
25 ;;
26 esac
27}
28 15
29finally() 16source ./src/finally.bash
30{
31 exec \
32 {HIJACK_0}<&0 \
33 {HIJACK_1}>&1 \
34 {HIJACK_2}>&2 \
35 0< <(unhijack eval "$1") \
36 &> /dev/null
37 {
38 "${@:2}"
39 } <&$HIJACK_0 >&$HIJACK_1 2>&$HIJACK_2
40}
41 17
42burld_read() 18burld_read()
43{ 19{
44 sleep 1 20 while r=0; POSIXLY_CORRECT=y read -N1 -p '[hullo? burld?]> ' || r=$?
45 read -p '[hullo? burld?]> ' 21 do
46 echo "Burly ${REPLY:-Burld!}" 22 if (( r > 128 ))
23 then
24 sleep .25
25 continue
26 elif [[ -n $REPLY ]]
27 then
28 echo "Burly ${REPLY:-Burld!}"
29 return 0
30 else
31 echo "read returned $r" >&2
32 return $r
33 fi
34 done
35 return 1
47} 36}
48 37
49quiet_fg() 38quiet_fg()
@@ -55,20 +44,124 @@ quiet_bg()
55{ 44{
56 local STDERR 45 local STDERR
57 { 46 {
58 eval "$(printf '%q ' "$@") 2>&\$STDERR {STDERR}>&- &" 47 eval "$(printf '%q ' "$@") 2>&$STDERR $STDERR>&- &"
59 } {STDERR}>&2 2>/dev/null 48 } {STDERR}>&2 2>/dev/null
60} 49}
61 50
62ring0() 51ring0()
63{ 52{
64 PS1="Burly boo\\\$ " 53 PS1="Burly ${SIGNAL:=bee}\\\$ "
54}
55
56lifetime()
57{
58 [[ $$ != $BASHPID ]] && trap 'exit 0' INT
59 sleep "$1" &
60 if wait -f $!
61 then
62 kill "${@:2}" 2>/dev/null
63 true
64 else
65 return $?
66 fi
67}
68
69h()
70{
71 quiet_bg sleep 5
72 jobs -x quiet_bg lifetime 3 -INT %%
73 finally 'ring0' \
74 quiet_fg %sleep
75}
76
77# Does this work?
78g()
79{
80 # lifetime 1 -INT $$ &
81 { burld_read; kill -INT $$; : reached ; } &
82 lifetime 3 -STOP $! &
83 PROMPT_COMMAND='pcmd fg'
84 fg
85}
86
87# Does this work?
88g()
89{
90 # lifetime 1 $$ &
91 { burld_read; kill -INT $$; : reached ; } &
92 lifetime 3 -INT $$ & disown
93 finally 'fg' eval 'sleep 3m & wait -f $!'
94}
95
96gn()
97{
98 { burld_read; kill -INT $$; : reached ; } &
99 lifetime 3 -TSTP $! & disown
100 finally 'fg' fg
101}
102
103gp()
104{
105 { burld_read; kill -INT $$; : reached ; } &
106 trap "finally fg :" SIGINT
107 lifetime 3 -INT $$ & disown
108# finally 'fg' fg
65} 109}
66 110
111# Interrupting read that works
67f() 112f()
68{ 113{
69 quiet_bg burld_read 114 quiet_bg burld_read
115 jobs -x quiet_bg lifetime 3 -INT %%
70 finally 'ring0' \ 116 finally 'ring0' \
71 quiet_fg burld_read 117 quiet_fg %burld_read
118}
119
120pcmd()
121{
122 if [ "$PROMPT_COMMAND" ]
123 then
124 PROMPT_COMMAND=
125 "$@"
126 else
127 PROMPT_COMMAND="pcmd ${*@Q}"
128 fi
129}
130
131ff()
132{
133 quiet_bg burld_read
134 jobs -x quiet_bg lifetime 3 -INT %%
135 pcmd ring0
136 quiet_fg %burld_read
137}
138
139ring0gg()
140{
141 kill -INT "$1" 2>/dev/null
142 PS1="Burly ${SIGNAL:=bee}\\\$ "
72} 143}
73 144
145gg()
146{
147 quiet_bg burld_read
148 jobs -x quiet_bg lifetime 3 -INT %%
149 finally "ring0gg $!" \
150 quiet_fg %burld_read
151}
152
153DEBUG=y
154
155trap 'SIGNAL=INT; : SIGINT' INT
156
74PS1="[type 'f']\\\$ " 157PS1="[type 'f']\\\$ "
158
159case "$1" in
160 '' ) ;;
161 ff )
162 "$1"
163 ;;
164 * )
165 "$1"
166 ;;
167esac
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
22 TOP_CMD="$SHELL -i" 22 TOP_CMD="$SHELL -i"
23 BOT_CMD=start 23 BOT_CMD=start
24 #TOP_EXIT=quit 24 #TOP_EXIT=quit
25 TOP_EXIT=prompt 25 #TOP_EXIT=prompt
26 #TOP_EXIT=restart 26 TOP_EXIT=restart
27elif [ "$TWOPANE" -a "$*" = detach ] 27elif [ "$TWOPANE" -a "$*" = detach ]
28then 28then
29 kill_tty_forward -TSTP 29 kill_tty_forward -TSTP
@@ -245,18 +245,19 @@ start()
245tty_forward() 245tty_forward()
246{ 246{
247 printf '%d\n' "$BASHPID" > "$TWOPANE"/tty_forward.pid 247 printf '%d\n' "$BASHPID" > "$TWOPANE"/tty_forward.pid
248 trap 'kill -INT $$' INT
248 read-tty 249 read-tty
249} 250}
250 251
251TOP_PANE() 252TOP_PANE()
252{ 253{
253 (exec -a bottom-pane-tty-forward socat - UNIX-CONNECT:"$TWOPANE"/socket,forever) 254 (exec -a bottom-pane-tty-forward socat - UNIX-CONNECT:"$TWOPANE"/socket,forever)
254 x kill_tty_forward 255 x kill_tty_forward -STOP
255 case "$TOP_EXIT" in 256 case "$TOP_EXIT" in
256 restart ) 257 restart )
257 # x kill -USR1 $$ 258 # x kill -USR1 $$
258 x kill -INT $$ 259 x kill -INT $$
259 with_screen_pane 1 start_screen_pane "$@" 260 # with_screen_pane 1 start_screen_pane "$@"
260 ;; 261 ;;
261 quit ) 262 quit )
262 kill -INT $$ 263 kill -INT $$
@@ -313,7 +314,7 @@ background()
313 disconnect_sink ECHOSEND 314 disconnect_sink ECHOSEND
314 connect 315 connect
315 connect_sink ECHOSEND echo_sender 316 connect_sink ECHOSEND echo_sender
316 kill %tty_forward 317 kill %tty_forward 2>/dev/null
317 %tty_forward & 318 %tty_forward &
318 disown %tty_forward 319 disown %tty_forward
319 i 'starting tty_forward' 320 i 'starting tty_forward'
@@ -379,6 +380,26 @@ SIGCHLD()
379 i "SIGCHILD: ${BASH_COMMAND@A}" 380 i "SIGCHILD: ${BASH_COMMAND@A}"
380} 381}
381 382
383prompt_command()
384{
385 set -- 'unset PROMPT_COMMAND; restart'
386
387 exec {FINALLY_0}<&0 {FINALLY_1}>&1 {FINALLY_2}>&2
388 if ! [ "$DEBUG" ]
389 then
390 exec &>/dev/null
391 fi
392 cmd="history -d -1; exec <&$FINALLY_0 >&$FINALLY_1 >&$FINALLY_2; $*"
393 exec <<< "$cmd"
394}
395
396SIGINT()
397{
398 i INT "${BASH_COMMAND@A}"
399 kill $TOP_PANE_PID $ECHOSEND_PID 2>/dev/null
400 PROMPT_COMMAND=prompt_command
401}
402
382our_bashrc_main() 403our_bashrc_main()
383{ 404{
384 BASH_ARGV0=twopane 405 BASH_ARGV0=twopane
@@ -388,6 +409,7 @@ our_bashrc_main()
388 set -o pipefail 409 set -o pipefail
389 trap 'SIGUSR1' USR1 410 trap 'SIGUSR1' USR1
390 # trap 'SIGCHLD' CHLD 411 # trap 'SIGCHLD' CHLD
412 trap 'SIGINT' INT
391 trap '! [ "$DEBUG" ] || read -p "Exit> "; quit' EXIT 413 trap '! [ "$DEBUG" ] || read -p "Exit> "; quit' EXIT
392 export PS1="$BOT_TITLE\\\$ " 414 export PS1="$BOT_TITLE\\\$ "
393} 415}
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()
10chr() 10chr()
11{ 11{
12 declare -i n="$*" 12 declare -i n="$*"
13 printf "\\$(printf %o "$n")" 13 printf "$(printf '\%o' "$n")"
14} 14}
15 15
16colorize() 16colorize()
@@ -20,25 +20,29 @@ colorize()
20 while read -r 20 while read -r
21 do 21 do
22 case "$REPLY" in 22 case "$REPLY" in
23 \\[0-7][0-7][0-7] ) ;; 23 \\[0-7][0-7][0-7] )
24 declare -i c=8#"${REPLY#?}"
25 ;;
26 \\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] )
27 declare -i c=16#"${REPLY#??}"
28 ;;
24 * ) 29 * )
25 printf '%s\n' "$REPLY" 30 printf '%s\n' "$REPLY"
26 continue 31 continue
27 ;; 32 ;;
28 esac 33 esac
29 declare -i c=8#"${REPLY#?}"
30 if (( c > 128 + 127 )) 34 if (( c > 128 + 127 ))
31 then 35 then
32 : 36 :
33 elif (( c > 128 + 32 )) 37 elif (( c > 128 + 32 ))
34 then 38 then
35 printf -v REPLY "M-$(chr c - 128)" 39 REPLY=M-$(chr c - 128)
36 elif (( c > 127 )) 40 elif (( c > 127 ))
37 then 41 then
38 printf -v REPLY "M-^$(chr c - 128 + 64)" 42 REPLY=M-^$(chr c - 128 + 64)
39 elif (( c < 32 )) 43 elif (( c < 32 ))
40 then 44 then
41 printf -v REPLY "^$(chr c + 64)" 45 REPLY=^$(chr c + 64)
42 fi 46 fi
43 printf $'\e[106m%s\e[m\n' "$REPLY" 47 printf $'\e[106m%s\e[m\n' "$REPLY"
44 done 48 done
@@ -48,7 +52,7 @@ tokenize()
48{ 52{
49 BASH_ARGV0=tokenize 53 BASH_ARGV0=tokenize
50 echo -n "$0" >/proc/$BASHPID/comm 54 echo -n "$0" >/proc/$BASHPID/comm
51 while read -r -N1 55 while read -r -n1 -d ''
52 do 56 do
53 if [[ "$REPLY" =~ [[:print:]] ]] 57 if [[ "$REPLY" =~ [[:print:]] ]]
54 then 58 then
@@ -56,13 +60,26 @@ tokenize()
56 # multibyte unicode character. 60 # multibyte unicode character.
57 printf '%s\n' "$REPLY" 61 printf '%s\n' "$REPLY"
58 continue 62 continue
59 else 63 elif [ "$REPLY" ]
64 then
60 # If it is a non-printable, then we output a 65 # If it is a non-printable, then we output a
61 # multi-character line. In this case we colorize it 66 # multi-character line. In this case we colorize it
62 # later so that it won't be confused with multiple 67 # later so that it won't be confused with multiple
63 # printable characters in the . 68 # printable characters.
64 printf '\\%.3o\n' "'$REPLY" 69 bytelen=$(LC_ALL=C; echo ${#REPLY})
65 continue 70 if (( bytelen == 1 ))
71 then
72 printf '\\%.3o\n' "'$REPLY"
73 else
74 hexdigits=$(LC_ALL=C; for ((i=0; i<$bytelen; ++i))
75 do
76 printf '%.2x' "'${REPLY:$i:1}"
77 printf '%.2x\n' "'${REPLY:$i:1}" >&2
78 done)
79 printf '%s%.8x\n' '\U' 0x"$hexdigits"
80 fi
81 else
82 printf '\\%.3o\n' 0
66 fi 83 fi
67 done 84 done
68} 85}
@@ -81,9 +98,4 @@ soft_cursor()
81 done 98 done
82} 99}
83 100
84if [ -t 1 ] 101output_filter
85then
86 output_filter
87else
88 exec -a write-tty-raw socat - -
89fi