Subject: Re: bug#65980: 30.0.50; C-e behaves surprisingly in minibuffer

From: Stephen Berman <[email-masked]>
Date: Fri, 15 Sep 2023 14:35:50 +0200

On Fri, 15 Sep 2023 08:40:25 +0300 Eli Zaretskii <[email-masked]> wrote:

>> From: Stephen Berman <[email-masked]>
>> Cc: [email-masked]
>> Date: Thu, 14 Sep 2023 22:37:41 +0200
>>
>> > It's because of fields.  If you want this to work disregarding fields,
>> > set inhibit-field-text-motion non-nil, and then C-a and C-e will do
>> > what you expect even if you enter the prompt (which has the field
>> > property).
>>
>> Yes, that makes C-e in step 6 work the same as in step 2, but it doesn't
>> explain why the two cases are different.  The point of my patch is to
>> make the behavior of C-e in the minibuffer the same in both cases.  It's
>> a change for the benefit of Emacs users, not for Elisp programmers.  Do
>> you know of any unwanted consequences of making such a change?
>
> Your patch changes one of the subroutines of next-line and
> previous-line. Those by now became very complex creatures, and handle
> many different cases of vertical cursor motion (with and without
> visual-line-mode, with and without line truncation, with and without
> R2L text, etc.)  So I hesitate to even consider it for this obscure use
> case.  I'd be much happier if the change was in move-beginning-of-line
> and move-end-of-line instead, so that it wouldn't have any chance of
> affecting other commands.  Could you try to come up with such a change
> instead?

Sure.  I think the easiest way is simply to take your observation about
inhibit-field-text-motion and confine it to the minibuffer:

diff --git a/lisp/simple.el b/lisp/simple.el
index 35dd0f59e29..1f987a30abb 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -8263,7 +8263,8 @@ move-end-of-line
       (let ((newpos
 	     (save-excursion
 	       (let ((goal-column 0)
-		     (line-move-visual nil))
+		     (line-move-visual nil)
+                     (inhibit-field-text-motion (minibufferp)))
 		 (and (line-move arg t)
 		      ;; With bidi reordering, we may not be at bol,
 		      ;; so make sure we are.

I see no need to change move-beginning-of-line, because it already
behaves the same regardless of the length of the text after the prompt,
namely, moving to the start of the text instead of the start of the
prompt, and this is useful behavior.

This does, however, raise the question of whether invoking
move-end-of-line with point within the prompt string should just move to
the end of the prompt, which would make it more like the mirror image of
move-beginning-of-line in the minibuffer.  This is easy to do for the
case of the text after the prompt extending beyond window-width:

diff --git a/lisp/simple.el b/lisp/simple.el
index 35dd0f59e29..d676fe46611 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -8265,15 +8265,16 @@ move-end-of-line
 	       (let ((goal-column 0)
 		     (line-move-visual nil))
 		 (and (line-move arg t)
-		      ;; With bidi reordering, we may not be at bol,
-		      ;; so make sure we are.
-		      (skip-chars-backward "^\n")
-		      (not (bobp))
-		      (progn
-			(while (and (not (bobp)) (invisible-p (1- (point))))
-			  (goto-char (previous-single-char-property-change
-                                      (point) 'invisible)))
-			(backward-char 1)))
+		      (if (minibufferp) t
+                        ;; With bidi reordering, we may not be at bol,
+		        ;; so make sure we are.
+		        (skip-chars-backward "^\n")
+		        (not (bobp))
+		        (progn
+                          (while (and (not (bobp)) (invisible-p (1- (point))))
+                            (goto-char (previous-single-char-property-change
+                                        (point) 'invisible)))
+                          (backward-char 1))))
 		 (point)))))
 	(goto-char newpos)
 	(if (and (> (point) newpos)

However, when the text after the prompt ends before window-width, typing
C-e with point within the prompt still moves to the end of the text,
even with this patch.  I currently don't see a way to confine the
movement to the prompt field in this case without changing line-move-1,
probably the code involving the test (zerop (vertical-motion 1)).  I
could try to do that, but maybe it's better just to retain the current
behavior of move-end-of-line in the minibuffer, but make it consistent
with respect to the length of the text after the prompt, as the first
patch does.

Steve Berman