summaryrefslogtreecommitdiff
path: root/src/normal.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-06-03 13:45:59 +0100
committerMaxime Coste <mawww@kakoune.org>2017-06-03 13:45:59 +0100
commit0e88a9695aa826ee4f8912593448603eeb727108 (patch)
tree7f682a91c72ac4ea98e2d6ca249e40654330d2bb /src/normal.cc
parent1d74e1edaf022895e1a35095724890fee6db9417 (diff)
Add support for more selection combining operations
Change append to 'a', add select longest/shortest, union and intersection.
Diffstat (limited to 'src/normal.cc')
-rw-r--r--src/normal.cc50
1 files 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<bool combine>