aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Editor.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Editor.cxx')
-rw-r--r--src/Editor.cxx274
1 files changed, 128 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);
}
}