-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathreflex-watch
123 lines (105 loc) · 3.1 KB
/
reflex-watch
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
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env bash
dk.watch() {
require-any reflex dk use: golang
require-any reflex go install github.com/bashup/reflex@bashup # Need reflex for this
require-any tput # for pager.watch
# Trap SIGUSR1 to restart the watch with new configuration
event quote "$@"
trap "echo Configuration changed: restarting watch; echo; exec dk watch ""$REPLY" SIGUSR1
export DEVKIT_PAGER=${DEVKIT_PAGER-pager.watch} # Use the watch pager by default
event emit "before_watch" || echo "[$?]" # Run any watch+ commands
isatty || export DEVKIT_ISATTY=0 # reflex always runs w/pseudo-tty
# Run reflex with our current watch configuration, suppressing "killed" msg
# via background job + wait
reflex -d none --sequential "$@" -c <(event emit reflex_config) </dev/null & wait $!
}
watch() {
# Output the command line as part of the reflex config
parse-watch "on reflex_config __put-watch" "$@"
}
parse-watch() {
# Parse `[globs...] [options...] command...`, converting globs to regexes
local re='' RE='' cmd=$1; shift
while (($#)) && [[ $1 != -* ]]; do
if [[ $1 == '!'* ]]; then
glob2re "${1:1}"
RE+=\|$REPLY
else
glob2re "$1"
re+=\|$REPLY
fi
shift
done
[[ ! $RE ]] || set -- -R "^(${RE#|})\$" "$@"
[[ ! $re ]] || set -- -r "^(${re#|})\$" "$@"
$cmd "$@"
}
watch+ () {
# Run the specified command at the start of watch, as well as on changes
watch "$@"
while (($#)) && [[ $1 != '--' ]]; do shift; done; [[ ${1-} != '--' ]] || shift
before watch "$@"
}
RELOAD_MATCH=
RELOAD_REJECT=
watch-reload() {
# Restart watch if given pattern matches
parse-watch __add_reload "$@"
}
__add_reload() {
RELOAD_MATCH+=$re
RELOAD_REJECT+=$RE
export WATCH_PID=$$
[[ ! "$re$RE" ]] || on reflex_config __reload-watch
}
__reload-watch() {
${RELOAD_REJECT:+ set -- -R "${RELOAD_REJECT#|}" "$@"}
${RELOAD_MATCH:+ set -- -r "${RELOAD_MATCH#|}" "$@"}
__put-watch "$@" -- bash -c 'kill -9 $PPID; kill -SIGUSR1 '$WATCH_PID';'
}
UNWATCH_RE=
unwatch() {
# Globally exclude the given globs from all watch patterns
for REPLY; do glob2re "$REPLY"; UNWATCH_RE+=${UNWATCH_RE:+|}"^($REPLY)\$"; done
}
unwatch-re() {
# Globally exclude the given regexes from all watch patterns
for REPLY; do UNWATCH_RE+=${UNWATCH_RE:+|}"($REPLY)"
done
}
__put-watch() {
# Output a reflex with global exclusion(s) added
reflex-quote ${UNWATCH_RE:+ -R "$UNWATCH_RE"} "$@"
echo -E "$REPLY"
}
reflex-quote() {
# Quote args in such a way that reflex will read them correctly
local q="'" qq="'\"'\"'"
set -- "${@//$q/$qq}"
set -- "${@/#/$q}"
set -- "${@/%/$q}"
REPLY="$*"
}
glob2re() {
# Convert a glob to a regex, w/globstar (**) support
local i c re=
for (( i=0; i<${#1}; i++ )); do
c=${1:$i:1}
case $c in
[!$^+.\(\)=!|?*]) re+=$c ;;
[$^+.\(\)=!|]) re+=\\$c ;;
"?") re+='[^/]' ;;
"*")
if [[ ${1:$i} =~ [*][*](/|$) ]] && { ! ((i)) || [[ ${1:$i-1:1} == '/' ]]; }; then
re+='(([^/]*(/|$))*)'; i+=2 # skip '*/'
else re+='[^/]*'
fi
;;
*) re+=$c ;;
esac
done
REPLY=$re
}
# We use the tty module for pager and such
dk use: tty
watch-reload .dkrc # automatically re-run watch if configuration changes