We only grow when the ring buffer is full, which allows for a nice
simplification of the code.
Tell grow_ifn if we pushed in current or next so that we can
distinguish between filled by next or filled by current when
m_current == m_next_begin
Instead of two stacks growing from the two ends of a buffer, use
a ring buffer growing from the same mid spot.
This avoids the costly memory copy every step when we set next
threads as the current ones.
Erasing fully trimmed display atoms one by one means we have to
shift all the remaining ones every time. This is wasteful and we
can just erase all the fully trimmed atom in one go.
Fixes#4797
Previously it would result in a stray single-character selection at the
beginning of the input text.
For example:
[abcabc] -> split on 'a' -> [a][bc]a[bc]
or
[foobarfoobar] -> split on 'foo' -> [f]oo[bar]foo[bar]
Note that this behavior was not occuring if the input text was at the
beginning of the buffer
Commit 933e4a599 (Load buffer in command line order, 2022-12-06)
introduced a regression: the command
$ kak /boot/grub/grub.cfg
Fatal error: no such buffer '/boot/grub/grub.cfg'
quits with no indication of the underlying error.
Prior to 933e4a599, it would open the *scratch* buffer instead,
and show an error in the status line, pointing to the debug buffer,
which would contain:
error while opening file '/boot/grub/grub.cfg':
/boot/grub/grub.cfg: Permission denied
Let's fix this scenario by matching the old behavior.
Recent changes for selection-undo added an assertion that triggers
when a mouse-drag overlaps with an insert mode, because both events
record selection history. However this is actually fine. The one
that finishes last concludes the selection edition, while the other
one will be a nop.
The test could be simpler (i.e. not require sleeps) but I figured it
doesn't hurt add this since we don't have any comparable tests.
After buffer modification - in particular after deletion - adjacent
selection history entries may correspond to the same effective
selection when applied to the current buffer. This means that we
sometimes need to press <c-h> multiple times to make one visible
change. This is not what the user expects, so let's keep walking the
selection history until we hit an actual change.
Alternatively, we could minimize the selection history after buffer
changes but I think that would make the it worse after content
undo+redo.
Each selection undo operation is surrounded by pair of
begin_edition()/end_edition() calls.
The original reason for adding these was that in one of my preliminary
versions, a WinDisplay hook could break an undo chain, even if the
hook did not affect selections at all. This has since been fixed.
By surrounding the undo with begin_edition()/end_edition(), try to
ensure that any selection modification that happens in a WinDisplay
hook would not break the undo chain. Essentially this means that,
after using <c-h> to undo a buffer change, this was meant to
make sure that <c-k> could redo that buffer change.
However, it turns out this actually doesn't work. The attached test
case triggers an assertion. As described in the first paragraph,
the only real-world motivation for this is gone, so let's simplify
the behavior.
The assertion fix means that we can test the next commit better.
This commit fixes a bug in Buffer::advance where it would first access
m_lines[-1], and then check whether or not that access would have
segfaulted. This commit moves the check to before the segfault would
occur.
Using BufferIterator adds overhead, but we know that DisplayAtoms
cannot span multiple buffer lines and hence we can directly iterate
using char pointers.
Each draft context gets its own private copy of the selections.
Any selection changes will be thrown away when the draft context
is disposed. Since selection-undo is only supported as top-level
command, it can never be used inside a draft context, so let's stop
recording it.
No functional change.
Calculating the length of an atom means we need to decode every
codepoint and compute its column width. This can prove quite expensive
in trim_from as we can have full buffer lines, so on buffer with long
lines we might have to go through megabytes of undisplayed data.
Pass the first buffer on the the command line explicitely to client
creation. This ensure the buffer list matches the command line, which
makes buffer-next/buffer-previous a bit more useful.
Fixes#2705
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
Comparing iterators between buffers should never happen, and the
only place we did was with default constructed BufferIterator which
we replace by casting the iterator to bool.
This should improve performance on iterator heavy code.
Commit 69053d962 (Use menu behavior when completing change-directory,
2022-07-19) made ":cd dir/" actually run ":cd dir/first-subdir",
which can be surprising.
This is usually irrelevant because you rarely type the trailing slash.
However it does happen after correcting an error with `<backspace>`
and friends. For for example,
:cd d<tab>/f<backspace>
results in
:cd dir/
We should probably fix user expectations here. Do this by adding "dir/"
as valid completion. This requires us to allow empty candidates in
"RankedMatch" but there's no harm in that. This means we need to
filter out empty completions from shell-script-candidates elsewhere.
Alternative fix: we could revert 69053d962. This would remove the
convenient menu behavior but that wouldn't be a huge deal.
Fixes#4775
Mapping upper case keys is legitimate, for exampled so that they behave
the same as a lower case mapping. The current rejection of those mappings
is a misguided attempt to prevent mapping *to* upper case keys as those
will never get triggered.
Closes#4769