Subject: Re: bug#77732: grep-edit-buffer errors with incionsistent behaviour

From: Visuwesh <[email-masked]>
Date: Fri, 11 Apr 2025 18:01:27 +0530

[வெள்ளி ஏப்ரல் 11, 2025] Eli Zaretskii wrote:

>> From: Johann Höchtl <[email-masked]>
>> Date: Fri, 11 Apr 2025 11:33:59 +0200
>> 
>> I am using Emacs from HEAD on Windows
>> 
>> I tried to reproduce the behaviour with emacs -Q but it still remains inconsistent.
>> 
>> When I rgrep and there are few results (< 15) , I can enter grep buffer pres 'e' to enter grep-edit mode, get
>> out of it with C-c C-c, re-enter with 'e' and so on.
>> 
>> When there are more results, (between 15 and 70)  I still can enter with 'e' get out with C-c C-c but when I try
>> to re-enter I get the error message Wrong type argument: stringp, nil
>> The buffer later although still in grp-mode does not behave any longer as a grep mode, 'g' or 'e' results in the
>> error Buffer is read only : #<buffer *grep*>
>> 
>> When there are many results, I get the error message Wrong type argument: stringp, nil already on the first
>> invocation attempt.
>
> I cannot reproduce this with today's master branch on MS-Windows.  I
> just tried with a Grep command that yielded 128 hits, and didn't see
> any errors.

It seems like the number of hits is specific for this bug to hit.

> Please show the complete recipe for reproducing the problem, with all
> the steps and commands explicitly shown.  It is best if you can show
> this in the Emacs source tree, so that all of us can easily try the
> same recipe with the same files.

Here's a reproduction:

  1. Download the attachment cp2k-mode.el
  2. emacs -Q
  3. M-x grep RET
  4. After '-e' in the command, type " '^(def[^ ]\+ cp2k-' cp2k-mode.el".
  5. The above grep command should produce 17 hits.
  6. Say e.
  7. Say C-c C-c.
  8. Say e.
  9. After this, move your point to "Grep finished..." message, and
     inspect the value of the text-property compilation-message.  It
     should have a non-nil value.
  10. Say C-c.
  11. Say e, and witness the reported error.

I inserted a few message statements (see patch below), and I cannot
figure out where the sudden addition in the compilation-message is
coming from.  We could bail from calling grep-edit--prepare-buffer if we
detect an occur-target-prefix text-property but there might be a deeper
seated bug somewhere.

diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index b0105f08ea2..ec2b600971c 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -1055,15 +1055,18 @@ grep
 (defun grep-edit--prepare-buffer ()
   "Mark relevant regions read-only, and add relevant occur text-properties."
   (save-excursion
+    (message "----")
     (goto-char (point-min))
     (let ((inhibit-read-only t)
           (dummy (make-marker))
           match)
-      (while (setq match (text-property-search-forward 'compilation-annotation))
+      (while (setq match (text-property-search-forward 'compilation-annotation
+                                                       nil (lambda (_val prop-val) prop-val)))
         (add-text-properties (prop-match-beginning match) (prop-match-end match)
                              '(read-only t)))
       (goto-char (point-min))
       (while (setq match (text-property-search-forward 'compilation-message))
+        (message "%S %S" (point) (get-text-property 2527 'compilation-message))
         (add-text-properties (prop-match-beginning match) (prop-match-end match)
                              '(read-only t occur-prefix t))
         (let ((loc (compilation--message->loc (prop-match-value match)))
@@ -1078,7 +1081,8 @@ grep-edit--prepare-buffer
                                     (prop-match-end match)
                                     'compilation-message)
                                    (1+ (pos-eol)))
-                               `(occur-target ((,m . ,m)))))))))
+                               `(occur-target ((,m . ,m))))))
+      (message "%S %S" (point) (get-text-property 2527 'compilation-message)))))
 
 (defvar-keymap grep-edit-mode-map
   :doc "Keymap for `grep-edit-mode'."
@@ -1109,21 +1113,26 @@ grep-change-to-grep-edit-mode
   (when (get-buffer-process (current-buffer))
     (error "Cannot switch when grep is running"))
   (use-local-map grep-edit-mode-map)
+  (message "before prep %S %S" (point) (get-text-property 2527 'compilation-message))
   (grep-edit--prepare-buffer)
+  (message "after prep %S %S" (point) (get-text-property 2527 'compilation-message))
   (setq buffer-read-only nil)
   (setq major-mode 'grep-edit-mode)
   (setq mode-name "Grep-Edit")
   (buffer-enable-undo)
+  (message "after undo %S %S" (point) (get-text-property 2527 'compilation-message))
   (set-buffer-modified-p nil)
   (setq buffer-undo-list nil)
   (add-hook 'after-change-functions #'occur-after-change-function nil t)
   (run-mode-hooks 'grep-edit-mode-hook)
+  (message "after hook %S %S" (point) (get-text-property 2527 'compilation-message))
   (message (substitute-command-keys
             "Editing: Type \\[grep-edit-save-changes] to return to Grep mode")))
 
 (defun grep-edit-save-changes ()
   "Switch back to Grep mode."
   (interactive)
+  (message "%S %S" (point) (get-text-property 2527 'compilation-message))
   (unless (derived-mode-p 'grep-edit-mode)
     (error "Not a Grep-Edit buffer"))
   (remove-hook 'after-change-functions #'occur-after-change-function t)
@@ -1134,7 +1143,8 @@ grep-edit-save-changes
   (force-mode-line-update)
   (buffer-disable-undo)
   (setq buffer-undo-list t)
-  (message "Switching to Grep mode"))
+  (message "Switching to Grep mode")
+  (message "%S %S" (point) (get-text-property 2527 'compilation-message)))
 
 ;;;###autoload
 (defun grep-find (command-args)