summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2019-02-21 12:09:03 -0500
committerStefan Monnier <monnier@iro.umontreal.ca>2019-02-21 12:09:03 -0500
commit3432f5545c1a0c8149d489d1df8cf1d037dae2df (patch)
tree4a55dddbc0d563afbc68e2ba7d92b6cebae3151d /lisp
parentfc78519b5e909d849ede63b537f58af8db53ceff (diff)
downloademacs-3432f5545c1a0c8149d489d1df8cf1d037dae2df.tar.gz
emacs-3432f5545c1a0c8149d489d1df8cf1d037dae2df.tar.bz2
emacs-3432f5545c1a0c8149d489d1df8cf1d037dae2df.zip
* 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.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/vc/diff-mode.el122
1 files changed, 62 insertions, 60 deletions
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 607c7b583ed..bad56391c6b 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -1458,7 +1458,7 @@ a diff with \\[diff-reverse-direction].
(lambda () (diff-find-file-name nil 'noprompt)))
(add-function :filter-return (local 'filter-buffer-substring-function)
#'diff--filter-substring)
- (unless (buffer-file-name)
+ (unless buffer-file-name
(hack-dir-local-variables-non-file-buffer)))
;;;###autoload
@@ -2123,6 +2123,26 @@ Return new point, if it was moved."
(match-end 0) end
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)
"Apply hunk refinement from font-lock."
(when diff-font-lock-refine
@@ -2138,27 +2158,19 @@ Return new point, if it was moved."
;; same hunk.
(goto-char (next-single-char-property-change
(point) 'diff--font-lock-refined nil max)))
- (let* ((min (point))
- (beg (or (ignore-errors (diff-beginning-of-hunk))
- (ignore-errors (diff-hunk-next) (point))
- max)))
- (while (< beg max)
- (let ((end
- (save-excursion (goto-char beg) (diff-end-of-hunk) (point))))
- (if (< end min) (setq beg min))
- (unless (or (< end beg)
- (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--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)
+ (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))
(defun diff-undo (&optional arg)
@@ -2365,29 +2377,17 @@ and the position in MAX."
(when (get-char-property (point) 'diff--font-lock-syntax)
(goto-char (next-single-char-property-change
(point) 'diff--font-lock-syntax nil max)))
- (let* ((min (point))
- (beg (or (ignore-errors (diff-beginning-of-hunk))
- (ignore-errors (diff-hunk-next) (point))
- max)))
- (while (< beg max)
- (let ((end
- (save-excursion (goto-char beg) (diff-end-of-hunk) (point))))
- (if (< end min) (setq beg min))
- (unless (or (< end beg)
- (get-char-property beg 'diff--font-lock-syntax))
- (diff-syntax-fontify beg end)
- (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))
+ (diff--iterate-hunks
+ max
+ (lambda (beg end)
+ (unless (get-char-property beg 'diff--font-lock-syntax)
+ (diff-syntax-fontify beg end)
+ (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--overlay-auto-delete))))))))
(defun diff-syntax-fontify (beg 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."
(let* ((hunk (buffer-substring-no-properties beg end))
;; Trim a trailing newline to find hunk in diff-syntax-fontify-props
;; 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,]+\\)\\)?")
(if old (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."
;; Try to reuse an existing buffer
(if (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
(with-temp-buffer
(insert-file-contents file)
@@ -2450,12 +2450,12 @@ When OLD is non-nil, highlight the hunk from the old source."
(puthash buffer-name buffer diff-syntax-fontify-revisions))))
(when 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
(setq file (car (diff-hunk-file-names old)))
(with-temp-buffer
(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)))
(let ((file (car (diff-hunk-file-names old))))
(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."
;; Otherwise, get properties from the hunk alone
(with-temp-buffer
(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))
(let ((file (car (diff-hunk-file-names old))))
(with-temp-buffer
(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
(goto-char beg)
@@ -2494,18 +2494,22 @@ When OLD is non-nil, highlight the hunk from the old source."
(overlay-put ol 'evaporate t)
(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.
-FILE is the name of the source file. TEXT is the literal source text from
-hunk. LINE-NB is a pair of numbers: start line number and the number of
+FILE is the name of the source file. If non-nil, it requests initialization
+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
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 is not found in the source file."
- (unless no-init
- (buffer-disable-undo)
- (font-lock-mode -1)
- (setq buffer-file-name nil)
+ (when file
+ ;; When initialization is requested, we should be in a brand new
+ ;; temp buffer.
+ (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:'
(buffer-file-name file))
(set-auto-mode)
@@ -2514,7 +2518,6 @@ hunk text is not found in the source file."
(generic-mode-find-file-hook))))
(let ((font-lock-defaults (or font-lock-defaults '(nil t)))
- (inhibit-read-only t)
props beg end)
(goto-char (point-min))
(if hunk-only
@@ -2546,7 +2549,6 @@ hunk text is not found in the source file."
(when val (push (list from eol val) line-props))
(push (nreverse line-props) props))
(forward-line 1)))
- (set-buffer-modified-p nil)
(nreverse props)))