GNU bug report logs - #78113
make F-keys work in perform-replace when running Emacs in terminal

Previous Next

Package: emacs;

Reported by: Toomas Rosin <toomas <at> rosin.ee>

Date: Mon, 28 Apr 2025 13:05:04 UTC

Severity: normal

To reply to this bug, email your comments to 78113 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#78113; Package emacs. (Mon, 28 Apr 2025 13:05:05 GMT) Full text and rfc822 format available.

Acknowledgement sent to Toomas Rosin <toomas <at> rosin.ee>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 28 Apr 2025 13:05:05 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Toomas Rosin <toomas <at> rosin.ee>
To: <bug-gnu-emacs <at> gnu.org>
Subject: make F-keys work in perform-replace when running Emacs in terminal
Date: Mon, 28 Apr 2025 15:53:58 +0300
Hi,

I have found it very convenient to run replace commands (query-replace and friends) with F11 mapped to #'skip and F12 to #'act in query-replace-map.  But because perform-replace reads commands via read-event, this does not work in terminal.  (Pressing F11 or F12 does nothing and terminates the search.)  I have modified replace.el to use read-key-sequence instead of read-event, and now my setup seems to work flawlessly in terminal too:

--- replace.el.orig
+++ replace.el
@@ -2895,7 +2895,8 @@
                              "%s with %s: "
                              (substitute-command-keys
                               "(\\<query-replace-map>\\[help] for help) "))
-                     minibuffer-prompt-properties))))
+                     minibuffer-prompt-properties)))
+	 (last-input-key-sequence []))

     ;; Unless a single contiguous chunk is selected, operate on multiple chunks.
     (when region-noncontiguous-p
@@ -2916,7 +2917,7 @@

     ;; If last typed key in previous call of multi-buffer perform-replace
     ;; was `automatic-all', don't ask more questions in next files
-    (when (eq (lookup-key map (vector last-input-event) t) 'automatic-all)
+    (when (eq (lookup-key map last-input-key-sequence t) 'automatic-all)
       (setq query-flag nil multi-buffer t))

     (cond
@@ -3092,14 +3093,14 @@
 			       (match-substitute-replacement next-replacement
 							     nocasify literal))
 			   next-replacement)))
-		    (message message
-                             (query-replace-descr from-string)
-                             (query-replace-descr replacement-presentation)))
-		  (setq key (read-event))
+		    (setq key (read-key-sequence
+			       (format message
+				       (query-replace-descr from-string)
+				       (query-replace-descr replacement-presentation))))
+		    (setq last-input-key-sequence key))
 		  ;; Necessary in case something happens during
 		  ;; read-event that clobbers the match data.
 		  (set-match-data real-match-data)
-		  (setq key (vector key))
 		  (setq def (lookup-key map key t))
 		  ;; Restore the match data while we process the command.
 		  (cond ((eq def 'help)

Best regards,
T.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78113; Package emacs. (Sat, 03 May 2025 09:07:02 GMT) Full text and rfc822 format available.

Message #8 received at 78113 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Toomas Rosin <toomas <at> rosin.ee>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>, Juri Linkov <juri <at> linkov.net>
Cc: 78113 <at> debbugs.gnu.org
Subject: Re: bug#78113: make F-keys work in perform-replace when running Emacs
 in terminal
Date: Sat, 03 May 2025 12:05:50 +0300
> From: Toomas Rosin <toomas <at> rosin.ee>
> Date: Mon, 28 Apr 2025 15:53:58 +0300
> 
> Hi,
> 
> I have found it very convenient to run replace commands (query-replace and friends) with F11 mapped to #'skip and F12 to #'act in query-replace-map.  But because perform-replace reads commands via read-event, this does not work in terminal.  (Pressing F11 or F12 does nothing and terminates the search.)  I have modified replace.el to use read-key-sequence instead of read-event, and now my setup seems to work flawlessly in terminal too:
> 
> --- replace.el.orig
> +++ replace.el
> @@ -2895,7 +2895,8 @@
>                               "%s with %s: "
>                               (substitute-command-keys
>                                "(\\<query-replace-map>\\[help] for help) "))
> -                     minibuffer-prompt-properties))))
> +                     minibuffer-prompt-properties)))
> +	 (last-input-key-sequence []))
> 
>      ;; Unless a single contiguous chunk is selected, operate on multiple chunks.
>      (when region-noncontiguous-p
> @@ -2916,7 +2917,7 @@
> 
>      ;; If last typed key in previous call of multi-buffer perform-replace
>      ;; was `automatic-all', don't ask more questions in next files
> -    (when (eq (lookup-key map (vector last-input-event) t) 'automatic-all)
> +    (when (eq (lookup-key map last-input-key-sequence t) 'automatic-all)
>        (setq query-flag nil multi-buffer t))
> 
>      (cond
> @@ -3092,14 +3093,14 @@
>  			       (match-substitute-replacement next-replacement
>  							     nocasify literal))
>  			   next-replacement)))
> -		    (message message
> -                             (query-replace-descr from-string)
> -                             (query-replace-descr replacement-presentation)))
> -		  (setq key (read-event))
> +		    (setq key (read-key-sequence
> +			       (format message
> +				       (query-replace-descr from-string)
> +				       (query-replace-descr replacement-presentation))))
> +		    (setq last-input-key-sequence key))
>  		  ;; Necessary in case something happens during
>  		  ;; read-event that clobbers the match data.
>  		  (set-match-data real-match-data)
> -		  (setq key (vector key))
>  		  (setq def (lookup-key map key t))
>  		  ;; Restore the match data while we process the command.
>  		  (cond ((eq def 'help)
> 
> Best regards,
> T.

Stefan and Juri, any comments?

As usual, when replacing one input function by another, there be
dragons.  So if there's a safer way of fixing this, which would not
affect every other use case with replace commands, I'd prefer that.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78113; Package emacs. (Sat, 03 May 2025 14:31:01 GMT) Full text and rfc822 format available.

Message #11 received at 78113 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Toomas Rosin <toomas <at> rosin.ee>, 78113 <at> debbugs.gnu.org,
 Juri Linkov <juri <at> linkov.net>
Subject: Re: bug#78113: make F-keys work in perform-replace when running
 Emacs in terminal
Date: Sat, 03 May 2025 10:30:43 -0400
>> @@ -3092,14 +3093,14 @@
>>  			       (match-substitute-replacement next-replacement
>>  							     nocasify literal))
>>  			   next-replacement)))
>> -		    (message message
>> -                             (query-replace-descr from-string)
>> -                             (query-replace-descr replacement-presentation)))
>> -		  (setq key (read-event))
>> +		    (setq key (read-key-sequence
>> +			       (format message
>> +				       (query-replace-descr from-string)
>> +				       (query-replace-descr replacement-presentation))))
>> +		    (setq last-input-key-sequence key))

