Subject: Re: bug#22544: 25.0.90; Long history items cause surprising positioning of cursor in minibuffer

From: Juri Linkov <[email-masked]>
Date: Sun, 07 Feb 2016 02:49:15 +0200

>> >> 1. Put the cursor at the end of the top visual line, not logical line.
>> >>    Drawback: the cursor will be in the middle of the logical line.
>> >>
>> >> 2. Go to the previous history element when the cursor is anywhere
>> >>    on any of the several visual lines of the top logical line,
>> >>    not just the top visual line.
>> >>    Drawback: can't move the cursor to the top visual line to edit text in it.
>> >>
>> >> 3. When moving the cursor from one visual line to another visual line of
>> >>    the logical line, keep the cursor at the end of the visual line.
>> >>    The problem is that this behavior should be implemented in previous-line.
>> >>
>> >> 4. Set temporary-goal-column like in the patch above, but instead of 0,
>> >>    set it to the column of the end of the top visual line, so <UP>
>> >>    will put the cursor at the end of the top visual line in your test case.
>> >
>> > Can't we special-case a line that isn't broken into several visual
>> > lines, and put the cursor at the end of such lines only?  That'd be
>> > the best.
>>
>> The problem here is that like bash and other shells with histories do,
>> we need to put the cursor at the end of the previous history element
>> so the user can start editing it immediately (usually deleting the chars
>> from the end of the logical line).  OTOH, a subsequent <UP> should
>> continue navigating the history and put the next previous element to the
>> minibuffer.  But then <UP> can't be used to move between visual lines.
>> This is a lose-lose situation, unless we'll find some clever DWIM.
>>
>> > If that is too hard, I guess 1 is the second best.  (I'm not really
>> > sure how 1 is different from 4, so maybe I actually mean 4 here.)
>>
>> 4 doesn't allow <UP> to navigate to the next previous element immediately
>> after arriving to the current previous element.
>
> Sorry, I still don't understand.  Can you give an example showing the
> difference between 1 and 4?

4 is like 1, but requires additional keystrokes from the user to
arrive to the top visual line from the end of the logical line.
Whereas 1 puts the cursor at the end of the visual line immediately
after <UP>.

I tested the implementation of 1 below, and it seems to solve the problem:

diff --git a/lisp/simple.el b/lisp/simple.el
index 72e87a4..957f2f7 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2078,7 +2078,15 @@ previous-line-or-history-element
 	   (if (= (line-number-at-pos) 1)
 	       (move-to-column (+ old-column (1- (minibuffer-prompt-end))))
 	     (move-to-column old-column))
-	 (goto-char (line-end-position)))))))
+	 ;; Put the cursor at the end of the visual line instead of the
+	 ;; logical line, so the next previous-line-or-history-element
+	 ;; would move to the previous history element, not to a possible upper
+	 ;; visual line from the end of logical line in line-move-visual mode.
+	 (end-of-visual-line)
+	 ;; Since `end-of-visual-line' puts the cursor at the beginning
+	 ;; of the next visual line, move it one char back to the end
+	 ;; of the first visual line.
+	 (unless (eolp) (backward-char 1)))))))

 (defun next-complete-history-element (n)
   "Get next history element which completes the minibuffer before the point.