#!/bin/bash set -a USAGE="gr v2.4 USAGE: gr [gr options] [grep options] expr Gr is a 'grep' wrapper designed to work in emacs M-x compile mode: it finds things in a hierarchy of files, and present them like gcc so that you can use the next-error command in emacs to visit all the hits. You can use gr even if you are not at the top level of the hierarchy: to achieve this, you need to 'mark' the top of the hierarchy either by putting a .gr file there, or listing the directory in your ~/.grrc file. if .gr is executable, it is taken as the grep command to run instead of the default command which is: ' grep -E -s -r -H -n' e.g: .gr can contain: grep -EsrHn --exclude=*.gif --exclude=*.jpg --exclude=*.php and running 'gr -i foo bar' will execute './.gr -i foo bar .' you can also add lines in your ~/.grrc of the form /directory /directory grep-command... x patterns... exclude files: e.g: x *.gif *.png *.pdf x patterns.. inlude patterns: e.g: i list.of.gifs -xxx -yyy -zzz will be uised as options # other lines ignored if you do not want or can - on cdroms, or other people dirs - create a .gr file in the directory. Spaces must be replaced by %20 in directories names. Directory must be the value given by /bin/pwd in this dir, not just any possible name for this directory. e.g: ~/.grrc can contain: /cdrom/data grep -EsrHn --exclude=*.avi /c/Program%20Files/foo If gr cannot find a mark in the directories above the current dir, or if we give '-.' as first argument, it justs recurse from the current dir Colas Nahaboo, http://colas.nahaboo.net GR Options: -. recurse from current dir, ignores .gr --grv verbose --grm Mark current dir: adds it to your ~/.grrc --gru [dir] Unmark dir (default current dir): removes it from your ~/.grrc --grc Clean: removes all non-existing dirs from your ~/.grrc " ################################################################## Main main () { prefix= profile= command='grep -E -s -r -H -n' options= recurse=true verbose=false while true; do case x"$1" in x-.) recurse=false; shift;; x--grm) mark_dir "`/bin/pwd`"; exit;; x--gru) unmark_dir "${2:-`/bin/pwd`}";exit;; x--grc) gr_clean;exit;; x--grv) verbose=true;shift;; x-[?]|x--help|x-help) echo "$USAGE";exit 1;; *) break;; esac; done declare -a paths commands n=0 if test -e ~/.grrc; then while read l; do case "$l" in /*) paths[$n]="${l%% *}" commands[$n]= case "$l" in *' '*) commands[$n]="${l#*}";; esac;; x*) for opt in ${l#x}; do options="$options --exclude=$opt"; done;; i*) for opt in ${l#i}; do options="$options --include=$opt"; done;; -*) options="$options $l";; esac let n++ done <~/.grrc fi if $recurse; then OPWD="$PWD" profile=`path_pwd` while test ! -e .gr -a "$PWD" != "/" -a -z "$profile"; do cd ..; prefix="../$prefix"; profile=`path_pwd` done # didn't find an ancestor, use current dir if test ! -e .gr -a -z "$profile"; then cd "$OPWD"; prefix=; fi if test -x .gr; then command=./.gr elif test -n "$profile" -a -n "${commmands[$profile]}"; then command="${commmands[$profile]} $options" fi fi V "# GR from $PWD" $command "$@" . | postprocess } ################################################################## Functions V () { if $verbose; then echo "$@"; fi; } path_pwd () { local n=0 pwd=`/bin/pwd` p for p in "${paths[@]}"; do if test x"$p" = x"$pwd"; then echo $n; break; fi let n++ done } # exclude management dir (SCM) here postprocess () { egrep -v '^[^:]*/(CVS|[.]svn|[.]git|[.]hg)/' | sed -e "s|^[.]/|$prefix|" } mark_dir () { if test -e ~/.grrc; then while read l; do path="${l%% *}" if test x"$path" = x"$1"; then return; fi done <~/.grrc fi V marking $1 echo "$1" >>~/.grrc } unmark_dir () { local tmp=~/.grrc.$$; >$tmp if test -e ~/.grrc; then while read l; do path="${l%% *}" if test x"$path" = x"$1"; then V "Unmarking $l" else print -- "$l" >>$tmp fi done <~/.grrc fi if ! cmp -s ~/.grrc $tmp; then mv $tmp ~/.grrc; else rm -f $tmp; fi } gr_clean () { local tmp=~/.grrc.$$; >$tmp if test -e ~/.grrc; then while read l; do path="${l%% *}" case "$path" in /*) if test ! -d "$path" then V "Removing $l" else print -- "$l" >>$tmp fi;; *) print -- "$l" >>$tmp;; esac done <~/.grrc fi if ! cmp -s ~/.grrc $tmp; then mv $tmp ~/.grrc; else rm -f $tmp; fi } main "$@"