-;;; diff-mode.el --- a mode for viewing/editing context diffs
+;;; diff-mode.el --- a mode for viewing/editing context diffs -*- lexical-binding: t -*-
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,2005, 2006,
-;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2012 Free Software Foundation, Inc.
;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
;; Keywords: convenience patch diff vc
("\C-m" . diff-goto-source)
([mouse-2] . diff-goto-source)
;; From XEmacs' diff-mode.
- ;; Standard M-w is useful, so don't change M-W.
- ;;("W" . widen)
+ ("W" . widen)
;;("." . diff-goto-source) ;display-buffer
;;("f" . diff-goto-source) ;find-file
("o" . diff-goto-source) ;other-window
;; Not useful if you have to metafy them.
;;(" " . scroll-up)
;;("\177" . scroll-down)
- ;; Standard M-a is useful, so don't change M-A.
- ;;("A" . diff-ediff-patch)
- ;; Standard M-r is useful, so don't change M-r or M-R.
- ;;("r" . diff-restrict-view)
- ;;("R" . diff-reverse-direction)
- ("g" . revert-buffer)
- ("q" . quit-window))
- "Basic keymap for `diff-mode', bound to various prefix keys.")
+ ("A" . diff-ediff-patch)
+ ("r" . diff-restrict-view)
+ ("R" . diff-reverse-direction))
+ "Basic keymap for `diff-mode', bound to various prefix keys."
+ :inherit special-mode-map)
(easy-mmode-defmap diff-mode-map
- `(("\e" . ,diff-mode-shared-map)
+ `(("\e" . ,(let ((map (make-sparse-keymap)))
+ ;; We want to inherit most bindings from diff-mode-shared-map,
+ ;; but not all since they may hide useful M-<foo> global
+ ;; bindings when editing.
+ (set-keymap-parent map diff-mode-shared-map)
+ (dolist (key '("A" "r" "R" "g" "q" "W" "z"))
+ (define-key map key nil))
+ map))
;; From compilation-minor-mode.
("\C-c\C-c" . diff-goto-source)
;; By analogy with the global C-x 4 a binding.
"Keymap for `diff-minor-mode'. See also `diff-mode-shared-map'.")
(define-minor-mode diff-auto-refine-mode
- "Automatically highlight changes in detail as the user visits hunks.
-When transitioning from disabled to enabled,
-try to refine the current hunk, as well."
+ "Toggle automatic diff hunk highlighting (Diff Auto Refine mode).
+With a prefix argument ARG, enable Diff Auto Refine mode if ARG
+is positive, and disable it otherwise. If called from Lisp,
+enable the mode if ARG is omitted or nil.
+
+Diff Auto Refine mode is a buffer-local minor mode used with
+`diff-mode'. When enabled, Emacs automatically highlights
+changes in detail as the user visits hunks. When transitioning
+from disabled to enabled, it tries to refine the current hunk, as
+well."
:group 'diff-mode :init-value t :lighter nil ;; " Auto-Refine"
(when diff-auto-refine-mode
(condition-case-no-debug nil (diff-refine-hunk) (error nil))))
(defvar diff-added-face 'diff-added)
(defface diff-changed
- '((((type tty pc) (class color) (background light))
+ ;; We normally apply a `shadow'-based face on the `diff-context'
+ ;; face, and keep `diff-changed' the default.
+ '((((class color grayscale) (min-colors 88)))
+ ;; If the terminal lacks sufficient colors for shadowing,
+ ;; highlight changed lines explicitly.
+ (((class color) (background light))
:foreground "magenta" :weight bold :slant italic)
- (((type tty pc) (class color) (background dark))
+ (((class color) (background dark))
:foreground "yellow" :weight bold :slant italic))
"`diff-mode' face used to highlight changed lines."
:group 'diff-mode)
(diff-find-file-name old noprompt (match-string 1)))
;; if all else fails, ask the user
(unless noprompt
- (let ((file (read-file-name (format "Use file %s: "
- (or (first fs) ""))
- nil (first fs) t (first fs))))
+ (let ((file (expand-file-name (or (first fs) ""))))
+ (setq file
+ (read-file-name (format "Use file %s: " file)
+ (file-name-directory file) file t
+ (file-name-nondirectory file)))
(set (make-local-variable 'diff-remembered-files-alist)
(cons (cons fs file) diff-remembered-files-alist))
file))))))
(defun diff-ediff-patch ()
"Call `ediff-patch-file' on the current buffer."
(interactive)
- (condition-case err
+ (condition-case nil
(ediff-patch-file nil (current-buffer))
(wrong-number-of-arguments (ediff-patch-file))))
(old2 (match-string 4))
(new1 (number-to-string (+ space minus)))
(new2 (number-to-string (+ space plus))))
- (if old2
- (unless (string= new2 old2) (replace-match new2 t t nil 4))
- (goto-char (match-end 4)) (insert "," new2))
- (if old1
- (unless (string= new1 old1) (replace-match new1 t t nil 2))
- (goto-char (match-end 2)) (insert "," new1))))
+ (if old2
+ (unless (string= new2 old2) (replace-match new2 t t nil 4))
+ (goto-char (match-end 3))
+ (insert "," new2))
+ (if old1
+ (unless (string= new1 old1) (replace-match new1 t t nil 2))
+ (goto-char (match-end 1))
+ (insert "," new1))))
((looking-at diff-context-mid-hunk-header-re)
(when (> (+ space bang plus) 0)
(let* ((old1 (match-string 1))
;; *-change-function is asking for trouble, whereas making them
;; from a post-command-hook doesn't pose much problems
(defvar diff-unhandled-changes nil)
-(defun diff-after-change-function (beg end len)
+(defun diff-after-change-function (beg end _len)
"Remember to fixup the hunk header.
See `after-change-functions' for the meaning of BEG, END and LEN."
;; Ignoring changes when inhibit-read-only is set is strictly speaking
;; Set up `whitespace-mode' so that turning it on will show trailing
;; whitespace problems on the modified lines of the diff.
- (set (make-local-variable 'whitespace-style) '(trailing))
+ (set (make-local-variable 'whitespace-style) '(face trailing))
(set (make-local-variable 'whitespace-trailing-regexp)
"^[-\+!<>].*?\\([\t ]+\\)$")
(add-hook 'after-change-functions 'diff-after-change-function nil t)
(add-hook 'post-command-hook 'diff-post-command-hook nil t))
;; Neat trick from Dave Love to add more bindings in read-only mode:
- (lexical-let ((ro-bind (cons 'buffer-read-only diff-mode-shared-map)))
+ (let ((ro-bind (cons 'buffer-read-only diff-mode-shared-map)))
(add-to-list 'minor-mode-overriding-map-alist ro-bind)
;; Turn off this little trick in case the buffer is put in view-mode.
(add-hook 'view-mode-hook
;;;###autoload
(define-minor-mode diff-minor-mode
- "Minor mode for viewing/editing context diffs.
+ "Toggle Diff minor mode.
+With a prefix argument ARG, enable Diff minor mode if ARG is
+positive, and disable it otherwise. If called from Lisp, enable
+the mode if ARG is omitted or nil.
+
\\{diff-minor-mode-map}"
:group 'diff-mode :lighter " Diff"
;; FIXME: setup font-lock
"See whether it's possible to apply the current hunk.
With a prefix argument, try to REVERSE the hunk."
(interactive "P")
- (destructuring-bind (buf line-offset pos src dst &optional switched)
+ (destructuring-bind (buf line-offset pos src _dst &optional switched)
(diff-find-source-location nil reverse)
(set-window-point (display-buffer buf) (+ (car pos) (cdr src)))
(diff-hunk-status-msg line-offset (diff-xor reverse switched) t)))
;; This is a convenient detail when using smerge-diff.
(if event (posn-set-point (event-end event)))
(let ((rev (not (save-excursion (beginning-of-line) (looking-at "[-<]")))))
- (destructuring-bind (buf line-offset pos src dst &optional switched)
+ (destructuring-bind (buf line-offset pos src _dst &optional switched)
(diff-find-source-location other-file rev)
(pop-to-buffer buf)
(goto-char (+ (car pos) (cdr src)))
(when (looking-at diff-hunk-header-re)
(forward-line 1)
(re-search-forward "^[^ ]" nil t))
- (destructuring-bind (&optional buf line-offset pos src dst switched)
+ (destructuring-bind (&optional buf _line-offset pos src dst switched)
;; Use `noprompt' since this is used in which-func-mode and such.
(ignore-errors ;Signals errors in place of prompting.
(diff-find-source-location nil nil 'noprompt))
(replace-match (cdr (assq (char-before) '((?+ . "-") (?> . "<"))))))
)
+(declare-function smerge-refine-subst "smerge-mode"
+ (beg1 end1 beg2 end2 props &optional preproc))
+
(defun diff-refine-hunk ()
"Highlight changes of hunk at point at a finer granularity."
(interactive)
- (eval-and-compile (require 'smerge-mode))
+ (require 'smerge-mode)
(save-excursion
(diff-beginning-of-hunk 'try-harder)
- (let* ((style (diff-hunk-style)) ;Skips the hunk header as well.
+ (let* ((start (point))
+ (style (diff-hunk-style)) ;Skips the hunk header as well.
(beg (point))
(props '((diff-mode . fine) (face diff-refine-change)))
- (end (progn (diff-end-of-hunk) (point))))
+ ;; Be careful to go back to `start' so diff-end-of-hunk gets
+ ;; to read the hunk header's line info.
+ (end (progn (goto-char start) (diff-end-of-hunk) (point))))
(remove-overlays beg end 'diff-mode 'fine)
;; good to call it for each change.
(save-excursion
(goto-char (point-min))
- (let ((orig-buffer (current-buffer)))
- (condition-case nil
- ;; Call add-change-log-entry-other-window for each hunk in
- ;; the diff buffer.
- (while (progn
- (diff-hunk-next)
- ;; Move to where the changes are,
- ;; `add-change-log-entry-other-window' works better in
- ;; that case.
- (re-search-forward
- (concat "\n[!+-<>]"
- ;; If the hunk is a context hunk with an empty first
- ;; half, recognize the "--- NNN,MMM ----" line
- "\\(-- [0-9]+\\(,[0-9]+\\)? ----\n"
- ;; and skip to the next non-context line.
- "\\( .*\n\\)*[+]\\)?")
- nil t))
- (save-excursion
- ;; FIXME: this pops up windows of all the buffers.
- (add-change-log-entry nil nil t nil t)))
- ;; When there's no more hunks, diff-hunk-next signals an error.
- (error nil)))))
+ (condition-case nil
+ ;; Call add-change-log-entry-other-window for each hunk in
+ ;; the diff buffer.
+ (while (progn
+ (diff-hunk-next)
+ ;; Move to where the changes are,
+ ;; `add-change-log-entry-other-window' works better in
+ ;; that case.
+ (re-search-forward
+ (concat "\n[!+-<>]"
+ ;; If the hunk is a context hunk with an empty first
+ ;; half, recognize the "--- NNN,MMM ----" line
+ "\\(-- [0-9]+\\(,[0-9]+\\)? ----\n"
+ ;; and skip to the next non-context line.
+ "\\( .*\n\\)*[+]\\)?")
+ nil t))
+ (save-excursion
+ ;; FIXME: this pops up windows of all the buffers.
+ (add-change-log-entry nil nil t nil t)))
+ ;; When there's no more hunks, diff-hunk-next signals an error.
+ (error nil))))
;; provide the package
(provide 'diff-mode)
;; use `combine-after-change-calls' to minimize the slowdown of font-lock.
;;
-;; arch-tag: 2571d7ff-bc28-4cf9-8585-42e21890be66
;;; diff-mode.el ends here