aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/EditModel.cxx
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2025-01-22 21:34:54 +1100
committerNeil <nyamatongwe@gmail.com>2025-01-22 21:34:54 +1100
commit3de9d37c7b8f4501558d309ada718dc52533e94c (patch)
treece87afaff43a86c26c562fefcf0c9a5ea409ef6b /src/EditModel.cxx
parentbac32d7fde0b1d052ac9e926c6b3c96afe39bcfd (diff)
downloadscintilla-mirror-3de9d37c7b8f4501558d309ada718dc52533e94c.tar.gz
Bug [#1224]. Remember selection in undo history. SCI_SETSELECTIONUNDOHISTORY.
Diffstat (limited to 'src/EditModel.cxx')
-rw-r--r--src/EditModel.cxx59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/EditModel.cxx b/src/EditModel.cxx
index 13b3da5b0..60848e6dc 100644
--- a/src/EditModel.cxx
+++ b/src/EditModel.cxx
@@ -58,6 +58,54 @@ 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);
+}
+
+void ModelState::ForgetSelectionForUndo() noexcept {
+ historyForUndo.indexCurrent = -1;
+}
+
+void ModelState::RememberSelectionOntoStack(int index) {
+ 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;
+ }
+}
+
+void ModelState::RememberSelectionForRedoOntoStack(int index, const Selection &sel) {
+ historyForRedo.stack[index] = SelectionSimple(sel);
+}
+
+const SelectionSimple *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);
+ if (it != sh.stack.end()) {
+ return &it->second;
+ }
+ return {};
+}
+
+void ModelState::TruncateUndo(int index) {
+ std::map<int, SelectionSimple>::iterator itUndo = historyForUndo.stack.find(index);
+ historyForUndo.stack.erase(itUndo, historyForUndo.stack.end());
+ std::map<int, SelectionSimple>::iterator itRedo = historyForRedo.stack.find(index);
+ historyForRedo.stack.erase(itRedo, historyForRedo.stack.end());
+}
+
EditModel::EditModel() : braces{} {
inOverstrike = false;
xOffset = 0;
@@ -131,3 +179,14 @@ InSelection EditModel::LineEndInSelection(Sci::Line lineDoc) const {
int EditModel::GetMark(Sci::Line line) const {
return pdoc->GetMark(line, FlagSet(changeHistoryOption, ChangeHistoryOption::Markers));
}
+
+void EditModel::EnsureModelState() {
+ if (!modelState && rememberingSelectionForUndo) {
+ if (ViewStateShared vss = pdoc->GetViewState(this)) {
+ modelState = std::dynamic_pointer_cast<ModelState>(vss);
+ } else {
+ modelState = std::make_shared<ModelState>();
+ pdoc->SetViewState(this, std::static_pointer_cast<ViewState>(modelState));
+ }
+ }
+}