- (message "Comparing RCS file %s..." new)
- (let* ((fullname (expand-file-name new))
- (rcsfile (concat (file-name-directory fullname)
- "RCS/"
- (file-name-nondirectory fullname)
- diff-rcs-extension)))
- (if (file-exists-p rcsfile)
- (diff-internal-diff "rcsdiff" (append diff-switches (list fullname)) 4)
- (error "%s does not exist" rcsfile))))
-
-(defun diff-internal-diff (diff-command sw strip)
- (let ((buffer-read-only nil))
- (with-output-to-temp-buffer "*Diff Output*"
- (buffer-disable-undo standard-output)
- (save-excursion
- (set-buffer standard-output)
- (erase-buffer)
- (apply 'call-process diff-command nil t nil sw)))
- (set-buffer "*Diff Output*")
- (goto-char (point-min))
- (while sw
- (if (string= (car sw) "-c")
- ;; strip leading filenames from context diffs
- (progn (forward-line 2) (delete-region (point-min) (point))))
- (if (and (string= (car sw) "-C") (string= "sccs" diff-command))
- ;; strip stuff from SCCS context diffs
- (progn (forward-line 2) (delete-region (point-min) (point))))
- (setq sw (cdr sw)))
- (if strip
- ;; strip stuff from SCCS context diffs
- (progn (forward-line strip) (delete-region (point-min) (point)))))
- (diff-mode)
- (if (string= "0" diff-total-differences)
- (let ((buffer-read-only nil))
- (insert (message "There are no differences.")))
- (narrow-to-region (point) (progn
- (forward-line 1)
- (if (re-search-forward diff-search-pattern
- nil t)
- (goto-char (match-beginning 0))
- (goto-char (point-max)))))
- (setq diff-current-difference "1")))
-
-;; Take a buffer full of Unix diff output and go into a mode to easily
-;; see the next and previous difference
-(defun diff-mode ()
- "Diff Mode is used by \\[diff] for perusing the output from the diff program.
-All normal editing commands are turned off. Instead, these are available:
-\\<diff-mode-map>
-\\[diff-beginning-of-diff] Move point to start of this difference.
-\\[scroll-up] Scroll to next screen of this difference.
-\\[scroll-down] Scroll to previous screen of this difference.
-\\[diff-next-difference] Move to Next Difference.
-\\[diff-previous-difference] Move to Previous Difference.
-\\[diff-show-difference] Jump to difference specified by numeric position.
-"
- (interactive)
- (use-local-map diff-mode-map)
- (setq buffer-read-only t
- major-mode 'diff-mode
- mode-name "Diff"
- mode-line-modified "--- "
- mode-line-process
- '(" " diff-current-difference "/" diff-total-differences))
- (make-local-variable 'diff-current-difference)
- (set (make-local-variable 'diff-total-differences)
- (int-to-string (diff-count-differences))))
-
-(defun diff-next-difference (n)
- "Go to the beginning of the next difference.
-Differences are delimited by `diff-search-pattern'."
- (interactive "p")
- (if (< n 0) (diff-previous-difference (- n))
- (if (zerop n) ()
- (goto-char (point-min))
- (forward-line 1) ; to get past the match for the start of this diff
- (widen)
- (if (re-search-forward diff-search-pattern nil 'move n)
- (let ((start (goto-char (match-beginning 0))))
- (forward-line 1)
- (if (re-search-forward diff-search-pattern nil 'move)
- (goto-char (match-beginning 0)))
- (narrow-to-region start (point))
- (setq diff-current-difference
- (int-to-string (+ n (string-to-int
- diff-current-difference)))))
- (re-search-backward diff-search-pattern nil)
- (narrow-to-region (point) (point-max))
- (message "No following differences.")
- (setq diff-current-difference diff-total-differences))
- (goto-char (point-min)))))
-
-(defun diff-previous-difference (n)
- "Go the the beginning of the previous difference.
-Differences are delimited by `diff-search-pattern'."
- (interactive "p")
- (if (< n 0) (diff-next-difference (- n))
- (if (zerop n) ()
- (goto-char (point-min))
- (widen)
- (if (re-search-backward diff-search-pattern nil 'move n)
- (setq diff-current-difference
- (int-to-string (- (string-to-int diff-current-difference) n)))
- (message "No previous differences.")
- (setq diff-current-difference "1"))
- (narrow-to-region (point) (progn
- (forward-line 1)
- (re-search-forward diff-search-pattern nil)
- (goto-char (match-beginning 0))))
- (goto-char (point-min)))))
-
-(defun diff-show-difference (n)
- "Show difference number N (prefix argument)."
- (interactive "p")
- (let ((cur (string-to-int diff-current-difference)))
- (cond ((or (= n cur)
- (zerop n)
- (not (natnump n))) ; should signal an error perhaps.
- ;; just redisplay.
- (goto-char (point-min)))
- ((< n cur)
- (diff-previous-difference (- cur n)))
- ((> n cur)
- (diff-next-difference (- n cur))))))
-
-(defun diff-beginning-of-diff ()
- "Go to beginning of current difference."
- (interactive)
- (goto-char (point-min)))
-
-;; This function counts up the number of differences in the buffer.
-(defun diff-count-differences ()
- "Count number of differences in the current buffer."
- (message "Counting differences...")
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (let ((cnt 0))
- (while (re-search-forward diff-search-pattern nil t)
- (setq cnt (1+ cnt)))
- (message "Counting differences...done (%d)" cnt)
- cnt))))
+;;;###autoload
+(defun diff-backup (file &optional switches)
+ "Diff this file with its backup file or vice versa.
+Uses the latest backup, if there are several numerical backups.
+If this file is a backup, diff it with its original.
+The backup file is the first file given to `diff'.
+With prefix arg, prompt for diff switches."
+ (interactive (list (read-file-name "Diff (file with backup): ")
+ (diff-switches)))
+ (let (bak ori)
+ (if (backup-file-name-p file)
+ (setq bak file
+ ori (file-name-sans-versions file))
+ (setq bak (or (diff-latest-backup-file file)
+ (error "No backup found for %s" file))
+ ori file))
+ (diff bak ori switches)))
+
+(defun diff-latest-backup-file (fn) ; actually belongs into files.el
+ "Return the latest existing backup of FILE, or nil."
+ (let ((handler (find-file-name-handler fn 'diff-latest-backup-file)))
+ (if handler
+ (funcall handler 'diff-latest-backup-file fn)
+ (file-newest-backup fn))))
+
+(provide 'diff)
+
+;;; arch-tag: 7de2c29b-7ea5-4b85-9b9d-72dd860de2bd
+;;; diff.el ends here