-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtbd-view
executable file
·110 lines (90 loc) · 2.82 KB
/
tbd-view
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/env bash
#
set -eo pipefail
prompt_prefix=${1:?}
tbd_pid=${1%%.*}
# where commands are written to and outputs are to be read from and shown
tbd_pipe=.tbd-out.$$
mkfifo "$tbd_pipe"
echo "$tbd_pipe" # output line 1
# where the current source line number should be written to by the debugger
view_pipe=.tbd-view.$$
mkfifo "$view_pipe"
echo "$view_pipe" # output line 2
fifo-ack () {
local fifo=${1:-${tbd_pipe:?}}
echo ACK > "$fifo"
}
main () {
: ${tbd_pid:?} ${prompt_prefix:?} ${window_id:?}
[[ -p "${tbd_pipe:?}" ]]
[[ -p "${view_pipe:?}" ]]
trap '
set +e
tmux kill-pane -t ":$window_id.right"
rm -f "$view_pipe" "$tbd_pipe" "$0"
history -a
' EXIT
( while kill -0 $tbd_pid >/dev/null 2>&1; do sleep 1; done
kill $$
) &
view-source-pane
HISTFILE=$HOME/.tbd_history; history -r || true
local line response rc
while true; do
response=$(cat "$tbd_pipe") && fifo-ack
if [[ $response == "$prompt_prefix"* ]]; then
IFS= read -erp "${response#$prompt_prefix}" line || rc=$?
[[ ! $line ]] || history -s "$line"
[[ ${rc:-0} == 0 ]] || break # NOTE: Exiting the loop on Ctrl-D could potentially make the debugged script stuck on a break point.
echo "$line" > "$tbd_pipe"
else
printf "%s\n" "$response"
fi
done
echo /resume > "$tbd_pipe"
}
view-source-pane () {
[[ -p ${view_pipe:?} ]]
source-viewer () {
if which batcat >/dev/null 2>&1; then bat () { batcat "$@"; }; fi
local pipe=${1:?} file from to
while true; do
file=$(cat "$pipe") && fifo-ack "$pipe"
read -t2 -r from to < "$pipe" && fifo-ack "$pipe"
bat --color always ${NO_COLOR:+--color never} \
--highlight-line "$from:${to:-$from}" "$file" \
| less -K -RX +${from}g
done
}
local view_script; view_script=$(mktemp)
cat > "$view_script" <<EOF
#!/usr/bin/env bash
#
set -eo pipefail
$(declare -f fifo-ack)
$(declare -f source-viewer)
$(if [[ ${NO_COLOR:-} ]]; then echo export NO_COLOR=x; fi)
trap 'rm -f "\$0"' EXIT
source-viewer "\$@"
EOF
chmod +x "$view_script"
tmux split-window -dh -t ":$window_id" "$view_script" "$view_pipe"
}
window_name=$$; tmux new-window -n "$window_name"
window_id=$(tmux display-message -t ":=$window_name" -pF '#{window_id}')
echo "$window_id" # output line 3
repl_script=$(mktemp)
cat > "$repl_script" <<EOF
#!/usr/bin/env bash
set -e
$(declare -p tbd_pid prompt_prefix tbd_pipe view_pipe window_id)
$(if [[ ${NO_COLOR:-} ]]; then echo export NO_COLOR=x; fi)
$(declare -f fifo-ack)
$(declare -f view-source-pane)
$(declare -f main)
clear
main \"\$@\"
EOF
chmod +x "$repl_script"
tmux send-key -t ":$window_id" "exec $(printf %q "$repl_script")"$'\n'