Subject: bug#76124: eglot buffer corruption

From: João Távora <[email-masked]>
Date: Sat, 08 Feb 2025 19:55:03 +0000

Johann Höchtl <[email-masked]> writes:

On Sat, Feb 8, 2025 at 4:47 PM Johann Höchtl <[email-masked]> wrote:

>> > Possibly eglot and the interaction with "track-changes" is at
>> > fault: When I eglot-shutdown, I never see this corruption.
>> I'm guess the information about the LSP server you are using might be
>> relevant?
> I also do not know if this is relevant, but it is https://github.com/mhersson/mpls

It's normally extremely relevant, as the corruption related to
track-changes and before/after change functions (which you hint at) is
directly dependent on whether the server accepts partial updates or not.

>> > Using emacs as of commit 5e12843fa32150d2f18ce21fc6f3ae58732df6a7
>> Is that from the master branch of the Emacs Git repository?  (Your
>> report elided all version and configuration information, so it's hard
>> to tell.)

(Indeed, I don't see this commit anywhere.  What branch is this?)

Anyway, as to the problem itself, I've reproduced it.

TL/DR: Something in Eglot is making transpose-regions not work correctly
in file-less buffers.

Reproduction: 

It's kind of a fugitive bug, so here's the recipe:

- ensure you have a markdown LSP installed (marksman was easy to do)

- emacs -Q -f package-initialize /tmp/doesntexist.md -f eglot

  'package-initialize' is necessary to somehow bring in markdown.el,
  which isn't a part of Emacs.

- enter this text (disregarding this email's alignment)

  * one
    two
  * three
    four

Place text on first line and type C-c <down>, which invokes
'markdown-move-down'.  The window will scroll, when you scroll up,
you'll see the corruption.  The buffer becomes

  * three
  \@ four
  * one  four

Some notes:

- Doesn't seem to happen in file-supported buffers.

- I used the https://github.com/artempyanykh/marksman server

- track-changes.el is _not_ to blame since the most recent version of
  Eglot I'm using no longer uses that library.

- The 'marksman' server does _not_ use incremental updates, it always
  sends the full buffer text on every didChange update.

- Therefore, this is not the "normal" LSP update-related corruption
  issue.  (for context, in those issues what you see is that the server
  has a skewed image of what exactly is in the buffer, so it misses
  everything).

- I've not been able to reproduce it without Eglot.  So it seems to be
  somewhat related indeed.  It's as if Eglot and the
  'markdown-mode-down' function clashed for some reason.

- Very often, even in file-less buffers, the bug goes away and the C-c
  <up/down> switch works fine, even in Eglot.  I think actually saving
  the buffer into a file does it.

- Part of the garbled text is always invalid character NULL, which Emacs
  renders as ^@, I think.

- The problem happens simplify if you evaluate:

     (transpose-regions 1 12 13 27 nil)

  in that buffer text (the one, two... example.).

- You can also set marks on the regions and call transpose-regions
  interactively. So maybe that particular markdown.el function isn't to
  blame, but buffer settings done by 'markdown-mode' may still be.

- That's all I had time for.