on master help sign in
Add a batgrep as Bash script syntax tests
96151c4Ethan P
tests/syntax-tests/highlighted/Bash/batgrep.shnew file+511
@@ -0,0 +1,511 @@
1+#!/usr/bin/env bash
2+# -----------------------------------------------------------------------------
3+# bat-extras | Copyright (C) 2020 eth-p and contributors | MIT License
4+#
5+# Repository: https://github.com/eth-p/bat-extras
6+# Issues: https://github.com/eth-p/bat-extras/issues
7+# -----------------------------------------------------------------------------
8+printc(){
9+printf "$(sed "$_PRINTC_PATTERN" <<<"$1")" "${@:2}"
10+}
11+printc_init(){
12+case "$1" in
13+true)_PRINTC_PATTERN="$_PRINTC_PATTERN_ANSI";;
14+false)_PRINTC_PATTERN="$_PRINTC_PATTERN_PLAIN";;
15+"[DEFINE]"){
16+_PRINTC_PATTERN_ANSI=""
17+_PRINTC_PATTERN_PLAIN=""
18+local name
19+local ansi
20+while read -r name ansi;do
21+if [[ -z $name && -z $ansi ]]||[[ ${name:0:1} == "#" ]];then
22+continue
23+fi
24+ansi="${ansi/\\/\\\\}"
25+_PRINTC_PATTERN_PLAIN="${_PRINTC_PATTERN_PLAIN}s/%{$name}//g;"
26+_PRINTC_PATTERN_ANSI="${_PRINTC_PATTERN_ANSI}s/%{$name}/$ansi/g;"
27+done
28+if [ -t 1 ];then
29+_PRINTC_PATTERN="$_PRINTC_PATTERN_ANSI"
30+else
31+_PRINTC_PATTERN="$_PRINTC_PATTERN_PLAIN"
32+fi
33+}
34+esac
35+}
36+print_warning(){
37+printc "%{YELLOW}[%s warning]%{CLEAR}: $1%{CLEAR}\n" "batgrep" "${@:2}" 1>&2
38+}
39+print_error(){
40+printc "%{RED}[%s error]%{CLEAR}: $1%{CLEAR}\n" "batgrep" "${@:2}" 1>&2
41+}
42+printc_init "[DEFINE]" <<END
43+ CLEAR \x1B[0m
44+ RED \x1B[31m
45+ GREEN \x1B[32m
46+ YELLOW \x1B[33m
47+ BLUE \x1B[34m
48+ MAGENTA \x1B[35m
49+ CYAN \x1B[36m
50+
51+ DEFAULT \x1B[39m
52+ DIM \x1B[2m
53+END
54+is_pager_less(){
55+[[ "$(pager_name)" == "less" ]]
56+return $?
57+}
58+is_pager_disabled(){
59+[[ -z "$(pager_name)" ]]
60+return $?
61+}
62+pager_name(){
63+_detect_pager 1>&2
64+echo "$_SCRIPT_PAGER_NAME"
65+}
66+pager_version(){
67+_detect_pager 1>&2
68+echo "$_SCRIPT_PAGER_VERSION"
69+}
70+pager_exec(){
71+if [[ -n $SCRIPT_PAGER_CMD ]];then
72+"$@"|pager_display
73+return $?
74+else
75+"$@"
76+return $?
77+fi
78+}
79+pager_display(){
80+if [[ -n $SCRIPT_PAGER_CMD ]];then
81+if [[ -n $SCRIPT_PAGER_ARGS ]];then
82+"${SCRIPT_PAGER_CMD[@]}" "${SCRIPT_PAGER_ARGS[@]}"
83+return $?
84+else
85+"${SCRIPT_PAGER_CMD[@]}"
86+return $?
87+fi
88+else
89+cat
90+return $?
91+fi
92+}
93+_detect_pager(){
94+if [[ $_SCRIPT_PAGER_DETECTED == "true" ]];then return;fi
95+_SCRIPT_PAGER_DETECTED=true
96+if [[ -z ${SCRIPT_PAGER_CMD[0]} ]];then
97+_SCRIPT_PAGER_VERSION=0
98+_SCRIPT_PAGER_NAME=""
99+return
100+fi
101+local output
102+local output1
103+output="$("${SCRIPT_PAGER_CMD[0]}" --version 2>&1)"
104+output1="$(head -n 1 <<<"$output")"
105+if [[ $output1 =~ ^less[[:blank:]]([[:digit:]]+) ]];then
106+_SCRIPT_PAGER_VERSION="${BASH_REMATCH[1]}"
107+_SCRIPT_PAGER_NAME="less"
108+else
109+_SCRIPT_PAGER_VERSION=0
110+_SCRIPT_PAGER_NAME="$(basename "${SCRIPT_PAGER_CMD[0]}")"
111+fi
112+}
113+_configure_pager(){
114+SCRIPT_PAGER_CMD=($PAGER)
115+SCRIPT_PAGER_ARGS=()
116+if [[ -n ${BAT_PAGER+x} ]];then
117+SCRIPT_PAGER_CMD=($BAT_PAGER)
118+SCRIPT_PAGER_ARGS=()
119+return
120+fi
121+if is_pager_less;then
122+SCRIPT_PAGER_CMD=("${SCRIPT_PAGER_CMD[0]}" -R --quit-if-one-screen)
123+if [[ "$(pager_version)" -lt 500 ]];then
124+SCRIPT_PAGER_CMD+=(--no-init)
125+fi
126+fi
127+}
128+if [[ -t 1 ]];then
129+_configure_pager
130+else
131+SCRIPT_PAGER_CMD=()
132+SCRIPT_PAGER_ARGS=()
133+fi
134+SHIFTOPT_HOOKS=()
135+setargs(){
136+_ARGV=("$@")
137+_ARGV_LAST="$((${#_ARGV[@]}-1))"
138+_ARGV_INDEX=0
139+}
140+shiftopt(){
141+[[ $_ARGV_INDEX -gt $_ARGV_LAST ]]&&return 1
142+OPT="${_ARGV[$_ARGV_INDEX]}"
143+unset OPT_VAL
144+if [[ $OPT =~ ^--[a-zA-Z0-9_-]+=.* ]];then
145+OPT_VAL="${OPT#*=}"
146+OPT="${OPT%%=*}"
147+fi
148+((_ARGV_INDEX++))
149+local hook
150+for hook in "${SHIFTOPT_HOOKS[@]}";do
151+if "$hook";then
152+shiftopt
153+return $?
154+fi
155+done
156+return 0
157+}
158+shiftval(){
159+if [[ -n ${OPT_VAL+x} ]];then
160+return 0
161+fi
162+if [[ $OPT =~ ^-[[:alpha:]][[:digit:]]{1,}$ ]];then
163+OPT_VAL="${OPT:2}"
164+return
165+fi
166+OPT_VAL="${_ARGV[$_ARGV_INDEX]}"
167+((_ARGV_INDEX++))
168+if [[ $OPT_VAL =~ -.* ]];then
169+printc "%{RED}%s: '%s' requires a value%{CLEAR}\n" "batgrep" "$ARG"
170+exit 1
171+fi
172+}
173+setargs "$@"
174+hook_color(){
175+SHIFTOPT_HOOKS+=("__shiftopt_hook__color")
176+__shiftopt_hook__color(){
177+case "$OPT" in
178+--no-color)OPT_COLOR=false;;
179+--color){
180+case "$OPT_VAL" in
181+"")OPT_COLOR=true;;
182+always|true)OPT_COLOR=true;;
183+never|false)OPT_COLOR=false;;
184+auto)return 0;;
185+*)printc "%{RED}%s: '--color' expects value of 'auto', 'always', or 'never'%{CLEAR}\n" "batgrep"
186+exit 1
187+esac
188+};;
189+*)return 1
190+esac
191+printc_init "$OPT_COLOR"
192+return 0
193+}
194+if [[ -z $OPT_COLOR ]];then
195+if [[ -t 1 ]];then
196+OPT_COLOR=true
197+else
198+OPT_COLOR=false
199+fi
200+printc_init "$OPT_COLOR"
201+fi
202+}
203+hook_pager(){
204+SHIFTOPT_HOOKS+=("__shiftopt_hook__pager")
205+__shiftopt_hook__pager(){
206+case "$OPT" in
207+\
208+--no-pager)shiftval
209+SCRIPT_PAGER_CMD=''
210+;;
211+--paging){
212+shiftval
213+case "$OPT_VAL" in
214+auto):;;
215+always):;;
216+never)SCRIPT_PAGER_CMD='';;
217+*)printc "%{RED}%s: '--paging' expects value of 'auto', 'always', or 'never'%{CLEAR}\n" "batgrep"
218+exit 1
219+esac
220+};;
221+\
222+--pager){
223+shiftval
224+{
225+SCRIPT_PAGER_CMD=($OPT_VAL)
226+PAGER_ARGS=()
227+}
228+};;
229+*)return 1
230+esac
231+}
232+}
233+hook_version(){
234+SHIFTOPT_HOOKS+=("__shiftopt_hook__version")
235+__shiftopt_hook__version(){
236+if [[ $OPT == "--version" ]];then
237+printf "%s %s\n\n%s\n%s\n" \
238+"batgrep" \
239+"2020.10.04" \
240+"Copyright (C) 2019-2020 eth-p | MIT License" \
241+"https://github.com/eth-p/bat-extras"
242+exit 0
243+fi
244+return 1
245+}
246+}
247+term_width(){
248+local width="$({ stty size 2>/dev/null||echo "22 80";}|cut -d ' ' -f2)"
249+if [[ $width -ne 0 ]];then
250+echo "$width"
251+else
252+echo "80"
253+fi
254+return 0
255+}
256+hook_width(){
257+SHIFTOPT_HOOKS+=("__shiftopt_hook__width")
258+__shiftopt_hook__width(){
259+case "$OPT" in
260+--terminal-width)shiftval
261+OPT_TERMINAL_WIDTH="$OPT_VAL"
262+;;
263+*)return 1
264+esac
265+return 0
266+}
267+OPT_TERMINAL_WIDTH="$(term_width)"
268+}
269+bat_version(){
270+"bat" --version|cut -d ' ' -f 2
271+return
272+}
273+version_compare(){
274+local version="$1"
275+local compare="$3"
276+if ! [[ $version =~ \.$ ]];then
277+version="$version."
278+fi
279+if ! [[ $compare =~ \.$ ]];then
280+compare="$compare."
281+fi
282+version_compare__recurse "$version" "$2" "$compare"
283+return $?
284+}
285+version_compare__recurse(){
286+local version="$1"
287+local operator="$2"
288+local compare="$3"
289+local v_major="${version%%.*}"
290+local c_major="${compare%%.*}"
291+local v_minor="${version#*.}"
292+local c_minor="${compare#*.}"
293+if [[ -z $v_minor && -z $c_minor ]];then
294+[ "$v_major" $operator "$c_major" ]
295+return $?
296+fi
297+if [[ -z $v_minor ]];then
298+v_minor="0."
299+fi
300+if [[ -z $c_minor ]];then
301+c_minor="0."
302+fi
303+case "$operator" in
304+-eq)[[ $v_major -ne $c_major ]]&&return 1;;
305+-ne)[[ $v_major -ne $c_major ]]&&return 0;;
306+-ge|-gt)[[ $v_major -lt $c_major ]]&&return 1
307+[[ $v_major -gt $c_major ]]&&return 0
308+;;
309+-le|-lt)[[ $v_major -gt $c_major ]]&&return 1
310+[[ $v_major -lt $c_major ]]&&return 0
311+esac
312+version_compare__recurse "$v_minor" "$operator" "$c_minor"
313+}
314+hook_color
315+hook_pager
316+hook_version
317+hook_width
318+RG_ARGS=()
319+BAT_ARGS=()
320+PATTERN=""
321+FILES=()
322+OPT_CASE_SENSITIVITY=''
323+OPT_CONTEXT_BEFORE=2
324+OPT_CONTEXT_AFTER=2
325+OPT_FOLLOW=true
326+OPT_SNIP=""
327+OPT_HIGHLIGHT=true
328+OPT_SEARCH_PATTERN=false
329+OPT_FIXED_STRINGS=false
330+BAT_STYLE="header,numbers"
331+if version_compare "$(bat_version)" -gt "0.12";then
332+OPT_SNIP=",snip"
333+fi
334+if [[ -n $RIPGREP_CONFIG_PATH && -e $RIPGREP_CONFIG_PATH ]];then
335+for arg in $(cat "$RIPGREP_CONFIG_PATH");do
336+case "$arg" in
337+--context=*)val="${arg:10}"
338+OPT_CONTEXT_BEFORE="$val"
339+OPT_CONTEXT_AFTER="$val"
340+;;
341+--before-context=*)val="${arg:17}"
342+OPT_CONTEXT_BEFORE="$val"
343+;;
344+--after-context=*)val="${arg:16}"
345+OPT_CONTEXT_AFTER="$val"
346+;;
347+-C*)val="${arg:2}"
348+OPT_CONTEXT_BEFORE="$val"
349+OPT_CONTEXT_AFTER="$val"
350+;;
351+-B*)val="${arg:2}"
352+OPT_CONTEXT_BEFORE="$val"
353+;;
354+-A*)val="${arg:2}"
355+OPT_CONTEXT_AFTER="$val"
356+esac
357+done
358+fi
359+while shiftopt;do
360+case "$OPT" in
361+\
362+-i|--ignore-case)OPT_CASE_SENSITIVITY="--ignore-case";;
363+-s|--case-sensitive)OPT_CASE_SENSITIVITY="--case-sensitive";;
364+-S|--smart-case)OPT_CASE_SENSITIVITY="--smart-case";;
365+-A*|--after-context)shiftval
366+OPT_CONTEXT_AFTER="$OPT_VAL"
367+;;
368+-B*|--before-context)shiftval
369+OPT_CONTEXT_BEFORE="$OPT_VAL"
370+;;
371+-C*|--context)shiftval
372+OPT_CONTEXT_BEFORE="$OPT_VAL"
373+OPT_CONTEXT_AFTER="$OPT_VAL"
374+;;
375+-F|--fixed-strings)OPT_FIXED_STRINGS=true
376+RG_ARGS+=("$OPT")
377+;;
378+-U|--multiline|\
379+-P|--pcre2|\
380+-z|--search-zip|\
381+-w|--word-regexp|\
382+--one-file-system|\
383+--multiline-dotall|\
384+--ignore|--no-ignore|\
385+--crlf|--no-crlf|\
386+--hidden|--no-hidden)RG_ARGS+=("$OPT")
387+;;
388+-E|--encoding|\
389+-g|--glob|\
390+-t|--type|\
391+-T|--type-not|\
392+-m|--max-count|\
393+--max-depth|\
394+--iglob|\
395+--ignore-file)shiftval
396+RG_ARGS+=("$OPT" "$OPT_VAL")
397+;;
398+\
399+\
400+\
401+--no-follow)OPT_FOLLOW=false;;
402+--no-snip)OPT_SNIP="";;
403+--no-highlight)OPT_HIGHLIGHT=false;;
404+-p|--search-pattern)OPT_SEARCH_PATTERN=true;;
405+--no-search-pattern)OPT_SEARCH_PATTERN=false;;
406+\
407+--rg:*){
408+if [[ ${OPT:5:1} == "-" ]];then
409+RG_ARGS+=("${OPT:5}")
410+else
411+RG_ARGS+=("--${OPT:5}")
412+fi
413+if [[ -n $OPT_VAL ]];then
414+RG_ARGS+=("$OPT_VAL")
415+fi
416+};;
417+\
418+-*){
419+printc "%{RED}%s: unknown option '%s'%{CLEAR}\n" "batgrep" "$OPT" 1>&2
420+exit 1
421+};;
422+\
423+*){
424+if [ -z "$PATTERN" ];then
425+PATTERN="$OPT"
426+else
427+FILES+=("$OPT")
428+fi
429+}
430+esac
431+done
432+if [[ -z $PATTERN ]];then
433+print_error "no pattern provided"
434+exit 1
435+fi
436+SEP="$(printc "%{DIM}%${OPT_TERMINAL_WIDTH}s%{CLEAR}"|sed "s/ /─/g")"
437+if [[ -n $OPT_CASE_SENSITIVITY ]];then
438+RG_ARGS+=("$OPT_CASE_SENSITIVITY")
439+fi
440+if "$OPT_FOLLOW";then
441+RG_ARGS+=("--follow")
442+fi
443+if "$OPT_COLOR";then
444+BAT_ARGS+=("--color=always")
445+else
446+BAT_ARGS+=("--color=never")
447+fi
448+if [[ $OPT_CONTEXT_BEFORE -eq 0 && $OPT_CONTEXT_AFTER -eq 0 ]];then
449+OPT_SNIP=""
450+OPT_HIGHLIGHT=false
451+fi
452+if "$OPT_SEARCH_PATTERN";then
453+if is_pager_less;then
454+if "$OPT_FIXED_STRINGS";then
455+SCRIPT_PAGER_ARGS+=(-p $'\x12'"$PATTERN")
456+else
457+SCRIPT_PAGER_ARGS+=(-p "$PATTERN")
458+fi
459+elif is_pager_disabled;then
460+print_error "%s %s %s" \
461+"The -p/--search-pattern option requires a pager, but" \
462+'the pager was explicitly disabled by $BAT_PAGER or the' \
463+"--paging option."
464+exit 1
465+else
466+print_error "Unsupported pager '%s' for option -p/--search-pattern" \
467+"$(pager_name)"
468+exit 1
469+fi
470+fi
471+main(){
472+FOUND_FILES=()
473+FOUND=0
474+FIRST_PRINT=true
475+LAST_LR=()
476+LAST_LH=()
477+LAST_FILE=''
478+do_print(){
479+[[ -z $LAST_FILE ]]&&return 0
480+"$FIRST_PRINT"&&echo "$SEP"
481+FIRST_PRINT=false
482+"bat" "${BAT_ARGS[@]}" \
483+"${LAST_LR[@]}" \
484+"${LAST_LH[@]}" \
485+--style="$BAT_STYLE$OPT_SNIP" \
486+--paging=never \
487+--terminal-width="$OPT_TERMINAL_WIDTH" \
488+"$LAST_FILE"
489+echo "$SEP"
490+}
491+while IFS=':' read -r file line column text;do
492+((FOUND++))
493+if [[ $LAST_FILE != "$file" ]];then
494+do_print
495+LAST_FILE="$file"
496+LAST_LR=()
497+LAST_LH=()
498+fi
499+line_start=$((line-OPT_CONTEXT_BEFORE))
500+line_end=$((line+OPT_CONTEXT_AFTER))
501+[[ $line_start -gt 0 ]]||line_start=''
502+LAST_LR+=("--line-range=$line_start:$line_end")
503+[[ $OPT_HIGHLIGHT == "true" ]]&&LAST_LH+=("--highlight-line=$line")
504+done < <(rg --with-filename --vimgrep "${RG_ARGS[@]}" --context=0 --no-context-separator --sort path "$PATTERN" "${FILES[@]}")
505+do_print
506+if [[ $FOUND -eq 0 ]];then
507+exit 2
508+fi
509+}
510+pager_exec main
511+exit $?
tests/syntax-tests/source/Bash/batgrep.shnew file+511
@@ -0,0 +1,511 @@
1+#!/usr/bin/env bash
2+# -----------------------------------------------------------------------------
3+# bat-extras | Copyright (C) 2020 eth-p and contributors | MIT License
4+#
5+# Repository: https://github.com/eth-p/bat-extras
6+# Issues: https://github.com/eth-p/bat-extras/issues
7+# -----------------------------------------------------------------------------
8+printc(){
9+printf "$(sed "$_PRINTC_PATTERN" <<<"$1")" "${@:2}"
10+}
11+printc_init(){
12+case "$1" in
13+true)_PRINTC_PATTERN="$_PRINTC_PATTERN_ANSI";;
14+false)_PRINTC_PATTERN="$_PRINTC_PATTERN_PLAIN";;
15+"[DEFINE]"){
16+_PRINTC_PATTERN_ANSI=""
17+_PRINTC_PATTERN_PLAIN=""
18+local name
19+local ansi
20+while read -r name ansi;do
21+if [[ -z $name && -z $ansi ]]||[[ ${name:0:1} == "#" ]];then
22+continue
23+fi
24+ansi="${ansi/\\/\\\\}"
25+_PRINTC_PATTERN_PLAIN="${_PRINTC_PATTERN_PLAIN}s/%{$name}//g;"
26+_PRINTC_PATTERN_ANSI="${_PRINTC_PATTERN_ANSI}s/%{$name}/$ansi/g;"
27+done
28+if [ -t 1 ];then
29+_PRINTC_PATTERN="$_PRINTC_PATTERN_ANSI"
30+else
31+_PRINTC_PATTERN="$_PRINTC_PATTERN_PLAIN"
32+fi
33+}
34+esac
35+}
36+print_warning(){
37+printc "%{YELLOW}[%s warning]%{CLEAR}: $1%{CLEAR}\n" "batgrep" "${@:2}" 1>&2
38+}
39+print_error(){
40+printc "%{RED}[%s error]%{CLEAR}: $1%{CLEAR}\n" "batgrep" "${@:2}" 1>&2
41+}
42+printc_init "[DEFINE]" <<END
43+ CLEAR \x1B[0m
44+ RED \x1B[31m
45+ GREEN \x1B[32m
46+ YELLOW \x1B[33m
47+ BLUE \x1B[34m
48+ MAGENTA \x1B[35m
49+ CYAN \x1B[36m
50+
51+ DEFAULT \x1B[39m
52+ DIM \x1B[2m
53+END
54+is_pager_less(){
55+[[ "$(pager_name)" == "less" ]]
56+return $?
57+}
58+is_pager_disabled(){
59+[[ -z "$(pager_name)" ]]
60+return $?
61+}
62+pager_name(){
63+_detect_pager 1>&2
64+echo "$_SCRIPT_PAGER_NAME"
65+}
66+pager_version(){
67+_detect_pager 1>&2
68+echo "$_SCRIPT_PAGER_VERSION"
69+}
70+pager_exec(){
71+if [[ -n $SCRIPT_PAGER_CMD ]];then
72+"$@"|pager_display
73+return $?
74+else
75+"$@"
76+return $?
77+fi
78+}
79+pager_display(){
80+if [[ -n $SCRIPT_PAGER_CMD ]];then
81+if [[ -n $SCRIPT_PAGER_ARGS ]];then
82+"${SCRIPT_PAGER_CMD[@]}" "${SCRIPT_PAGER_ARGS[@]}"
83+return $?
84+else
85+"${SCRIPT_PAGER_CMD[@]}"
86+return $?
87+fi
88+else
89+cat
90+return $?
91+fi
92+}
93+_detect_pager(){
94+if [[ $_SCRIPT_PAGER_DETECTED == "true" ]];then return;fi
95+_SCRIPT_PAGER_DETECTED=true
96+if [[ -z ${SCRIPT_PAGER_CMD[0]} ]];then
97+_SCRIPT_PAGER_VERSION=0
98+_SCRIPT_PAGER_NAME=""
99+return
100+fi
101+local output
102+local output1
103+output="$("${SCRIPT_PAGER_CMD[0]}" --version 2>&1)"
104+output1="$(head -n 1 <<<"$output")"
105+if [[ $output1 =~ ^less[[:blank:]]([[:digit:]]+) ]];then
106+_SCRIPT_PAGER_VERSION="${BASH_REMATCH[1]}"
107+_SCRIPT_PAGER_NAME="less"
108+else
109+_SCRIPT_PAGER_VERSION=0
110+_SCRIPT_PAGER_NAME="$(basename "${SCRIPT_PAGER_CMD[0]}")"
111+fi
112+}
113+_configure_pager(){
114+SCRIPT_PAGER_CMD=($PAGER)
115+SCRIPT_PAGER_ARGS=()
116+if [[ -n ${BAT_PAGER+x} ]];then
117+SCRIPT_PAGER_CMD=($BAT_PAGER)
118+SCRIPT_PAGER_ARGS=()
119+return
120+fi
121+if is_pager_less;then
122+SCRIPT_PAGER_CMD=("${SCRIPT_PAGER_CMD[0]}" -R --quit-if-one-screen)
123+if [[ "$(pager_version)" -lt 500 ]];then
124+SCRIPT_PAGER_CMD+=(--no-init)
125+fi
126+fi
127+}
128+if [[ -t 1 ]];then
129+_configure_pager
130+else
131+SCRIPT_PAGER_CMD=()
132+SCRIPT_PAGER_ARGS=()
133+fi
134+SHIFTOPT_HOOKS=()
135+setargs(){
136+_ARGV=("$@")
137+_ARGV_LAST="$((${#_ARGV[@]}-1))"
138+_ARGV_INDEX=0
139+}
140+shiftopt(){
141+[[ $_ARGV_INDEX -gt $_ARGV_LAST ]]&&return 1
142+OPT="${_ARGV[$_ARGV_INDEX]}"
143+unset OPT_VAL
144+if [[ $OPT =~ ^--[a-zA-Z0-9_-]+=.* ]];then
145+OPT_VAL="${OPT#*=}"
146+OPT="${OPT%%=*}"
147+fi
148+((_ARGV_INDEX++))
149+local hook
150+for hook in "${SHIFTOPT_HOOKS[@]}";do
151+if "$hook";then
152+shiftopt
153+return $?
154+fi
155+done
156+return 0
157+}
158+shiftval(){
159+if [[ -n ${OPT_VAL+x} ]];then
160+return 0
161+fi
162+if [[ $OPT =~ ^-[[:alpha:]][[:digit:]]{1,}$ ]];then
163+OPT_VAL="${OPT:2}"
164+return
165+fi
166+OPT_VAL="${_ARGV[$_ARGV_INDEX]}"
167+((_ARGV_INDEX++))
168+if [[ $OPT_VAL =~ -.* ]];then
169+printc "%{RED}%s: '%s' requires a value%{CLEAR}\n" "batgrep" "$ARG"
170+exit 1
171+fi
172+}
173+setargs "$@"
174+hook_color(){
175+SHIFTOPT_HOOKS+=("__shiftopt_hook__color")
176+__shiftopt_hook__color(){
177+case "$OPT" in
178+--no-color)OPT_COLOR=false;;
179+--color){
180+case "$OPT_VAL" in
181+"")OPT_COLOR=true;;
182+always|true)OPT_COLOR=true;;
183+never|false)OPT_COLOR=false;;
184+auto)return 0;;
185+*)printc "%{RED}%s: '--color' expects value of 'auto', 'always', or 'never'%{CLEAR}\n" "batgrep"
186+exit 1
187+esac
188+};;
189+*)return 1
190+esac
191+printc_init "$OPT_COLOR"
192+return 0
193+}
194+if [[ -z $OPT_COLOR ]];then
195+if [[ -t 1 ]];then
196+OPT_COLOR=true
197+else
198+OPT_COLOR=false
199+fi
200+printc_init "$OPT_COLOR"
201+fi
202+}
203+hook_pager(){
204+SHIFTOPT_HOOKS+=("__shiftopt_hook__pager")
205+__shiftopt_hook__pager(){
206+case "$OPT" in
207+\
208+--no-pager)shiftval
209+SCRIPT_PAGER_CMD=''
210+;;
211+--paging){
212+shiftval
213+case "$OPT_VAL" in
214+auto):;;
215+always):;;
216+never)SCRIPT_PAGER_CMD='';;
217+*)printc "%{RED}%s: '--paging' expects value of 'auto', 'always', or 'never'%{CLEAR}\n" "batgrep"
218+exit 1
219+esac
220+};;
221+\
222+--pager){
223+shiftval
224+{
225+SCRIPT_PAGER_CMD=($OPT_VAL)
226+PAGER_ARGS=()
227+}
228+};;
229+*)return 1
230+esac
231+}
232+}
233+hook_version(){
234+SHIFTOPT_HOOKS+=("__shiftopt_hook__version")
235+__shiftopt_hook__version(){
236+if [[ $OPT == "--version" ]];then
237+printf "%s %s\n\n%s\n%s\n" \
238+"batgrep" \
239+"2020.10.04" \
240+"Copyright (C) 2019-2020 eth-p | MIT License" \
241+"https://github.com/eth-p/bat-extras"
242+exit 0
243+fi
244+return 1
245+}
246+}
247+term_width(){
248+local width="$({ stty size 2>/dev/null||echo "22 80";}|cut -d ' ' -f2)"
249+if [[ $width -ne 0 ]];then
250+echo "$width"
251+else
252+echo "80"
253+fi
254+return 0
255+}
256+hook_width(){
257+SHIFTOPT_HOOKS+=("__shiftopt_hook__width")
258+__shiftopt_hook__width(){
259+case "$OPT" in
260+--terminal-width)shiftval
261+OPT_TERMINAL_WIDTH="$OPT_VAL"
262+;;
263+*)return 1
264+esac
265+return 0
266+}
267+OPT_TERMINAL_WIDTH="$(term_width)"
268+}
269+bat_version(){
270+"bat" --version|cut -d ' ' -f 2
271+return
272+}
273+version_compare(){
274+local version="$1"
275+local compare="$3"
276+if ! [[ $version =~ \.$ ]];then
277+version="$version."
278+fi
279+if ! [[ $compare =~ \.$ ]];then
280+compare="$compare."
281+fi
282+version_compare__recurse "$version" "$2" "$compare"
283+return $?
284+}
285+version_compare__recurse(){
286+local version="$1"
287+local operator="$2"
288+local compare="$3"
289+local v_major="${version%%.*}"
290+local c_major="${compare%%.*}"
291+local v_minor="${version#*.}"
292+local c_minor="${compare#*.}"
293+if [[ -z $v_minor && -z $c_minor ]];then
294+[ "$v_major" $operator "$c_major" ]
295+return $?
296+fi
297+if [[ -z $v_minor ]];then
298+v_minor="0."
299+fi
300+if [[ -z $c_minor ]];then
301+c_minor="0."
302+fi
303+case "$operator" in
304+-eq)[[ $v_major -ne $c_major ]]&&return 1;;
305+-ne)[[ $v_major -ne $c_major ]]&&return 0;;
306+-ge|-gt)[[ $v_major -lt $c_major ]]&&return 1
307+[[ $v_major -gt $c_major ]]&&return 0
308+;;
309+-le|-lt)[[ $v_major -gt $c_major ]]&&return 1
310+[[ $v_major -lt $c_major ]]&&return 0
311+esac
312+version_compare__recurse "$v_minor" "$operator" "$c_minor"
313+}
314+hook_color
315+hook_pager
316+hook_version
317+hook_width
318+RG_ARGS=()
319+BAT_ARGS=()
320+PATTERN=""
321+FILES=()
322+OPT_CASE_SENSITIVITY=''
323+OPT_CONTEXT_BEFORE=2
324+OPT_CONTEXT_AFTER=2
325+OPT_FOLLOW=true
326+OPT_SNIP=""
327+OPT_HIGHLIGHT=true
328+OPT_SEARCH_PATTERN=false
329+OPT_FIXED_STRINGS=false
330+BAT_STYLE="header,numbers"
331+if version_compare "$(bat_version)" -gt "0.12";then
332+OPT_SNIP=",snip"
333+fi
334+if [[ -n $RIPGREP_CONFIG_PATH && -e $RIPGREP_CONFIG_PATH ]];then
335+for arg in $(cat "$RIPGREP_CONFIG_PATH");do
336+case "$arg" in
337+--context=*)val="${arg:10}"
338+OPT_CONTEXT_BEFORE="$val"
339+OPT_CONTEXT_AFTER="$val"
340+;;
341+--before-context=*)val="${arg:17}"
342+OPT_CONTEXT_BEFORE="$val"
343+;;
344+--after-context=*)val="${arg:16}"
345+OPT_CONTEXT_AFTER="$val"
346+;;
347+-C*)val="${arg:2}"
348+OPT_CONTEXT_BEFORE="$val"
349+OPT_CONTEXT_AFTER="$val"
350+;;
351+-B*)val="${arg:2}"
352+OPT_CONTEXT_BEFORE="$val"
353+;;
354+-A*)val="${arg:2}"
355+OPT_CONTEXT_AFTER="$val"
356+esac
357+done
358+fi
359+while shiftopt;do
360+case "$OPT" in
361+\
362+-i|--ignore-case)OPT_CASE_SENSITIVITY="--ignore-case";;
363+-s|--case-sensitive)OPT_CASE_SENSITIVITY="--case-sensitive";;
364+-S|--smart-case)OPT_CASE_SENSITIVITY="--smart-case";;
365+-A*|--after-context)shiftval
366+OPT_CONTEXT_AFTER="$OPT_VAL"
367+;;
368+-B*|--before-context)shiftval
369+OPT_CONTEXT_BEFORE="$OPT_VAL"
370+;;
371+-C*|--context)shiftval
372+OPT_CONTEXT_BEFORE="$OPT_VAL"
373+OPT_CONTEXT_AFTER="$OPT_VAL"
374+;;
375+-F|--fixed-strings)OPT_FIXED_STRINGS=true
376+RG_ARGS+=("$OPT")
377+;;
378+-U|--multiline|\
379+-P|--pcre2|\
380+-z|--search-zip|\
381+-w|--word-regexp|\
382+--one-file-system|\
383+--multiline-dotall|\
384+--ignore|--no-ignore|\
385+--crlf|--no-crlf|\
386+--hidden|--no-hidden)RG_ARGS+=("$OPT")
387+;;
388+-E|--encoding|\
389+-g|--glob|\
390+-t|--type|\
391+-T|--type-not|\
392+-m|--max-count|\
393+--max-depth|\
394+--iglob|\
395+--ignore-file)shiftval
396+RG_ARGS+=("$OPT" "$OPT_VAL")
397+;;
398+\
399+\
400+\
401+--no-follow)OPT_FOLLOW=false;;
402+--no-snip)OPT_SNIP="";;
403+--no-highlight)OPT_HIGHLIGHT=false;;
404+-p|--search-pattern)OPT_SEARCH_PATTERN=true;;
405+--no-search-pattern)OPT_SEARCH_PATTERN=false;;
406+\
407+--rg:*){
408+if [[ ${OPT:5:1} == "-" ]];then
409+RG_ARGS+=("${OPT:5}")
410+else
411+RG_ARGS+=("--${OPT:5}")
412+fi
413+if [[ -n $OPT_VAL ]];then
414+RG_ARGS+=("$OPT_VAL")
415+fi
416+};;
417+\
418+-*){
419+printc "%{RED}%s: unknown option '%s'%{CLEAR}\n" "batgrep" "$OPT" 1>&2
420+exit 1
421+};;
422+\
423+*){
424+if [ -z "$PATTERN" ];then
425+PATTERN="$OPT"
426+else
427+FILES+=("$OPT")
428+fi
429+}
430+esac
431+done
432+if [[ -z $PATTERN ]];then
433+print_error "no pattern provided"
434+exit 1
435+fi
436+SEP="$(printc "%{DIM}%${OPT_TERMINAL_WIDTH}s%{CLEAR}"|sed "s/ /─/g")"
437+if [[ -n $OPT_CASE_SENSITIVITY ]];then
438+RG_ARGS+=("$OPT_CASE_SENSITIVITY")
439+fi
440+if "$OPT_FOLLOW";then
441+RG_ARGS+=("--follow")
442+fi
443+if "$OPT_COLOR";then
444+BAT_ARGS+=("--color=always")
445+else
446+BAT_ARGS+=("--color=never")
447+fi
448+if [[ $OPT_CONTEXT_BEFORE -eq 0 && $OPT_CONTEXT_AFTER -eq 0 ]];then
449+OPT_SNIP=""
450+OPT_HIGHLIGHT=false
451+fi
452+if "$OPT_SEARCH_PATTERN";then
453+if is_pager_less;then
454+if "$OPT_FIXED_STRINGS";then
455+SCRIPT_PAGER_ARGS+=(-p $'\x12'"$PATTERN")
456+else
457+SCRIPT_PAGER_ARGS+=(-p "$PATTERN")
458+fi
459+elif is_pager_disabled;then
460+print_error "%s %s %s" \
461+"The -p/--search-pattern option requires a pager, but" \
462+'the pager was explicitly disabled by $BAT_PAGER or the' \
463+"--paging option."
464+exit 1
465+else
466+print_error "Unsupported pager '%s' for option -p/--search-pattern" \
467+"$(pager_name)"
468+exit 1
469+fi
470+fi
471+main(){
472+FOUND_FILES=()
473+FOUND=0
474+FIRST_PRINT=true
475+LAST_LR=()
476+LAST_LH=()
477+LAST_FILE=''
478+do_print(){
479+[[ -z $LAST_FILE ]]&&return 0
480+"$FIRST_PRINT"&&echo "$SEP"
481+FIRST_PRINT=false
482+"bat" "${BAT_ARGS[@]}" \
483+"${LAST_LR[@]}" \
484+"${LAST_LH[@]}" \
485+--style="$BAT_STYLE$OPT_SNIP" \
486+--paging=never \
487+--terminal-width="$OPT_TERMINAL_WIDTH" \
488+"$LAST_FILE"
489+echo "$SEP"
490+}
491+while IFS=':' read -r file line column text;do
492+((FOUND++))
493+if [[ $LAST_FILE != "$file" ]];then
494+do_print
495+LAST_FILE="$file"
496+LAST_LR=()
497+LAST_LH=()
498+fi
499+line_start=$((line-OPT_CONTEXT_BEFORE))
500+line_end=$((line+OPT_CONTEXT_AFTER))
501+[[ $line_start -gt 0 ]]||line_start=''
502+LAST_LR+=("--line-range=$line_start:$line_end")
503+[[ $OPT_HIGHLIGHT == "true" ]]&&LAST_LH+=("--highlight-line=$line")
504+done < <(rg --with-filename --vimgrep "${RG_ARGS[@]}" --context=0 --no-context-separator --sort path "$PATTERN" "${FILES[@]}")
505+do_print
506+if [[ $FOUND -eq 0 ]];then
507+exit 2
508+fi
509+}
510+pager_exec main
511+exit $?