diff options
| author | Stefan Monnier | 2010-11-22 14:22:03 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2010-11-22 14:22:03 -0500 |
| commit | b2e4481906ec08e2c6072b6fe14dd1efca4784b9 (patch) | |
| tree | 76e3aae5ccdd3865ab33b3b6394d412311f4fd42 /lisp/vc/diff.el | |
| parent | a6d3e72e37fc3c641bacc52ac3495c97f8e28e88 (diff) | |
| download | emacs-b2e4481906ec08e2c6072b6fe14dd1efca4784b9.tar.gz emacs-b2e4481906ec08e2c6072b6fe14dd1efca4784b9.zip | |
Cleanup diff-buffer-with-file.
* lisp/vc/diff.el (diff-old-temp-file, diff-new-temp-file): Remove.
(diff-sentinel): Get them as arguments instead.
(diff-old-file, diff-new-file, diff-extra-args): Remove.
(diff-file-local-copy, diff-better-file-name): New funs.
(diff-no-select): Rename from diff-into-buffer.
Support buffers additionally to files. Move `buf' arg. Don't display buf.
Prefer closures to buffer-local variables.
(diff): Adjust accordingly.
(diff-buffer-with-file): Move from files.el.
* lisp/files.el (diff-buffer-with-file): Move to vc/diff.el.
(diff-buffer-internal): Remove.
(diff-buffer-buffer): Remove.
(save-some-buffers-action-alist): Use diff-no-select so as not to guess
the buffer name used, and so as not to mess up windows and frames.
Diffstat (limited to 'lisp/vc/diff.el')
| -rw-r--r-- | lisp/vc/diff.el | 123 |
1 files changed, 71 insertions, 52 deletions
diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el index 1a835b59994..5c0a222cffd 100644 --- a/lisp/vc/diff.el +++ b/lisp/vc/diff.el | |||
| @@ -31,6 +31,8 @@ | |||
| 31 | 31 | ||
| 32 | ;;; Code: | 32 | ;;; Code: |
| 33 | 33 | ||
| 34 | (eval-when-compile (require 'cl)) | ||
| 35 | |||
| 34 | (defgroup diff nil | 36 | (defgroup diff nil |
| 35 | "Comparing files with `diff'." | 37 | "Comparing files with `diff'." |
| 36 | :group 'tools) | 38 | :group 'tools) |
| @@ -47,11 +49,6 @@ | |||
| 47 | :type 'string | 49 | :type 'string |
| 48 | :group 'diff) | 50 | :group 'diff) |
| 49 | 51 | ||
| 50 | (defvar diff-old-temp-file nil | ||
| 51 | "This is the name of a temp file to be deleted after diff finishes.") | ||
| 52 | (defvar diff-new-temp-file nil | ||
| 53 | "This is the name of a temp file to be deleted after diff finishes.") | ||
| 54 | |||
| 55 | ;; prompt if prefix arg present | 52 | ;; prompt if prefix arg present |
| 56 | (defun diff-switches () | 53 | (defun diff-switches () |
| 57 | (if current-prefix-arg | 54 | (if current-prefix-arg |
| @@ -60,12 +57,12 @@ | |||
| 60 | diff-switches | 57 | diff-switches |
| 61 | (mapconcat 'identity diff-switches " "))))) | 58 | (mapconcat 'identity diff-switches " "))))) |
| 62 | 59 | ||
| 63 | (defun diff-sentinel (code) | 60 | (defun diff-sentinel (code old-temp-file new-temp-file) |
| 64 | "Code run when the diff process exits. | 61 | "Code run when the diff process exits. |
| 65 | CODE is the exit code of the process. It should be 0 only if no diffs | 62 | CODE is the exit code of the process. It should be 0 only if no diffs |
| 66 | were found." | 63 | were found." |
| 67 | (if diff-old-temp-file (delete-file diff-old-temp-file)) | 64 | (if old-temp-file (delete-file old-temp-file)) |
| 68 | (if diff-new-temp-file (delete-file diff-new-temp-file)) | 65 | (if new-temp-file (delete-file new-temp-file)) |
| 69 | (save-excursion | 66 | (save-excursion |
| 70 | (goto-char (point-max)) | 67 | (goto-char (point-max)) |
| 71 | (let ((inhibit-read-only t)) | 68 | (let ((inhibit-read-only t)) |
| @@ -75,10 +72,6 @@ were found." | |||
| 75 | (t "")) | 72 | (t "")) |
| 76 | (current-time-string)))))) | 73 | (current-time-string)))))) |
| 77 | 74 | ||
| 78 | (defvar diff-old-file nil) | ||
| 79 | (defvar diff-new-file nil) | ||
| 80 | (defvar diff-extra-args nil) | ||
| 81 | |||
| 82 | ;;;###autoload | 75 | ;;;###autoload |
| 83 | (defun diff (old new &optional switches no-async) | 76 | (defun diff (old new &optional switches no-async) |
| 84 | "Find and display the differences between OLD and NEW files. | 77 | "Find and display the differences between OLD and NEW files. |
| @@ -91,16 +84,15 @@ When called interactively with a prefix argument, prompt | |||
| 91 | interactively for diff switches. Otherwise, the switches | 84 | interactively for diff switches. Otherwise, the switches |
| 92 | specified in `diff-switches' are passed to the diff command." | 85 | specified in `diff-switches' are passed to the diff command." |
| 93 | (interactive | 86 | (interactive |
| 94 | (let (oldf newf) | 87 | (let ((newf (buffer-file-name)) |
| 95 | (setq newf (buffer-file-name) | 88 | (oldf (file-newest-backup newf))) |
| 96 | newf (if (and newf (file-exists-p newf)) | 89 | (setq newf (if (and newf (file-exists-p newf)) |
| 97 | (read-file-name | 90 | (read-file-name |
| 98 | (concat "Diff new file (default " | 91 | (concat "Diff new file (default " |
| 99 | (file-name-nondirectory newf) "): ") | 92 | (file-name-nondirectory newf) "): ") |
| 100 | nil newf t) | 93 | nil newf t) |
| 101 | (read-file-name "Diff new file: " nil nil t))) | 94 | (read-file-name "Diff new file: " nil nil t))) |
| 102 | (setq oldf (file-newest-backup newf) | 95 | (setq oldf (if (and oldf (file-exists-p oldf)) |
| 103 | oldf (if (and oldf (file-exists-p oldf)) | ||
| 104 | (read-file-name | 96 | (read-file-name |
| 105 | (concat "Diff original file (default " | 97 | (concat "Diff original file (default " |
| 106 | (file-name-nondirectory oldf) "): ") | 98 | (file-name-nondirectory oldf) "): ") |
| @@ -108,63 +100,82 @@ specified in `diff-switches' are passed to the diff command." | |||
| 108 | (read-file-name "Diff original file: " | 100 | (read-file-name "Diff original file: " |
| 109 | (file-name-directory newf) nil t))) | 101 | (file-name-directory newf) nil t))) |
| 110 | (list oldf newf (diff-switches)))) | 102 | (list oldf newf (diff-switches)))) |
| 111 | (diff-into-buffer nil old new switches no-async)) | 103 | (display-buffer |
| 112 | 104 | (diff-no-select old new switches no-async))) | |
| 113 | (defun diff-into-buffer (buf old new &optional switches no-async) | 105 | |
| 114 | ;; Noninteractive helper for creating and reverting diff buffers. | 106 | (defun diff-file-local-copy (file-or-buf) |
| 115 | (setq new (expand-file-name new) | 107 | (if (bufferp file-or-buf) |
| 116 | old (expand-file-name old)) | 108 | (with-current-buffer file-or-buf |
| 109 | (let ((tempfile (make-temp-file "buffer-content-"))) | ||
| 110 | (write-region nil nil tempfile nil 'nomessage) | ||
| 111 | tempfile)) | ||
| 112 | (file-local-copy file-or-buf))) | ||
| 113 | |||
| 114 | (defun diff-better-file-name (file) | ||
| 115 | (if (bufferp file) file | ||
| 116 | (let ((rel (file-relative-name file)) | ||
| 117 | (abbr (abbreviate-file-name (expand-file-name file)))) | ||
| 118 | (if (< (length abbr) (length rel)) | ||
| 119 | abbr | ||
| 120 | rel)))) | ||
| 121 | |||
| 122 | (defun diff-no-select (old new &optional switches no-async buf) | ||
| 123 | ;; Noninteractive helper for creating and reverting diff buffers | ||
| 124 | (setq new (diff-better-file-name new) | ||
| 125 | old (diff-better-file-name old)) | ||
| 117 | (or switches (setq switches diff-switches)) ; If not specified, use default. | 126 | (or switches (setq switches diff-switches)) ; If not specified, use default. |
| 127 | (unless (listp switches) (setq switches (list switches))) | ||
| 118 | (or buf (setq buf (get-buffer-create "*Diff*"))) | 128 | (or buf (setq buf (get-buffer-create "*Diff*"))) |
| 119 | (let* ((old-alt (file-local-copy old)) | 129 | (let* ((old-alt (diff-file-local-copy old)) |
| 120 | (new-alt (file-local-copy new)) | 130 | (new-alt (diff-file-local-copy new)) |
| 121 | (command | 131 | (command |
| 122 | (mapconcat 'identity | 132 | (mapconcat 'identity |
| 123 | `(,diff-command | 133 | `(,diff-command |
| 124 | ;; Use explicitly specified switches | 134 | ;; Use explicitly specified switches |
| 125 | ,@(if (listp switches) switches (list switches)) | 135 | ,@switches |
| 126 | ,@(if (or old-alt new-alt) | 136 | ,@(mapcar #'shell-quote-argument |
| 127 | (list "-L" old "-L" new)) | 137 | (nconc |
| 128 | ,(shell-quote-argument (or old-alt old)) | 138 | (when (or old-alt new-alt) |
| 129 | ,(shell-quote-argument (or new-alt new))) | 139 | (list "-L" (if (stringp old) |
| 140 | old (prin1-to-string old)) | ||
| 141 | "-L" (if (stringp new) | ||
| 142 | new (prin1-to-string new)))) | ||
| 143 | (list (or old-alt old) | ||
| 144 | (or new-alt new))))) | ||
| 130 | " ")) | 145 | " ")) |
| 131 | (thisdir default-directory) | 146 | (thisdir default-directory)) |
| 132 | proc) | 147 | (with-current-buffer buf |
| 133 | (save-excursion | 148 | (setq buffer-read-only t) |
| 134 | (display-buffer buf) | ||
| 135 | (set-buffer buf) | ||
| 136 | (setq buffer-read-only nil) | ||
| 137 | (buffer-disable-undo (current-buffer)) | 149 | (buffer-disable-undo (current-buffer)) |
| 138 | (let ((inhibit-read-only t)) | 150 | (let ((inhibit-read-only t)) |
| 139 | (erase-buffer)) | 151 | (erase-buffer)) |
| 140 | (buffer-enable-undo (current-buffer)) | 152 | (buffer-enable-undo (current-buffer)) |
| 141 | (diff-mode) | 153 | (diff-mode) |
| 142 | ;; Use below 2 vars for backward-compatibility. | ||
| 143 | (set (make-local-variable 'diff-old-file) old) | ||
| 144 | (set (make-local-variable 'diff-new-file) new) | ||
| 145 | (set (make-local-variable 'diff-extra-args) (list switches no-async)) | ||
| 146 | (set (make-local-variable 'revert-buffer-function) | 154 | (set (make-local-variable 'revert-buffer-function) |
| 147 | (lambda (ignore-auto noconfirm) | 155 | (lexical-let ((old old) (new new) |
| 148 | (apply 'diff diff-old-file diff-new-file diff-extra-args))) | 156 | (switches switches) |
| 149 | (set (make-local-variable 'diff-old-temp-file) old-alt) | 157 | (no-async no-async)) |
| 150 | (set (make-local-variable 'diff-new-temp-file) new-alt) | 158 | (lambda (ignore-auto noconfirm) |
| 159 | (diff-no-select old new switches no-async (current-buffer))))) | ||
| 151 | (setq default-directory thisdir) | 160 | (setq default-directory thisdir) |
| 152 | (let ((inhibit-read-only t)) | 161 | (let ((inhibit-read-only t)) |
| 153 | (insert command "\n")) | 162 | (insert command "\n")) |
| 154 | (if (and (not no-async) (fboundp 'start-process)) | 163 | (if (and (not no-async) (fboundp 'start-process)) |
| 155 | (progn | 164 | (let ((proc (start-process "Diff" buf shell-file-name |
| 156 | (setq proc (start-process "Diff" buf shell-file-name | 165 | shell-command-switch command))) |
| 157 | shell-command-switch command)) | ||
| 158 | (set-process-filter proc 'diff-process-filter) | 166 | (set-process-filter proc 'diff-process-filter) |
| 159 | (set-process-sentinel | 167 | (lexical-let ((old-alt old-alt) (new-alt new-alt)) |
| 160 | proc (lambda (proc msg) | 168 | (set-process-sentinel |
| 161 | (with-current-buffer (process-buffer proc) | 169 | proc (lambda (proc msg) |
| 162 | (diff-sentinel (process-exit-status proc)))))) | 170 | (with-current-buffer (process-buffer proc) |
| 171 | (diff-sentinel (process-exit-status proc) | ||
| 172 | old-alt new-alt)))))) | ||
| 163 | ;; Async processes aren't available. | 173 | ;; Async processes aren't available. |
| 164 | (let ((inhibit-read-only t)) | 174 | (let ((inhibit-read-only t)) |
| 165 | (diff-sentinel | 175 | (diff-sentinel |
| 166 | (call-process shell-file-name nil buf nil | 176 | (call-process shell-file-name nil buf nil |
| 167 | shell-command-switch command))))) | 177 | shell-command-switch command) |
| 178 | old-alt new-alt)))) | ||
| 168 | buf)) | 179 | buf)) |
| 169 | 180 | ||
| 170 | (defun diff-process-filter (proc string) | 181 | (defun diff-process-filter (proc string) |
| @@ -203,6 +214,14 @@ With prefix arg, prompt for diff switches." | |||
| 203 | (funcall handler 'diff-latest-backup-file fn) | 214 | (funcall handler 'diff-latest-backup-file fn) |
| 204 | (file-newest-backup fn)))) | 215 | (file-newest-backup fn)))) |
| 205 | 216 | ||
| 217 | ;;;###autoload | ||
| 218 | (defun diff-buffer-with-file (&optional buffer) | ||
| 219 | "View the differences between BUFFER and its associated file. | ||
| 220 | This requires the external program `diff' to be in your `exec-path'." | ||
| 221 | (interactive "bBuffer: ") | ||
| 222 | (with-current-buffer (get-buffer (or buffer (current-buffer))) | ||
| 223 | (diff buffer-file-name (current-buffer) nil 'noasync))) | ||
| 224 | |||
| 206 | (provide 'diff) | 225 | (provide 'diff) |
| 207 | 226 | ||
| 208 | ;; arch-tag: 7de2c29b-7ea5-4b85-9b9d-72dd860de2bd | 227 | ;; arch-tag: 7de2c29b-7ea5-4b85-9b9d-72dd860de2bd |