diff options
-rwxr-xr-x | twopane.bash | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/twopane.bash b/twopane.bash index d4d6459..0398ed7 100755 --- a/twopane.bash +++ b/twopane.bash | |||
@@ -174,7 +174,7 @@ background() | |||
174 | connect stdin stdout | 174 | connect stdin stdout |
175 | } | 175 | } |
176 | 176 | ||
177 | foreground() | 177 | foreground_loop() |
178 | { | 178 | { |
179 | while true | 179 | while true |
180 | do | 180 | do |
@@ -196,25 +196,92 @@ foreground() | |||
196 | done | 196 | done |
197 | } | 197 | } |
198 | 198 | ||
199 | forward() | 199 | forwarding() |
200 | { | 200 | { |
201 | forward_input "$@" | 201 | [ "$FORWARD_PID" ] || return |
202 | FORWARD_JOBSPEC=$(jobs -sl | pid_to_jobspec "$FORWARD_PID") | ||
203 | [ "$FORWARD_JOBSPEC" ] | ||
202 | } | 204 | } |
203 | 205 | ||
204 | forward_input() | 206 | forward() |
205 | { | 207 | { |
208 | declare -g FORWARD_PID | ||
206 | if ! check_top | 209 | if ! check_top |
207 | then | 210 | then |
208 | echo "$0: Warning: Nothing to forward. Starting anew." >&2 | 211 | echo "$0: Warning: Nothing to forward. Starting anew." >&2 |
209 | background "$@" | 212 | background "$@" |
213 | elif forwarding | ||
214 | then | ||
215 | resume_forward | ||
216 | return | ||
210 | fi | 217 | fi |
218 | |||
211 | focus top | 219 | focus top |
212 | socat FD:100,cfmakeraw!!STDOUT - <&$stdin | | 220 | old_stty=$(stty -g) |
213 | tee >(output_filter | soft_cursor >&101) >&$stdout | 221 | # Lowercase $stdin/$stdout are the SOCAT coprocess connected to |
222 | # the other pane's terminal. Uppercase $STDIN/$STDOUT are the | ||
223 | # real stdin/stdout of this function, connected to the lower | ||
224 | # pane's terminal. Socat here merges inputs from both sources. | ||
225 | |||
226 | # The input is put out raw back over the socket. The input is | ||
227 | # copied to stdout after being filtered (to display control | ||
228 | # characters with carrot-encoding like '^[' etc). | ||
229 | exec {STDIN}<&0 {STDOUT}>&1 {STDERR}>&2 | ||
230 | exec {TEE}> >(tee >(output_filter | soft_cursor >&$STDOUT) >&$stdout) | ||
231 | socat FD:$STDIN,cfmakeraw,opost=1,onlcr=1!!STDOUT - <&$stdin >&$TEE & | ||
232 | FORWARD_PID=$! | ||
233 | printf '%s\n' "#!/bin/bash" "kill $!" "screen -X focus bottom" > "$TWOPANE"/unforward | ||
234 | chmod +x "$TWOPANE"/unforward | ||
235 | fg | ||
214 | stty "$old_stty" | 236 | stty "$old_stty" |
215 | focus bottom | 237 | focus bottom |
216 | } | 238 | } |
217 | 239 | ||
240 | cfmakeraw() | ||
241 | { | ||
242 | cmd=(stty -ignbrk -brkint -parmrk -istrip -inlcr -igncr -icrnl | ||
243 | -ixon -opost -echo -echonl -icanon -isig -iexten -parenb cs8) | ||
244 | "${cmd[@]}" "$@" | ||
245 | } | ||
246 | |||
247 | pid_to_jobspec() | ||
248 | { | ||
249 | while read jspec pid status cmd | ||
250 | do | ||
251 | [ "$pid" = "$1" ] || continue | ||
252 | jspec=${jspec%]*} | ||
253 | jspec=%${jspec#[} | ||
254 | echo $jspec | ||
255 | return | ||
256 | done | ||
257 | false | ||
258 | } | ||
259 | |||
260 | resume_forward() | ||
261 | { | ||
262 | old_stty=$(stty -g) | ||
263 | cfmakeraw opost onlcr | ||
264 | focus top | ||
265 | fg "$FORWARD_JOBSPEC" | ||
266 | stty "$old_stty" | ||
267 | focus bottom | ||
268 | } | ||
269 | |||
270 | foreground() | ||
271 | { | ||
272 | if forwarding | ||
273 | then | ||
274 | resume_forward | ||
275 | else | ||
276 | foreground_loop "$@" | ||
277 | fi | ||
278 | } | ||
279 | |||
280 | twopane() | ||
281 | { | ||
282 | start "$@" | ||
283 | } | ||
284 | |||
218 | quit() | 285 | quit() |
219 | { | 286 | { |
220 | screen -X quit | 287 | screen -X quit |