summaryrefslogtreecommitdiff
path: root/test/normal
AgeCommit message (Collapse)Author
2025-06-26Remove spurious newline when | replaces at buffer endJohannes Altmanninger
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.
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
2025-05-11Fix <a-?> crash when first selection wrapsJohannes Altmanninger
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
2025-05-11Test for <?> dropping selections where search wrapsJohannes Altmanninger
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 "<".
2024-07-22Handle word completion when recording macrosMaxime Coste
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.
2024-07-19Record macros in repeat last insertMaxime Coste
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.
2024-02-24Make insert repeat (.) more consistentTobias Pisani
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
2023-08-14Change `+` command not to duplicate identical selections more than onceMaxime Coste
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
2023-05-09Map undo selection change to <a-u>/<a-U>Johannes Altmanninger
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.
2022-12-27Make selection undo skip over entries that are nop after buffer changeJohannes Altmanninger
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.
2022-12-27Tweak selection-undo interaction with WinDisplay hooksJohannes Altmanninger
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.
2022-12-27Add tests for selection undoJohannes Altmanninger
2022-07-05Move user mappings to <space> and keep/remove selection to ,Maxime Coste
2022-07-05Make `x` just select the full linesMaxime Coste
`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
2021-12-14Use `grep -E` as OpenBSD grep does not like `|` in regexp otherwiseSidharth Kshatriya
2021-09-30Add tests for <a-p>/<a-P>/<a-R>Maxime Coste
2021-02-25Add test for selecting horizontal whitespaceJacob Collins
2020-10-20Support explicit register for :, |, ! and $ commandsMaxime Coste
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
2020-08-02Support count argument for [s and ]sJohannes Altmanninger
Part of #795
2020-08-02Support count argument for [p and ]pJohannes Altmanninger
Part of #795
2020-08-02Move tests to accommodate tests with countJohannes Altmanninger
2020-03-02Expand env vars as list of stringsMaxime Coste
This makes it possible to do :select `%val{selections_decs}` and to correctly combine $kak_quoted with those.
2019-10-13test: Allow expect-style UI tests, testing any varJason Felice
2019-04-17Replace egrep with grepAlex Leferry 2
2018-11-27Add a test case for dropping full whitespace selections on trimMaxime Coste
2018-11-27Make '_' the default extra_word_chars, and remove built-in supportMaxime Coste
Fixes #2599
2018-10-27test: add end-extending-parent/braces for }B}B - Ref #2479Delapouite
2018-08-29Fix tests with new shell escaping syntaxMaxime Coste
2018-07-05Change `a` on end of line behaviour to be consistentMaxime Coste
`a` will just jump on next line, `a` on last end of line opens a new line beneath it. Fixes #1164
2018-07-05Fix selection save/restore from registers post selection list syntax changeMaxime Coste
2018-07-05tests: Update selections files to match the new selection list syntaxMaxime Coste
2018-07-05Fix extra-word-chars test post list option refactoringMaxime Coste
2018-06-22Use egrep instead of grep for EREdahlbaek
Some implementations of grep do not support extended regular expressions (ERE). Using egrep instead seems to be more portable.
2018-03-27Support count in <a-s> to split on groups of n linesMaxime Coste
Fixes #1966
2018-03-25Move rotate selection and rotate selection contents to ) and <a-)>Maxime Coste
Backward rotation are supported with (. Fixes #1210
2018-03-10Move WORD text object to <a-w>Maxime Coste
It improves consistency and it looked like there was support for that change on github. Fixes #1861
2018-03-04Insert: Do not move end of line on open line (o/O)Maxime Coste
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.
2018-03-02Remove <scope> from user-modes commandsDelapouite
2018-02-27Add -lock switch to enter-user-mode commandDelapouite
2018-02-25Remove avoidance of end of linesMaxime Coste
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.
2018-02-24goto last change: do not try to avoid end of linesMaxime Coste
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).
2018-02-22Merge remote-tracking branch 'Delapouite/trim'Maxime Coste
2018-02-13Add trim_selections primitiveDelapouite
2018-02-12Add declare-user-mode / enter-user-mode commandsDelapouite
2018-01-24Add unit tests for copy selections commandsMaxime Coste
2017-12-03test/: Add more tests for object selection corner casesMaxime Coste
2017-11-13Add count support to jumps (<c-o> and <c-i>). Add jumps testsDelapouite
2017-11-08Add test case for replaying insert with normal mode commandsMaxime Coste
2017-08-18Change selection extension code to be simplerMaxime Coste
Selection extension now just keeps the anchor in place insead of trying to be smart depending on the direction of selections.