diff options
author | Neil <nyamatongwe@gmail.com> | 2025-02-01 09:39:53 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2025-02-01 09:39:53 +1100 |
commit | db6332fa9933244c45c44063afbdcccb462cfc03 (patch) | |
tree | b09bb8f87572f084ad0e701745059351ed6e86d0 | |
parent | bd03d24f8bd44813db8ed1c73c5a46400d94a7cf (diff) | |
download | scintilla-mirror-db6332fa9933244c45c44063afbdcccb462cfc03.tar.gz |
Use string form for selection undo history as it saves significant space.
On average takes around 20% of SelectionSimple.
-rw-r--r-- | src/EditModel.cxx | 26 | ||||
-rw-r--r-- | src/EditModel.h | 23 | ||||
-rw-r--r-- | src/Editor.cxx | 17 | ||||
-rw-r--r-- | src/Editor.h | 2 |
4 files changed, 21 insertions, 47 deletions
diff --git a/src/EditModel.cxx b/src/EditModel.cxx index 1f9c2d064..033d79bd2 100644 --- a/src/EditModel.cxx +++ b/src/EditModel.cxx @@ -58,21 +58,9 @@ using namespace Scintilla::Internal; Caret::Caret() noexcept : active(false), on(false), period(500) {} -SelectionSimple::SelectionSimple(const Selection &sel) { - selType = sel.selType; - if (sel.IsRectangular()) { - // rectangular or thin - // Could be large so don't remember each range, just the rectangular bounds then reconstitute when undone - rangeRectangular = sel.RectangularCopy(); - } else { - ranges = sel.RangesCopy(); - } - mainRange = sel.Main(); -} - void ModelState::RememberSelectionForUndo(int index, const Selection &sel) { historyForUndo.indexCurrent = index; - historyForUndo.ssCurrent = SelectionSimple(sel); + historyForUndo.ssCurrent = sel.ToString(); } void ModelState::ForgetSelectionForUndo() noexcept { @@ -87,22 +75,22 @@ void ModelState::RememberSelectionOntoStack(int index) { } void ModelState::RememberSelectionForRedoOntoStack(int index, const Selection &sel) { - historyForRedo.stack[index] = SelectionSimple(sel); + historyForRedo.stack[index] = sel.ToString(); } -const SelectionSimple *ModelState::SelectionFromStack(int index, UndoRedo history) const { +std::string_view ModelState::SelectionFromStack(int index, UndoRedo history) const { const SelectionHistory &sh = history == UndoRedo::undo ? historyForUndo : historyForRedo; - std::map<int, SelectionSimple>::const_iterator it = sh.stack.find(index); + const SelectionStack::const_iterator it = sh.stack.find(index); if (it != sh.stack.end()) { - return &it->second; + return it->second; } return {}; } void ModelState::TruncateUndo(int index) { - std::map<int, SelectionSimple>::iterator itUndo = historyForUndo.stack.find(index); + const SelectionStack::const_iterator itUndo = historyForUndo.stack.find(index); historyForUndo.stack.erase(itUndo, historyForUndo.stack.end()); - std::map<int, SelectionSimple>::iterator itRedo = historyForRedo.stack.find(index); + const SelectionStack::const_iterator itRedo = historyForRedo.stack.find(index); historyForRedo.stack.erase(itRedo, historyForRedo.stack.end()); } diff --git a/src/EditModel.h b/src/EditModel.h index f75cece44..b9c331573 100644 --- a/src/EditModel.h +++ b/src/EditModel.h @@ -21,26 +21,15 @@ public: Caret() noexcept; }; -// Simplified version of selection which won't contain rectangular selection realized -// into ranges as too much data. -// Just a type and single range for now. - -struct SelectionSimple { - std::vector<SelectionRange> ranges; - SelectionRange rangeRectangular; - size_t mainRange = 0; - Selection::SelTypes selType = Selection::SelTypes::stream; - - SelectionSimple() = default; - explicit SelectionSimple(const Selection &sel); -}; - enum class UndoRedo { undo, redo }; +// Selection stack is sparse so use a map +using SelectionStack = std::map<int, std::string>; + struct SelectionHistory { int indexCurrent = 0; - SelectionSimple ssCurrent; - std::map<int, SelectionSimple> stack; + std::string ssCurrent; + SelectionStack stack; }; struct ModelState : ViewState { @@ -50,7 +39,7 @@ struct ModelState : ViewState { void ForgetSelectionForUndo() noexcept; void RememberSelectionOntoStack(int index); void RememberSelectionForRedoOntoStack(int index, const Selection &sel); - const SelectionSimple *SelectionFromStack(int index, UndoRedo history) const; + std::string_view SelectionFromStack(int index, UndoRedo history) const; virtual void TruncateUndo(int index) final; }; diff --git a/src/Editor.cxx b/src/Editor.cxx index 0d1a221cd..10c694990 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -2403,19 +2403,18 @@ 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 SelectionSimple *pss = modelState->SelectionFromStack(index, history); - if (pss) { - sel.selType = pss->selType; + const std::string_view ss = modelState->SelectionFromStack(index, history); + if (!ss.empty()) { + sel = Selection(ss); if (sel.IsRectangular()) { - sel.Rectangular() = pss->rangeRectangular; + const size_t mainForRectangular = sel.Main(); // Reconstitute ranges from rectangular range SetRectangularRange(); - } else { - sel.SetRanges(pss->ranges); + // Restore main if possible. + if (mainForRectangular < sel.Count()) { + sel.SetMain(mainForRectangular); + } } - // Unsure if this is safe with SetMain potentially failing if document doesn't appear the same. - // Maybe this can occur if the user changes font or wrap mode? - sel.SetMain(pss->mainRange); newPos = -1; // Used selection from stack so don't use position returned from undo/redo. } } diff --git a/src/Editor.h b/src/Editor.h index 655184a31..a6a484ede 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -178,8 +178,6 @@ constexpr XYScrollOptions operator|(XYScrollOptions a, XYScrollOptions b) noexce return static_cast<XYScrollOptions>(static_cast<int>(a) | static_cast<int>(b)); } -struct SelectionStack; - /** */ class Editor : public EditModel, public DocWatcher { |