diff options
Diffstat (limited to 'lisp/vc/diff-mode.el')
-rw-r--r-- | lisp/vc/diff-mode.el | 93 |
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 () |