Add support for more selection combining operations

Change append to 'a', add select longest/shortest, union and
intersection.
This commit is contained in:
Maxime Coste 2017-06-03 13:45:59 +01:00
parent 1d74e1edaf
commit 0e88a9695a

View File

@ -1535,28 +1535,58 @@ SelectionList read_selections_from_register(char reg, Context& context)
enum class CombineOp enum class CombineOp
{ {
Append, Append,
Union,
Intersect,
SelectLeftmostCursor, SelectLeftmostCursor,
SelectRightmostCursor, SelectRightmostCursor,
SelectLongest,
SelectShortest,
}; };
CombineOp key_to_combine_op(Key key) CombineOp key_to_combine_op(Key key)
{ {
switch (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::SelectLeftmostCursor;
case '>': return CombineOp::SelectRightmostCursor; case '>': return CombineOp::SelectRightmostCursor;
case '+': return CombineOp::SelectLongest;
case '-': return CombineOp::SelectShortest;
} }
throw runtime_error{format("unknown combine operator '{}'", key.key)}; 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) switch (op)
{ {
case CombineOp::SelectLeftmostCursor: return lhs.cursor() < rhs.cursor() ? lhs : rhs; case CombineOp::Union:
case CombineOp::SelectRightmostCursor: return lhs.cursor() < rhs.cursor() ? rhs : lhs; sel.set(std::min(sel.min(), other.min()),
default: kak_assert(false); return lhs; 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()) if (list.size() != sels.size())
throw runtime_error{"The two selection lists dont have the same number of elements"}; throw runtime_error{"The two selection lists dont have the same number of elements"};
for (int i = 0; i < list.size(); ++i) 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()); list.set_main_index(sels.main_index());
} }
func(context, std::move(list)); func(context, std::move(list));
}, "enter combining operator", }, "enter combining operator",
"'+': append lists\n" "'a': append lists\n"
"'u': union\n"
"'i': intersection\n"
"'<': select leftmost cursor\n" "'<': select leftmost cursor\n"
"'>': select rightmost cursor\n"); "'>': select rightmost cursor\n"
"'+': select longest\n"
"'-': select shortest\n");
} }
template<bool combine> template<bool combine>