Fix fontification outside hunks in Git patches
* lisp/vc/diff-mode.el (diff-font-lock-keywords): Don't fontify lines in Git patches starting with + or - as added/removed, if they are either before the first hunk, or in the email signature. (Bug#75884) (diff-buffer-type): Move definition up. (diff--indicator-added-re, diff--indicator-removed-re): New variables. (diff--git-preamble-end, diff--git-footer-start) (diff--indicator-matcher-helper, diff--indicator-added-matcher) (diff--indicator-removed-matcher): New functions. * test/lisp/vc/diff-mode-tests.el (diff-mode-test-git-patch) (diff-mode-test-git-patch/before-first-hunk) (diff-mode-test-git-patch/signature): New tests. * test/lisp/vc/diff-mode-resources/git.patch: New file.
This commit is contained in:
parent
eeda2a8ab1
commit
10abb87f05
3 changed files with 146 additions and 3 deletions
|
@ -481,6 +481,59 @@ 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-buffer-type nil)
|
||||
|
||||
(defvar diff--indicator-added-re
|
||||
(rx bol
|
||||
(group (any "+>"))
|
||||
(group (zero-or-more nonl) "\n")))
|
||||
|
||||
(defvar diff--indicator-removed-re
|
||||
(rx bol
|
||||
(group (any "<-"))
|
||||
(group (zero-or-more nonl) "\n")))
|
||||
|
||||
(defun diff--git-preamble-end ()
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "^diff --git .+ .+$" nil t)
|
||||
(forward-line 2)
|
||||
(point)))
|
||||
|
||||
(defun diff--git-footer-start ()
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(re-search-backward "^-- $" nil t)
|
||||
(point)))
|
||||
|
||||
(defun diff--indicator-matcher-helper (limit regexp)
|
||||
"Fontify added/removed lines from point to LIMIT using REGEXP.
|
||||
|
||||
If this is a Git patch, don't fontify lines before the first hunk, or in
|
||||
the email signature at the end."
|
||||
(catch 'return
|
||||
(when (eq diff-buffer-type 'git)
|
||||
(let ((preamble-end (diff--git-preamble-end))
|
||||
(footer-start (diff--git-footer-start))
|
||||
(beg (point))
|
||||
(end limit))
|
||||
(cond ((or (<= end preamble-end)
|
||||
(>= beg footer-start))
|
||||
(throw 'return nil))
|
||||
;; end is after preamble, adjust beg:
|
||||
((< beg preamble-end)
|
||||
(goto-char preamble-end))
|
||||
;; beg is before footer, adjust end:
|
||||
((> end footer-start)
|
||||
(setq limit footer-start)))))
|
||||
(re-search-forward regexp limit t)))
|
||||
|
||||
(defun diff--indicator-added-matcher (limit)
|
||||
(diff--indicator-matcher-helper limit diff--indicator-added-re))
|
||||
|
||||
(defun diff--indicator-removed-matcher (limit)
|
||||
(diff--indicator-matcher-helper limit diff--indicator-removed-re))
|
||||
|
||||
(defvar diff-font-lock-keywords
|
||||
`((,(concat "\\(" diff-hunk-header-re-unified "\\)\\(.*\\)$")
|
||||
(1 'diff-hunk-header) (6 'diff-function))
|
||||
|
@ -495,9 +548,9 @@ use the face `diff-removed' for removed lines, and the face
|
|||
("^\\(---\\|\\+\\+\\+\\|\\*\\*\\*\\) \\([^\t\n]+?\\)\\(?:\t.*\\| \\(\\*\\*\\*\\*\\|----\\)\\)?\n"
|
||||
(0 'diff-header)
|
||||
(2 (if (not (match-end 3)) 'diff-file-header) prepend))
|
||||
("^\\([-<]\\)\\(.*\n\\)"
|
||||
(diff--indicator-removed-matcher
|
||||
(1 diff-indicator-removed-face) (2 'diff-removed))
|
||||
("^\\([+>]\\)\\(.*\n\\)"
|
||||
(diff--indicator-added-matcher
|
||||
(1 diff-indicator-added-face) (2 'diff-added))
|
||||
("^\\(!\\)\\(.*\n\\)"
|
||||
(1 (if diff-use-changed-face
|
||||
|
@ -562,7 +615,6 @@ See https://lists.gnu.org/r/emacs-devel/2007-11/msg01990.html")
|
|||
(defconst diff-separator-re "^--+ ?$")
|
||||
|
||||
(defvar diff-narrowed-to nil)
|
||||
(defvar diff-buffer-type nil)
|
||||
|
||||
(defun diff-hunk-style (&optional style)
|
||||
(when (looking-at diff-hunk-header-re)
|
||||
|
|
51
test/lisp/vc/diff-mode-resources/git.patch
Normal file
51
test/lisp/vc/diff-mode-resources/git.patch
Normal file
|
@ -0,0 +1,51 @@
|
|||
From 1234567890abcdef1234567890abcdef12345678 Mon Sep 17 00:00:00 2001
|
||||
From: Alyssa P. Hacker <alyssa.p.hacker@example.com>
|
||||
Date: Sun, 3 Mar 2025 10:30:00 -0400
|
||||
Subject: [PATCH] Subtle bug fixes and slight improvements
|
||||
|
||||
- This is not a removed line
|
||||
+ This is not an added line
|
||||
|
||||
---
|
||||
src/main.py | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/main.py b/src/main.py
|
||||
index 9f6c5fe43e47eab441232e54456c5c2b06297b65..7b3f91a8b4ed923c8f43183276e3ab36fe04f6c9 100644
|
||||
--- a/src/main.py
|
||||
+++ b/src/main.py
|
||||
@@ -2,25 +2,24 @@
|
||||
|
||||
def main():
|
||||
# Initialize the magic number generator
|
||||
- magic_number = 42
|
||||
- print("Magic number: ", magic_number)
|
||||
|
||||
- # TODO: Fix the infinite loop
|
||||
- while True:
|
||||
- print("This loop will never end")
|
||||
+ magic_number = 73 # After reconsidering, 73 seems more appropriate
|
||||
+ print("Updated magic number: ", magic_number)
|
||||
|
||||
+ # The infinite loop was probably not the best approach
|
||||
+ # while True:
|
||||
+ # print("This loop will never end.")
|
||||
|
||||
# This part of the code handles other important tasks
|
||||
print("Processing other tasks...")
|
||||
|
||||
# Error handling has been updated for clarity
|
||||
- if not fixed_it_yet:
|
||||
- print("ERROR: Still broken!")
|
||||
+ if not fixed_it_yet: # This should be fine now
|
||||
+ print("ERROR: No longer an issue.")
|
||||
|
||||
# Exiting the function on a positive note
|
||||
- print("Goodbye, cruel world!")
|
||||
+ print("Goodbye, world!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
--
|
||||
2.40.0
|
|
@ -557,5 +557,45 @@ baz"))))
|
|||
+1
|
||||
")))))
|
||||
|
||||
(ert-deftest diff-mode-test-git-patch ()
|
||||
(let ((file (ert-resource-file "git.patch")))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(diff-mode)
|
||||
(font-lock-ensure)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "magic_number = 42")
|
||||
(should (eq (get-text-property (match-beginning 0) 'face)
|
||||
'diff-removed))
|
||||
(re-search-forward "magic_number = 73")
|
||||
(should (eq (get-text-property (match-beginning 0) 'face)
|
||||
'diff-added)))))
|
||||
|
||||
(ert-deftest diff-mode-test-git-patch/before-first-hunk ()
|
||||
(let ((file (ert-resource-file "git.patch")))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(diff-mode)
|
||||
(font-lock-ensure)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "This is not a removed line")
|
||||
(should (eq (get-text-property (match-beginning 0) 'face)
|
||||
'diff-context))
|
||||
(re-search-forward "This is not an added line")
|
||||
(font-lock-ensure)
|
||||
(should (eq (get-text-property (match-beginning 0) 'face)
|
||||
'diff-context)))))
|
||||
|
||||
(ert-deftest diff-mode-test-git-patch/signature ()
|
||||
(let ((file (ert-resource-file "git.patch")))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(diff-mode)
|
||||
(font-lock-ensure)
|
||||
(goto-char (point-max))
|
||||
(re-search-backward "^-- $")
|
||||
(should (eq (get-text-property (match-beginning 0) 'face)
|
||||
'diff-context)))))
|
||||
|
||||
(provide 'diff-mode-tests)
|
||||
;;; diff-mode-tests.el ends here
|
||||
|
|
Loading…
Add table
Reference in a new issue