From dd49ab3921744930b422dc408f44206055c94cae Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 12 Jan 2017 23:32:44 -0500 Subject: [PATCH v2] Avoid inefficient regex in diff-refine-hunk (Bug#25410) * lisp/vc/diff-mode.el (diff--forward-while-leading-char): New function. (diff-refine-hunk): Use it instead of trying to match multiple lines with a single lines. --- lisp/vc/diff-mode.el | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 9dfcd94..b50b4a2 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -2062,6 +2062,15 @@ diff-refine-preproc (declare-function smerge-refine-subst "smerge-mode" (beg1 end1 beg2 end2 props-c &optional preproc props-r props-a)) +(defun diff--forward-while-leading-char (char bound) + "Move point until reaching a line not starting with CHAR. +Return new point, if it was moved." + (let ((pt nil)) + (while (and (< (point) bound) (eql (following-char) char)) + (forward-line 1) + (setq pt (point))) + pt)) + (defun diff-refine-hunk () "Highlight changes of hunk at point at a finer granularity." (interactive) @@ -2081,16 +2090,18 @@ diff-refine-hunk (goto-char beg) (pcase style (`unified - (while (re-search-forward - (eval-when-compile - (let ((no-LF-at-eol-re "\\(?:\\\\.*\n\\)?")) - (concat "^\\(?:-.*\n\\)+" no-LF-at-eol-re - "\\(\\)" - "\\(?:\\+.*\n\\)+" no-LF-at-eol-re))) - end t) - (smerge-refine-subst (match-beginning 0) (match-end 1) - (match-end 1) (match-end 0) - nil 'diff-refine-preproc props-r props-a))) + (while (re-search-forward "^-" end t) + (let ((beg-del (progn (beginning-of-line) (point))) + beg-add end-add) + (when (and (diff--forward-while-leading-char ?- end) + ;; Allow for "\ No newline at end of file". + (progn (diff--forward-while-leading-char ?\\ end) + (setq beg-add (point))) + (diff--forward-while-leading-char ?+ end) + (progn (diff--forward-while-leading-char ?\\ end) + (setq end-add (point)))) + (smerge-refine-subst beg-del beg-add beg-add end-add + nil 'diff-refine-preproc props-r props-a))))) (`context (let* ((middle (save-excursion (re-search-forward "^---"))) (other middle)) -- 2.9.3