;;; ediff-diff.el --- diff-related utilities
;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-;; 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+;; 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
;; GNU Emacs 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, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
(eval-when-compile
(let ((load-path (cons (expand-file-name ".") load-path)))
(or (featurep 'ediff-init)
- (load "ediff-init.el" nil nil 'nosuffix))
+ (load "ediff-init.el" nil t 'nosuffix))
(or (featurep 'ediff-util)
- (load "ediff-util.el" nil nil 'nosuffix))
+ (load "ediff-util.el" nil t 'nosuffix))
))
;; end pacifier
:prefix "ediff-"
:group 'ediff)
-;; these two must be here to prevent ediff-test-utility from barking
(defcustom ediff-diff-program "diff"
"*Program to use for generating the differential of the two files."
:type 'string
;; The following functions must precede all defcustom-defined variables.
-;; The following functions needed for setting diff/diff3 options
-;; test if diff supports the --binary option
-(defsubst ediff-test-utility (diff-util option &optional files)
- (condition-case ()
- (eq 0 (apply 'call-process
- (append (list diff-util nil nil nil option) files)))
- (file-error nil)))
-
-(defun ediff-diff-mandatory-option (diff-util)
- (let ((file (if (boundp 'null-device) null-device "/dev/null")))
- (cond ((not (memq system-type '(ms-dos windows-nt windows-95)))
- "")
- ((and (string= diff-util ediff-diff-program)
- (ediff-test-utility
- ediff-diff-program "--binary" (list file file)))
- "--binary")
- ((and (string= diff-util ediff-diff3-program)
- (ediff-test-utility
- ediff-diff3-program "--binary" (list file file file)))
- "--binary")
- (t ""))))
-
-;; make sure that mandatory options are added even if the user changes
-;; ediff-diff-options or ediff-diff3-options in the customization widget
-(defun ediff-reset-diff-options (symb val)
- (let* ((diff-program
- (if (eq symb 'ediff-diff-options)
- ediff-diff-program
- ediff-diff3-program))
- (mandatory-option (ediff-diff-mandatory-option diff-program))
- (spacer (if (string-equal mandatory-option "") "" " ")))
- (set symb
- (if (string-match mandatory-option val)
- val
- (concat mandatory-option spacer val)))
- ))
-
+(fset 'ediff-set-actual-diff-options '(lambda () nil))
(defcustom ediff-shell
(cond ((eq system-type 'emx) "cmd") ; OS/2
:type '(repeat string)
:group 'ediff-diff)
-(defcustom ediff-diff-options ""
+(defun ediff-set-diff-options (symbol value)
+ (set symbol value)
+ (ediff-set-actual-diff-options))
+
+(defcustom ediff-diff-options
+ (if (memq system-type '(ms-dos windows-nt windows-95)) "--binary" "")
"*Options to pass to `ediff-diff-program'.
If Unix diff is used as `ediff-diff-program',
- then a useful option is `-w', to ignore space.
-Options `-c' and `-i' are not allowed. Case sensitivity can be
- toggled interactively using \\[ediff-toggle-ignore-case]."
- :set 'ediff-reset-diff-options
+then a useful option is `-w', to ignore space.
+Options `-c', `-u', and `-i' are not allowed. Case sensitivity can be
+toggled interactively using \\[ediff-toggle-ignore-case].
+
+Do not remove the default options. If you need to change this variable, add new
+options after the default ones.
+
+This variable is not for customizing the look of the differences produced by
+the command \\[ediff-show-diff-output]. Use the variable
+`ediff-custom-diff-options' for that."
+ :set 'ediff-set-diff-options
:type 'string
:group 'ediff-diff)
:group 'ediff-diff)
;; the actual options used in comparison
-(ediff-defvar-local ediff-actual-diff-options "" "")
+(ediff-defvar-local ediff-actual-diff-options ediff-diff-options "")
(defcustom ediff-custom-diff-program ediff-diff-program
"*Program to use for generating custom diff output for saving it in a file.
"Pattern to match lines produced by diff3 that describe differences.")
(defcustom ediff-diff3-options ""
"*Options to pass to `ediff-diff3-program'."
- :set 'ediff-reset-diff-options
+ :set 'ediff-set-diff-options
:type 'string
:group 'ediff-diff)
;; the actual options used in comparison
-(ediff-defvar-local ediff-actual-diff3-options "" "")
+(ediff-defvar-local ediff-actual-diff3-options ediff-diff3-options "")
(defcustom ediff-diff3-ok-lines-regexp
"^\\([1-3]:\\|====\\| \\|.*Warning *:\\|.*No newline\\|.*missing newline\\|^\C-m$\\)"
;; ediff-setup-diff-regions-function, which can also have the value
;; ediff-setup-diff-regions3, which takes 4 arguments.
(defun ediff-setup-diff-regions (file-A file-B file-C)
- ;; looking for '-c', '-i', or a 'c', 'i' among clustered non-long options
- (if (string-match "^-[ci]\\| -[ci]\\|\\(^\\| \\)-[^- ]+[ci]"
+ ;; looking for '-c', '-i', '-u', or 'c', 'i', 'u' among clustered non-long options
+ (if (string-match "^-[ciu]\\| -[ciu]\\|\\(^\\| \\)-[^- ]+[ciu]"
ediff-diff-options)
- (error "Options `-c' and `-i' are not allowed in `ediff-diff-options'"))
+ (error "Options `-c', `-u', and `-i' are not allowed in `ediff-diff-options'"))
;; create, if it doesn't exist
(or (ediff-buffer-live-p ediff-diff-buffer)
;; fixup diff-list
(if diff3-job
(cond ((not file-A)
- (mapcar (lambda (elt)
- (aset elt 0 nil)
- (aset elt 1 nil))
- (cdr diff-list)))
+ (mapc (lambda (elt)
+ (aset elt 0 nil)
+ (aset elt 1 nil))
+ (cdr diff-list)))
((not file-B)
- (mapcar (lambda (elt)
- (aset elt 2 nil)
- (aset elt 3 nil))
- (cdr diff-list)))
+ (mapc (lambda (elt)
+ (aset elt 2 nil)
+ (aset elt 3 nil))
+ (cdr diff-list)))
((not file-C)
- (mapcar (lambda (elt)
- (aset elt 4 nil)
- (aset elt 5 nil))
- (cdr diff-list)))
+ (mapc (lambda (elt)
+ (aset elt 4 nil)
+ (aset elt 5 nil))
+ (cdr diff-list)))
))
(ediff-convert-fine-diffs-to-overlays diff-list reg-num)
(get-buffer-create (ediff-unique-buffer-name
"*ediff-errors" "*"))))
(ediff-with-current-buffer ediff-error-buffer
+ (setq buffer-undo-list t)
(erase-buffer)
(insert (ediff-with-current-buffer diff-buff (buffer-string)))
(goto-char (point-min))
(ediff-make-fine-diffs n 'noforce)
(ediff-make-fine-diffs n 'skip)))
- ;; highlight iff fine diffs already exist
+ ;; highlight if fine diffs already exist
((eq ediff-auto-refine 'off)
(ediff-make-fine-diffs n 'skip))))
(let ((fine-diff-vector (ediff-get-fine-diff-vector n buf-type))
(face (if default
'default
- (face-name
- (ediff-get-symbol-from-alist
- buf-type ediff-fine-diff-face-alist))))
+ (ediff-get-symbol-from-alist
+ buf-type ediff-fine-diff-face-alist)
+ ))
(priority (if default
0
(1+ (or (ediff-overlay-get
)))
-(defsubst ediff-convert-fine-diffs-to-overlays (diff-list region-num)
+(defun ediff-convert-fine-diffs-to-overlays (diff-list region-num)
(ediff-set-fine-overlays-in-one-buffer 'A diff-list region-num)
(ediff-set-fine-overlays-in-one-buffer 'B diff-list region-num)
(if ediff-3way-job
Used for splitting difference regions into individual words.")
(make-variable-buffer-local 'ediff-forward-word-function)
-(defvar ediff-whitespace " \n\t\f"
+;; \240 is unicode symbol for nonbreakable whitespace
+(defvar ediff-whitespace " \n\t\f\r\240"
"*Characters constituting white space.
These characters are ignored when differing regions are split into words.")
(make-variable-buffer-local 'ediff-whitespace)
(not (file-directory-p f2)))
(let ((res
(apply 'call-process ediff-cmp-program nil nil nil
- (append ediff-cmp-options (list f1 f2)))))
- (and (numberp res) (eq res 0))))
- )
+ (append ediff-cmp-options (list (expand-file-name f1)
+ (expand-file-name f2))))
+ ))
+ (and (numberp res) (eq res 0)))
+ ))
(defun ediff-same-contents (d1 d2 &optional filter-re)
- "Returns t iff D1 and D2 have the same content.
+ "Return t if D1 and D2 have the same content.
D1 and D2 can either be both directories or both regular files.
Symlinks and the likes are not handled.
If FILTER-RE is non-nil, recursive checking in directories
(setq file-list-list (cdr file-list-list)))
(reverse result)))
+
+(defun ediff-set-actual-diff-options ()
+ (if ediff-ignore-case
+ (setq ediff-actual-diff-options
+ (concat ediff-diff-options " " ediff-ignore-case-option)
+ ediff-actual-diff3-options
+ (concat ediff-diff3-options " " ediff-ignore-case-option3))
+ (setq ediff-actual-diff-options ediff-diff-options
+ ediff-actual-diff3-options ediff-diff3-options)
+ )
+ (setq-default ediff-actual-diff-options ediff-actual-diff-options
+ ediff-actual-diff3-options ediff-actual-diff3-options)
+ )
+
+
;; Ignore case handling - some ideas from drew.adams@@oracle.com
(defun ediff-toggle-ignore-case ()
(interactive)
(ediff-barf-if-not-control-buffer)
(setq ediff-ignore-case (not ediff-ignore-case))
- (cond (ediff-ignore-case
- (setq ediff-actual-diff-options
- (concat ediff-diff-options " " ediff-ignore-case-option)
- ediff-actual-diff3-options
- (concat ediff-diff3-options " " ediff-ignore-case-option3))
- (message "Ignoring regions that differ only in case"))
- (t
- (setq ediff-actual-diff-options ediff-diff-options
- ediff-actual-diff3-options ediff-diff3-options)
- (message "Ignoring case differences turned OFF")))
+ (ediff-set-actual-diff-options)
+ (if ediff-ignore-case
+ (message "Ignoring regions that differ only in case")
+ (message "Ignoring case differences turned OFF"))
(cond (ediff-merge-job
(message "Ignoring letter case is too dangerous in merge jobs"))
((and ediff-diff3-job (string= ediff-ignore-case-option3 ""))