Subject: Re: bug#77438: [FEATURE REQUEST] Freely positioning the cursor anywhere in the buffer (Vim’s virtualedit=all Equivalent in Emacs)

From: James Cherti <[email-masked]>
Date: Thu, 3 Apr 2025 11:33:02 -0400

Hello Eli,

Thank you for your comments, which helped clarify the purpose of
this feature request.

If you have any ideas on how this could be implemented, whether or
not it involves changing the Emacs internals, please feel free to
share your insights.

--
James Cherti
GitHub: https://github.com/jamescherti
Website: https://www.jamescherti.com/

On 2025-04-02 11:22, James Cherti wrote:
> On 2025-04-02 09:25, Eli Zaretskii wrote:
>>> Date: Wed, 2 Apr 2025 09:02:04 -0400
>>> From: James Cherti <[email-masked]>
>>>
>>>>> This distinction is important because, in `virtualedit=all`, the
>>>>> absence of real spaces ensures that the undo/redo history remains
>>>>> unaffected by cursor movements alone.
>>>>
>>>> Can't one do this using overlays instead of inserting spaces?
>>>
>>> I previously attempted to implement this behavior using overlays, but
>>> I encountered an issue: when adding virtual spaces with overlays,
>>> Emacs still treated all the added spaces as a single space for
>>> movement and alignment purposes. This made precise cursor positioning
>>> difficult, as the cursor did not behave as expected when navigating or
>>> attempting to place text at arbitrary positions.
>>
>> You could either replace the overlay on each cursor motion command, or
>> set the 'cursor' property of the overlay string to tell Emacs where to
>> place the cursor, and move that property with each cursor motion
>> command.
>>
>>>> But eventually, you'd need to insert spaces, if you actually type
>>>> something wherever you move cursor.  So maybe an easier way is to use
>>>> picture-mode after forcing undo to not record some commands for a
>>>> period.  (Not that I understand why not touching the undo history is
>>>> such a big deal.)
>>>
>>> One of the purposes of this bug report is to explore the possibility
>>> of implementing a feature in Emacs that allows positioning the cursor
>>> anywhere within the buffer. This would benefit not only modes like
>>> picture-mode, but also indentation-sensitive modes such as Python
>>> and YAML.
>>
>> I'm not sure I understand how this is related to indentation-sensitive
>> modes.  Can you tell more?
> 
> When navigating up or down, a cursor that shifts left or right due to
> varying line lengths can be visually distracting and disrupt the
> editing flow. Keeping the cursor in a fixed column ensures a
> straight-line movement, making it easier to track its position and
> maintain indentation accuracy.
> 
>>> Not recording cursor movement in the undo history is advantageous
>>> because it prevents unnecessary undo entries from being created. This
>>> helps keep the undo tree clean and ensures that reverting meaningful
>>> edits remains efficient and straightforward.
>>
>> Emacs normally records cursor motion commands in the undo list, so I'm
>> not sure I understand why undo revert commands that are not just
>> buffer text modifications would be annoying enough to justify the
>> complicated implementation you'd need to use overlays.
>>
>>> For example:
>>> - Modify line 10 (change 1).
>>> - Move the cursor down 10 times.
>>> - Modify line 21 (change 2).
>>>
>>> If undo records every cursor movement due to spaces being added
>>> multiple times, reverting to "change 1" would require 12 undo
>>> steps instead of just two, making the process inefficient.
>>
>> Yes, but this happens also in normal editing, doesn't it?
> 
> In my setup, cursor movement is only included in the undo history
> when a change is made.
> 
> I am using evil-mode and undo-fu with the following settings:
> (setq evil-want-fine-undo t)
> (setq evil-undo-system 'undo-fu)
> 
> Here is what happens in this setup:
> 1. Modify line 10 (change 1).
> 2. Move the cursor down 10 times.
> 3. Modify line 21 (change 2).
> 
> When I press u (undo) the first time, only the change on line 21 is
> undone.
> 
> When I press u (undo) again, the change on line 10 is undone.
> 
> (I don’t need to press u (undo) 10 more times to undo the cursor
> movement before I can undo the change on line 10.)
> 
> -- 
> James Cherti
> GitHub: https://github.com/jamescherti
> Website: https://www.jamescherti.com/
> 
> 
>