| Age | Commit message (Collapse) | Author |
|
My
kak -e "exec %{%ca<ret>b<esc>%|printf '\n\n'<ret>}"
adds a spurious third line.
When we replace up to the end everything, we keep around a single
newline to uphold the buffer invariant, but that newline
Commit de1433d30 (Avoid the spurious newline insertion when replacing
at end of buffer, 2016-03-16) fixed an issue for most commands that
replace until the buffer end.
A similar issue exists for the "|" command. It triggers in fewer
cases because the replacement is implemented by applying edits
computed by the diff algorithm. It does trigger when "|" replaces
the entire buffer.
Fix that by erasing the spurious newline.
Alternatively, we could allow the diff steps of kind "remove" to
delete the entire buffer, and only restore the invariant after the
whole diff is applied. This should work because the one-past-end
position is valid for Buffer::insert() even if the buffer is empty. It
is not valid for Buffer::erase() or Buffer::advance() where count>0
but if we do that when we're already at the buffer end, that is
probably a bug in the diff. I tried this but ran into a assertion
in ForwardChangesTracker (kak_assert(change.begin >= cur_pos)).
Alternatively, we could change the diff algorithm to always insert
before deleting.
I encountered this issue when using ansi-enable on a fifo buffer.
Specifically, the first BufReadFifo hook would replace the entire
inserted text but leave around a spurious newline.
|
|
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
|
|
The <?> and <a-?> commands drop selections where the search wrapped.
If a selection is dropped this way, we adjust the new main index.
If the very first selection is dropped this way, *and* it happens to
be the main index, "--main_index" overflows and chaos ensues.
Fix this by saturating main index at zero. This seems more intuitive
than wrapping around ("% new_sels.size()").
This issue only happens to <a-?>, not <?>. When <?> wraps when starting
from the first selection, it necessarily also wraps after all other
selections. (Based on this insight, I started drafting an optimization
to skip searches whose results would be discarded anyway because they
will definitely wrap. Not sure if it's worth it, since it applies
only to the rare edge case of <?>/<a-?> with multiple selections.)
Fixes #5314
|
|
Add a test covering this branch in extend_to_next_matches():
else if (new_sels.size() <= main_index)
--main_index;
Specifically, this test would fail if the "<=" were to be replaced with "<".
|
|
Make last insert and macro recording closer together, paving the
way towards moving last insert to a register.
Use a FunctionRef for insert completer key insertion support.
|
|
This fixes an issue with the following hooks:
hook global InsertCompletionShow .* %{ map window insert <tab> <c-n> }
hook global InsertCompletionHide .* %{ unmap window insert <tab> <c-n> }
When repeating a last insert using <tab> to select a completion, it
inserts a <tab> instead of selecting, then the insert completion tries
to erase the inserted text with backspaces but fails to totally do that
as it erases the tab character first.
|
|
Insert repeat will now only record non-synthesized keys, and when played back
execute mappings as well. Constructing some tests, and with the specific goal
of fixing https://github.com/alexherbo2/auto-pairs.kak/issues/38, this appeared to
be the best approach. Other options could be evaluating the maps only when recording,
but this gave other issues (see tests/normal/repeat-insert/repeat-insert-mapped)
At this point, repeat-insert may be essentially just a hardcoded macro, at least I
haven't identified the difference. If this really is the case, it may make sense to
give it a dedicated register, and implement it as a macro.
Fixes #3600
|
|
The current exponential behaviour does not seem that useful, it seems
more predictible that pressing `+` twice would end up with 3 copies
of the original selections instead of 4.
Fixes #4533
|
|
Change the initial <c-h>/<c-k> bindings to the recently freed-up
<a-u></a-U>.
Pros:
- easier to remember
- the redo binding is logical.
- works on legacy terminals, unlike <c-h>
Cons:
- It's less convenient to toggle between selection undo and redo
keys. I think this is okay since this scenario does not happen that
often in practice.
|
|
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.
|
|
|
|
|
|
`x` is often criticized as hard to predict due to its slightly complex
behaviour of selecting next line if the current one is fully selected.
Change `x` to use the previous `<a-x>` behaviour, and change `<a-x>` to
trim to fully selected lines as `<a-X>` did.
Adapt existing indentation script to the new behaviour
|
|
|
|
|
|
|
|
Giving an explicit register uses its content for the default value
to use if the user does not enter anything. This enables:
`set-register a %{commands}; execute-keys '"a:<ret>'`
`set-register a %{shell script}; execute-keys '"a|<ret>'`
...
This provides a nice way to avoid the need to escape keys to use
those normal mode commands.
Fixes #3825
|
|
Part of #795
|
|
Part of #795
|
|
|
|
This makes it possible to do :select `%val{selections_decs}` and to
correctly combine $kak_quoted with those.
|
|
|
|
|
|
|
|
Fixes #2599
|
|
|
|
|
|
`a` will just jump on next line, `a` on last end of line opens a new
line beneath it.
Fixes #1164
|
|
|
|
|
|
|
|
Some implementations of grep do not support extended regular
expressions (ERE). Using egrep instead seems to be more portable.
|
|
Fixes #1966
|
|
Backward rotation are supported with (.
Fixes #1210
|
|
It improves consistency and it looked like there was support for that
change on github.
Fixes #1861
|
|
Change the logic of open line commands so that if a selection lies
on the end of line character of the line from which we open a new
line, that selection does not move.
If we have two clients, A and B, with B's cursor on the eol character
of line L, and A hits `o` while on line L, B's cursor should stay
on the same (logical) line. Previous behaviour would make B's cursor
jump on the newly inserted line.
|
|
|
|
|
|
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.
|
|
Avoiding end of line is a behaviour we avoid (pun intended) more and more
in Kakoune source code, now that end of lines are regularly selected, it
makes no sense to just to next line when last modification lies on an EOL
(and it probably did not make much sense back when that code was written).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Selection extension now just keeps the anchor in place insead of
trying to be smart depending on the direction of selections.
|