diff options
| author | Stefan Monnier | 2019-02-21 12:09:03 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2019-02-21 12:09:03 -0500 |
| commit | 3432f5545c1a0c8149d489d1df8cf1d037dae2df (patch) | |
| tree | 4a55dddbc0d563afbc68e2ba7d92b6cebae3151d | |
| parent | fc78519b5e909d849ede63b537f58af8db53ceff (diff) | |
| download | emacs-3432f5545c1a0c8149d489d1df8cf1d037dae2df.tar.gz 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.
| -rw-r--r-- | lisp/vc/diff-mode.el | 122 |
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]. | |||
| 1458 | (lambda () (diff-find-file-name nil 'noprompt))) | 1458 | (lambda () (diff-find-file-name nil 'noprompt))) |
| 1459 | (add-function :filter-return (local 'filter-buffer-substring-function) | 1459 | (add-function :filter-return (local 'filter-buffer-substring-function) |
| 1460 | #'diff--filter-substring) | 1460 | #'diff--filter-substring) |
| 1461 | (unless (buffer-file-name) | 1461 | (unless buffer-file-name |
| 1462 | (hack-dir-local-variables-non-file-buffer))) | 1462 | (hack-dir-local-variables-non-file-buffer))) |
| 1463 | 1463 | ||
| 1464 | ;;;###autoload | 1464 | ;;;###autoload |
| @@ -2123,6 +2123,26 @@ Return new point, if it was moved." | |||
| 2123 | (match-end 0) end | 2123 | (match-end 0) end |
| 2124 | nil #'diff-refine-preproc props-r props-a))))))) | 2124 | nil #'diff-refine-preproc props-r props-a))))))) |
| 2125 | 2125 | ||
| 2126 | (defun diff--iterate-hunks (max fun) | ||
| 2127 | "Iterate over all hunks between point and MAX. | ||
| 2128 | Call FUN with two args (BEG and END) for each hunk." | ||
| 2129 | (save-excursion | ||
| 2130 | (let* ((beg (or (ignore-errors (diff-beginning-of-hunk)) | ||
| 2131 | (ignore-errors (diff-hunk-next) (point)) | ||
| 2132 | max))) | ||
| 2133 | (while (< beg max) | ||
| 2134 | (goto-char beg) | ||
| 2135 | (cl-assert (looking-at diff-hunk-header-re)) | ||
| 2136 | (let ((end | ||
| 2137 | (save-excursion (diff-end-of-hunk) (point)))) | ||
| 2138 | (cl-assert (< beg end)) | ||
| 2139 | (funcall fun beg end) | ||
| 2140 | (goto-char end) | ||
| 2141 | (setq beg (if (looking-at diff-hunk-header-re) | ||
| 2142 | end | ||
| 2143 | (or (ignore-errors (diff-hunk-next) (point)) | ||
| 2144 | max)))))))) | ||
| 2145 | |||
| 2126 | (defun diff--font-lock-refined (max) | 2146 | (defun diff--font-lock-refined (max) |
| 2127 | "Apply hunk refinement from font-lock." | 2147 | "Apply hunk refinement from font-lock." |
| 2128 | (when diff-font-lock-refine | 2148 | (when diff-font-lock-refine |
| @@ -2138,27 +2158,19 @@ Return new point, if it was moved." | |||
| 2138 | ;; same hunk. | 2158 | ;; same hunk. |
| 2139 | (goto-char (next-single-char-property-change | 2159 | (goto-char (next-single-char-property-change |
| 2140 | (point) 'diff--font-lock-refined nil max))) | 2160 | (point) 'diff--font-lock-refined nil max))) |
| 2141 | (let* ((min (point)) | 2161 | (diff--iterate-hunks |
| 2142 | (beg (or (ignore-errors (diff-beginning-of-hunk)) | 2162 | max |
| 2143 | (ignore-errors (diff-hunk-next) (point)) | 2163 | (lambda (beg end) |
| 2144 | max))) | 2164 | (unless (get-char-property beg 'diff--font-lock-refined) |
| 2145 | (while (< beg max) | 2165 | (diff--refine-hunk beg end) |
| 2146 | (let ((end | 2166 | (let ((ol (make-overlay beg end))) |
| 2147 | (save-excursion (goto-char beg) (diff-end-of-hunk) (point)))) | 2167 | (overlay-put ol 'diff--font-lock-refined t) |
| 2148 | (if (< end min) (setq beg min)) | 2168 | (overlay-put ol 'diff-mode 'fine) |
| 2149 | (unless (or (< end beg) | 2169 | (overlay-put ol 'evaporate t) |
| 2150 | (get-char-property beg 'diff--font-lock-refined)) | 2170 | (overlay-put ol 'modification-hooks |
| 2151 | (diff--refine-hunk beg end) | 2171 | '(diff--overlay-auto-delete)))))))) |
| 2152 | (let ((ol (make-overlay beg end))) | 2172 | |
| 2153 | (overlay-put ol 'diff--font-lock-refined t) | 2173 | (defun diff--overlay-auto-delete (ol _after _beg _end &optional _len) |
| 2154 | (overlay-put ol 'diff-mode 'fine) | ||
| 2155 | (overlay-put ol 'evaporate t) | ||
| 2156 | (overlay-put ol 'modification-hooks | ||
| 2157 | '(diff--font-lock-refine--refresh)))) | ||
| 2158 | (goto-char (max beg end)) | ||
| 2159 | (setq beg (or (ignore-errors (diff-hunk-next) (point)) max))))))) | ||
| 2160 | |||
| 2161 | (defun diff--font-lock-refine--refresh (ol _after _beg _end &optional _len) | ||
| 2162 | (delete-overlay ol)) | 2174 | (delete-overlay ol)) |
| 2163 | 2175 | ||
| 2164 | (defun diff-undo (&optional arg) | 2176 | (defun diff-undo (&optional arg) |
| @@ -2365,29 +2377,17 @@ and the position in MAX." | |||
| 2365 | (when (get-char-property (point) 'diff--font-lock-syntax) | 2377 | (when (get-char-property (point) 'diff--font-lock-syntax) |
| 2366 | (goto-char (next-single-char-property-change | 2378 | (goto-char (next-single-char-property-change |
| 2367 | (point) 'diff--font-lock-syntax nil max))) | 2379 | (point) 'diff--font-lock-syntax nil max))) |
| 2368 | (let* ((min (point)) | 2380 | (diff--iterate-hunks |
| 2369 | (beg (or (ignore-errors (diff-beginning-of-hunk)) | 2381 | max |
| 2370 | (ignore-errors (diff-hunk-next) (point)) | 2382 | (lambda (beg end) |
| 2371 | max))) | 2383 | (unless (get-char-property beg 'diff--font-lock-syntax) |
| 2372 | (while (< beg max) | 2384 | (diff-syntax-fontify beg end) |
| 2373 | (let ((end | 2385 | (let ((ol (make-overlay beg end))) |
| 2374 | (save-excursion (goto-char beg) (diff-end-of-hunk) (point)))) | 2386 | (overlay-put ol 'diff--font-lock-syntax t) |
| 2375 | (if (< end min) (setq beg min)) | 2387 | (overlay-put ol 'diff-mode 'syntax) |
| 2376 | (unless (or (< end beg) | 2388 | (overlay-put ol 'evaporate t) |
| 2377 | (get-char-property beg 'diff--font-lock-syntax)) | 2389 | (overlay-put ol 'modification-hooks |
| 2378 | (diff-syntax-fontify beg end) | 2390 | '(diff--overlay-auto-delete)))))))) |
| 2379 | (let ((ol (make-overlay beg end))) | ||
| 2380 | (overlay-put ol 'diff--font-lock-syntax t) | ||
| 2381 | (overlay-put ol 'diff-mode 'syntax) | ||
| 2382 | (overlay-put ol 'evaporate t) | ||
| 2383 | (overlay-put ol 'modification-hooks | ||
| 2384 | '(diff--font-lock-syntax--refresh)))) | ||
| 2385 | (goto-char (max beg end)) | ||
| 2386 | (setq beg (or (ignore-errors (diff-hunk-next) (point)) max)))))) | ||
| 2387 | nil) | ||
| 2388 | |||
| 2389 | (defun diff--font-lock-syntax--refresh (ol _after _beg _end &optional _len) | ||
| 2390 | (delete-overlay ol)) | ||
| 2391 | 2391 | ||
| 2392 | (defun diff-syntax-fontify (beg end) | 2392 | (defun diff-syntax-fontify (beg end) |
| 2393 | "Highlight source language syntax in diff hunk between BEG and END." | 2393 | "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 | (let* ((hunk (buffer-substring-no-properties beg end)) | 2407 | (let* ((hunk (buffer-substring-no-properties beg end)) |
| 2408 | ;; Trim a trailing newline to find hunk in diff-syntax-fontify-props | 2408 | ;; Trim a trailing newline to find hunk in diff-syntax-fontify-props |
| 2409 | ;; in diffs that have no newline at end of diff file. | 2409 | ;; in diffs that have no newline at end of diff file. |
| 2410 | (text (string-trim-right (or (ignore-errors (diff-hunk-text hunk (not old) nil)) ""))) | 2410 | (text (string-trim-right (or (with-demoted-errors (diff-hunk-text hunk (not old) nil)) ""))) |
| 2411 | (line (if (looking-at "\\(?:\\*\\{15\\}.*\n\\)?[-@* ]*\\([0-9,]+\\)\\([ acd+]+\\([0-9,]+\\)\\)?") | 2411 | (line (if (looking-at "\\(?:\\*\\{15\\}.*\n\\)?[-@* ]*\\([0-9,]+\\)\\([ acd+]+\\([0-9,]+\\)\\)?") |
| 2412 | (if old (match-string 1) | 2412 | (if old (match-string 1) |
| 2413 | (if (match-end 3) (match-string 3) (match-string 1))))) | 2413 | (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 | ;; Try to reuse an existing buffer | 2430 | ;; Try to reuse an existing buffer |
| 2431 | (if (get-file-buffer (expand-file-name file)) | 2431 | (if (get-file-buffer (expand-file-name file)) |
| 2432 | (with-current-buffer (get-file-buffer (expand-file-name file)) | 2432 | (with-current-buffer (get-file-buffer (expand-file-name file)) |
| 2433 | (setq props (diff-syntax-fontify-props nil text line-nb t))) | 2433 | (setq props (diff-syntax-fontify-props nil text line-nb))) |
| 2434 | ;; Get properties from the file | 2434 | ;; Get properties from the file |
| 2435 | (with-temp-buffer | 2435 | (with-temp-buffer |
| 2436 | (insert-file-contents file) | 2436 | (insert-file-contents file) |
| @@ -2450,12 +2450,12 @@ When OLD is non-nil, highlight the hunk from the old source." | |||
| 2450 | (puthash buffer-name buffer diff-syntax-fontify-revisions)))) | 2450 | (puthash buffer-name buffer diff-syntax-fontify-revisions)))) |
| 2451 | (when buffer | 2451 | (when buffer |
| 2452 | (with-current-buffer buffer | 2452 | (with-current-buffer buffer |
| 2453 | (setq props (diff-syntax-fontify-props file text line-nb t)))))) | 2453 | (setq props (diff-syntax-fontify-props file text line-nb)))))) |
| 2454 | ;; If file is unavailable, get properties from the hunk alone | 2454 | ;; If file is unavailable, get properties from the hunk alone |
| 2455 | (setq file (car (diff-hunk-file-names old))) | 2455 | (setq file (car (diff-hunk-file-names old))) |
| 2456 | (with-temp-buffer | 2456 | (with-temp-buffer |
| 2457 | (insert text) | 2457 | (insert text) |
| 2458 | (setq props (diff-syntax-fontify-props file text line-nb nil t)))))) | 2458 | (setq props (diff-syntax-fontify-props file text line-nb t)))))) |
| 2459 | ((and diff-default-directory (not (eq diff-font-lock-syntax 'hunk-only))) | 2459 | ((and diff-default-directory (not (eq diff-font-lock-syntax 'hunk-only))) |
| 2460 | (let ((file (car (diff-hunk-file-names old)))) | 2460 | (let ((file (car (diff-hunk-file-names old)))) |
| 2461 | (if (and file (file-exists-p file) (file-regular-p file)) | 2461 | (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 | ;; Otherwise, get properties from the hunk alone | 2466 | ;; Otherwise, get properties from the hunk alone |
| 2467 | (with-temp-buffer | 2467 | (with-temp-buffer |
| 2468 | (insert text) | 2468 | (insert text) |
| 2469 | (setq props (diff-syntax-fontify-props file text line-nb nil t)))))) | 2469 | (setq props (diff-syntax-fontify-props file text line-nb t)))))) |
| 2470 | ((memq diff-font-lock-syntax '(hunk-also hunk-only)) | 2470 | ((memq diff-font-lock-syntax '(hunk-also hunk-only)) |
| 2471 | (let ((file (car (diff-hunk-file-names old)))) | 2471 | (let ((file (car (diff-hunk-file-names old)))) |
| 2472 | (with-temp-buffer | 2472 | (with-temp-buffer |
| 2473 | (insert text) | 2473 | (insert text) |
| 2474 | (setq props (diff-syntax-fontify-props file text line-nb nil t)))))) | 2474 | (setq props (diff-syntax-fontify-props file text line-nb t)))))) |
| 2475 | 2475 | ||
| 2476 | ;; Put properties over the hunk text | 2476 | ;; Put properties over the hunk text |
| 2477 | (goto-char beg) | 2477 | (goto-char beg) |
| @@ -2494,18 +2494,22 @@ When OLD is non-nil, highlight the hunk from the old source." | |||
| 2494 | (overlay-put ol 'evaporate t) | 2494 | (overlay-put ol 'evaporate t) |
| 2495 | (overlay-put ol 'face (nth 2 prop)))))))))))) | 2495 | (overlay-put ol 'face (nth 2 prop)))))))))))) |
| 2496 | 2496 | ||
| 2497 | (defun diff-syntax-fontify-props (file text line-nb &optional no-init hunk-only) | 2497 | (defun diff-syntax-fontify-props (file text line-nb &optional hunk-only) |
| 2498 | "Get font-lock properties from the source code. | 2498 | "Get font-lock properties from the source code. |
| 2499 | FILE is the name of the source file. TEXT is the literal source text from | 2499 | FILE is the name of the source file. If non-nil, it requests initialization |
| 2500 | hunk. LINE-NB is a pair of numbers: start line number and the number of | 2500 | of the mode according to FILE. |
| 2501 | TEXT is the literal source text from hunk. | ||
| 2502 | LINE-NB is a pair of numbers: start line number and the number of | ||
| 2501 | lines in the hunk. NO-INIT means no initialization is needed to set major | 2503 | lines in the hunk. NO-INIT means no initialization is needed to set major |
| 2502 | mode. When HUNK-ONLY is non-nil, then don't verify the existence of the | 2504 | mode. When HUNK-ONLY is non-nil, then don't verify the existence of the |
| 2503 | hunk text in the source file. Otherwise, don't highlight the hunk if the | 2505 | hunk text in the source file. Otherwise, don't highlight the hunk if the |
| 2504 | hunk text is not found in the source file." | 2506 | hunk text is not found in the source file." |
| 2505 | (unless no-init | 2507 | (when file |
| 2506 | (buffer-disable-undo) | 2508 | ;; When initialization is requested, we should be in a brand new |
| 2507 | (font-lock-mode -1) | 2509 | ;; temp buffer. |
| 2508 | (setq buffer-file-name nil) | 2510 | (cl-assert (eq t buffer-undo-list)) |
| 2511 | (cl-assert (not font-lock-mode)) | ||
| 2512 | (cl-assert (null buffer-file-name)) | ||
| 2509 | (let ((enable-local-variables :safe) ;; to find `mode:' | 2513 | (let ((enable-local-variables :safe) ;; to find `mode:' |
| 2510 | (buffer-file-name file)) | 2514 | (buffer-file-name file)) |
| 2511 | (set-auto-mode) | 2515 | (set-auto-mode) |
| @@ -2514,7 +2518,6 @@ hunk text is not found in the source file." | |||
| 2514 | (generic-mode-find-file-hook)))) | 2518 | (generic-mode-find-file-hook)))) |
| 2515 | 2519 | ||
| 2516 | (let ((font-lock-defaults (or font-lock-defaults '(nil t))) | 2520 | (let ((font-lock-defaults (or font-lock-defaults '(nil t))) |
| 2517 | (inhibit-read-only t) | ||
| 2518 | props beg end) | 2521 | props beg end) |
| 2519 | (goto-char (point-min)) | 2522 | (goto-char (point-min)) |
| 2520 | (if hunk-only | 2523 | (if hunk-only |
| @@ -2546,7 +2549,6 @@ hunk text is not found in the source file." | |||
| 2546 | (when val (push (list from eol val) line-props)) | 2549 | (when val (push (list from eol val) line-props)) |
| 2547 | (push (nreverse line-props) props)) | 2550 | (push (nreverse line-props) props)) |
| 2548 | (forward-line 1))) | 2551 | (forward-line 1))) |
| 2549 | (set-buffer-modified-p nil) | ||
| 2550 | (nreverse props))) | 2552 | (nreverse props))) |
| 2551 | 2553 | ||
| 2552 | 2554 | ||