> Stefan and Juri, any comments?

I generally like the direction this is going.

> As usual, when replacing one input function by another, there be
> dragons.  So if there's a safer way of fixing this, which would not
> affect every other use case with replace commands, I'd prefer that.

Using `read-key` instead of `read-key-sequence` should also allow the
use of F-keys (and arrow keys, ...) but would minimize the differences
with `read-event` (since `read-key` is exactly that: a wrapper around
`read-key-sequence` which tries to minimize the differences with
`read-event`).


        Stefan


@@ -3091,18 +3091,18 @@ perform-replace
                             next-replacement nocasify literal))))
 		  ;; Bind message-log-max so we don't fill up the
 		  ;; message log with a bunch of identical messages.
-		  (let ((message-log-max nil)
-			(replacement-presentation
-			 (if query-replace-show-replacement
-			     (save-match-data
-			       (set-match-data real-match-data)
-			       (match-substitute-replacement next-replacement
-							     nocasify literal))
-			   next-replacement)))
-		    (message message
-                             (query-replace-descr from-string)
-                             (query-replace-descr replacement-presentation)))
-		  (setq key (read-event))
+		  (let* ((replacement-presentation
+			  (if query-replace-show-replacement
+			      (save-match-data
+			        (set-match-data real-match-data)
+			        (match-substitute-replacement next-replacement
+							      nocasify literal))
+			    next-replacement))
+			 (prompt
+			  (format message
+                                  (query-replace-descr from-string)
+                                  (query-replace-descr replacement-presentation))))
+		    (setq key (read-key prompt)))
 		  ;; Necessary in case something happens during
 		  ;; read-event that clobbers the match data.
 		  (set-match-data real-match-data)





This bug report was last modified today.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.