summaryrefslogtreecommitdiff
path: root/lisp/vc/diff-mode.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/vc/diff-mode.el')
-rw-r--r--lisp/vc/diff-mode.el93
1 files changed, 61 insertions, 32 deletions
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 7a474201811..eeb32f8fe50 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -357,6 +357,18 @@ well."
:foreground "green" :extend t))
"`diff-mode' face used to highlight added lines.")
+(defface diff-changed-unspecified
+ '((default
+ :inherit diff-changed)
+ (((class color) (min-colors 88) (background light))
+ :background "grey90" :extend t)
+ (((class color) (min-colors 88) (background dark))
+ :background "grey20" :extend t)
+ (((class color))
+ :foreground "grey" :extend t))
+ "`diff-mode' face used to highlight changed lines."
+ :version "28.1")
+
(defface diff-changed
'((t nil))
"`diff-mode' face used to highlight changed lines."
@@ -436,9 +448,10 @@ well."
(defvar diff-use-changed-face (and (face-differs-from-default-p 'diff-changed)
(not (face-equal 'diff-changed 'diff-added))
(not (face-equal 'diff-changed 'diff-removed)))
- "If non-nil, use the face `diff-changed' for changed lines in context diffs.
-Otherwise, use the face `diff-removed' for removed lines,
-and the face `diff-added' for added lines.")
+ "Controls how changed lines are fontified in context diffs.
+If non-nil, use the face `diff-changed-unspecified'. Otherwise,
+use the face `diff-removed' for removed lines, and the face
+`diff-added' for added lines.")
(defvar diff-font-lock-keywords
`((,(concat "\\(" diff-hunk-header-re-unified "\\)\\(.*\\)$")
@@ -470,7 +483,7 @@ and the face `diff-added' for added lines.")
diff-indicator-added-face
diff-indicator-removed-face)))))
(2 (if diff-use-changed-face
- 'diff-changed
+ 'diff-changed-unspecified
;; Otherwise, use the same method as above.
(save-match-data
(let ((limit (save-excursion (diff-beginning-of-hunk))))
@@ -739,7 +752,7 @@ start and end positions."
"Restrict the view to the current hunk.
If the prefix ARG is given, restrict the view to the current file instead."
(interactive "P")
- (apply 'narrow-to-region
+ (apply #'narrow-to-region
(if arg (diff-bounds-of-file) (diff-bounds-of-hunk)))
(setq-local diff-narrowed-to (if arg 'file 'hunk)))
@@ -770,7 +783,7 @@ If the prefix ARG is given, restrict the view to the current file instead."
file-bounds
hunk-bounds))
(inhibit-read-only t))
- (apply 'kill-region bounds)
+ (apply #'kill-region bounds)
(goto-char (car bounds))
(ignore-errors (diff-beginning-of-hunk t)))))
@@ -828,7 +841,7 @@ data such as \"Index: ...\" and such."
(error "No hunks")
(diff-beginning-of-hunk t)
(let ((inhibit-read-only t))
- (apply 'kill-region (diff-bounds-of-file)))
+ (apply #'kill-region (diff-bounds-of-file)))
(ignore-errors (diff-beginning-of-hunk t))))
(defun diff-kill-junk ()
@@ -956,11 +969,11 @@ If the OLD prefix arg is passed, tell the file NAME of the old file."
(list (match-string 1)))
header-files
;; this assumes that there are no spaces in filenames
- (when (re-search-backward
- "^diff \\(-\\S-+ +\\)*\\(\\S-+\\)\\( +\\(\\S-+\\)\\)?"
- nil t)
- (list (if old (match-string 2) (match-string 4))
- (if old (match-string 4) (match-string 2)))))))))
+ (and (re-search-backward "^diff " nil t)
+ (looking-at
+ "^diff \\(-[^ \t\nL]+ +\\)*\\(-L +\\S-+ +\\)*\\(\\S-+\\)\\( +\\(\\S-+\\)\\)?")
+ (list (if old (match-string 3) (match-string 5))
+ (if old (match-string 4) (match-string 3)))))))))
(defun diff-find-file-name (&optional old noprompt prefix)
"Return the file corresponding to the current patch.
@@ -1767,13 +1780,26 @@ char-offset in TEXT."
(delete-region (point-min) keep))
;; Remove line-prefix characters, and unneeded lines (unified diffs).
;; Also skip lines like "\ No newline at end of file"
- (let ((kill-chars (list (if destp ?- ?+) ?\\)))
+ (let ((kill-chars (list (if destp ?- ?+) ?\\))
+ curr-char last-char)
(goto-char (point-min))
(while (not (eobp))
- (if (memq (char-after) kill-chars)
- (delete-region (point) (progn (forward-line 1) (point)))
+ (setq curr-char (char-after))
+ (if (memq curr-char kill-chars)
+ (delete-region
+ ;; Check for "\ No newline at end of file"
+ (if (and (eq curr-char ?\\)
+ (not (eq last-char (if destp ?- ?+)))
+ (save-excursion
+ (forward-line 1)
+ (or (eobp) (and (eq last-char ?-)
+ (eq (char-after) ?+)))))
+ (max (1- (point)) (point-min))
+ (point))
+ (progn (forward-line 1) (point)))
(delete-char num-pfx-chars)
- (forward-line 1)))))
+ (forward-line 1))
+ (setq last-char curr-char))))
(let ((text (buffer-substring-no-properties (point-min) (point-max))))
(if char-offset (cons text (- (point) (point-min))) text))))))
@@ -1810,7 +1836,7 @@ Whitespace differences are ignored."
(if (> (- (car forw) orig) (- orig (car back))) back forw)
(or back forw))))
-(define-obsolete-function-alias 'diff-xor 'xor "27.1")
+(define-obsolete-function-alias 'diff-xor #'xor "27.1")
(defun diff-find-source-location (&optional other-file reverse noprompt)
"Find current diff location within the source file.
@@ -1984,7 +2010,7 @@ With a prefix argument, try to REVERSE the hunk."
(diff-hunk-kill)
(diff-hunk-next)))))
-(defalias 'diff-mouse-goto-source 'diff-goto-source)
+(defalias 'diff-mouse-goto-source #'diff-goto-source)
(defun diff-goto-source (&optional other-file event)
"Jump to the corresponding source line.
@@ -2003,7 +2029,7 @@ revision of the file otherwise."
(if event (posn-set-point (event-end event)))
(let ((buffer (when event (current-buffer)))
(reverse (not (save-excursion (beginning-of-line) (looking-at "[-<]")))))
- (pcase-let ((`(,buf ,line-offset ,pos ,src ,_dst ,switched)
+ (pcase-let ((`(,buf ,_line-offset ,pos ,src ,_dst ,_switched)
(diff-find-source-location other-file reverse)))
(pop-to-buffer buf)
(goto-char (+ (car pos) (cdr src)))
@@ -2080,7 +2106,7 @@ For use in `add-log-current-defun-function'."
(write-region (concat lead (car new)) nil file2 nil 'nomessage)
(with-temp-buffer
(let ((status
- (apply 'call-process
+ (apply #'call-process
`(,diff-command nil t nil
,@opts ,file1 ,file2))))
(pcase status
@@ -2252,17 +2278,20 @@ Call FUN with two args (BEG and END) for each hunk."
;; same hunk.
(goto-char (next-single-char-property-change
(point) 'diff--font-lock-refined nil max)))
- (diff--iterate-hunks
- max
- (lambda (beg end)
- (unless (get-char-property beg 'diff--font-lock-refined)
- (diff--refine-hunk beg end)
- (let ((ol (make-overlay beg end)))
- (overlay-put ol 'diff--font-lock-refined t)
- (overlay-put ol 'diff-mode 'fine)
- (overlay-put ol 'evaporate t)
- (overlay-put ol 'modification-hooks
- '(diff--overlay-auto-delete))))))))
+ ;; Ignore errors that diff cannot be found so that custom font-lock
+ ;; keywords after `diff--font-lock-refined' can still be evaluated.
+ (ignore-error file-missing
+ (diff--iterate-hunks
+ max
+ (lambda (beg end)
+ (unless (get-char-property beg 'diff--font-lock-refined)
+ (diff--refine-hunk beg end)
+ (let ((ol (make-overlay beg end)))
+ (overlay-put ol 'diff--font-lock-refined t)
+ (overlay-put ol 'diff-mode 'fine)
+ (overlay-put ol 'evaporate t)
+ (overlay-put ol 'modification-hooks
+ '(diff--overlay-auto-delete)))))))))
(defun diff--overlay-auto-delete (ol _after _beg _end &optional _len)
(delete-overlay ol))
@@ -2826,7 +2855,7 @@ hunk text is not found in the source file."
;;; Support for converting a diff to diff3 markers via `wiggle'.
-;; Wiggle can be found at http://neil.brown.name/wiggle/ or in your nearest
+;; Wiggle can be found at https://neil.brown.name/wiggle/ or in your nearest
;; Debian repository.
(defun diff-wiggle ()