aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/vc/diff.el
diff options
context:
space:
mode:
authorStefan Monnier2010-11-22 14:22:03 -0500
committerStefan Monnier2010-11-22 14:22:03 -0500
commitb2e4481906ec08e2c6072b6fe14dd1efca4784b9 (patch)
tree76e3aae5ccdd3865ab33b3b6394d412311f4fd42 /lisp/vc/diff.el
parenta6d3e72e37fc3c641bacc52ac3495c97f8e28e88 (diff)
downloademacs-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.el123
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.
65CODE is the exit code of the process. It should be 0 only if no diffs 62CODE is the exit code of the process. It should be 0 only if no diffs
66were found." 63were 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
91interactively for diff switches. Otherwise, the switches 84interactively for diff switches. Otherwise, the switches
92specified in `diff-switches' are passed to the diff command." 85specified 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.
220This 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