home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / mac / vim55rt.sit / runtime / tools / gvimdiff < prev    next >
Encoding:
Text File  |  1999-09-25  |  6.1 KB  |  230 lines  |  [TEXT/ALFA]

  1. #!/bin/sh
  2. #
  3. # gvimdiff: display highlighted differences between two files side-by-side in
  4. #           gvim
  5. #
  6. # Note: This program uses the Unix trick of using its name to alter behavior.
  7. #       If this file is called gvimdiff, it brings up the differences in gvim.
  8. #       If it is called vimdiff, it brings up the differences in vim.  If it is
  9. #       called anything else, it fails with an error.  If you need vimdiff,
  10. #       create a symbolic or hard link from gvimdiff to vimdiff.
  11. #
  12. # Author: Gautam H. Mudunuri (gmudunuri@informatica.com)
  13. #
  14. # $Revision: 1.1 $
  15. #
  16.  
  17.  
  18. # Get my name and verify it and determine whether to use vim/gvim
  19. progname=`basename $0`
  20. case "$progname" in
  21.     vimdiff)
  22.         vim_exe="vim"
  23.         ;;
  24.     gvimdiff)
  25.         vim_exe="gvim"
  26.         ;;
  27.     *)
  28.         echo >&2 "This program has an invalid name \"$progname\""
  29.         exit 1
  30.         ;;
  31. esac
  32.  
  33. # Display usage and exit
  34. Usage()
  35. {
  36.     # Options common to vimdiff and gvimdiff
  37.     options="[ -s ]"
  38.     options_desc="\
  39.    -s          do not display identical lines
  40.    -w width    width of diff output
  41.                (default is set for diffs of 80 column wide files)"
  42.  
  43.     # Add gvimdiff specific options
  44.     [ $vim_exe = "gvim" ] && {
  45.         options="$options [ -f font ] [ -n ] [ -w width ]"
  46.         options_desc="\
  47.    -f font     font to use for display
  48.    -n          do not create a wide window
  49.                (useful if your display is not too wide)
  50. $options_desc"
  51.     }
  52.  
  53.     # Display usage and exit
  54.     echo >&2 "\
  55. $progname: \
  56. display highlighted differences between two files side-by-side in $vim_exe
  57.  
  58. Usage: $progname $options arg1 arg2
  59.  
  60. Both the arguments must be file names OR one must be a file name and the
  61. other a directory name.  If one of the arguments is a directory name, it
  62. refers to the file in that directory with the same name as the other
  63. argument.
  64.  
  65. Options:
  66. $options_desc"
  67.     exit 1
  68. }
  69.  
  70. # Parse commandline
  71. n_flag="n"
  72. s_flag="n"
  73. width=
  74. font=
  75. while getopts f:nsw: option
  76. do
  77.     case "$option" in
  78.         f)
  79.             [ $vim_exe != "gvim" ] && Usage
  80.             [ "$font" != "" ] && Usage
  81.             font="$OPTARG"
  82.             ;;
  83.         n)
  84.             [ $vim_exe != "gvim" ] && Usage
  85.             n_flag="y"
  86.             ;;
  87.         s)
  88.             s_flag="y"
  89.             ;;
  90.         w)
  91.             [ "$width" != "" ] && Usage
  92.             width="$OPTARG"
  93.             ;;
  94.         *)
  95.             Usage
  96.             ;;
  97.     esac
  98. done
  99. shift `expr $OPTIND - 1`
  100. [ $# -eq 2 ] || Usage
  101.  
  102. # Arguments must be files or directories
  103. arg1="$1"
  104. [ -f $arg1 -o -d $arg1 ] || {
  105.     echo >&2 "$progname: $arg1 is not a valid file or directory"
  106.     exit 1
  107. }
  108. arg2="$2"
  109. [ -f $arg2 -o -d $arg2 ] || {
  110.     echo >&2 "$progname: $arg2 is not a valid file or directory"
  111.     exit 1
  112. }
  113.  
  114. # Both arguments cannot be directories
  115. [ -d "$arg1" -a -d "$arg2" ] && {
  116.     echo >&2 "$progname: $arg1 and $arg2 are both directories"
  117.     echo >&2 "Atleast one file must be specified"
  118.     exit 1
  119. }
  120.  
  121. # If one argument is a directory, convert it to a filename using the other,
  122. # otherwise use it directly
  123. [ -d "$arg1" ] && file1="$arg1/`basename $arg2`" || file1="$arg1"
  124. [ -d "$arg2" ] && file2="$arg2/`basename $arg1`" || file2="$arg2"
  125.  
  126. # Both files must be readable
  127. [ -r "$file1" ] || {
  128.     echo >&2 "$progname: cannot open $file1 for reading"
  129.     exit 1
  130. }
  131. [ -r "$file2" ] || {
  132.     echo >&2 "$progname: cannot open $file2 for reading"
  133.     exit 1
  134. }
  135.  
  136. # Width not specified, use default for 80-column wide files and 9 character
  137. # sdiff "gutter".  (169 = 2 * 80 +  9)
  138. [ "$width" = "" ] && width=169
  139.  
  140. # Validate width
  141. expr "$width" + 0 > /dev/null 2>&1
  142. status="$?"
  143. [ $status -eq 0 -o $status -eq 1 ] || {
  144.     echo >&2 "$progname: invalid width \"$width\""
  145.     exit 1
  146. }
  147. [ $width -gt 0 ] || {
  148.     echo >&2 "$progname: width $width cannot be zero or negative"
  149.     exit 1
  150. }
  151. [ $width -ge 49 ] || {
  152.     echo >&2 "$progname: width $width is too small, should be atleast 29"
  153.     exit 1
  154. }
  155. [ $width -le 209 ] || {
  156.     echo >&2 "$progname: width $width is too large, should be atmost 209"
  157.     exit 1
  158. }
  159.  
  160. # Compute width per file, allowing 9 characters for the sdiff "gutter"
  161. file_width=`expr '(' $width - 9 ')' / 2`
  162.  
  163. # Compute the range of the number of characters we can expect before the sdiff
  164. # separators |, < and >.  This is range rather than a specific number because
  165. # the presence of tabs can shorten the length
  166. min_chars=`expr $file_width - 5`
  167. max_chars=`expr $file_width + 2`
  168.  
  169. # Define Vim commands for manipulating the sdiff buffer
  170. buffercmds="
  171.     set ts=8 et noro
  172.     retab
  173.     set nomod ro nows
  174. "
  175.  
  176. # Define Vim commands for sdiff syntax highlighting.  We are going to define
  177. # our custom syntax that is not loaded through the standard syntax mechanism.
  178. # But we still need the standard colors to be defined.  So turn syntax on to
  179. # get them and immediately turn it off
  180. syncmds="
  181.     syn on
  182.     syn off
  183.     syn match sdiffRemoved \"^.\{$min_chars,$max_chars}  <\"
  184.     syn match sdiffChanged \"^.\{$min_chars,$max_chars}  |  .*$\"
  185.     syn match sdiffAdded \"^.\{$min_chars,$max_chars}  >  .*$\"
  186.     hi link sdiffRemoved  Comment
  187.     hi link sdiffChanged  PreProc
  188.     hi link sdiffAdded    Identifier
  189.     let b:current_syntax = \"vimdiff\"
  190. "
  191.  
  192. # Help commands (doesn't always work)
  193. helpcmd_next="\
  194.     echo 'Ctrl-N: Next Difference Line   Ctrl-P: Previous Difference Line'\
  195. "
  196. helpcmd_prev="\
  197.     echo 'Ctrl-P: Previous Difference Line   Ctrl-N: Next Difference Line'\
  198. "
  199.  
  200. # Define Vim mappings to jump to next/previous difference
  201. mapcmds="
  202.     nmap <c-n> /^.\{$min_chars,$max_chars}  [<>\|]/e<nl>:$helpcmd_next<nl>
  203.     nmap <c-p> ?^.\{$min_chars,$max_chars}  [<>\|]?e<nl>:$helpcmd_prev<nl>
  204. "
  205.  
  206. # Collect vim commands to be run
  207. vimcmds="
  208.     set titlestring=\\$progname\\ \\$arg1\\ \\$arg2
  209.     set noml nows nowrap go=agrb ch=2
  210.     $buffercmds
  211.     $syncmds
  212.     $mapcmds
  213.     execute \"normal gg0$max_chars|3l\"
  214.     $helpcmd_next
  215. "
  216.  
  217. # Set sdiff_flags flags
  218. sdiff_flags=
  219. [ "$s_flag" = "y" ] && sdiff_flags="$flags -s"
  220.  
  221. # Set vim flags
  222. vim_flags="-R -N"
  223. [ "$font" != "" ] && vim_flags="$vim_flags -fn $font"
  224. [ $n_flag != "y" -a $vim_exe = "gvim" ] && {
  225.     vim_flags="$vim_flags -geometry $width"
  226. }
  227.  
  228. # Run the diff and display the output in gvim
  229. sdiff -w$width $sdiff_flags $file1 $file2 | $vim_exe $vim_flags -c "$vimcmds" -
  230.