From 724429a7c661eeafe3094a049f747267d0496a69 Mon Sep 17 00:00:00 2001 From: Neil Date: Mon, 8 Dec 2025 14:38:07 +1100 Subject: Bug [#2488]. Fix SCI_SETSELECTIONNSTART and SCI_SETSELECTIONNEND. --- doc/ScintillaHistory.html | 12 ++++++ src/Editor.cxx | 4 +- src/Selection.cxx | 28 ++++++++++++++ src/Selection.h | 2 + test/simpleTests.py | 22 +++++++++++ test/unit/testSelection.cxx | 90 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 156 insertions(+), 2 deletions(-) diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 0cced840e..48529c8d6 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -594,6 +594,18 @@

Releases

+

+ Release 5.5.9 +

+

Release 5.5.8

diff --git a/src/Editor.cxx b/src/Editor.cxx index e7a309e67..1ad99c3ca 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -6178,11 +6178,11 @@ void Editor::SetSelectionNMessage(Message iMessage, uptr_t wParam, sptr_t lParam break; case Message::SetSelectionNStart: - sel.Range(wParam).anchor.SetPosition(lParam); + sel.Range(wParam).StartSet(SelectionPosition(lParam)); break; case Message::SetSelectionNEnd: - sel.Range(wParam).caret.SetPosition(lParam); + sel.Range(wParam).EndSet(SelectionPosition(lParam)); break; default: diff --git a/src/Selection.cxx b/src/Selection.cxx index 967033bff..e8d0148f5 100644 --- a/src/Selection.cxx +++ b/src/Selection.cxx @@ -182,6 +182,34 @@ SelectionSegment SelectionRange::Intersect(SelectionSegment check) const noexcep }; } +void SelectionRange::StartSet(SelectionPosition sp) noexcept { + if (anchor <= caret) { + anchor = sp; + if (caret < anchor) { + caret = anchor; + } + } else { + caret = sp; + if (anchor < caret) { + anchor = caret; + } + } +} + +void SelectionRange::EndSet(SelectionPosition sp) noexcept { + if (caret >= anchor) { + caret = sp; + if (anchor > caret) { + anchor = caret; + } + } else { + anchor = sp; + if (caret > anchor) { + caret = anchor; + } + } +} + void SelectionRange::Swap() noexcept { std::swap(caret, anchor); } diff --git a/src/Selection.h b/src/Selection.h index 1a57d2e78..0b3bb9159 100644 --- a/src/Selection.h +++ b/src/Selection.h @@ -156,6 +156,8 @@ struct SelectionRange { SelectionPosition End() const noexcept { return (anchor < caret) ? caret : anchor; } + void StartSet(SelectionPosition sp) noexcept; + void EndSet(SelectionPosition sp) noexcept; void Swap() noexcept; bool Trim(SelectionRange range) noexcept; void Truncate(Sci::Position length) noexcept; diff --git a/test/simpleTests.py b/test/simpleTests.py index 020b72e99..4e6a51d59 100644 --- a/test/simpleTests.py +++ b/test/simpleTests.py @@ -1967,6 +1967,28 @@ class TestMultiSelection(unittest.TestCase): self.assertEqual(self.ed.GetSelectionNStart(0), 2) self.assertEqual(self.ed.GetSelectionNEnd(0), 3) + self.ed.SetSelectionNStart(0, 1) + self.assertEqual(self.ed.GetSelectionNAnchor(0), 1) + self.assertEqual(self.ed.GetSelectionNCaret(0), 3) + self.assertEqual(self.ed.GetSelectionNStart(0), 1) + self.assertEqual(self.ed.GetSelectionNEnd(0), 3) + + self.ed.SetSelectionNAnchor(0, 2) + self.ed.SetSelectionNCaret(0, 2) + self.ed.SetSelectionNStart(0, 9) + self.assertEqual(self.ed.GetSelectionNAnchor(0), 9) + self.assertEqual(self.ed.GetSelectionNCaret(0), 9) + self.assertEqual(self.ed.GetSelectionNStart(0), 9) + self.assertEqual(self.ed.GetSelectionNEnd(0), 9) + + self.ed.SetSelectionNAnchor(0, 2) + self.ed.SetSelectionNCaret(0, 3) + self.ed.SetSelectionNStart(0, 9) + self.assertEqual(self.ed.GetSelectionNAnchor(0), 9) + self.assertEqual(self.ed.GetSelectionNCaret(0), 9) + self.assertEqual(self.ed.GetSelectionNStart(0), 9) + self.assertEqual(self.ed.GetSelectionNEnd(0), 9) + def test2Selections(self): self.ed.SetSelection(1, 2) self.ed.AddSelection(4, 5) diff --git a/test/unit/testSelection.cxx b/test/unit/testSelection.cxx index ab0065624..76eebca21 100644 --- a/test/unit/testSelection.cxx +++ b/test/unit/testSelection.cxx @@ -198,6 +198,96 @@ TEST_CASE("SelectionRange") { REQUIRE(thin == single); } + SECTION("StartEndSet") { + { + SelectionRange range; + + range.StartSet(SelectionPosition(2)); + range.EndSet(SelectionPosition(3)); + REQUIRE(range.Start() == SelectionPosition(2)); + REQUIRE(range.End() == SelectionPosition(3)); + REQUIRE(range == SelectionRange(3, 2)); + + range.StartSet(SelectionPosition(1)); + REQUIRE(range.Start() == SelectionPosition(1)); + REQUIRE(range.End() == SelectionPosition(3)); + REQUIRE(range == SelectionRange(3, 1)); + } + + { + // Outside after + SelectionRange range(2, 1); + range.StartSet(SelectionPosition(3)); + REQUIRE(range.Start() == SelectionPosition(3)); + REQUIRE(range.End() == SelectionPosition(3)); + REQUIRE(range == SelectionRange(3, 3)); + } + + { + // Outside after + SelectionRange range(2, 1); + range.EndSet(SelectionPosition(3)); + REQUIRE(range.Start() == SelectionPosition(1)); + REQUIRE(range.End() == SelectionPosition(3)); + REQUIRE(range == SelectionRange(3, 1)); + } + + { + // Outside before + SelectionRange range(2, 1); + range.StartSet(SelectionPosition(0)); + REQUIRE(range.Start() == SelectionPosition(0)); + REQUIRE(range.End() == SelectionPosition(2)); + REQUIRE(range == SelectionRange(2, 0)); + } + + { + // Outside before + SelectionRange range(2, 1); + range.EndSet(SelectionPosition(0)); + REQUIRE(range.Start() == SelectionPosition(0)); + REQUIRE(range.End() == SelectionPosition(0)); + REQUIRE(range == SelectionRange(0, 0)); + } + + { + // Inside + SelectionRange range(3, 1); + range.EndSet(SelectionPosition(2)); + REQUIRE(range.Start() == SelectionPosition(1)); + REQUIRE(range.End() == SelectionPosition(2)); + REQUIRE(range == SelectionRange(2, 1)); + } + + { + // Inside + SelectionRange range(3, 1); + range.StartSet(SelectionPosition(2)); + REQUIRE(range.Start() == SelectionPosition(2)); + REQUIRE(range.End() == SelectionPosition(3)); + REQUIRE(range == SelectionRange(3, 2)); + } + + { + // Empty then outside + SelectionRange range(2); + range.StartSet(SelectionPosition(9)); + REQUIRE(range.Start() == SelectionPosition(9)); + REQUIRE(range.End() == SelectionPosition(9)); + REQUIRE(range == SelectionRange(9, 9)); + } + + { + // Empty then outside + SelectionRange range(2); + range.StartSet(SelectionPosition(0)); + REQUIRE(range.Start() == SelectionPosition(0)); + REQUIRE(range.End() == SelectionPosition(2)); + REQUIRE(range == SelectionRange(2, 0)); + } + + } + } TEST_CASE("Selection") { -- cgit v1.2.3