From 1cccf5165b891eb95c85932474bb872ab0fbe638 Mon Sep 17 00:00:00 2001 From: Neil Date: Sun, 28 Jul 2024 09:48:13 +1000 Subject: Add SCI_GETUNDOSEQUENCE to determine whether an undo sequence is active and its nesting depth. --- call/ScintillaCall.cxx | 4 ++++ doc/ScintillaDoc.html | 9 ++++++++- doc/ScintillaHistory.html | 3 +++ include/Scintilla.h | 1 + include/Scintilla.iface | 3 +++ include/ScintillaCall.h | 1 + include/ScintillaMessages.h | 1 + src/CellBuffer.cxx | 4 ++++ src/CellBuffer.h | 1 + src/Document.cxx | 4 ++++ src/Document.h | 1 + src/Editor.cxx | 3 +++ src/UndoHistory.cxx | 4 ++++ src/UndoHistory.h | 1 + test/simpleTests.py | 19 +++++++++++++++++++ 15 files changed, 58 insertions(+), 1 deletion(-) diff --git a/call/ScintillaCall.cxx b/call/ScintillaCall.cxx index 4cb1f19d4..d1732a463 100644 --- a/call/ScintillaCall.cxx +++ b/call/ScintillaCall.cxx @@ -799,6 +799,10 @@ void ScintillaCall::EndUndoAction() { Call(Message::EndUndoAction); } +int ScintillaCall::UndoSequence() { + return static_cast(Call(Message::GetUndoSequence)); +} + int ScintillaCall::UndoActions() { return static_cast(Call(Message::GetUndoActions)); } diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index 0e0300d95..b9a5971b2 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -1936,6 +1936,7 @@ struct Sci_TextToFindFull { SCI_GETUNDOCOLLECTION → bool
SCI_BEGINUNDOACTION
SCI_ENDUNDOACTION
+ SCI_GETUNDOSEQUENCE → int
SCI_ADDUNDOACTION(int token, int flags)
@@ -1979,11 +1980,17 @@ struct Sci_TextToFindFull {

SCI_BEGINUNDOACTION
SCI_ENDUNDOACTION
- Send these two messages to Scintilla to mark the beginning and end of a set of operations that + Send these two messages to Scintilla to mark the beginning and end of a sequence of operations that you want to undo all as one operation but that you have to generate as several operations. Alternatively, you can use these to mark a set of operations that you do not want to have combined with the preceding or following operations if they are undone.

+

SCI_GETUNDOSEQUENCE → int
+ Determine if an undo sequence is active with a positive value indicating that a sequence is active and 0 that there is no current sequence. + The value returned is the nesting depth of the sequence, that is, the number of times SCI_BEGINUNDOACTION + was called without a correspnding SCI_ENDUNDOACTION. + A negative value indicates an error.

+

SCI_ADDUNDOACTION(int token, int flags)
The container can add its own actions into the undo stack by calling SCI_ADDUNDOACTION and an SCN_MODIFIED diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 520760784..3a820fb92 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -596,6 +596,9 @@ Add SCI_SETCOPYSEPARATOR for separator between parts of a multiple selection when copied to the clipboard. Feature #1530. +

  • + Add SCI_GETUNDOSEQUENCE to determine whether an undo sequence is active and its nesting depth. +
  • Release 5.5.1 diff --git a/include/Scintilla.h b/include/Scintilla.h index 719b44afd..d97da016f 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -342,6 +342,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_GETCHARACTERCATEGORYOPTIMIZATION 2721 #define SCI_BEGINUNDOACTION 2078 #define SCI_ENDUNDOACTION 2079 +#define SCI_GETUNDOSEQUENCE 2799 #define SCI_GETUNDOACTIONS 2790 #define SCI_SETUNDOSAVEPOINT 2791 #define SCI_GETUNDOSAVEPOINT 2792 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 195c87d37..c04d23a80 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -837,6 +837,9 @@ fun void BeginUndoAction=2078(,) # End a sequence of actions that is undone and redone as a unit. fun void EndUndoAction=2079(,) +# Is an undo sequence active? +get int GetUndoSequence=2799(,) + # How many undo actions are in the history? get int GetUndoActions=2790(,) diff --git a/include/ScintillaCall.h b/include/ScintillaCall.h index 6212a42cd..02c383883 100644 --- a/include/ScintillaCall.h +++ b/include/ScintillaCall.h @@ -245,6 +245,7 @@ public: int CharacterCategoryOptimization(); void BeginUndoAction(); void EndUndoAction(); + int UndoSequence(); int UndoActions(); void SetUndoSavePoint(int action); int UndoSavePoint(); diff --git a/include/ScintillaMessages.h b/include/ScintillaMessages.h index cac6d9d62..c511720c5 100644 --- a/include/ScintillaMessages.h +++ b/include/ScintillaMessages.h @@ -171,6 +171,7 @@ enum class Message { GetCharacterCategoryOptimization = 2721, BeginUndoAction = 2078, EndUndoAction = 2079, + GetUndoSequence = 2799, GetUndoActions = 2790, SetUndoSavePoint = 2791, GetUndoSavePoint = 2792, diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx index b0b9d9c39..4985517e0 100644 --- a/src/CellBuffer.cxx +++ b/src/CellBuffer.cxx @@ -1070,6 +1070,10 @@ void CellBuffer::EndUndoAction() noexcept { uh->EndUndoAction(); } +int CellBuffer::UndoSequenceDepth() const noexcept { + return uh->UndoSequenceDepth(); +} + void CellBuffer::AddUndoAction(Sci::Position token, bool mayCoalesce) { bool startSequence = false; uh->AppendAction(ActionType::container, token, nullptr, 0, startSequence, mayCoalesce); diff --git a/src/CellBuffer.h b/src/CellBuffer.h index 3a72601a6..d5d9a0467 100644 --- a/src/CellBuffer.h +++ b/src/CellBuffer.h @@ -166,6 +166,7 @@ public: bool IsCollectingUndo() const noexcept; void BeginUndoAction(bool mayCoalesce=false) noexcept; void EndUndoAction() noexcept; + int UndoSequenceDepth() const noexcept; void AddUndoAction(Sci::Position token, bool mayCoalesce); void DeleteUndoHistory() noexcept; diff --git a/src/Document.cxx b/src/Document.cxx index 3ae8964ba..88b876ebd 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -1543,6 +1543,10 @@ Sci::Position Document::Redo() { return newPos; } +int Document::UndoSequenceDepth() const noexcept { + return cb.UndoSequenceDepth(); +} + void Document::DelChar(Sci::Position pos) { DeleteChars(pos, LenChar(pos)); } diff --git a/src/Document.h b/src/Document.h index efb1ae6d6..fa1c3fe42 100644 --- a/src/Document.h +++ b/src/Document.h @@ -397,6 +397,7 @@ public: bool IsCollectingUndo() const noexcept { return cb.IsCollectingUndo(); } void BeginUndoAction(bool coalesceWithPrior=false) noexcept { cb.BeginUndoAction(coalesceWithPrior); } void EndUndoAction() noexcept { cb.EndUndoAction(); } + int UndoSequenceDepth() const noexcept; void AddUndoAction(Sci::Position token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); } void SetSavePoint(); bool IsSavePoint() const noexcept { return cb.IsSavePoint(); } diff --git a/src/Editor.cxx b/src/Editor.cxx index 390c83898..0561b42f8 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -6636,6 +6636,9 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { pdoc->EndUndoAction(); return 0; + case Message::GetUndoSequence: + return pdoc->UndoSequenceDepth(); + case Message::GetUndoActions: return pdoc->UndoActions(); diff --git a/src/UndoHistory.cxx b/src/UndoHistory.cxx index c4b241103..c0d7ba5f2 100644 --- a/src/UndoHistory.cxx +++ b/src/UndoHistory.cxx @@ -350,6 +350,10 @@ void UndoHistory::EndUndoAction() noexcept { } } +int UndoHistory::UndoSequenceDepth() const noexcept { + return undoSequenceDepth; +} + void UndoHistory::DropUndoSequence() noexcept { undoSequenceDepth = 0; } diff --git a/src/UndoHistory.h b/src/UndoHistory.h index 8cde395ae..be639c541 100644 --- a/src/UndoHistory.h +++ b/src/UndoHistory.h @@ -101,6 +101,7 @@ public: void BeginUndoAction(bool mayCoalesce=false) noexcept; void EndUndoAction() noexcept; + int UndoSequenceDepth() const noexcept; void DropUndoSequence() noexcept; void DeleteUndoHistory() noexcept; diff --git a/test/simpleTests.py b/test/simpleTests.py index 1ca5b76cb..ce67edfde 100644 --- a/test/simpleTests.py +++ b/test/simpleTests.py @@ -221,6 +221,25 @@ class TestSimple(unittest.TestCase): self.assertEqual(self.ed.CanRedo(), 0) self.assertEqual(self.ed.CanUndo(), 1) + def testUndoSequence(self): + data = b"xy" + self.assertEqual(self.ed.UndoSequence, 0) + self.ed.InsertText(0, data) + self.assertEqual(self.ed.UndoSequence, 0) + # Check that actions between BeginUndoAction and EndUndoAction are undone together + self.ed.BeginUndoAction() + self.assertEqual(self.ed.UndoSequence, 1) + self.ed.InsertText(0, data) + self.ed.InsertText(1, data) + # xxyyxy + self.assertEqual(self.ed.Length, 6) + self.ed.EndUndoAction() + self.assertEqual(self.ed.UndoSequence, 0) + self.ed.Undo() + # xy as 2 inserts removed + self.assertEqual(self.ed.Length, 2) + self.assertEqual(self.ed.UndoSequence, 0) + def testUndoSavePoint(self): data = b"xy" self.assertEqual(self.ed.Modify, 0) -- cgit v1.2.3