Subject: bug#79200: 31.0.50; Duplicated elements for '#<marker at' in buffer-undo-list

From: Gerd Möllmann <[email-masked]>
Date: Tue, 12 Aug 2025 11:22:50 +0200

Helmut Eller <[email-masked]> writes:

> On Tue, Aug 12 2025, Gerd Möllmann wrote:
>
> [...]
>>> For a time we had weak-ref Lisp objects.  I suppose putting such
>>> weak-refs in the undo list would still break some code.  Instead of
>>> weak-refs one could also use another layer of indirection, e.g. put a
>>> fixnum in the undo list and the fixnum is a key in a weak hashtable that
>>> holds markers weakly.
>>
>> Yes. Or one could give markers a unique integer id, store that instead
>> of the marker itself in the marker adjustment entries. Then,
>> primitive-undo could iterate over the buffer's markers and only do
>> something for those markers it has an id entry for.
>>
>> If that would work, we wouldn't need to employ weakness, which I think
>> might be a win. It's of course fiddly again. How to find all places
>> relying on the fact that markers are in the entries, with some
>> certainty?
>
> Maybe we could create a new kind of entry, e.g
>
>   (adjust-marker MARKER-ID ADJUSTMENT)

That looks good. We could extend Elisp manual, which currently says

‘(MARKER . ADJUSTMENT)’
     This kind of element records the fact that the marker MARKER was
     relocated due to deletion of surrounding text, and that it moved
     ADJUSTMENT character positions.  If the marker's location is
     consistent with the (TEXT .  POSITION) element preceding it in the
     undo list, then undoing this element moves MARKER − ADJUSTMENT
     characters.

And the new entry would use 3 or 2 conses, but who cares.

Managing an id could be tricky though. I don't know how to handle
pdumped markers in this regard. Maybe one could arrange that pdumped
markers get ids from 0...N, or negative ones perhaps, and newly created
markers would then start with N+1 or 0. WDYT?

> instead of (MARKER . ADJUSTMENT).  Or create (apply FUN . ARGS).
>
>> What breakage are you thinking of?
>
> Code in the wild that is inspecting the undo list.

Hadn't thought about that. But I guess a new entry format would handle
that. New Emacs version, new record -> extend your hack.

Let's see what the others think about such a plan.