diff --git a/doc/pages/keys.asciidoc b/doc/pages/keys.asciidoc index 5bdb7a03..1398ee75 100644 --- a/doc/pages/keys.asciidoc +++ b/doc/pages/keys.asciidoc @@ -286,6 +286,12 @@ Yanking (copying) and pasting use the *"* register by default (See <*:: merge contiguous selections together (works across lines as well) +*<+>*, **:: + duplicate each selection (generating overlapping selections) + +**, **:: + merge overlapping selections + *>*, **:: indent selected lines diff --git a/src/input_handler.cc b/src/input_handler.cc index a287b2db..e2c1bb17 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -1555,8 +1555,6 @@ private: kak_assert(false); // invalid for interactive insert break; } - if (mode != InsertMode::Append and mode != InsertMode::Replace) - selections.sort_and_merge_overlapping(); selections.check_invariant(); buffer.check_invariant(); } diff --git a/src/normal.cc b/src/normal.cc index fba39d17..53ddfdf1 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -2146,6 +2146,22 @@ void merge_consecutive(Context& context, NormalParams params) context.selections().merge_consecutive(); } +void merge_overlapping(Context& context, NormalParams params) +{ + ensure_forward(context, params); + context.selections().merge_overlapping(); +} + +void duplicate_selections(Context& context, NormalParams params) +{ + SelectionList& sels = context.selections(); + Vector new_sels; + const int count = params.count ? params.count : 2; + for (const auto& sel : sels) + new_sels.insert(new_sels.end(), count, sel); + context.selections().set(std::move(new_sels), sels.main_index() * count); +} + void force_redraw(Context& context, NormalParams) { if (context.has_client()) @@ -2258,6 +2274,8 @@ static constexpr HashMap { {alt(';')}, {"swap selections cursor and anchor", flip_selections} }, { {alt(':')}, {"ensure selection cursor is after anchor", ensure_forward} }, { {alt('_')}, {"merge consecutive selections", merge_consecutive} }, + { {'+'}, {"duplicate each selection", duplicate_selections} }, + { {alt('+')}, {"merge overlapping selections", merge_overlapping} }, { {'w'}, {"select to next word start", repeated<&select>>} }, { {'e'}, {"select to next word end", repeated>>} }, diff --git a/src/selection.cc b/src/selection.cc index 4c908efb..350b3acc 100644 --- a/src/selection.cc +++ b/src/selection.cc @@ -48,7 +48,7 @@ void SelectionList::set(Vector list, size_t main) m_selections = std::move(list); m_main = main; m_timestamp = m_buffer->timestamp(); - sort_and_merge_overlapping(); + sort(); check_invariant(); } diff --git a/test/regression/0-crash-on-pipe-with-selection-access/cmd b/test/regression/0-crash-on-pipe-with-selection-access/cmd index be5c4524..18090d7e 100644 --- a/test/regression/0-crash-on-pipe-with-selection-access/cmd +++ b/test/regression/0-crash-on-pipe-with-selection-access/cmd @@ -1 +1 @@ -%|[ $kak_selection = "bar" ] && echo "yes" +%|[ $kak_selection = "bar" ] && echo "yes" diff --git a/test/regression/1504-assertion-on-incorrect-pipe-use/cmd b/test/regression/1504-assertion-on-incorrect-pipe-use/cmd index 5c38e31d..9ac6cd2d 100644 --- a/test/regression/1504-assertion-on-incorrect-pipe-use/cmd +++ b/test/regression/1504-assertion-on-incorrect-pipe-use/cmd @@ -1 +1 @@ -2o|echo>&2 +2o|echo>&2