Commits

Matthew Turk committed 9ec66e0

Adding cwdiff script and the wdiff option for hg

  • Participants
  • Parent commits 177d8c8

Comments (0)

Files changed (2)

+#! /bin/bash
+
+#(C) 2009-2012 C. Junghans
+# junghans@votca.org
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+#version 0.1    04.08.10 -- initial version
+#version 0.1.1, 05.08.10 -- added -D and -o
+#version 0.1.2, 04.10.10 -- make -D work again and better help
+#version 0.1.3, 10.05.11 -- added --text to diff_opts to allow diff of binary files (issue #3)
+#version 0.1.4, 10.05.11 -- removed --text again and handle case of binary files
+#version 0.2.0, 15.04.12 -- clean up + bugfix thanks to Arne
+#version 0.2.1, 15.04.12 -- clean up + new bug report address
+#version 0.2.2, 20.04.12 -- fixed a bug if argument were dirs
+#version 0.2.3, 18.12.12 -- replace usage of mktemp with bash built-ins
+
+FAT_GREEN=""
+GREEN=""
+FAT_RED=""
+RED=""
+MAGENTA=""
+FAT_BLACK=""
+OFF=""
+NL="
+"
+
+usage="Usage: ${0##*/} [OPTIONS] FILE1 FILE2"
+quiet="no"
+diff="no"
+filter="no"
+diff_opts='--new-file --unified --show-c-function --recursive'
+ab="no"
+out="-"
+style="wdiff"
+a2ps=""
+a2ps_opts="--prologue=color"
+color="yes"
+
+color_filter() {
+  if [[ $a2ps ]]; then
+    #seems like a bug in the a2ps style file
+    sed -e "s/\[-/[wd-/g" -e "s/-\]/-wd]/g" -e "s/{+/{wd+/g" -e "s/+}/+wd}/g" $1
+  elif [[ $color = yes ]]; then
+    sed -e "s/\[-/$RED/g" -e "s/-\]/$OFF/g" -e "s/{+/$GREEN/g" -e "s/+}/$OFF/g" $1
+  else
+    cat $1
+  fi
+}
+
+die() {
+  [[ $* ]] && echo "$*"
+  exit 1
+}
+
+qecho() {
+  [[ $quiet = yes ]] || echo "$*"
+}
+
+show_help () {
+  cat << eof
+A colorized version of wdiff
+$usage
+
+OPTIONS:
+-f, --filter        Act as a color filter only and don't excute diff/wdiff
+                    internally, just colorize input (no ARGS = read from stdin)
+-d, --diff          Preprocess input with diff and before giving it to wdiff
+                    (very useful for dirs). Option can be used in combination
+                    with --filter option meaning input is a patch.
+-D, --diffonly      Process input with diff only and NOT with wdiff, so ${0##*/}
+                    basically acts like a colorized version of diff. Option
+                    can be used in combination with --filter option meaning
+                    input is a patch.
+    --diffopts XXX  Change opts of diff
+                    Default: '$diff_opts'
+    --ab            replace trunc of dirname by 'a' and 'b'
+    --no-color      Disable color
+                    (implies --a2psopts '--prologue=ul')
+-a, --a2ps          Pipe the output to a2ps, which will produce ps code
+                    (also work with --filter)
+    --a2psopts XXX  Change opts of a2ps
+                    Default: '$a2ps_opts'
+-o, --out FILE      Change output file
+                    Default: stdout
+    --              Stop parsing options
+-h, --help          Show this help
+-v, --version       Show version
+    --hg            Show last log message for hg (or cvs)
+
+Examples:  ${0##*/} -d dir1 dir2
+           ${0##*/} file1 file2
+           ${0##*/} --ab -D dir1 dir2
+	   ${0##*/} -a --ab -D dir1 dir2 > file.ps
+	   wdiff file1 file2 | ${0##*/} -f
+	   diff -u file1 file2 | ${0##*/} -D -f
+
+
+Report bugs and comments at https://code.google.com/p/cj-overlay/issues/list
+                         or junghans@votca.org
+eof
+}
+
+shopt -s extglob
+while [[ ${1} = -?* ]]; do
+  if [[ ${1} = --??*=* ]]; then # case --xx=yy
+    set -- "${1%%=*}" "${1#*=}" "${@:2}" # --xx=yy to --xx yy
+  elif [[ ${1} = -[^-]?* ]]; then # case -xy split
+    if [[ ${1} = -[o]* ]]; then #short opts with arguments
+       set -- "${1:0:2}" "${1:2}" "${@:2}" # -xy to -x y
+    else #short opts without arguments
+       set -- "${1:0:2}" "-${1:2}" "${@:2}" # -xy to -x -y
+    fi
+  fi
+  case $1 in
+   --ab)
+    ab="yes"
+    shift;;
+   --no-color)
+    unset FAT_GREEN GREEN FAT_RED RED MAGENTA OFF FAT_BLACK
+    a2ps_opts="--prologue=ul"
+    color="no"
+    shift;;
+   -f | --filter)
+    filter="yes"
+    shift ;;
+   -d | --diff)
+    diff="yes"
+    shift ;;
+   -D | --diffonly)
+    diff="only"
+    shift ;;
+   -a | --a2ps)
+    a2ps="a2ps"
+    unset FAT_GREEN GREEN FAT_RED RED MAGENTA OFF FAT_BLACK
+    shift ;;
+  --a2psopts)
+    a2ps_opts="$2"
+    shift 2;;
+   -o | --out)
+    out="$2"
+    [[ ! $out ]] && die "Missing filename after --out option"
+    shift 2;;
+   --diffopts)
+    diff_opts="$2"
+    shift ;;
+   -q | --quiet)
+    quiet="yes"
+    shift ;;
+   -h | --help)
+    show_help
+    exit 0;;
+   --hg)
+    echo "${0##*/}: $(sed -ne 's/^#version.* -- \(.*$\)/\1/p' $0 | sed -n '$p')"
+    exit 0;;
+   -v | --version)
+    echo "${0##*/}, $(sed -ne 's/^#\(version.*\) -- .*$/\1/p' $0 | sed -n '$p') by C. Junghans"
+    exit 0;;
+   --)
+    shift
+    break;;
+  *)
+   die "Unknown option '$1'";;
+  esac
+done
+
+[[ $1 = - ]] && filter="yes" && shift
+if [[ $filter = no ]]; then
+  [[ ! $1 || ! $2 ]]  && die "Please specify two files or add --filter option"
+  #use -e as it could be file or dir
+  [[ -e $1 ]] || die "Could not read file/dir '$1'"
+  [[ -e $2 ]] || die "Could not read file/dir '$2'"
+  [[ $3 ]] && die "I don't know what to do with arguments '${@:3}'"
+else
+  [[ $* ]] && die "I don't know what to do with arguments '$*' together --filter option"
+fi
+
+if [[ $diff != no ]]; then
+  if [[ $filter = no ]]; then
+    exec 3< <(diff $diff_opts "$1" "$2")
+    #don't die here, because diff of binary files give exit code = 2
+  else
+    exec 3<&0 || die
+  fi
+  # don't do this if we have not files ;-)
+  if [[ $ab = yes && $1 && $2 ]]; then
+    #find the longest equal part in $1 and $2 from the end
+    for ((i=1;i<=(${#1}<${#2}?${#1}:${#2});i++)); do
+      [[ ${1:0-$i} != ${2:0-$i} ]] && break
+    done
+    ((i--))
+    a="${1:0:${#1}-$i}"
+    b="${2:0:${#2}-$i}"
+  else
+    a=a; b=b
+  fi
+  while read -u 3 i; do
+    if [[ $i = "Files "*" and "*" differ" ]]; then # binary case
+      i="${i/$a/a}"
+      i="${i/$b/b}"
+      echo "$i"
+    elif [[ $i = diff* ]]; then # diff header line
+      i="${i/ $diff_opts}"
+      i="${i/$a/a}"
+      echo "$FAT_BLACK${i/$b/b}$OFF"
+    elif [[ $i = ---* ]]; then
+      echo "${FAT_RED}${i/$a/a}${OFF}"
+    elif [[ $i = +++* ]]; then
+      echo "${FAT_GREEN}${i/$b/b}${OFF}"
+    elif [[ $i = @@* ]]; then
+      echo "${MAGENTA}${i}${OFF}"
+    elif [[ $i = -* ]]; then
+      [[ $diff = only ]] && echo "${RED}${i}${OFF}" || t1+="${i#-}$NL"
+    elif [[ $i = +* ]]; then
+      [[ $diff = only ]] && echo "${GREEN}${i}${OFF}" || t2+="${i#+}$NL"
+    else
+      # only true for diff != only
+      # cut the last newline do avoid an empty line at the end (echo append newline)
+      # echo -n would also work, but wdiff has strange behaviour if the 2nd file is
+      # empty, it will not append newline, which make the output look strange
+      [[ $t1 || $t2 ]] && { wdiff <(echo "${t1%$NL}") <(echo "${t2%$NL}") | color_filter; }
+      t1=
+      t2=
+      [[ $diff = only ]] && echo "${i}" || echo "${i## }"
+    fi
+  done
+  # thanks to Arne Babenhauserheide for pointing out this case is missing
+  # if there was + or - lines at the end, which has not been printed yet
+  [[ $t1 || $t2 ]] && { wdiff <(echo "${t1%$NL}") <(echo "${t2%$NL}") | color_filter; }
+elif [[ $filter = yes ]]; then
+  color_filter
+else
+  wdiff "$1" "$2" | color_filter
+fi | if [[ $a2ps ]]; then
+  a2ps $a2ps_opts "--pretty-print=$style" -o "$out"
+else
+  [[ $out = - ]] && cat || cat > "$out"
+fi
 
 [extdiff]
 cmd.vimdiff = vimdiff
+cmd.wdiff = /home/mturk/dotfiles/cwdiff
+opts.wdiff = --diff --ab
 
 [pager] 
 pager = LESS='FSRX' less