aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/hilit-chg.el191
1 files changed, 119 insertions, 72 deletions
diff --git a/lisp/hilit-chg.el b/lisp/hilit-chg.el
index 77e47216b2d..6c2c7e26ea0 100644
--- a/lisp/hilit-chg.el
+++ b/lisp/hilit-chg.el
@@ -61,7 +61,8 @@
61;; 61;;
62;; You can also use the command highlight-compare-with-file to show changes 62;; You can also use the command highlight-compare-with-file to show changes
63;; in this file compared with another file (typically the previous version 63;; in this file compared with another file (typically the previous version
64;; of the file). 64;; of the file). The command highlight-compare-buffers can be used to
65;; compare two buffers.
65;; 66;;
66;; 67;;
67;; There are currently three hooks run by `highlight-changes-mode': 68;; There are currently three hooks run by `highlight-changes-mode':
@@ -147,6 +148,7 @@
147;; highlight-changes-remove-highlight 148;; highlight-changes-remove-highlight
148;; highlight-changes-rotate-faces 149;; highlight-changes-rotate-faces
149;; highlight-compare-with-file 150;; highlight-compare-with-file
151;; highlight-compare-buffers
150 152
151;; 153;;
152;; You can automatically rotate faces when the buffer is saved; 154;; You can automatically rotate faces when the buffer is saved;
@@ -174,7 +176,7 @@
174 176
175;;; History: 177;;; History:
176 178
177;; R Sharman (rsharman@magma.ca) Feb 1998: 179;; R Sharman (rsharman@pobox.com) Feb 1998:
178;; - initial release as change-mode. 180;; - initial release as change-mode.
179;; Jari Aalto <jari.aalto@ntc.nokia.com> Mar 1998 181;; Jari Aalto <jari.aalto@ntc.nokia.com> Mar 1998
180;; - fixes for byte compile errors 182;; - fixes for byte compile errors
@@ -187,7 +189,9 @@
187;; - Changed to use overlays 189;; - Changed to use overlays
188;; August 98 190;; August 98
189;; - renamed to Highlight Changes mode. 191;; - renamed to Highlight Changes mode.
190 192;; Dec 2003
193;; - Use require for ediff stuff
194;; - Added highlight-compare-buffers
191 195
192;;; Code: 196;;; Code:
193 197
@@ -401,17 +405,8 @@ Otherwise, this list will be constructed when needed from
401(make-variable-buffer-local 'hilit-chg-string) 405(make-variable-buffer-local 'hilit-chg-string)
402 406
403 407
404 408(require 'ediff-init)
405(eval-and-compile 409(require 'ediff-util)
406 ;; For highlight-compare-with-file
407 (defvar ediff-number-of-differences)
408 (autoload 'ediff-setup "ediff")
409 (autoload 'ediff-with-current-buffer "ediff")
410 (autoload 'ediff-really-quit "ediff")
411 (autoload 'ediff-make-fine-diffs "ediff")
412 (autoload 'ediff-get-fine-diff-vector "ediff")
413 (autoload 'ediff-get-difference "ediff"))
414
415 410
416 411
417;;; Functions... 412;;; Functions...
@@ -803,16 +798,108 @@ buffer to be saved):
803 nil) 798 nil)
804 799
805;; ======================================================================== 800;; ========================================================================
806;; Comparing with an existing file. 801;; Comparing buffers/files
807;; This uses ediff to find the differences. 802;; These use ediff to find the differences.
803
804(defun highlight-markup-buffers
805 (buf-a file-a buf-b file-b &optional markup-a-only)
806 "Get differences between two buffers and set highlight changes.
807Both buffers are done unless optional parameter MARKUP-A-ONLY
808is non-nil."
809 (save-window-excursion
810 (let* (change-info
811 change-a change-b
812 a-start a-end len-a
813 b-start b-end len-b
814 (bufa-modified (buffer-modified-p buf-a))
815 (bufb-modified (buffer-modified-p buf-b))
816 (buf-a-read-only (with-current-buffer buf-a buffer-read-only))
817 (buf-b-read-only (with-current-buffer buf-b buffer-read-only))
818 temp-a temp-b)
819 (if (and file-a bufa-modified)
820 (if (y-or-n-p (format "Save buffer %s? " buf-a))
821 (with-current-buffer buf-a
822 (save-buffer)
823 (setq bufa-modified (buffer-modified-p buf-a)))
824 (setq file-a nil)))
825 (or file-a
826 (setq temp-a (setq file-a (ediff-make-temp-file buf-a nil))))
827
828 (if (and file-b bufb-modified)
829 (if (y-or-n-p (format "Save buffer %s? " buf-b))
830 (with-current-buffer buf-b
831 (save-buffer)
832 (setq bufb-modified (buffer-modified-p buf-b)))
833 (setq file-b nil)))
834 (or file-b
835 (setq temp-b (setq file-b (ediff-make-temp-file buf-b nil))))
836 (set-buffer buf-a)
837 (highlight-changes-mode 'active)
838 (or markup-a-only (with-current-buffer buf-b
839 (highlight-changes-mode 'active)))
840 (setq change-info (hilit-chg-get-diff-info buf-a file-a buf-b file-b))
841
842
843 (setq change-a (car change-info))
844 (setq change-b (car (cdr change-info)))
845
846 (hilit-chg-make-list)
847 (while change-a
848 (setq a-start (nth 0 (car change-a)))
849 (setq a-end (nth 1 (car change-a)))
850 (setq b-start (nth 0 (car change-b)))
851 (setq b-end (nth 1 (car change-b)))
852 (setq len-a (- a-end a-start))
853 (setq len-b (- b-end b-start))
854 (set-buffer buf-a)
855 (hilit-chg-set-face-on-change a-start a-end len-b buf-a-read-only)
856 (or markup-a-only
857 (with-current-buffer buf-b
858 (hilit-chg-set-face-on-change b-start b-end len-a
859 buf-b-read-only)
860 ))
861 (setq change-a (cdr change-a))
862 (setq change-b (cdr change-b)))
863 (or bufa-modified
864 (with-current-buffer buf-a (set-buffer-modified-p nil)))
865 (or bufb-modified
866 (with-current-buffer buf-b (set-buffer-modified-p nil)))
867 (if temp-a
868 (delete-file temp-a))
869 (if temp-b
870 (delete-file temp-b)))
871 ))
872
873;;;###autoload
874(defun highlight-compare-buffers (buf-a buf-b)
875"Compare two buffers and highlight the differences.
876
877The default is the current buffer and the one in the next window.
878
879If either buffer is modified and is visiting a file, you are prompted
880to save the file.
881
882Unless the buffer is unmodified and visiting a file, the buffer is
883written to a temporary file for comparison.
884
885If a buffer is read-only, differences will be highlighted but no property
886changes are made, so \\[highlight-changes-next-change] and
887\\[highlight-changes-previous-change] will not work."
888 (interactive
889 (list
890 (get-buffer (read-buffer "buffer-a " (current-buffer) t))
891 (get-buffer
892 (read-buffer "buffer-b "
893 (window-buffer (next-window (selected-window))) t))))
894 (let ((file-a (buffer-file-name buf-a))
895 (file-b (buffer-file-name buf-b)))
896 (highlight-markup-buffers buf-a file-a buf-b file-b)
897 ))
808 898
809;;;###autoload 899;;;###autoload
810(defun highlight-compare-with-file (file-b) 900(defun highlight-compare-with-file (file-b)
811 "Compare this buffer with a file, and highlight differences. 901 "Compare this buffer with a file, and highlight differences.
812 902
813The current buffer must be an unmodified buffer visiting a file,
814and must not be read-only.
815
816If the buffer has a backup filename, it is used as the default when 903If the buffer has a backup filename, it is used as the default when
817this function is called interactively. 904this function is called interactively.
818 905
@@ -829,64 +916,24 @@ changes are made, so \\[highlight-changes-next-change] and
829 "" ;; directory 916 "" ;; directory
830 nil ;; default 917 nil ;; default
831 'yes ;; must exist 918 'yes ;; must exist
832 (let ((f (make-backup-file-name 919 (let ((f (buffer-file-name (current-buffer))))
833 (or (buffer-file-name (current-buffer)) 920 (if f
834 (error "no file for this buffer"))))) 921 (progn
835 (if (file-exists-p f) f ""))))) 922 (setq f (make-backup-file-name f))
836 923 (or (file-exists-p f)
924 (setq f nil)))
925 )
926 f))))
837 (let* ((buf-a (current-buffer)) 927 (let* ((buf-a (current-buffer))
838 (buf-a-read-only buffer-read-only)
839 (orig-pos (point))
840 (file-a (buffer-file-name)) 928 (file-a (buffer-file-name))
841 (existing-buf (get-file-buffer file-b)) 929 (existing-buf (get-file-buffer file-b))
842 (buf-b (or existing-buf 930 (buf-b (or existing-buf
843 (find-file-noselect file-b))) 931 (find-file-noselect file-b)))
844 (buf-b-read-only (with-current-buffer buf-b buffer-read-only)) 932 (buf-b-read-only (with-current-buffer buf-b buffer-read-only)))
845 xy xx yy p q 933 (highlight-markup-buffers buf-a file-a buf-b file-b (not existing-buf))
846 a-start a-end len-a 934 (unless existing-buf
847 b-start b-end len-b) 935 (kill-buffer buf-b))
848 936 ))
849 ;; We use the fact that the buffer is not marked modified at the
850 ;; end where we clear its modified status
851 (if (buffer-modified-p buf-a)
852 (if (y-or-n-p (format "OK to save %s? " file-a))
853 (save-buffer buf-a)
854 (error "Buffer must be saved before comparing with a file")))
855 (if (and existing-buf (buffer-modified-p buf-b))
856 (if (y-or-n-p (format "OK to save %s? " file-b))
857 (save-buffer buf-b)
858 (error "Cannot compare with a file in an unsaved buffer")))
859 (highlight-changes-mode 'active)
860 (if existing-buf (with-current-buffer buf-b
861 (highlight-changes-mode 'active)))
862 (save-window-excursion
863 (setq xy (hilit-chg-get-diff-info buf-a file-a buf-b file-b)))
864 (setq xx (car xy))
865 (setq p xx)
866 (setq yy (car (cdr xy)))
867 (setq q yy)
868 (hilit-chg-make-list)
869 (while p
870 (setq a-start (nth 0 (car p)))
871 (setq a-end (nth 1 (car p)))
872 (setq b-start (nth 0 (car q)))
873 (setq b-end (nth 1 (car q)))
874 (setq len-a (- a-end a-start))
875 (setq len-b (- b-end b-start))
876 (set-buffer buf-a)
877 (hilit-chg-set-face-on-change a-start a-end len-b buf-a-read-only)
878 (set-buffer-modified-p nil)
879 (goto-char orig-pos)
880 (if existing-buf
881 (with-current-buffer buf-b
882 (hilit-chg-set-face-on-change b-start b-end len-a
883 buf-b-read-only )
884 ))
885 (setq p (cdr p))
886 (setq q (cdr q)))
887 (if existing-buf
888 (set-buffer-modified-p nil)
889 (kill-buffer buf-b))))
890 937
891 938
892(defun hilit-chg-get-diff-info (buf-a file-a buf-b file-b) 939(defun hilit-chg-get-diff-info (buf-a file-a buf-b file-b)