diff options
Diffstat (limited to 'twopane.bash')
-rwxr-xr-x | twopane.bash | 122 |
1 files changed, 78 insertions, 44 deletions
diff --git a/twopane.bash b/twopane.bash index 672448e..3389d51 100755 --- a/twopane.bash +++ b/twopane.bash | |||
@@ -14,7 +14,7 @@ then | |||
14 | else | 14 | else |
15 | TOP_CMD=$* | 15 | TOP_CMD=$* |
16 | fi | 16 | fi |
17 | TOP_TITLE=$TOP_CMD | 17 | TOP_TITLE="Command: $TOP_CMD" |
18 | 18 | ||
19 | TWOPANE=$(mktemp -d) | 19 | TWOPANE=$(mktemp -d) |
20 | export TWOPANE TOP_CMD BOT_CMD TOP_TITLE BOT_TITLE BOT_SIZE | 20 | export TWOPANE TOP_CMD BOT_CMD TOP_TITLE BOT_TITLE BOT_SIZE |
@@ -52,7 +52,6 @@ save_screenrc 'startpane' <<. | |||
52 | focus top | 52 | focus top |
53 | screen -ln -t "\$TOP_TITLE" 1 $TOP_CMD | 53 | screen -ln -t "\$TOP_TITLE" 1 $TOP_CMD |
54 | exec .!. sh -c 'socat UNIX-LISTEN:"\$TWOPANE"/socket STDIN,rawer!!STDOUT' | 54 | exec .!. sh -c 'socat UNIX-LISTEN:"\$TWOPANE"/socket STDIN,rawer!!STDOUT' |
55 | title 'output' | ||
56 | focus top | 55 | focus top |
57 | . | 56 | . |
58 | 57 | ||
@@ -65,30 +64,58 @@ restart_top() | |||
65 | screen -X source "$TWOPANE"/screenrc.startpane | 64 | screen -X source "$TWOPANE"/screenrc.startpane |
66 | } | 65 | } |
67 | 66 | ||
67 | socat_connect() | ||
68 | { | ||
69 | socat STDIN!!STDOUT UNIX-CONNECT:"$TWOPANE"/socket,forever | ||
70 | kill -USR1 $$ | ||
71 | [ "$TOP_EXIT" != restart ] || restart_top | ||
72 | } | ||
73 | |||
68 | connect() | 74 | connect() |
69 | { | 75 | { |
70 | coproc SOCAT \ | 76 | case $# in |
71 | { | 77 | 2 ) declare -n std0="$1" std1="$2"; local pid ;; |
72 | socat STDIN!!STDOUT UNIX-CONNECT:"$TWOPANE"/socket,forever | 78 | 3 ) declare -n pid="$1" std0="$2" std1="$3" ;; |
73 | kill -USR1 $$ | 79 | * ) exit 1 ;; |
74 | [ "$TOP_EXIT" != restart ] || restart_top | 80 | esac |
75 | } | 81 | std0=${3:-200} |
76 | eval "exec $1<&${SOCAT[0]} $2>&${SOCAT[1]}" | 82 | std1=${4:-201} |
83 | disconnect $std0 $std1 | ||
84 | coproc SOCAT { socat_connect; } | ||
85 | pid=${SOCAT_PID} | ||
86 | eval "exec ${std0}<&${SOCAT[0]} ${std1}>&${SOCAT[1]}" | ||
87 | } | ||
88 | |||
89 | sendc() | ||
90 | { | ||
91 | [ "${SOCAT[0]}" || connect stdin stdout | ||
92 | printf '%s' "$*" >&$stdout | ||
93 | } | ||
94 | |||
95 | send() | ||
96 | { | ||
97 | [ "${SOCAT[0]}" || connect stdin stdout | ||
98 | printf '%s\n' "$*" >&$stdout | ||
77 | } | 99 | } |
78 | 100 | ||
79 | disconnect() | 101 | disconnect() |
80 | { | 102 | { |
81 | eval "exec $1<&- $2>&-" | 103 | eval "exec ${1:-200}<&- ${2:-201}>&-" |
82 | } | 104 | } |
83 | 105 | ||
84 | restart() | 106 | restart() |
85 | { | 107 | { |
86 | [ "${SOCAT[0]}" ] || restart_top | ||
87 | start | 108 | start |
88 | } | 109 | } |
89 | 110 | ||
90 | start() | 111 | start() |
91 | { | 112 | { |
113 | if [ "$STARTED" ] | ||
114 | then | ||
115 | restart_top | ||
116 | else | ||
117 | STARTED=y | ||
118 | fi | ||
92 | socat_stty_opts=( | 119 | socat_stty_opts=( |
93 | rawer | 120 | rawer |
94 | echo=0 | 121 | echo=0 |
@@ -106,17 +133,16 @@ start() | |||
106 | ) | 133 | ) |
107 | stty=$(printf %s, "${socat_stty_opts[@]}") | 134 | stty=$(printf %s, "${socat_stty_opts[@]}") |
108 | 135 | ||
109 | trap ': SIGUSR1 ; ' USR1 | 136 | trap ': SIGUSR1 ; SOCAT=() ; ' USR1 |
110 | exec 100<&0 101>&1 | 137 | exec 100<&0 101>&1 |
111 | while true | 138 | while true |
112 | do | 139 | do |
113 | connect 200 201 | 140 | connect stdin stdout |
114 | socat FD:100,${stty%,}!!STDOUT STDIN!!STDOUT <&200 | | 141 | socat FD:100,${stty%,}!!STDOUT STDIN!!STDOUT <&$stdin | |
115 | input_filter | | 142 | tee >(output_filter | soft_cursor >&101) >&$stdout |
116 | tee >(output_filter | soft_cursor >&101) >&201 | ||
117 | 143 | ||
118 | reset -I -Q -w | 144 | reset -I -Q -w |
119 | disconnect 200 201 | 145 | disconnect |
120 | wait -f "$SOCAT_PID" 2>/dev/null | 146 | wait -f "$SOCAT_PID" 2>/dev/null |
121 | 147 | ||
122 | case "$TOP_EXIT" in | 148 | case "$TOP_EXIT" in |
@@ -143,49 +169,57 @@ focus() | |||
143 | screen -X focus "$@" | 169 | screen -X focus "$@" |
144 | } | 170 | } |
145 | 171 | ||
146 | input_filter() | 172 | output_filter() |
147 | { | 173 | { |
148 | while read -N1 | 174 | exec 15> >(exec cat -v) |
175 | while read -r -N1 | ||
149 | do | 176 | do |
150 | case "$REPLY" in | 177 | case "$REPLY" in |
151 | a ) echo -n "${REPLY@U}" ;; | 178 | $'\n' ) |
152 | A ) echo -n "${REPLY@L}" ;; | 179 | echo -n '^J' |
153 | * ) echo -n "$REPLY" ;; | 180 | continue |
181 | ;; | ||
154 | esac | 182 | esac |
183 | if [[ "$REPLY" =~ [[:print:]] ]] | ||
184 | then | ||
185 | printf '%s' "$REPLY" | ||
186 | else | ||
187 | printf '%s' "$REPLY" >&15 | ||
188 | fi | ||
155 | done | 189 | done |
156 | } | 190 | } |
157 | 191 | ||
158 | output_filter() | ||
159 | { | ||
160 | cat -vt | ||
161 | } | ||
162 | |||
163 | soft_cursor() | 192 | soft_cursor() |
164 | { | 193 | { |
165 | cursor_color=104 | 194 | cursor=$'\033['${cursor_color:=104}$'m \b\033[00m' |
166 | cursor=$'\033['"$cursor_color"$'m \b\033[00m' | ||
167 | printf '%s' "$cursor" | 195 | printf '%s' "$cursor" |
168 | while read -N1 | 196 | while read -r -N1 |
169 | do | 197 | do |
170 | printf '%s' "$REPLY" "$cursor" | 198 | case "$REPLY" in |
199 | $'\r' ) printf '%s' "$REPLY" "$cursor" ;; | ||
200 | * ) printf '%s' $' \b' "$REPLY" "$cursor" ;; | ||
201 | esac | ||
171 | done | 202 | done |
172 | } | 203 | } |
173 | 204 | ||
205 | our_bashrc_main() | ||
206 | { | ||
207 | set -f | ||
208 | set -o pipefail | ||
209 | shopt -s lastpipe | ||
210 | trap "screen -X quit" EXIT | ||
211 | export PS1="\$BOT_TITLE\$ " | ||
212 | if [ "\$SHOW_SOCAT_ERRORS" ] | ||
213 | then | ||
214 | exec 20>&2 | ||
215 | else | ||
216 | exec 20>/dev/null | ||
217 | fi | ||
218 | } | ||
219 | |||
174 | save_file bashrc <<. | 220 | save_file bashrc <<. |
175 | set -f | ||
176 | set -o pipefail | ||
177 | shopt -s lastpipe | ||
178 | trap "screen -X quit" EXIT | ||
179 | $(declare -f) | 221 | $(declare -f) |
180 | export PS1="\$BOT_TITLE\$ " | 222 | our_bashrc_main |
181 | |||
182 | if [ "\$SHOW_SOCAT_ERRORS" ] | ||
183 | then | ||
184 | exec 20>&2 | ||
185 | else | ||
186 | exec 20>/dev/null | ||
187 | fi | ||
188 | |||
189 | \$BOT_CMD | 223 | \$BOT_CMD |
190 | . | 224 | . |
191 | 225 | ||