Subject: 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: Wed, 2 Apr 2025 11:22:20 -0400

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/