Commit 3432f554 authored by Stefan Monnier's avatar Stefan Monnier

* lisp/vc/diff-mode.el: Reduce redundancy in diff-syntax-fontify code

(diff--iterate-hunks): New function extracted from diff--font-lock-refined.
(diff--font-lock-refined, diff--font-lock-syntax): Use it.
(diff--overlay-auto-delete): Rename from diff--font-lock-refine--refresh.
(diff--font-lock-syntax--refresh): Delete.
(diff-syntax-fontify-hunk): Don't completely silence errors.
(diff-syntax-fontify-props): Remove `no-init` arg, testing if `file` is
nil instead.  Adjust all callers.
(diff-syntax-fontify-props): Remove redundant code since we don't
modify the buffer.
parent fc78519b
Pipeline #832 passed with stage
in 51 minutes and 34 seconds
...@@ -1458,7 +1458,7 @@ a diff with \\[diff-reverse-direction]. ...@@ -1458,7 +1458,7 @@ a diff with \\[diff-reverse-direction].
(lambda () (diff-find-file-name nil 'noprompt))) (lambda () (diff-find-file-name nil 'noprompt)))
(add-function :filter-return (local 'filter-buffer-substring-function) (add-function :filter-return (local 'filter-buffer-substring-function)
#'diff--filter-substring) #'diff--filter-substring)
(unless (buffer-file-name) (unless buffer-file-name
(hack-dir-local-variables-non-file-buffer))) (hack-dir-local-variables-non-file-buffer)))
;;;###autoload ;;;###autoload
...@@ -2123,6 +2123,26 @@ Return new point, if it was moved." ...@@ -2123,6 +2123,26 @@ Return new point, if it was moved."
(match-end 0) end (match-end 0) end
nil #'diff-refine-preproc props-r props-a))))))) nil #'diff-refine-preproc props-r props-a)))))))
(defun diff--iterate-hunks (max fun)
"Iterate over all hunks between point and MAX.
Call FUN with two args (BEG and END) for each hunk."
(save-excursion
(let* ((beg (or (ignore-errors (diff-beginning-of-hunk))
(ignore-errors (diff-hunk-next) (point))
max)))
(while (< beg max)
(goto-char beg)
(cl-assert (looking-at diff-hunk-header-re))
(let ((end
(save-excursion (diff-end-of-hunk) (point))))
(cl-assert (< beg end))
(funcall fun beg end)
(goto-char end)
(setq beg (if (looking-at diff-hunk-header-re)
end
(or (ignore-errors (diff-hunk-next) (point))
max))))))))
(defun diff--font-lock-refined (max) (defun diff--font-lock-refined (max)
"Apply hunk refinement from font-lock." "Apply hunk refinement from font-lock."
(when diff-font-lock-refine (when diff-font-lock-refine
...@@ -2138,27 +2158,19 @@ Return new point, if it was moved." ...@@ -2138,27 +2158,19 @@ Return new point, if it was moved."
;; same hunk. ;; same hunk.
(goto-char (next-single-char-property-change (goto-char (next-single-char-property-change
(point) 'diff--font-lock-refined nil max))) (point) 'diff--font-lock-refined nil max)))
(let* ((min (point)) (diff--iterate-hunks
(beg (or (ignore-errors (diff-beginning-of-hunk)) max
(ignore-errors (diff-hunk-next) (point)) (lambda (beg end)
max))) (unless (get-char-property beg 'diff--font-lock-refined)
(while (< beg max) (diff--refine-hunk beg end)
(let ((end (let ((ol (make-overlay beg end)))
(save-excursion (goto-char beg) (diff-end-of-hunk) (point)))) (overlay-put ol 'diff--font-lock-refined t)
(if (< end min) (setq beg min)) (overlay-put ol 'diff-mode 'fine)
(unless (or (< end beg) (overlay-put ol 'evaporate t)
(get-char-property beg 'diff--font-lock-refined)) (overlay-put ol 'modification-hooks
(diff--refine-hunk beg end) '(diff--overlay-auto-delete))))))))
(let ((ol (make-overlay beg end)))
(overlay-put ol 'diff--font-lock-refined t) (defun diff--overlay-auto-delete (ol _after _beg _end &optional _len)
(overlay-put ol 'diff-mode 'fine)
(overlay-put ol 'evaporate t)
(overlay-put ol 'modification-hooks
'(diff--font-lock-refine--refresh))))
(goto-char (max beg end))
(setq beg (or (ignore-errors (diff-hunk-next) (point)) max)))))))
(defun diff--font-lock-refine--refresh (ol _after _beg _end &optional _len)
(delete-overlay ol)) (delete-overlay ol))
(defun diff-undo (&optional arg) (defun diff-undo (&optional arg)
...@@ -2365,29 +2377,17 @@ and the position in MAX." ...@@ -2365,29 +2377,17 @@ and the position in MAX."
(when (get-char-property (point) 'diff--font-lock-syntax) (when (get-char-property (point) 'diff--font-lock-syntax)
(goto-char (next-single-char-property-change (goto-char (next-single-char-property-change
(point) 'diff--font-lock-syntax nil max))) (point) 'diff--font-lock-syntax nil max)))
(let* ((min (point)) (diff--iterate-hunks
(beg (or (ignore-errors (diff-beginning-of-hunk)) max
(ignore-errors (diff-hunk-next) (point)) (lambda (beg end)
max))) (unless (get-char-property beg 'diff--font-lock-syntax)
(while (< beg max) (diff-syntax-fontify beg end)
(let ((end (let ((ol (make-overlay beg end)))
(save-excursion (goto-char beg) (diff-end-of-hunk) (point)))) (overlay-put ol 'diff--font-lock-syntax t)
(if (< end min) (setq beg min)) (overlay-put ol 'diff-mode 'syntax)
(unless (or (< end beg) (overlay-put ol 'evaporate t)
(get-char-property beg 'diff--font-lock-syntax)) (overlay-put ol 'modification-hooks
(diff-syntax-fontify beg end) '(diff--overlay-auto-delete))))))))
(let ((ol (make-overlay beg end)))
(overlay-put ol 'diff--font-lock-syntax t)
(overlay-put ol 'diff-mode 'syntax)
(overlay-put ol 'evaporate t)
(overlay-put ol 'modification-hooks
'(diff--font-lock-syntax--refresh))))
(goto-char (max beg end))
(setq beg (or (ignore-errors (diff-hunk-next) (point)) max))))))
nil)
(defun diff--font-lock-syntax--refresh (ol _after _beg _end &optional _len)
(delete-overlay ol))
(defun diff-syntax-fontify (beg end) (defun diff-syntax-fontify (beg end)
"Highlight source language syntax in diff hunk between BEG and END." "Highlight source language syntax in diff hunk between BEG and END."
...@@ -2407,7 +2407,7 @@ When OLD is non-nil, highlight the hunk from the old source." ...@@ -2407,7 +2407,7 @@ When OLD is non-nil, highlight the hunk from the old source."
(let* ((hunk (buffer-substring-no-properties beg end)) (let* ((hunk (buffer-substring-no-properties beg end))
;; Trim a trailing newline to find hunk in diff-syntax-fontify-props ;; Trim a trailing newline to find hunk in diff-syntax-fontify-props
;; in diffs that have no newline at end of diff file. ;; in diffs that have no newline at end of diff file.
(text (string-trim-right (or (ignore-errors (diff-hunk-text hunk (not old) nil)) ""))) (text (string-trim-right (or (with-demoted-errors (diff-hunk-text hunk (not old) nil)) "")))
(line (if (looking-at "\\(?:\\*\\{15\\}.*\n\\)?[-@* ]*\\([0-9,]+\\)\\([ acd+]+\\([0-9,]+\\)\\)?") (line (if (looking-at "\\(?:\\*\\{15\\}.*\n\\)?[-@* ]*\\([0-9,]+\\)\\([ acd+]+\\([0-9,]+\\)\\)?")
(if old (match-string 1) (if old (match-string 1)
(if (match-end 3) (match-string 3) (match-string 1))))) (if (match-end 3) (match-string 3) (match-string 1)))))
...@@ -2430,7 +2430,7 @@ When OLD is non-nil, highlight the hunk from the old source." ...@@ -2430,7 +2430,7 @@ When OLD is non-nil, highlight the hunk from the old source."
;; Try to reuse an existing buffer ;; Try to reuse an existing buffer
(if (get-file-buffer (expand-file-name file)) (if (get-file-buffer (expand-file-name file))
(with-current-buffer (get-file-buffer (expand-file-name file)) (with-current-buffer (get-file-buffer (expand-file-name file))
(setq props (diff-syntax-fontify-props nil text line-nb t))) (setq props (diff-syntax-fontify-props nil text line-nb)))
;; Get properties from the file ;; Get properties from the file
(with-temp-buffer (with-temp-buffer
(insert-file-contents file) (insert-file-contents file)
...@@ -2450,12 +2450,12 @@ When OLD is non-nil, highlight the hunk from the old source." ...@@ -2450,12 +2450,12 @@ When OLD is non-nil, highlight the hunk from the old source."
(puthash buffer-name buffer diff-syntax-fontify-revisions)))) (puthash buffer-name buffer diff-syntax-fontify-revisions))))
(when buffer (when buffer
(with-current-buffer buffer (with-current-buffer buffer
(setq props (diff-syntax-fontify-props file text line-nb t)))))) (setq props (diff-syntax-fontify-props file text line-nb))))))
;; If file is unavailable, get properties from the hunk alone ;; If file is unavailable, get properties from the hunk alone
(setq file (car (diff-hunk-file-names old))) (setq file (car (diff-hunk-file-names old)))
(with-temp-buffer (with-temp-buffer
(insert text) (insert text)
(setq props (diff-syntax-fontify-props file text line-nb nil t)))))) (setq props (diff-syntax-fontify-props file text line-nb t))))))
((and diff-default-directory (not (eq diff-font-lock-syntax 'hunk-only))) ((and diff-default-directory (not (eq diff-font-lock-syntax 'hunk-only)))
(let ((file (car (diff-hunk-file-names old)))) (let ((file (car (diff-hunk-file-names old))))
(if (and file (file-exists-p file) (file-regular-p file)) (if (and file (file-exists-p file) (file-regular-p file))
...@@ -2466,12 +2466,12 @@ When OLD is non-nil, highlight the hunk from the old source." ...@@ -2466,12 +2466,12 @@ When OLD is non-nil, highlight the hunk from the old source."
;; Otherwise, get properties from the hunk alone ;; Otherwise, get properties from the hunk alone
(with-temp-buffer (with-temp-buffer
(insert text) (insert text)
(setq props (diff-syntax-fontify-props file text line-nb nil t)))))) (setq props (diff-syntax-fontify-props file text line-nb t))))))
((memq diff-font-lock-syntax '(hunk-also hunk-only)) ((memq diff-font-lock-syntax '(hunk-also hunk-only))
(let ((file (car (diff-hunk-file-names old)))) (let ((file (car (diff-hunk-file-names old))))
(with-temp-buffer (with-temp-buffer
(insert text) (insert text)
(setq props (diff-syntax-fontify-props file text line-nb nil t)))))) (setq props (diff-syntax-fontify-props file text line-nb t))))))
;; Put properties over the hunk text ;; Put properties over the hunk text
(goto-char beg) (goto-char beg)
...@@ -2494,18 +2494,22 @@ When OLD is non-nil, highlight the hunk from the old source." ...@@ -2494,18 +2494,22 @@ When OLD is non-nil, highlight the hunk from the old source."
(overlay-put ol 'evaporate t) (overlay-put ol 'evaporate t)
(overlay-put ol 'face (nth 2 prop)))))))))))) (overlay-put ol 'face (nth 2 prop))))))))))))
(defun diff-syntax-fontify-props (file text line-nb &optional no-init hunk-only) (defun diff-syntax-fontify-props (file text line-nb &optional hunk-only)
"Get font-lock properties from the source code. "Get font-lock properties from the source code.
FILE is the name of the source file. TEXT is the literal source text from FILE is the name of the source file. If non-nil, it requests initialization
hunk. LINE-NB is a pair of numbers: start line number and the number of of the mode according to FILE.
TEXT is the literal source text from hunk.
LINE-NB is a pair of numbers: start line number and the number of
lines in the hunk. NO-INIT means no initialization is needed to set major lines in the hunk. NO-INIT means no initialization is needed to set major
mode. When HUNK-ONLY is non-nil, then don't verify the existence of the mode. When HUNK-ONLY is non-nil, then don't verify the existence of the
hunk text in the source file. Otherwise, don't highlight the hunk if the hunk text in the source file. Otherwise, don't highlight the hunk if the
hunk text is not found in the source file." hunk text is not found in the source file."
(unless no-init (when file
(buffer-disable-undo) ;; When initialization is requested, we should be in a brand new
(font-lock-mode -1) ;; temp buffer.
(setq buffer-file-name nil) (cl-assert (eq t buffer-undo-list))
(cl-assert (not font-lock-mode))
(cl-assert (null buffer-file-name))
(let ((enable-local-variables :safe) ;; to find `mode:' (let ((enable-local-variables :safe) ;; to find `mode:'
(buffer-file-name file)) (buffer-file-name file))
(set-auto-mode) (set-auto-mode)
...@@ -2514,7 +2518,6 @@ hunk text is not found in the source file." ...@@ -2514,7 +2518,6 @@ hunk text is not found in the source file."
(generic-mode-find-file-hook)))) (generic-mode-find-file-hook))))
(let ((font-lock-defaults (or font-lock-defaults '(nil t))) (let ((font-lock-defaults (or font-lock-defaults '(nil t)))
(inhibit-read-only t)
props beg end) props beg end)
(goto-char (point-min)) (goto-char (point-min))
(if hunk-only (if hunk-only
...@@ -2546,7 +2549,6 @@ hunk text is not found in the source file." ...@@ -2546,7 +2549,6 @@ hunk text is not found in the source file."
(when val (push (list from eol val) line-props)) (when val (push (list from eol val) line-props))
(push (nreverse line-props) props)) (push (nreverse line-props) props))
(forward-line 1))) (forward-line 1)))
(set-buffer-modified-p nil)
(nreverse props))) (nreverse props)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment