| Age | Commit message (Collapse) | Author |
|
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
|
|
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
|
|
|
|
Move more code into the implementation files to reduce the amount
of code pulled by headers.
|
|
With overlapping selections, pasting after breaks assumption of
SelectionList::for_each as our changes are no longer happening in
increasing locations.
We hence cannot rely on the ForwardChangeTracker in that case and
have to rely on the more general (and more costly) ranges update logic.
This interacts poorly with paste linewise pastes and we try to preserve
the current behaviour by tracking the last paste position.
Overall, this change really begs for overlapping selections to be
removed, but we will fix them like that for now.
Fixes #4779
|
|
Closes #1468
|
|
They are quite different use cases, and this allow moving InsertMode
to input_handler.hh which is what uses it.
This also cleans up the code as we can get rid of get_insert_pos and
rely more on SelectionList::for_each.
|
|
expose that method so that various commands can take advantage of
it for performance or simplicity purposes.
|
|
This makes it unnecessary to allocate Vector<String> to insert and
allows to remove the insert_pos pointer hack by passing it to the
callback.
|
|
This is an experiment and might get reverted if overlapping selections
prove too cumbersome.
Fixes #4041
|
|
Remove the need to allocate anything when removing selections.
|
|
Fixes #3275
|
|
Do not access Buffer::m_changes to find the inserted range, return
it directly from Buffer::insert and Buffer::replace. This fixes a
wrong behaviour where replacing at eof would lose the selected end
of line (as the implementation does not actually replace that end
of line)
|
|
Closes #3201
|
|
Fixes #2724
|
|
|
|
Fixes #3194
|
|
|
|
|
|
|
|
Fixes #2861
|
|
Fixes #2829
|
|
|
|
|
|
Relying on general selection update code is error prone due to
diffing.
Fixes #2394
|
|
`a` will just jump on next line, `a` on last end of line opens a new
line beneath it.
Fixes #1164
|
|
Clamp those selection after updating them to the current timestamp
Fixes #2078
|
|
It makes more sense to use the list nature of the register to store
the selections instead of storing them as a single string separated
by spaces.
|
|
|
|
This avoids recording no-op undo groups.
|
|
This single line member function was only used once, inline it
directly.
|
|
Various places in Kakoune code used to modify selections so that
cursors would not lie on an end of line. Remove those to increase
Kakoune's consistency and simplicity.
Now that end of lines are highlighted separately, they should not
be handled specially in most commands.
|
|
Always consider that the first selection in the list is the main
one, save selections that way.
This approach was suggested by PR #1786 but the implementation here
is different, and is used more generally whenever we save selections
to strings.
This is also the prefered way to work only on the main selection:
save selections with Z, reduce to main with <space>, restore with z.
Closes #1786
Fixes #1750
|
|
Fixes #1751
|
|
Fixes #1506
Fixes #1215
|
|
|
|
|
|
Selection extension now just keeps the anchor in place insead of
trying to be smart depending on the direction of selections.
|
|
|
|
Broken by 8650c99f131aae8b10eb2141f7c2152fff25b7d1
|
|
Replacing with empty strings is essentially a deletion, which means
it can end up push some selections out of the buffer (imagine 3 a
2 empty line buffer, and deleting the second one). We are fixing
the selections in SelectionList::erase, but we were not doing that
in SelectionList::insert.
Fixes #1504
|
|
|
|
|
|
Until now, buffer had multiple recognized end coordinates, either
{ line_count, 0 } or { line_count - 1, line[line_count - 1].length }.
Now the only correct end coord is { line_count, 0 }, removing the need
for various special cases.
|
|
In certain cases, we could end up with a unsorted selection list,
leading to broken invariant.
|
|
|
|
|
|
|
|
|
|
Fixes #1053
|