This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Heuristic to avoid desync if editors are confused about newline-at-eof
ClosedPublic

Authored by sammccall on Oct 7 2022, 9:40 PM.

Details

Summary

As strange as it seems to our files-are-strings view of the world, some editors
that treat files as arrays of lines can get confused about whether the last line
has a newline or not.

The consequences of failing to handle a bad incremental update are catastrophic.
If an update would be valid except for a missing newline at end of file, pretend
one exists.

This fixes problems still present in neovim where deleting all text often leads
to a desync shortly afterwards: https://github.com/neovim/neovim/issues/17085

Diff Detail

Event Timeline

sammccall created this revision.Oct 7 2022, 9:40 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 7 2022, 9:40 PM
Herald added a subscriber: arphaman. · View Herald Transcript
sammccall requested review of this revision.Oct 7 2022, 9:40 PM

Sorry to dump more patches on you, but I want your opinion on whether we should carry such a hack.

My initial inclination is no, but the class of bug is not very hard to understand, could plausibly come up in other clients, and the fix is fairly simple.
I'd like to get this bug fixed in neovim. However it's survived two attempts by me to debug it and an attempt by the maintainer to fix it!

(also the desyncs are incredibly annoying, and happen pretty much any time you clear all text out of a file)

i also would rather not have the workaround solely for an editor (we usually try to address these on editor/plugin side). i am also worried about the understanding of that inferred line afterwards (e.g. what if editor thinks that line doesn't have a trailing \n and send edits with that view of the world, or somehow attributes the \n to the next line instead)

moreover, this won't fix the issue for existing clangd's (and until the next release). so i'd rather get it fixed on the client side (and if we can't, i guess editors that can't have delta changes reliably just send full text as changes).

i also would rather not have the workaround solely for an editor (we usually try to address these on editor/plugin side).

Yeah, for sure. My main concern is that in practice it won't get fixed, but I'll open a new bug and see (the old one is closed because we thought it was fixed).

i am also worried about the understanding of that inferred line afterwards (e.g. what if editor thinks that line doesn't have a trailing \n and send edits with that view of the world, or somehow attributes the \n to the next line instead)

The former can't really happen: the only edits that can touch this phantom newline either a) replace it, or b) replace text after it.
In the a) case it's gone so we'd agree with the editor, in the b) case... I can't imagine how a line-array-based editor could x on line 3 and then later claim line 2 and 3 are the same line as "I never added the newline".

moreover, this won't fix the issue for existing clangd's (and until the next release).

This is very true, though it cuts both ways: if we fix nvim then nvim 0.5-0.8 remain broken. The release & update cadence there is pretty similar to clangd.

so i'd rather get it fixed on the client side (and if we can't, i guess editors that can't have delta changes reliably just send full text as changes).

Turning off delta is an interesting idea, I'll mention that on the bug.

kadircet accepted this revision.Nov 29 2022, 3:58 AM

as discussed, this is a rather contained fix that are likely to help with other editors that might get confused with new-lines at EOF. so LGTM

This revision is now accepted and ready to land.Nov 29 2022, 3:58 AM