From 23ea6e6a5230a62fc4c183b1898efb550db0c347 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 10 May 2025 21:39:27 +0200 Subject: Work around non-forward insertions by linewise Given a buffer with two selections %(a)b%(c) Consider , which inserts all elements of the dquote register, joined to a scalar string. This insertion happens once before each selection. Let the dquote register contain "\n" and "\nd". Since the first element ends in a newline, we enable linewise paste mode. The insertion at the first selection results in: contents: \n\nd%(a)b%(c) timestamps: 11111000000000 On top of that, the insertion at the second selection would result in: contents: \n\n\n\ndd%(a)b%(c) timestamps: 1111222221000000000 Observe that the second insertion actually takes place inside the text added by the first insertion. This is because we are inserting before the current line, and the first insertion does not end in a newline. This breaks the forward change tracker's assumption that each change takes place after the previous one, causing an assertion failure. We use this data structure to translate from old to new coordinates. Specifically, after the first insertion, the selection around %(c) which is initially 1.3,1.3 needs to be updated to 3.4,3.4. Work around this by instantiating a new ForwardChangesTracker after each step. This is very ugly because it's quadratic, and because it doesn't change the fact that the second insertion is made inside the first one. I think we can revert the workaround added by this patch, see the next patch. Closes #5312 --- test/normal/paste-all-before-missing-newline/cmd | 1 + test/normal/paste-all-before-missing-newline/in | 1 + test/normal/paste-all-before-missing-newline/out | 5 +++++ test/normal/paste-all-before-missing-newline/rc | 3 +++ 4 files changed, 10 insertions(+) create mode 100644 test/normal/paste-all-before-missing-newline/cmd create mode 100644 test/normal/paste-all-before-missing-newline/in create mode 100644 test/normal/paste-all-before-missing-newline/out create mode 100644 test/normal/paste-all-before-missing-newline/rc (limited to 'test/normal') diff --git a/test/normal/paste-all-before-missing-newline/cmd b/test/normal/paste-all-before-missing-newline/cmd new file mode 100644 index 00000000..f497a3b1 --- /dev/null +++ b/test/normal/paste-all-before-missing-newline/cmd @@ -0,0 +1 @@ + diff --git a/test/normal/paste-all-before-missing-newline/in b/test/normal/paste-all-before-missing-newline/in new file mode 100644 index 00000000..49739293 --- /dev/null +++ b/test/normal/paste-all-before-missing-newline/in @@ -0,0 +1 @@ +%(a)b%(c) diff --git a/test/normal/paste-all-before-missing-newline/out b/test/normal/paste-all-before-missing-newline/out new file mode 100644 index 00000000..aef9f4e9 --- /dev/null +++ b/test/normal/paste-all-before-missing-newline/out @@ -0,0 +1,5 @@ + + + + +ddabc diff --git a/test/normal/paste-all-before-missing-newline/rc b/test/normal/paste-all-before-missing-newline/rc new file mode 100644 index 00000000..2f690299 --- /dev/null +++ b/test/normal/paste-all-before-missing-newline/rc @@ -0,0 +1,3 @@ +set-register dquote ' +' ' +d' -- cgit v1.2.3