diff options
| -rw-r--r-- | lisp/hilit-chg.el | 191 |
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. | ||
| 807 | Both buffers are done unless optional parameter MARKUP-A-ONLY | ||
| 808 | is 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 | |||
| 877 | The default is the current buffer and the one in the next window. | ||
| 878 | |||
| 879 | If either buffer is modified and is visiting a file, you are prompted | ||
| 880 | to save the file. | ||
| 881 | |||
| 882 | Unless the buffer is unmodified and visiting a file, the buffer is | ||
| 883 | written to a temporary file for comparison. | ||
| 884 | |||
| 885 | If a buffer is read-only, differences will be highlighted but no property | ||
| 886 | changes 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 | ||
| 813 | The current buffer must be an unmodified buffer visiting a file, | ||
| 814 | and must not be read-only. | ||
| 815 | |||
| 816 | If the buffer has a backup filename, it is used as the default when | 903 | If the buffer has a backup filename, it is used as the default when |
| 817 | this function is called interactively. | 904 | this 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) |