-
Notifications
You must be signed in to change notification settings - Fork 44
/
spot.sh
executable file
·201 lines (168 loc) · 3.82 KB
/
spot.sh
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#!/usr/bin/env bash
version="0.3.1"
# search directory defaults to current
dir=.
# Exclude directories
exclude="! -path '*/.git*' ! -path '*/.hg*' ! -path '*/.svn*'"
# case sensitive search
sensitive=
# colors enabled by default in ttys
if [ -t 1 ]; then
colors=1
else
colors=
fi
# show matches by default
showmatches=1
# line numbers shown by default
linenums=1
# ansi colors
cyan=$(echo -e '\033[96m')
reset=$(echo -e '\033[39m')
# max line length
mline=500
# usage info
usage() {
cat <<EOF
Usage: spot [options] [directory] [term ...]
Options:
-e, --exclude [dir] Exclude directory from search
-s, --sensitive Force case sensitive search.
-i, --insensitive Force case insensitive search.
-C, --no-colors Force avoid colors.
-l, --filenames-only Only list filenames with matches.
-L, --no-linenums Hide line numbers.
-U, --update Update spot(1)
-V, --version Output version
-h, --help This message.
-- End of options
EOF
}
# update spot(1) via git clone
update() {
cd /tmp &&
echo "... updating" &&
git clone --depth 1 git://github.com/guille/spot.git &&
cd spot &&
make install &&
echo "... updated to $(spot --version)"
exit
}
# parse options
while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do
case $1 in
-V | --version)
echo $version
exit
;;
-e | --exclude)
shift
edir=$1
exclude="$exclude ! -path '*/$edir*'"
;;
-s | --sensitive)
sensitive=1
;;
-i | --insensitive)
sensitive=
;;
-C | --no-colors)
colors=
;;
-l | --filenames-only)
showmatches=
;;
-L | --no-linenums)
linenums=
;;
-U | --update)
update
;;
-h | --help)
usage
exit
;;
esac
shift
done
if [[ "$1" == "--" ]]; then shift; fi
# check for directory as first parameter
if [[ "$1" =~ / ]]; then
if [ -d "$1" ]; then
dir=$(echo $1 | sed "s/\/$//")
shift
fi
fi
# check for empty search
if [[ "" = "$@" ]]; then
echo "(no search term. \`spot -h\` for usage)"
exit 1
fi
# auto-detect case sensitive based on an uppercase letter
if [[ "$@" =~ [A-Z] ]]; then
sensitive=1
fi
# grep default params
grepopt="--binary-files=without-match --devices=skip"
# add case insensitive search
if [ ! $sensitive ]; then
grepopt="$grepopt --ignore-case"
fi
# add filename only options
if [ ! $showmatches ]; then
grepopt="$grepopt -l"
fi
# add line number options
if [ $linenums ]; then
grepopt="$grepopt -n"
fi
# add force colors
grepopt="$grepopt --color=always"
# run search
eval "find "$dir" -type f $exclude -print0" |
GREP_COLORS="1;33;40" xargs -0 grep $grepopt -e "$(echo $@)" |
sed "s/^\([^:]*\):\(.*\)/ \\
$cyan\1$reset \\
\2 /" |
awk -v linenums=$linenums -v reset=$(tput sgr0) -v colors=$colors -v mline=$mline '{
if (length($0) > mline) {
# Get line number string
i = index($0, ":")
linenum = substr($0, 1, i)
# Loop through all individual matches
i = index($0, "\033[1;33;40m")
str = $0
while(i > 0) {
# Clean coloring
line = reset
if (linenums) {
line = line linenum reset
}
# Build match string with `...` in front if not beginning of line and `...` in the tail
if (i > 3) {
line = line "..."substr(str, i - (mline / 2), mline)"..."
} else {
line = line substr(str, i, (mline / 2))"..."
}
# Strip colors if colors are disabled
if (colors != 1) {
gsub(/\033\[0m/, "", line)
gsub(/\033\[1;33;40m/, "", line)
}
# Move window
str = substr(str, i + (mline / 2))
i = index(str, "\033[1;33;40m")
# Show string
print line
}
} else {
# Strip colors if colors are disabled
if (colors != 1) {
gsub(/\033\[0m/, "", $0)
gsub(/\033\[1;33;40m/, "", $0)
}
print $0
}
}'
echo ""
tput sgr0 # Clean leftover colors