From 0e88a9695aa826ee4f8912593448603eeb727108 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 3 Jun 2017 13:45:59 +0100 Subject: [PATCH] Add support for more selection combining operations Change append to 'a', add select longest/shortest, union and intersection. --- src/normal.cc | 50 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/src/normal.cc b/src/normal.cc index e363fa81..11af09ab 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -1535,28 +1535,58 @@ SelectionList read_selections_from_register(char reg, Context& context) enum class CombineOp { Append, + Union, + Intersect, SelectLeftmostCursor, SelectRightmostCursor, + SelectLongest, + SelectShortest, }; CombineOp key_to_combine_op(Key key) { switch (key.key) { - case '+': return CombineOp::Append; + case 'a': return CombineOp::Append; + case 'u': return CombineOp::Union; + case 'i': return CombineOp::Intersect; case '<': return CombineOp::SelectLeftmostCursor; case '>': return CombineOp::SelectRightmostCursor; + case '+': return CombineOp::SelectLongest; + case '-': return CombineOp::SelectShortest; } throw runtime_error{format("unknown combine operator '{}'", key.key)}; } -const Selection& select_selection(const Selection& lhs, const Selection& rhs, CombineOp op) +void combine_selection(const Buffer& buffer, Selection& sel, const Selection& other, CombineOp op) { switch (op) { - case CombineOp::SelectLeftmostCursor: return lhs.cursor() < rhs.cursor() ? lhs : rhs; - case CombineOp::SelectRightmostCursor: return lhs.cursor() < rhs.cursor() ? rhs : lhs; - default: kak_assert(false); return lhs; + case CombineOp::Union: + sel.set(std::min(sel.min(), other.min()), + std::max(sel.max(), other.max())); + break; + case CombineOp::Intersect: + sel.set(std::max(sel.min(), other.min()), + std::min(sel.max(), other.max())); + break; + case CombineOp::SelectLeftmostCursor: + if (sel.cursor() > other.cursor()) + sel = other; + break; + case CombineOp::SelectRightmostCursor: + if (sel.cursor() < other.cursor()) + sel = other; + break; + case CombineOp::SelectLongest: + if (char_length(buffer, sel) < char_length(buffer, other)) + sel = other; + break; + case CombineOp::SelectShortest: + if (char_length(buffer, sel) > char_length(buffer, other)) + sel = other; + break; + default: kak_assert(false); } } @@ -1584,14 +1614,18 @@ void combine_selections(Context& context, SelectionList list, Func func) if (list.size() != sels.size()) throw runtime_error{"The two selection lists dont have the same number of elements"}; for (int i = 0; i < list.size(); ++i) - list[i] = select_selection(list[i], sels[i], op); + combine_selection(sels.buffer(), list[i], sels[i], op); list.set_main_index(sels.main_index()); } func(context, std::move(list)); }, "enter combining operator", - "'+': append lists\n" + "'a': append lists\n" + "'u': union\n" + "'i': intersection\n" "'<': select leftmost cursor\n" - "'>': select rightmost cursor\n"); + "'>': select rightmost cursor\n" + "'+': select longest\n" + "'-': select shortest\n"); } template