aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2023-10-27 21:12:32 +1100
committerNeil <nyamatongwe@gmail.com>2023-10-27 21:12:32 +1100
commit29ff682132a9de383243794764bd12d9e43e4899 (patch)
tree748fa43404ce3b10ba7c89f13ab1ade57746e60e
parentd6d33d9460fb5fba165cbbd743b501324baa7516 (diff)
downloadscintilla-mirror-29ff682132a9de383243794764bd12d9e43e4899.tar.gz
Extract key code from HorizontalMove to shorten and simplify it.
New methods are SelectionMove, PositionMove, HomeWrapPosition and SelectionPosition::AddVirtualSpace. This refactoring commit does not change behaviour.
-rw-r--r--src/Editor.cxx274
-rw-r--r--src/Editor.h3
-rw-r--r--src/Selection.h3
3 files changed, 134 insertions, 146 deletions
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 7d4417115..ade5094f7 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -3442,6 +3442,14 @@ constexpr bool IsRectExtend(Message iMessage, bool isRectMoveExtends) noexcept {
}
+Sci::Position Editor::HomeWrapPosition(Sci::Position position) {
+ const Sci::Position viewLineStart = StartEndDisplayLine(position, true);
+ const Sci::Position homePos = MovePositionSoVisible(viewLineStart, -1).Position();
+ if (position <= homePos)
+ return pdoc->LineStartPosition(position);
+ return homePos;
+}
+
Sci::Position Editor::VCHomeDisplayPosition(Sci::Position position) {
const Sci::Position homePos = pdoc->VCHomePosition(position);
const Sci::Position viewLineStart = StartEndDisplayLine(position, true);
@@ -3470,6 +3478,125 @@ Sci::Position Editor::LineEndWrapPosition(Sci::Position position) {
return endPos;
}
+SelectionPosition Editor::PositionMove(Message iMessage, SelectionPosition spCaret) {
+ switch (iMessage) {
+ case Message::CharLeft:
+ case Message::CharLeftExtend:
+ if (spCaret.VirtualSpace()) {
+ spCaret.AddVirtualSpace(-1);
+ } else if (!FlagSet(virtualSpaceOptions, VirtualSpace::NoWrapLineStart) || pdoc->GetColumn(spCaret.Position()) > 0) {
+ spCaret.Add(-1);
+ }
+ return spCaret;
+ case Message::CharRight:
+ case Message::CharRightExtend:
+ if (FlagSet(virtualSpaceOptions, VirtualSpace::UserAccessible) && pdoc->IsLineEndPosition(spCaret.Position())) {
+ spCaret.AddVirtualSpace(1);
+ } else {
+ spCaret.Add(1);
+ }
+ return spCaret;
+ case Message::WordLeft:
+ case Message::WordLeftExtend:
+ return SelectionPosition(pdoc->NextWordStart(spCaret.Position(), -1));
+ case Message::WordRight:
+ case Message::WordRightExtend:
+ return SelectionPosition(pdoc->NextWordStart(spCaret.Position(), 1));
+ case Message::WordLeftEnd:
+ case Message::WordLeftEndExtend:
+ return SelectionPosition(pdoc->NextWordEnd(spCaret.Position(), -1));
+ case Message::WordRightEnd:
+ case Message::WordRightEndExtend:
+ return SelectionPosition(pdoc->NextWordEnd(spCaret.Position(), 1));
+ case Message::WordPartLeft:
+ case Message::WordPartLeftExtend:
+ return SelectionPosition(pdoc->WordPartLeft(spCaret.Position()));
+ case Message::WordPartRight:
+ case Message::WordPartRightExtend:
+ return SelectionPosition(pdoc->WordPartRight(spCaret.Position()));
+ case Message::Home:
+ case Message::HomeExtend:
+ return SelectionPosition(pdoc->LineStartPosition(spCaret.Position()));
+ case Message::HomeDisplay:
+ case Message::HomeDisplayExtend:
+ return SelectionPosition(StartEndDisplayLine(spCaret.Position(), true));
+ case Message::HomeWrap:
+ case Message::HomeWrapExtend:
+ return SelectionPosition(HomeWrapPosition(spCaret.Position()));
+ case Message::VCHome:
+ case Message::VCHomeExtend:
+ // VCHome alternates between beginning of line and beginning of text so may move back or forwards
+ return SelectionPosition(pdoc->VCHomePosition(spCaret.Position()));
+ case Message::VCHomeDisplay:
+ case Message::VCHomeDisplayExtend:
+ return SelectionPosition(VCHomeDisplayPosition(spCaret.Position()));
+ case Message::VCHomeWrap:
+ case Message::VCHomeWrapExtend:
+ return SelectionPosition(VCHomeWrapPosition(spCaret.Position()));
+ case Message::LineEnd:
+ case Message::LineEndExtend:
+ return SelectionPosition(pdoc->LineEndPosition(spCaret.Position()));
+ case Message::LineEndDisplay:
+ case Message::LineEndDisplayExtend:
+ return SelectionPosition(StartEndDisplayLine(spCaret.Position(), false));
+ case Message::LineEndWrap:
+ case Message::LineEndWrapExtend:
+ return SelectionPosition(LineEndWrapPosition(spCaret.Position()));
+
+ default:
+ break;
+ }
+ // Above switch should be exhaustive so this will never be reached.
+ PLATFORM_ASSERT(false);
+ return spCaret;
+}
+
+SelectionRange Editor::SelectionMove(Scintilla::Message iMessage, size_t r) {
+ const SelectionPosition spCaretStart = sel.Range(r).caret;
+ const SelectionPosition spCaretMoved = PositionMove(iMessage, spCaretStart);
+
+ const int directionMove = (spCaretMoved < spCaretStart) ? -1 : 1;
+ const SelectionPosition spCaret = MovePositionSoVisible(spCaretMoved, directionMove);
+
+ // Handle move versus extend, and special behaviour for non-empty left/right
+ switch (iMessage) {
+ case Message::CharLeft:
+ case Message::CharRight:
+ if (sel.Range(r).Empty()) {
+ return SelectionRange(spCaret);
+ }
+ if (iMessage == Message::CharLeft) {
+ return SelectionRange(sel.Range(r).Start());
+ }
+ return SelectionRange(sel.Range(r).End());
+
+ case Message::WordLeft:
+ case Message::WordRight:
+ case Message::WordLeftEnd:
+ case Message::WordRightEnd:
+ case Message::WordPartLeft:
+ case Message::WordPartRight:
+ case Message::Home:
+ case Message::HomeDisplay:
+ case Message::HomeWrap:
+ case Message::VCHome:
+ case Message::VCHomeDisplay:
+ case Message::VCHomeWrap:
+ case Message::LineEnd:
+ case Message::LineEndDisplay:
+ case Message::LineEndWrap:
+ return SelectionRange(spCaret);
+
+ default:
+ break;
+ }
+
+ // All remaining cases are *Extend
+ const SelectionRange rangeNew = SelectionRange(spCaret, sel.Range(r).anchor);
+ sel.TrimOtherSelections(r, rangeNew);
+ return rangeNew;
+}
+
int Editor::HorizontalMove(Message iMessage) {
if (sel.selType == Selection::SelTypes::lines) {
return 0; // horizontal moves with line selection have no effect
@@ -3554,152 +3681,7 @@ int Editor::HorizontalMove(Message iMessage) {
sel.DropAdditionalRanges();
}
for (size_t r = 0; r < sel.Count(); r++) {
- const SelectionPosition spCaretNow = sel.Range(r).caret;
- SelectionPosition spCaret = spCaretNow;
- switch (iMessage) {
- case Message::CharLeft:
- case Message::CharLeftExtend:
- if (spCaret.VirtualSpace()) {
- spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
- } else if (!FlagSet(virtualSpaceOptions, VirtualSpace::NoWrapLineStart) || pdoc->GetColumn(spCaret.Position()) > 0) {
- spCaret = SelectionPosition(spCaret.Position() - 1);
- }
- break;
- case Message::CharRight:
- case Message::CharRightExtend:
- if (FlagSet(virtualSpaceOptions, VirtualSpace::UserAccessible) && pdoc->IsLineEndPosition(spCaret.Position())) {
- spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
- } else {
- spCaret = SelectionPosition(spCaret.Position() + 1);
- }
- break;
- case Message::WordLeft:
- case Message::WordLeftExtend:
- spCaret = SelectionPosition(pdoc->NextWordStart(spCaret.Position(), -1));
- break;
- case Message::WordRight:
- case Message::WordRightExtend:
- spCaret = SelectionPosition(pdoc->NextWordStart(spCaret.Position(), 1));
- break;
- case Message::WordLeftEnd:
- case Message::WordLeftEndExtend:
- spCaret = SelectionPosition(pdoc->NextWordEnd(spCaret.Position(), -1));
- break;
- case Message::WordRightEnd:
- case Message::WordRightEndExtend:
- spCaret = SelectionPosition(pdoc->NextWordEnd(spCaret.Position(), 1));
- break;
- case Message::WordPartLeft:
- case Message::WordPartLeftExtend:
- spCaret = SelectionPosition(pdoc->WordPartLeft(spCaret.Position()));
- break;
- case Message::WordPartRight:
- case Message::WordPartRightExtend:
- spCaret = SelectionPosition(pdoc->WordPartRight(spCaret.Position()));
- break;
- case Message::Home:
- case Message::HomeExtend:
- spCaret = SelectionPosition(pdoc->LineStartPosition(spCaret.Position()));
- break;
- case Message::HomeDisplay:
- case Message::HomeDisplayExtend:
- spCaret = SelectionPosition(StartEndDisplayLine(spCaret.Position(), true));
- break;
- case Message::HomeWrap:
- case Message::HomeWrapExtend:
- spCaret = MovePositionSoVisible(StartEndDisplayLine(spCaret.Position(), true), -1);
- if (spCaretNow <= spCaret)
- spCaret = SelectionPosition(pdoc->LineStartPosition(spCaret.Position()));
- break;
- case Message::VCHome:
- case Message::VCHomeExtend:
- // VCHome alternates between beginning of line and beginning of text so may move back or forwards
- spCaret = SelectionPosition(pdoc->VCHomePosition(spCaret.Position()));
- break;
- case Message::VCHomeDisplay:
- case Message::VCHomeDisplayExtend:
- spCaret = SelectionPosition(VCHomeDisplayPosition(spCaret.Position()));
- break;
- case Message::VCHomeWrap:
- case Message::VCHomeWrapExtend:
- spCaret = SelectionPosition(VCHomeWrapPosition(spCaret.Position()));
- break;
- case Message::LineEnd:
- case Message::LineEndExtend:
- spCaret = SelectionPosition(pdoc->LineEndPosition(spCaret.Position()));
- break;
- case Message::LineEndDisplay:
- case Message::LineEndDisplayExtend:
- spCaret = SelectionPosition(StartEndDisplayLine(spCaret.Position(), false));
- break;
- case Message::LineEndWrap:
- case Message::LineEndWrapExtend:
- spCaret = SelectionPosition(LineEndWrapPosition(spCaret.Position()));
- break;
-
- default:
- PLATFORM_ASSERT(false);
- }
-
- const int directionMove = (spCaret < spCaretNow) ? -1 : 1;
- spCaret = MovePositionSoVisible(spCaret, directionMove);
-
- // Handle move versus extend, and special behaviour for non-empty left/right
- switch (iMessage) {
- case Message::CharLeft:
- case Message::CharRight:
- if (sel.Range(r).Empty()) {
- sel.Range(r) = SelectionRange(spCaret);
- } else {
- sel.Range(r) = SelectionRange(
- (iMessage == Message::CharLeft) ? sel.Range(r).Start() : sel.Range(r).End());
- }
- break;
-
- case Message::WordLeft:
- case Message::WordRight:
- case Message::WordLeftEnd:
- case Message::WordRightEnd:
- case Message::WordPartLeft:
- case Message::WordPartRight:
- case Message::Home:
- case Message::HomeDisplay:
- case Message::HomeWrap:
- case Message::VCHome:
- case Message::VCHomeDisplay:
- case Message::VCHomeWrap:
- case Message::LineEnd:
- case Message::LineEndDisplay:
- case Message::LineEndWrap:
- sel.Range(r) = SelectionRange(spCaret);
- break;
-
- case Message::CharLeftExtend:
- case Message::CharRightExtend:
- case Message::WordLeftExtend:
- case Message::WordRightExtend:
- case Message::WordLeftEndExtend:
- case Message::WordRightEndExtend:
- case Message::WordPartLeftExtend:
- case Message::WordPartRightExtend:
- case Message::HomeExtend:
- case Message::HomeDisplayExtend:
- case Message::HomeWrapExtend:
- case Message::VCHomeExtend:
- case Message::VCHomeDisplayExtend:
- case Message::VCHomeWrapExtend:
- case Message::LineEndExtend:
- case Message::LineEndDisplayExtend:
- case Message::LineEndWrapExtend: {
- SelectionRange rangeNew = SelectionRange(spCaret, sel.Range(r).anchor);
- sel.TrimOtherSelections(r, SelectionRange(rangeNew));
- sel.Range(r) = rangeNew;
- }
- break;
-
- default:
- PLATFORM_ASSERT(false);
- }
+ sel.Range(r) = SelectionMove(iMessage, r);
}
}
diff --git a/src/Editor.h b/src/Editor.h
index 54ca1110f..8c6458879 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -491,9 +491,12 @@ protected: // ScintillaBase subclass needs access to much of Editor
void ParaUpOrDown(int direction, Selection::SelTypes selt);
Range RangeDisplayLine(Sci::Line lineVisible);
Sci::Position StartEndDisplayLine(Sci::Position pos, bool start);
+ Sci::Position HomeWrapPosition(Sci::Position position);
Sci::Position VCHomeDisplayPosition(Sci::Position position);
Sci::Position VCHomeWrapPosition(Sci::Position position);
Sci::Position LineEndWrapPosition(Sci::Position position);
+ SelectionPosition PositionMove(Scintilla::Message iMessage, SelectionPosition spCaretNow);
+ SelectionRange SelectionMove(Scintilla::Message iMessage, size_t r);
int HorizontalMove(Scintilla::Message iMessage);
int DelWordOrLine(Scintilla::Message iMessage);
virtual int KeyCommand(Scintilla::Message iMessage);
diff --git a/src/Selection.h b/src/Selection.h
index bc0f2208a..30e1e27ad 100644
--- a/src/Selection.h
+++ b/src/Selection.h
@@ -49,6 +49,9 @@ public:
void Add(Sci::Position increment) noexcept {
position = position + increment;
}
+ void AddVirtualSpace(Sci::Position increment) noexcept {
+ SetVirtualSpace(virtualSpace + increment);
+ }
bool IsValid() const noexcept {
return position >= 0;
}