summaryrefslogtreecommitdiff
path: root/test/normal/paste-all-before-missing-newline
AgeCommit message (Collapse)Author
2025-05-11Use linewise paste only if register is missing no trailing newlineJohannes Altmanninger
We use linewise paste if any of the pasted register elements has a trailing newline. As shown in the previous patch, this leads to awkward situations where insertion positions from <a-P> are not monotonically increasing. This complicated behavior is questionable. The root cause is that linewise paste may insert some strings that don't have a trailing newline. This leads to weird cases of GIGO, especially when using <a-P> when the last element is missing a trailing newline. Simplify the implementation by not activating linewise paste in that case. Instead of special-casing the last element, try to simplify the behavior further by using line-wise paste only if *all* elements are properly terminated. I can't think of a real-world case where the existing behavior would be desired. A regression test shows a change in behavior. Might be less weird now. The added test case is a copy except it uses "P" instead of "p" (the extra newline is because "d" deletes the last newline in the buffer which gets added back implicitly). (I think the list of register elements is never empty, so this should never cause a trivial linewise paste. Even if so, that would be fine because inserting nothing is a nop either way.) Fixes #5312
2025-05-11Work around non-forward insertions by linewise <a-P>Johannes Altmanninger
Given a buffer with two selections %(a)b%(c) Consider <a-P>, 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