aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/Selection.cxx23
-rw-r--r--src/Selection.h9
-rw-r--r--test/unit/testSelection.cxx32
3 files changed, 50 insertions, 14 deletions
diff --git a/src/Selection.cxx b/src/Selection.cxx
index 7b517cc4a..20fb1efca 100644
--- a/src/Selection.cxx
+++ b/src/Selection.cxx
@@ -170,20 +170,15 @@ bool SelectionRange::ContainsCharacter(SelectionPosition spCharacter) const noex
}
SelectionSegment SelectionRange::Intersect(SelectionSegment check) const noexcept {
- const SelectionSegment inOrder(caret, anchor);
- if ((inOrder.start <= check.end) || (inOrder.end >= check.start)) {
- SelectionSegment portion = check;
- if (portion.start < inOrder.start)
- portion.start = inOrder.start;
- if (portion.end > inOrder.end)
- portion.end = inOrder.end;
- if (portion.start > portion.end)
- return SelectionSegment();
- else
- return portion;
- } else {
- return SelectionSegment();
- }
+ const SelectionSegment inOrder = AsSegment();
+ if ((inOrder.start > check.end) || (inOrder.end < check.start)) {
+ // Nothing in common, not even touching so return empty *invalid* segment
+ return {};
+ }
+ return {
+ std::max(check.start, inOrder.start),
+ std::min(check.end, inOrder.end)
+ };
}
void SelectionRange::Swap() noexcept {
diff --git a/src/Selection.h b/src/Selection.h
index 57de92a57..8ffcbb0bb 100644
--- a/src/Selection.h
+++ b/src/Selection.h
@@ -81,6 +81,12 @@ struct SelectionSegment {
end = a;
}
}
+ constexpr SelectionSegment(Sci::Position a, Sci::Position b) :
+ SelectionSegment(SelectionPosition(a), SelectionPosition(b)) {
+ }
+ [[nodiscard]] constexpr bool operator ==(const SelectionSegment &other) const noexcept {
+ return (start == other.start) && (end == other.end);
+ }
bool Empty() const noexcept {
return start == end;
}
@@ -115,6 +121,9 @@ struct SelectionRange {
constexpr SelectionRange(Sci::Position caret_, Sci::Position anchor_) noexcept : caret(caret_), anchor(anchor_) {
}
explicit SelectionRange(std::string_view sv);
+ SelectionSegment AsSegment() const noexcept {
+ return {caret, anchor};
+ }
bool Empty() const noexcept {
return anchor == caret;
}
diff --git a/test/unit/testSelection.cxx b/test/unit/testSelection.cxx
index 64148bf61..d708607d2 100644
--- a/test/unit/testSelection.cxx
+++ b/test/unit/testSelection.cxx
@@ -162,6 +162,38 @@ TEST_CASE("SelectionRange") {
REQUIRE(range123Returned == range123);
}
+ SECTION("Intersect") {
+ constexpr SelectionSegment segmentEmpty;
+
+ // Range from 1 to 2 with 3 virtual spaces
+ const SelectionRange range123(SelectionPosition(2, 3), SelectionPosition(1));
+ const SelectionSegment segment12(1, 2);
+ const SelectionSegment inside = range123.Intersect(segment12);
+ REQUIRE(inside == segment12);
+
+ const SelectionSegment segment121(SelectionPosition(1), SelectionPosition(2, 1));
+ const SelectionSegment withVirtual = range123.Intersect(segment121);
+ REQUIRE(withVirtual == segment121);
+
+ const SelectionSegment segment052(SelectionPosition(0), SelectionPosition(5, 2));
+ const SelectionSegment internal = range123.Intersect(segment052); // All inside
+ REQUIRE(internal == range123.AsSegment());
+
+ const SelectionSegment wayOut(SelectionPosition(100), SelectionPosition(105, 2));
+ const SelectionSegment nothing = range123.Intersect(wayOut);
+ REQUIRE(nothing == segmentEmpty);
+
+ const SelectionSegment edge(1, 1);
+ const SelectionSegment nowt = range123.Intersect(edge);
+ REQUIRE(nowt == edge);
+
+ // (0, 1) and (1, 2v3) touch so intersection is a single position.
+ const SelectionSegment front(0, 1);
+ const SelectionSegment single(1, 1);
+ const SelectionSegment thin = range123.Intersect(front);
+ REQUIRE(thin == single);
+ }
+
}
TEST_CASE("Selection") {