diff options
-rw-r--r-- | src/EditModel.cxx | 10 | ||||
-rw-r--r-- | src/EditModel.h | 14 | ||||
-rw-r--r-- | src/Editor.cxx | 11 |
3 files changed, 21 insertions, 14 deletions
diff --git a/src/EditModel.cxx b/src/EditModel.cxx index 5263de38b..e12aab38e 100644 --- a/src/EditModel.cxx +++ b/src/EditModel.cxx @@ -67,18 +67,18 @@ void ModelState::ForgetSelectionForUndo() noexcept { historyForUndo.indexCurrent = -1; } -void ModelState::RememberSelectionOntoStack(int index) { +void ModelState::RememberSelectionOntoStack(int index, Sci::Line topLine) { if ((historyForUndo.indexCurrent >= 0) && (index == historyForUndo.indexCurrent + 1)) { // Don't overwrite initial selection save if most recent action was coalesced - historyForUndo.stack[index] = historyForUndo.ssCurrent; + historyForUndo.stack[index] = { historyForUndo.ssCurrent, topLine }; } } -void ModelState::RememberSelectionForRedoOntoStack(int index, const Selection &sel) { - historyForRedo.stack[index] = sel.ToString(); +void ModelState::RememberSelectionForRedoOntoStack(int index, const Selection &sel, Sci::Line topLine) { + historyForRedo.stack[index] = { sel.ToString(), topLine }; } -std::string_view ModelState::SelectionFromStack(int index, UndoRedo history) const { +SelectionWithScroll ModelState::SelectionFromStack(int index, UndoRedo history) const { const SelectionHistory &sh = history == UndoRedo::undo ? historyForUndo : historyForRedo; const SelectionStack::const_iterator it = sh.stack.find(index); if (it != sh.stack.end()) { diff --git a/src/EditModel.h b/src/EditModel.h index 1c4823b2e..dcaf99613 100644 --- a/src/EditModel.h +++ b/src/EditModel.h @@ -24,7 +24,13 @@ public: enum class UndoRedo { undo, redo }; // Selection stack is sparse so use a map -using SelectionStack = std::map<int, std::string>; + +struct SelectionWithScroll { + std::string selection; + Sci::Line topLine = 0; +}; + +using SelectionStack = std::map<int, SelectionWithScroll>; struct SelectionHistory { int indexCurrent = 0; @@ -37,9 +43,9 @@ struct ModelState : ViewState { SelectionHistory historyForRedo; void RememberSelectionForUndo(int index, const Selection &sel); void ForgetSelectionForUndo() noexcept; - void RememberSelectionOntoStack(int index); - void RememberSelectionForRedoOntoStack(int index, const Selection &sel); - std::string_view SelectionFromStack(int index, UndoRedo history) const; + void RememberSelectionOntoStack(int index, Sci::Line topLine); + void RememberSelectionForRedoOntoStack(int index, const Selection &sel, Sci::Line topLine); + SelectionWithScroll SelectionFromStack(int index, UndoRedo history) const; virtual void TruncateUndo(int index) final; }; diff --git a/src/Editor.cxx b/src/Editor.cxx index 77d2eb175..283edff8f 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -951,7 +951,7 @@ void Editor::RememberSelectionOntoStack(int index) { if (!pdoc->AfterUndoSequenceStart()) { // Don't remember selections inside a grouped sequence as can only // unto or redo to the start and end of the group. - modelState->RememberSelectionOntoStack(index); + modelState->RememberSelectionOntoStack(index, topLine); } } } @@ -960,7 +960,7 @@ void Editor::RememberCurrentSelectionForRedoOntoStack() { if (needRedoRemembered && (pdoc->UndoSequenceDepth() == 0)) { EnsureModelState(); if (modelState) { - modelState->RememberSelectionForRedoOntoStack(pdoc->UndoCurrent(), sel); + modelState->RememberSelectionForRedoOntoStack(pdoc->UndoCurrent(), sel, topLine); needRedoRemembered = false; } } @@ -2412,9 +2412,10 @@ void Editor::RestoreSelection(Sci::Position newPos, UndoRedo history) { if ((undoSelectionHistoryOption == UndoSelectionHistoryOption::Enabled) && modelState) { // Undo wants the element after the current as it just undid it const int index = pdoc->UndoCurrent() + (history == UndoRedo::undo ? 1 : 0); - const std::string_view ss = modelState->SelectionFromStack(index, history); - if (!ss.empty()) { - sel = Selection(ss); + const SelectionWithScroll selAndLine = modelState->SelectionFromStack(index, history); + if (!selAndLine.selection.empty()) { + ScrollTo(selAndLine.topLine); + sel = Selection(selAndLine.selection); if (sel.IsRectangular()) { const size_t mainForRectangular = sel.Main(); // Reconstitute ranges from rectangular range |