38414
|
1 ;;; diff.el --- run `diff' in compilation-mode
|
846
|
2
|
101092
|
3 ;; Copyright (C) 1992, 1994, 1996, 2001, 2002, 2003, 2004, 2005, 2006,
|
|
4 ;; 2007, 2008, 2009 Free Software Foundation, Inc.
|
894
|
5
|
101092
|
6 ;; Author: Frank Bresz
|
|
7 ;; (according to authors.el)
|
38697
|
8 ;; Maintainer: FSF
|
2247
|
9 ;; Keywords: unix, tools
|
807
|
10
|
349
|
11 ;; This file is part of GNU Emacs.
|
|
12
|
94678
|
13 ;; GNU Emacs is free software: you can redistribute it and/or modify
|
349
|
14 ;; it under the terms of the GNU General Public License as published by
|
94678
|
15 ;; the Free Software Foundation, either version 3 of the License, or
|
|
16 ;; (at your option) any later version.
|
349
|
17
|
|
18 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21 ;; GNU General Public License for more details.
|
|
22
|
|
23 ;; You should have received a copy of the GNU General Public License
|
94678
|
24 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
349
|
25
|
2307
|
26 ;;; Commentary:
|
|
27
|
|
28 ;; This package helps you explore differences between files, using the
|
|
29 ;; UNIX command diff(1). The commands are `diff' and `diff-backup'.
|
|
30 ;; You can specify options with `diff-switches'.
|
|
31
|
894
|
32 ;;; Code:
|
807
|
33
|
18143
|
34 (defgroup diff nil
|
|
35 "Comparing files with `diff'."
|
|
36 :group 'tools)
|
894
|
37
|
18143
|
38 ;;;###autoload
|
105939
|
39 (defcustom diff-switches (purecopy "-c")
|
100171
|
40 "A string or list of strings specifying switches to be passed to diff."
|
18143
|
41 :type '(choice string (repeat string))
|
|
42 :group 'diff)
|
|
43
|
|
44 ;;;###autoload
|
105939
|
45 (defcustom diff-command (purecopy "diff")
|
100171
|
46 "The command to use to run diff."
|
18150
|
47 :type 'string
|
18143
|
48 :group 'diff)
|
9736
|
49
|
1134
|
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
|
53914
|
55 ;; prompt if prefix arg present
|
|
56 (defun diff-switches ()
|
|
57 (if current-prefix-arg
|
|
58 (read-string "Diff switches: "
|
|
59 (if (stringp diff-switches)
|
|
60 diff-switches
|
|
61 (mapconcat 'identity diff-switches " ")))))
|
|
62
|
53918
|
63 (defun diff-sentinel (code)
|
|
64 "Code run when the diff process exits.
|
78492
|
65 CODE is the exit code of the process. It should be 0 only if no diffs
|
|
66 were found."
|
53918
|
67 (if diff-old-temp-file (delete-file diff-old-temp-file))
|
|
68 (if diff-new-temp-file (delete-file diff-new-temp-file))
|
|
69 (save-excursion
|
|
70 (goto-char (point-max))
|
71248
|
71 (let ((inhibit-read-only t))
|
|
72 (insert (format "\nDiff finished%s. %s\n"
|
99893
|
73 (cond ((equal 0 code) " (no differences)")
|
|
74 ((equal 2 code) " (diff error)")
|
|
75 (t ""))
|
71248
|
76 (current-time-string))))))
|
53918
|
77
|
85686
|
78 (defvar diff-old-file nil)
|
|
79 (defvar diff-new-file nil)
|
|
80 (defvar diff-extra-args nil)
|
|
81
|
349
|
82 ;;;###autoload
|
47301
bac8aaf18835
(diff): Add optional argument no-async, and use the above argument.
Colin Walters <walters@gnu.org>
diff
changeset
|
83 (defun diff (old new &optional switches no-async)
|
349
|
84 "Find and display the differences between OLD and NEW files.
|
100729
|
85 When called interactively, read OLD and NEW using the minibuffer;
|
|
86 the default for NEW is the current buffer's file name, and the
|
|
87 default for OLD is a backup file for NEW, if one exists.
|
53914
|
88 If NO-ASYNC is non-nil, call diff synchronously.
|
100729
|
89
|
|
90 When called interactively with a prefix argument, prompt
|
|
91 interactively for diff switches. Otherwise, the switches
|
|
92 specified in `diff-switches' are passed to the diff command."
|
349
|
93 (interactive
|
53914
|
94 (let (oldf newf)
|
|
95 (setq newf (buffer-file-name)
|
|
96 newf (if (and newf (file-exists-p newf))
|
|
97 (read-file-name
|
65680
|
98 (concat "Diff new file (default "
|
|
99 (file-name-nondirectory newf) "): ")
|
53914
|
100 nil newf t)
|
|
101 (read-file-name "Diff new file: " nil nil t)))
|
|
102 (setq oldf (file-newest-backup newf)
|
|
103 oldf (if (and oldf (file-exists-p oldf))
|
|
104 (read-file-name
|
65680
|
105 (concat "Diff original file (default "
|
|
106 (file-name-nondirectory oldf) "): ")
|
53914
|
107 (file-name-directory oldf) oldf t)
|
|
108 (read-file-name "Diff original file: "
|
|
109 (file-name-directory newf) nil t)))
|
|
110 (list oldf newf (diff-switches))))
|
349
|
111 (setq new (expand-file-name new)
|
|
112 old (expand-file-name old))
|
53917
|
113 (or switches (setq switches diff-switches)) ; If not specified, use default.
|
|
114 (let* ((old-alt (file-local-copy old))
|
1134
|
115 (new-alt (file-local-copy new))
|
53918
|
116 (command
|
|
117 (mapconcat 'identity
|
|
118 `(,diff-command
|
|
119 ;; Use explicitly specified switches
|
|
120 ,@(if (listp switches) switches (list switches))
|
|
121 ,@(if (or old-alt new-alt)
|
|
122 (list "-L" old "-L" new))
|
|
123 ,(shell-quote-argument (or old-alt old))
|
|
124 ,(shell-quote-argument (or new-alt new)))
|
|
125 " "))
|
|
126 (buf (get-buffer-create "*Diff*"))
|
55117
|
127 (thisdir default-directory)
|
53918
|
128 proc)
|
15932
|
129 (save-excursion
|
53918
|
130 (display-buffer buf)
|
|
131 (set-buffer buf)
|
|
132 (setq buffer-read-only nil)
|
|
133 (buffer-disable-undo (current-buffer))
|
71248
|
134 (let ((inhibit-read-only t))
|
|
135 (erase-buffer))
|
53918
|
136 (buffer-enable-undo (current-buffer))
|
|
137 (diff-mode)
|
80857
b8d11546ac61
(diff): Use buffer-local vars diff-old-file and diff-new-file
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
138 ;; Use below 2 vars for backward-compatibility.
|
b8d11546ac61
(diff): Use buffer-local vars diff-old-file and diff-new-file
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
139 (set (make-local-variable 'diff-old-file) old)
|
b8d11546ac61
(diff): Use buffer-local vars diff-old-file and diff-new-file
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
140 (set (make-local-variable 'diff-new-file) new)
|
b8d11546ac61
(diff): Use buffer-local vars diff-old-file and diff-new-file
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
141 (set (make-local-variable 'diff-extra-args) (list switches no-async))
|
53918
|
142 (set (make-local-variable 'revert-buffer-function)
|
80857
b8d11546ac61
(diff): Use buffer-local vars diff-old-file and diff-new-file
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
143 (lambda (ignore-auto noconfirm)
|
b8d11546ac61
(diff): Use buffer-local vars diff-old-file and diff-new-file
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
144 (apply 'diff diff-old-file diff-new-file diff-extra-args)))
|
53918
|
145 (set (make-local-variable 'diff-old-temp-file) old-alt)
|
|
146 (set (make-local-variable 'diff-new-temp-file) new-alt)
|
55117
|
147 (setq default-directory thisdir)
|
71248
|
148 (let ((inhibit-read-only t))
|
|
149 (insert command "\n"))
|
53918
|
150 (if (and (not no-async) (fboundp 'start-process))
|
|
151 (progn
|
|
152 (setq proc (start-process "Diff" buf shell-file-name
|
|
153 shell-command-switch command))
|
71248
|
154 (set-process-filter proc 'diff-process-filter)
|
53918
|
155 (set-process-sentinel
|
|
156 proc (lambda (proc msg)
|
|
157 (with-current-buffer (process-buffer proc)
|
|
158 (diff-sentinel (process-exit-status proc))))))
|
|
159 ;; Async processes aren't available.
|
71248
|
160 (let ((inhibit-read-only t))
|
|
161 (diff-sentinel
|
|
162 (call-process shell-file-name nil buf nil
|
|
163 shell-command-switch command)))))
|
53918
|
164 buf))
|
474
|
165
|
71248
|
166 (defun diff-process-filter (proc string)
|
|
167 (with-current-buffer (process-buffer proc)
|
|
168 (let ((moving (= (point) (process-mark proc))))
|
|
169 (save-excursion
|
|
170 ;; Insert the text, advancing the process marker.
|
|
171 (goto-char (process-mark proc))
|
|
172 (let ((inhibit-read-only t))
|
|
173 (insert string))
|
|
174 (set-marker (process-mark proc) (point)))
|
|
175 (if moving (goto-char (process-mark proc))))))
|
|
176
|
894
|
177 ;;;###autoload
|
|
178 (defun diff-backup (file &optional switches)
|
881
|
179 "Diff this file with its backup file or vice versa.
|
|
180 Uses the latest backup, if there are several numerical backups.
|
|
181 If this file is a backup, diff it with its original.
|
53914
|
182 The backup file is the first file given to `diff'.
|
|
183 With prefix arg, prompt for diff switches."
|
894
|
184 (interactive (list (read-file-name "Diff (file with backup): ")
|
53914
|
185 (diff-switches)))
|
881
|
186 (let (bak ori)
|
|
187 (if (backup-file-name-p file)
|
|
188 (setq bak file
|
|
189 ori (file-name-sans-versions file))
|
|
190 (setq bak (or (diff-latest-backup-file file)
|
|
191 (error "No backup found for %s" file))
|
|
192 ori file))
|
894
|
193 (diff bak ori switches)))
|
474
|
194
|
881
|
195 (defun diff-latest-backup-file (fn) ; actually belongs into files.el
|
|
196 "Return the latest existing backup of FILE, or nil."
|
7028
|
197 (let ((handler (find-file-name-handler fn 'diff-latest-backup-file)))
|
6147
f89879182407
(diff-latest-backup-file): Check for a file-name-handler and run it.
Roland McGrath <roland@gnu.org>
diff
changeset
|
198 (if handler
|
6321
|
199 (funcall handler 'diff-latest-backup-file fn)
|
45472
6b7dcaa53b5c
(diff-latest-backup-file): Replace the main code by a call of
Markus Rost <rost@math.uni-bielefeld.de>
diff
changeset
|
200 (file-newest-backup fn))))
|
474
|
201
|
2541
09e58f572f19
(diff-parse-differences): Small robustification --- don't lose if we
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
202 (provide 'diff)
|
09e58f572f19
(diff-parse-differences): Small robustification --- don't lose if we
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
203
|
80857
b8d11546ac61
(diff): Use buffer-local vars diff-old-file and diff-new-file
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
204 ;; arch-tag: 7de2c29b-7ea5-4b85-9b9d-72dd860de2bd
|
662
|
205 ;;; diff.el ends here
|