Start anew
[msysgit.git] / share / vim / vim58 / tools / gvimdiff
blob59da5d803949a67f77092df1e5b03297334282ec
1 #!/bin/sh
3 # gvimdiff: display highlighted differences between two files side-by-side in
4 # gvim
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.
12 # Author: Gautam H. Mudunuri (gmudunuri@informatica.com)
14 # $Revision: 1.1.1.1 $
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"
24 gvimdiff)
25 vim_exe="gvim"
28 echo >&2 "This program has an invalid name \"$progname\""
29 exit 1
31 esac
33 # Display usage and exit
34 Usage()
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)"
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"
53 # Display usage and exit
54 echo >&2 "\
55 $progname: \
56 display highlighted differences between two files side-by-side in $vim_exe
58 Usage: $progname $options arg1 arg2
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.
65 Options:
66 $options_desc"
67 exit 1
70 # Parse commandline
71 n_flag="n"
72 s_flag="n"
73 width=
74 font=
75 while getopts f:nsw: option
77 case "$option" in
79 [ $vim_exe != "gvim" ] && Usage
80 [ "$font" != "" ] && Usage
81 font="$OPTARG"
84 [ $vim_exe != "gvim" ] && Usage
85 n_flag="y"
88 s_flag="y"
91 [ "$width" != "" ] && Usage
92 width="$OPTARG"
95 Usage
97 esac
98 done
99 shift `expr $OPTIND - 1`
100 [ $# -eq 2 ] || Usage
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
108 arg2="$2"
109 [ -f $arg2 -o -d $arg2 ] || {
110 echo >&2 "$progname: $arg2 is not a valid file or directory"
111 exit 1
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
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"
126 # Both files must be readable
127 [ -r "$file1" ] || {
128 echo >&2 "$progname: cannot open $file1 for reading"
129 exit 1
131 [ -r "$file2" ] || {
132 echo >&2 "$progname: cannot open $file2 for reading"
133 exit 1
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
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
147 [ $width -gt 0 ] || {
148 echo >&2 "$progname: width $width cannot be zero or negative"
149 exit 1
151 [ $width -ge 49 ] || {
152 echo >&2 "$progname: width $width is too small, should be atleast 29"
153 exit 1
155 [ $width -le 209 ] || {
156 echo >&2 "$progname: width $width is too large, should be atmost 209"
157 exit 1
160 # Compute width per file, allowing 9 characters for the sdiff "gutter"
161 file_width=`expr '(' $width - 9 ')' / 2`
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`
169 # Define Vim commands for manipulating the sdiff buffer
170 buffercmds="
171 set ts=8 et noro
172 retab
173 set nomod ro nows
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\"
192 # Help commands (doesn't always work)
193 helpcmd_next="\
194 echo 'Ctrl-N: Next Difference Line Ctrl-P: Previous Difference Line'\
196 helpcmd_prev="\
197 echo 'Ctrl-P: Previous Difference Line Ctrl-N: Next Difference Line'\
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>
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
217 # Set sdiff_flags flags
218 sdiff_flags=
219 [ "$s_flag" = "y" ] && sdiff_flags="$flags -s"
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"
228 # Run the diff and display the output in gvim
229 sdiff -w$width $sdiff_flags $file1 $file2 | $vim_exe $vim_flags -c "$vimcmds" -