Package: emacs;
Reported by: Tino Calancha <tino.calancha <at> gmail.com>
Date: Tue, 10 Jan 2017 10:09:01 UTC
Severity: normal
Tags: fixed, patch
Found in version 26.0.50
Fixed in version 26.1
Done: npostavs <at> users.sourceforge.net
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Tino Calancha <tino.calancha <at> gmail.com> To: npostavs <at> users.sourceforge.net Cc: 25410 <at> debbugs.gnu.org, Tino Calancha <tino.calancha <at> gmail.com> Subject: bug#25410: 26.0.50; Refine an unified diff hunk only if adds lines Date: Wed, 11 Jan 2017 11:49:45 +0900
npostavs <at> users.sourceforge.net writes: > Tino Calancha <tino.calancha <at> gmail.com> writes: > >> After deletion of a large file from CVS, a diff shows >> a very large hunk with just deleted lines. Then, for unified diffs, a call >> to `diff-refine-hunk' on that hunk takes a huge time. >> Instead, it's better to first check if the hunk adds new lines: only when >> this is true, then proceed with the hunk refinement. > > What about a diff that adds a very large file? Perhaps we should only > refine if there added lines *and* deleted lines? I have updated the patch. Now it checks before the `pcase' that the hunk adds and removes lines. Only when this is true, we enter in the `pcase'. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From 0ff79ca6f106f121a05b8c5de55990b88fecb4d2 Mon Sep 17 00:00:00 2001 From: Tino Calancha <tino.calancha <at> gmail.com> Date: Wed, 11 Jan 2017 11:42:56 +0900 Subject: [PATCH] Only refine diff hunks that both remove and add lines * lisp/vc/diff-mode.el (diff-refine-hunk): Refine the hunk only if it adds and removes some lines (Bug#25410). --- lisp/vc/diff-mode.el | 77 ++++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 9dfcd944bb..f0c53e6f8a 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -2075,44 +2075,45 @@ diff-refine-hunk (props-c '((diff-mode . fine) (face diff-refine-changed))) (props-r '((diff-mode . fine) (face diff-refine-removed))) (props-a '((diff-mode . fine) (face diff-refine-added)))) - - (remove-overlays beg end 'diff-mode 'fine) - - (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))) - (`context - (let* ((middle (save-excursion (re-search-forward "^---"))) - (other middle)) - (while (re-search-forward "^\\(?:!.*\n\\)+" middle t) - (smerge-refine-subst (match-beginning 0) (match-end 0) - (save-excursion - (goto-char other) - (re-search-forward "^\\(?:!.*\n\\)+" end) - (setq other (match-end 0)) - (match-beginning 0)) - other - (if diff-use-changed-face props-c) - 'diff-refine-preproc - (unless diff-use-changed-face props-r) - (unless diff-use-changed-face props-a))))) - (_ ;; Normal diffs. - (let ((beg1 (1+ (point)))) - (when (re-search-forward "^---.*\n" end t) - ;; It's a combined add&remove, so there's something to do. - (smerge-refine-subst beg1 (match-beginning 0) - (match-end 0) end - nil 'diff-refine-preproc props-r props-a)))))))) + ;; Only refine the hunk if both adds and removes lines (Bug#25410). + (when (and (save-excursion (re-search-forward "^-.*\n" end t)) + (re-search-forward "^\\+.*\n" end t)) + (remove-overlays beg end 'diff-mode 'fine) + (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))) + (`context + (let* ((middle (save-excursion (re-search-forward "^---"))) + (other middle)) + (while (re-search-forward "^\\(?:!.*\n\\)+" middle t) + (smerge-refine-subst (match-beginning 0) (match-end 0) + (save-excursion + (goto-char other) + (re-search-forward "^\\(?:!.*\n\\)+" end) + (setq other (match-end 0)) + (match-beginning 0)) + other + (if diff-use-changed-face props-c) + 'diff-refine-preproc + (unless diff-use-changed-face props-r) + (unless diff-use-changed-face props-a))))) + (_ ;; Normal diffs. + (let ((beg1 (1+ (point)))) + (when (re-search-forward "^---.*\n" end t) + ;; It's a combined add&remove, so there's something to do. + (smerge-refine-subst beg1 (match-beginning 0) + (match-end 0) end + nil 'diff-refine-preproc props-r props-a))))))))) (defun diff-undo (&optional arg) "Perform `undo', ignoring the buffer's read-only status." -- 2.11.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.5) of 2017-01-10 Repository revision: fa0a2b4e7c81f57aecc1d94df00588a4dd5c281d
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.