Subject: bug#11382: M-x grep sometimes mark matches erroneously

From: Troels Nielsen <[email-masked]>
Date: Mon, 30 Apr 2012 12:06:00 +0200

Hi all, and thanks for all the good work with emacs!

When running M-x grep and getting many matches, when walking through
the *grep* buffer (with <n> for example) eventually the matches will
fail to be highlighted appropriately.

To reproduce e.g.

1. emacs -Q
2. goto emacs trunk/src directory
3. M-x grep
4. Enter the command: grep -nH -e .c bytecode.c
5. Walk through the *grep* buffer with n, and notice erroneous
highlights in bytecode.c-buffer.

This patch fixes the problem for me.
It works by calculating the start-position correctly when end-col, but
not end-line is set.

I've also taken the liberty of not using loc for line in the upper
part of compilation-internal-error-properties, as I think that use is
a little confusing and possibly the cause of some bugs.

Regards
Troels

=== modified file 'lisp/progmodes/compile.el'
--- lisp/progmodes/compile.el	2012-04-09 13:05:48 +0000
+++ lisp/progmodes/compile.el	2012-04-30 09:57:39 +0000
@@ -1068,14 +1068,14 @@
 	 end-marker loc end-loc)
     (if (not (and marker (marker-buffer marker)))
 	(setq marker nil)		; no valid marker for this file
-      (setq loc (or line 1))		; normalize no linenumber to line 1
+      (unless line (setq line 1))       ; normalize no linenumber to line 1
       (catch 'marker			; find nearest loc, at least one exists
 	(dolist (x (cddr (compilation--file-struct->loc-tree
                           file-struct)))	; Loop over remaining lines.
-	  (if (> (car x) loc)		; Still bigger.
+	  (if (> (car x) line)		; Still bigger.
 	      (setq marker-line x)
-	    (if (> (- (or (car marker-line) 1) loc)
-		   (- loc (car x)))	; Current line is nearer.
+	    (if (> (- (or (car marker-line) 1) line)
+		   (- line (car x)))	; Current line is nearer.
 		(setq marker-line x))
 	    (throw 'marker t))))
       (setq marker (compilation--loc->marker (cadr marker-line))
@@ -1093,15 +1093,18 @@
 	  (save-restriction
 	    (widen)
 	    (goto-char (marker-position marker))
-	    (when (or end-col end-line)
-	      (beginning-of-line (- (or end-line line) marker-line -1))
-	      (if (or (null end-col) (< end-col 0))
-		  (end-of-line)
-		(compilation-move-to-column end-col screen-columns))
-	      (setq end-marker (point-marker)))
-	    (beginning-of-line (if end-line
-				   (- line end-line -1)
-				 (- loc marker-line -1)))
+
+            ; set end-marker if appropriate and goto line
+	    (if (not (or end-col end-line))
+                (beginning-of-line (- line marker-line -1))
+
+              (beginning-of-line (- (or end-line line) marker-line -1))
+              (if (or (null end-col) (< end-col 0))
+                  (end-of-line)
+                (compilation-move-to-column end-col screen-columns))
+              (setq end-marker (point-marker))
+              (when end-line (beginning-of-line (- line end-line -1))))
+
 	    (if col
 		(compilation-move-to-column col screen-columns)
 	      (forward-to-indentation 0))