diff options
author | Neil <nyamatongwe@gmail.com> | 2024-02-16 09:52:43 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2024-02-16 09:52:43 +1100 |
commit | f39367fc4c7af72caef8e20b1e9b1a038e242b0a (patch) | |
tree | b5f2fddf5ad5d2b79e72e93ebefa8cf8e7abe4d4 | |
parent | 1681b7fc9da6d455ab73a96816a47f6ba263017c (diff) | |
download | scintilla-mirror-f39367fc4c7af72caef8e20b1e9b1a038e242b0a.tar.gz |
Implement detach point access with SCI_SETUNDODETACH and SCI_GETUNDODETACH.
Write more documentation for undo history.
-rw-r--r-- | call/ScintillaCall.cxx | 16 | ||||
-rw-r--r-- | doc/ScintillaDoc.html | 47 | ||||
-rw-r--r-- | include/Scintilla.h | 16 | ||||
-rw-r--r-- | include/Scintilla.iface | 24 | ||||
-rw-r--r-- | include/ScintillaCall.h | 6 | ||||
-rw-r--r-- | include/ScintillaMessages.h | 16 | ||||
-rw-r--r-- | src/CellBuffer.cxx | 16 | ||||
-rw-r--r-- | src/CellBuffer.h | 6 | ||||
-rw-r--r-- | src/Document.cxx | 16 | ||||
-rw-r--r-- | src/Document.h | 6 | ||||
-rw-r--r-- | src/Editor.cxx | 15 | ||||
-rw-r--r-- | src/UndoHistory.cxx | 12 | ||||
-rw-r--r-- | src/UndoHistory.h | 4 |
13 files changed, 140 insertions, 60 deletions
diff --git a/call/ScintillaCall.cxx b/call/ScintillaCall.cxx index 97cd64886..78100e774 100644 --- a/call/ScintillaCall.cxx +++ b/call/ScintillaCall.cxx @@ -811,12 +811,12 @@ int ScintillaCall::UndoSavePoint() { return static_cast<int>(Call(Message::GetUndoSavePoint)); } -void ScintillaCall::SetUndoCurrent(int action) { - Call(Message::SetUndoCurrent, action); +void ScintillaCall::SetUndoDetach(int action) { + Call(Message::SetUndoDetach, action); } -int ScintillaCall::UndoCurrent() { - return static_cast<int>(Call(Message::GetUndoCurrent)); +int ScintillaCall::UndoDetach() { + return static_cast<int>(Call(Message::GetUndoDetach)); } void ScintillaCall::SetUndoTentative(int action) { @@ -827,6 +827,14 @@ int ScintillaCall::UndoTentative() { return static_cast<int>(Call(Message::GetUndoTentative)); } +void ScintillaCall::SetUndoCurrent(int action) { + Call(Message::SetUndoCurrent, action); +} + +int ScintillaCall::UndoCurrent() { + return static_cast<int>(Call(Message::GetUndoCurrent)); +} + void ScintillaCall::PushUndoActionType(int type, Position pos) { Call(Message::PushUndoActionType, type, pos); } diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index 4a10d280f..b866cf291 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -129,7 +129,7 @@ <h1>Scintilla Documentation</h1> - <p>Last edited 19 December 2023 NH</p> + <p>Last edited 16 February 2024 NH</p> <p style="background:#90F0C0">Scintilla 5 has moved the lexers from Scintilla into a new <a href="Lexilla.html">Lexilla</a> project.<br /> @@ -1995,11 +1995,23 @@ struct Sci_TextToFindFull { <h2 id="UndoSaveRestore">Undo Save and Restore</h2> <p>This feature is unfinished and has limitations. - Restoring undo state is not compatible with change history so turn change history off before restoral. + Restoring change history alongside undo state is unfinished so turn change history off before restoral. The operation sequences discussed here are a 'golden path' that has been tested to some extent and calling - the APIs in other circumstances or with out-of-bounds values may cause failures. - The behaviour of tentative actions in save and restore is uncertain as these are meant to be short-term states in language input - and which need to synchronize with a language IME (input method editor).</p> + the APIs in other circumstances or with out-of-bounds values may cause failures.</p> + + <p>The behaviour of tentative actions in save and restore is uncertain as these are meant to be short-term states in language input + and which need to synchronize with a language IME (input method editor). + For now, restore the tentative point to -1 as it seems safest to regard the tentative change as committed.</p> + + <p>Scintilla stores each change in an undo stack. + Various inter-action points play roles in undo behaviour: actions count, save point, detach point, + tentative point, and current action. Just like positions in documents, these points are between actions in the + undo stack. Thus the current action specifies the number of actions that led to the current document state and + actions after this are for redo. + The save point specifies that the actions before this point are in the most recent save and actions after this are not yet saved.</p> + <p>When the user undoes from a save point and then performs a new change, the save point can no longer be reached and is -1. + The detach point is the point at which the undo stack branched away from the saved state and is used by + change history.</p> <p>It is possible to retrieve the undo stack from Scintilla and subsequently restore the state of the stack.</p> @@ -2012,10 +2024,12 @@ struct Sci_TextToFindFull { <code><a class="message" href="#SCI_GETUNDOACTIONS">SCI_GETUNDOACTIONS → int</a><br /> <a class="message" href="#SCI_SETUNDOSAVEPOINT">SCI_SETUNDOSAVEPOINT(int action)</a><br /> <a class="message" href="#SCI_GETUNDOSAVEPOINT">SCI_GETUNDOSAVEPOINT → int</a><br /> - <a class="message" href="#SCI_SETUNDOCURRENT">SCI_SETUNDOCURRENT(int action)</a><br /> - <a class="message" href="#SCI_GETUNDOCURRENT">SCI_GETUNDOCURRENT → int</a><br /> + <a class="message" href="#SCI_SETUNDODETACH">SCI_SETUNDODETACH(int action)</a><br /> + <a class="message" href="#SCI_GETUNDODETACH">SCI_GETUNDODETACH → int</a><br /> <a class="message" href="#SCI_SETUNDOTENTATIVE">SCI_SETUNDOTENTATIVE(int action)</a><br /> <a class="message" href="#SCI_GETUNDOTENTATIVE">SCI_GETUNDOTENTATIVE → int</a><br /> + <a class="message" href="#SCI_SETUNDOCURRENT">SCI_SETUNDOCURRENT(int action)</a><br /> + <a class="message" href="#SCI_GETUNDOCURRENT">SCI_GETUNDOCURRENT → int</a><br /> <a class="message" href="#SCI_PUSHUNDOACTIONTYPE">SCI_PUSHUNDOACTIONTYPE(int type, position pos)</a><br /> <a class="message" href="#SCI_CHANGELASTUNDOACTIONTEXT">SCI_CHANGELASTUNDOACTIONTEXT(position length, const char *text)</a><br /> <a class="message" href="#SCI_GETUNDOACTIONTYPE">SCI_GETUNDOACTIONTYPE(int action) → int</a><br /> @@ -2028,16 +2042,18 @@ struct Sci_TextToFindFull { <p>The retrieval APIs are the 'GET*' ones: <code>SCI_GETUNDOACTIONS</code>, <code>SCI_GETUNDOSAVEPOINT</code>, - <code>SCI_GETUNDOCURRENT</code>, + <code>SCI_GETUNDODETACH</code>, <code>SCI_GETUNDOTENTATIVE</code>, + <code>SCI_GETUNDOCURRENT</code>, <code>SCI_GETUNDOACTIONTYPE</code>, <code>SCI_GETUNDOACTIONPOSITION</code>, and <code>SCI_GETUNDOACTIONTEXT</code>. </p> <p>The <code>SCI_GETUNDOACTIONS</code>, - <code>SCI_GETUNDOSAVEPOINT</code>, <code>SCI_GETUNDOCURRENT</code>, and - <code>SCI_GETUNDOTENTATIVE</code> APIs each return a single value and may be called in any order. + <code>SCI_GETUNDOSAVEPOINT</code>, <code>SCI_GETUNDODETACH</code>, + <code>SCI_GETUNDOTENTATIVE</code>, and <code>SCI_GETUNDOCURRENT</code> + APIs each return a single value and may be called in any order. </p> <p>The <code>SCI_GETUNDOACTIONTYPE</code>, @@ -2056,15 +2072,16 @@ struct Sci_TextToFindFull { <p>The restore APIs are the 'SET*' and others: <code>SCI_SETUNDOSAVEPOINT</code>, - <code>SCI_SETUNDOCURRENT</code>, + <code>SCI_SETUNDODETACH</code>, <code>SCI_SETUNDOTENTATIVE</code>, + <code>SCI_SETUNDOCURRENT</code>, <code>SCI_PUSHUNDOACTIONTYPE</code>, and <code>SCI_CHANGELASTUNDOACTIONTEXT</code>. </p> - <p>The history should first be set up with <code>SCI_PUSHUNDOACTIONTYPE</code>, and - <code>SCI_CHANGELASTUNDOACTIONTEXT</code> then the save, current, and tentative points set - with <code>SCI_SETUNDOSAVEPOINT</code>, <code>SCI_SETUNDOTENTATIVE</code>, and + <p>The history should first be set up with <code>SCI_PUSHUNDOACTIONTYPE</code> and + <code>SCI_CHANGELASTUNDOACTIONTEXT</code> then the save, detach, tentative, and current points set + with <code>SCI_SETUNDOSAVEPOINT</code>, <code>SCI_SETUNDODETACH</code>, <code>SCI_SETUNDOTENTATIVE</code>, and <code>SCI_SETUNDOCURRENT</code>. </p> @@ -2076,7 +2093,7 @@ struct Sci_TextToFindFull { <p> The last restoration API called should be <code>SCI_SETUNDOCURRENT</code> as this validates the restored history and values against the document. For example, an undo history that could cause a negative - document length or inserting / removing text outside the document is invalid. + document length or insert / remove text outside the document is invalid. If the restored undo state is invalid then a failure status is set and the undo history cleared. Check for failure with <a class="seealso" href="#SCI_GETSTATUS">SCI_GETSTATUS</a>. </p> diff --git a/include/Scintilla.h b/include/Scintilla.h index be537abad..4ea264d8e 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -342,15 +342,17 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_GETUNDOACTIONS 2790 #define SCI_SETUNDOSAVEPOINT 2791 #define SCI_GETUNDOSAVEPOINT 2792 -#define SCI_SETUNDOCURRENT 2793 -#define SCI_GETUNDOCURRENT 2794 +#define SCI_SETUNDODETACH 2793 +#define SCI_GETUNDODETACH 2794 #define SCI_SETUNDOTENTATIVE 2795 #define SCI_GETUNDOTENTATIVE 2796 -#define SCI_PUSHUNDOACTIONTYPE 2797 -#define SCI_CHANGELASTUNDOACTIONTEXT 2798 -#define SCI_GETUNDOACTIONTYPE 2799 -#define SCI_GETUNDOACTIONPOSITION 2800 -#define SCI_GETUNDOACTIONTEXT 2801 +#define SCI_SETUNDOCURRENT 2797 +#define SCI_GETUNDOCURRENT 2798 +#define SCI_PUSHUNDOACTIONTYPE 2800 +#define SCI_CHANGELASTUNDOACTIONTEXT 2801 +#define SCI_GETUNDOACTIONTYPE 2802 +#define SCI_GETUNDOACTIONPOSITION 2803 +#define SCI_GETUNDOACTIONTEXT 2804 #define INDIC_PLAIN 0 #define INDIC_SQUIGGLE 1 #define INDIC_TT 2 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index dd7495a6f..9f5b5a054 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -842,11 +842,11 @@ set void SetUndoSavePoint=2791(int action,) # Which action is the save point? get int GetUndoSavePoint=2792(,) -# Set action as the current point -set void SetUndoCurrent=2793(int action,) +# Set action as the detach point +set void SetUndoDetach=2793(int action,) -# Which action is the current point? -get int GetUndoCurrent=2794(,) +# Which action is the detach point? +get int GetUndoDetach=2794(,) # Set action as the tentative point set void SetUndoTentative=2795(int action,) @@ -854,20 +854,26 @@ set void SetUndoTentative=2795(int action,) # Which action is the tentative point? get int GetUndoTentative=2796(,) +# Set action as the current point +set void SetUndoCurrent=2797(int action,) + +# Which action is the current point? +get int GetUndoCurrent=2798(,) + # Push one action onto undo history with no text -fun void PushUndoActionType=2797(int type, position pos) +fun void PushUndoActionType=2800(int type, position pos) # Set the text and length of the most recently pushed action -fun void ChangeLastUndoActionText=2798(position length, string text) +fun void ChangeLastUndoActionText=2801(position length, string text) # What is the type of an action? -get int GetUndoActionType=2799(int action,) +get int GetUndoActionType=2802(int action,) # What is the position of an action? -get position GetUndoActionPosition=2800(int action,) +get position GetUndoActionPosition=2803(int action,) # What is the text of an action? -get int GetUndoActionText=2801(int action, stringresult text) +get int GetUndoActionText=2804(int action, stringresult text) # Indicator style enumeration and some constants enu IndicatorStyle=INDIC_ diff --git a/include/ScintillaCall.h b/include/ScintillaCall.h index 47122fcfe..2f2e4f0cb 100644 --- a/include/ScintillaCall.h +++ b/include/ScintillaCall.h @@ -248,10 +248,12 @@ public: int UndoActions(); void SetUndoSavePoint(int action); int UndoSavePoint(); - void SetUndoCurrent(int action); - int UndoCurrent(); + void SetUndoDetach(int action); + int UndoDetach(); void SetUndoTentative(int action); int UndoTentative(); + void SetUndoCurrent(int action); + int UndoCurrent(); void PushUndoActionType(int type, Position pos); void ChangeLastUndoActionText(Position length, const char *text); int UndoActionType(int action); diff --git a/include/ScintillaMessages.h b/include/ScintillaMessages.h index 5cff5ed26..a00ed44b4 100644 --- a/include/ScintillaMessages.h +++ b/include/ScintillaMessages.h @@ -174,15 +174,17 @@ enum class Message { GetUndoActions = 2790, SetUndoSavePoint = 2791, GetUndoSavePoint = 2792, - SetUndoCurrent = 2793, - GetUndoCurrent = 2794, + SetUndoDetach = 2793, + GetUndoDetach = 2794, SetUndoTentative = 2795, GetUndoTentative = 2796, - PushUndoActionType = 2797, - ChangeLastUndoActionText = 2798, - GetUndoActionType = 2799, - GetUndoActionPosition = 2800, - GetUndoActionText = 2801, + SetUndoCurrent = 2797, + GetUndoCurrent = 2798, + PushUndoActionType = 2800, + ChangeLastUndoActionText = 2801, + GetUndoActionType = 2802, + GetUndoActionPosition = 2803, + GetUndoActionText = 2804, IndicSetStyle = 2080, IndicGetStyle = 2081, IndicSetFore = 2082, diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx index 691a811dd..6dde7eb84 100644 --- a/src/CellBuffer.cxx +++ b/src/CellBuffer.cxx @@ -1160,12 +1160,12 @@ int CellBuffer::UndoSavePoint() const noexcept { return uh->SavePoint(); } -void CellBuffer::SetUndoCurrent(int action) { - uh->SetCurrent(action, Length()); +void CellBuffer::SetUndoDetach(int action) noexcept { + uh->SetDetachPoint(action); } -int CellBuffer::UndoCurrent() const noexcept { - return uh->Current(); +int CellBuffer::UndoDetach() const noexcept { + return uh->DetachPoint(); } void CellBuffer::SetUndoTentative(int action) noexcept { @@ -1176,6 +1176,14 @@ int CellBuffer::UndoTentative() const noexcept { return uh->TentativePoint(); } +void CellBuffer::SetUndoCurrent(int action) { + uh->SetCurrent(action, Length()); +} + +int CellBuffer::UndoCurrent() const noexcept { + return uh->Current(); +} + int CellBuffer::UndoActionType(int action) const noexcept { return uh->Type(action); } diff --git a/src/CellBuffer.h b/src/CellBuffer.h index 916937845..1c598480f 100644 --- a/src/CellBuffer.h +++ b/src/CellBuffer.h @@ -183,10 +183,12 @@ public: int UndoActions() const noexcept; void SetUndoSavePoint(int action) noexcept; int UndoSavePoint() const noexcept; - void SetUndoCurrent(int action); - int UndoCurrent() const noexcept; + void SetUndoDetach(int action) noexcept; + int UndoDetach() const noexcept; void SetUndoTentative(int action) noexcept; int UndoTentative() const noexcept; + void SetUndoCurrent(int action); + int UndoCurrent() const noexcept; int UndoActionType(int action) const noexcept; Sci::Position UndoActionPosition(int action) const noexcept; std::string_view UndoActionText(int action) const noexcept; diff --git a/src/Document.cxx b/src/Document.cxx index 8ab837daa..5f77ec2de 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -363,12 +363,12 @@ int Document::UndoSavePoint() const noexcept { return cb.UndoSavePoint(); } -void Document::SetUndoCurrent(int action) { - cb.SetUndoCurrent(action); +void Document::SetUndoDetach(int action) noexcept { + cb.SetUndoDetach(action); } -int Document::UndoCurrent() const noexcept { - return cb.UndoCurrent(); +int Document::UndoDetach() const noexcept { + return cb.UndoDetach(); } void Document::SetUndoTentative(int action) noexcept { @@ -379,6 +379,14 @@ int Document::UndoTentative() const noexcept { return cb.UndoTentative(); } +void Document::SetUndoCurrent(int action) { + cb.SetUndoCurrent(action); +} + +int Document::UndoCurrent() const noexcept { + return cb.UndoCurrent(); +} + int Document::UndoActionType(int action) const noexcept { return cb.UndoActionType(action); } diff --git a/src/Document.h b/src/Document.h index 66f954724..912c719b5 100644 --- a/src/Document.h +++ b/src/Document.h @@ -409,10 +409,12 @@ public: int UndoActions() const noexcept; void SetUndoSavePoint(int action) noexcept; int UndoSavePoint() const noexcept; - void SetUndoCurrent(int action); - int UndoCurrent() const noexcept; + void SetUndoDetach(int action) noexcept; + int UndoDetach() const noexcept; void SetUndoTentative(int action) noexcept; int UndoTentative() const noexcept; + void SetUndoCurrent(int action); + int UndoCurrent() const noexcept; int UndoActionType(int action) const noexcept; Sci::Position UndoActionPosition(int action) const noexcept; std::string_view UndoActionText(int action) const noexcept; diff --git a/src/Editor.cxx b/src/Editor.cxx index e6aec550a..343529510 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -6605,12 +6605,12 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { case Message::GetUndoSavePoint: return pdoc->UndoSavePoint(); - case Message::SetUndoCurrent: - pdoc->SetUndoCurrent(static_cast<int>(wParam)); + case Message::SetUndoDetach: + pdoc->SetUndoDetach(static_cast<int>(wParam)); break; - case Message::GetUndoCurrent: - return pdoc->UndoCurrent(); + case Message::GetUndoDetach: + return pdoc->UndoDetach(); case Message::SetUndoTentative: pdoc->SetUndoTentative(static_cast<int>(wParam)); @@ -6619,6 +6619,13 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { case Message::GetUndoTentative: return pdoc->UndoTentative(); + case Message::SetUndoCurrent: + pdoc->SetUndoCurrent(static_cast<int>(wParam)); + break; + + case Message::GetUndoCurrent: + return pdoc->UndoCurrent(); + case Message::GetUndoActionType: return pdoc->UndoActionType(static_cast<int>(wParam)); diff --git a/src/UndoHistory.cxx b/src/UndoHistory.cxx index 62f871a60..810cd9a14 100644 --- a/src/UndoHistory.cxx +++ b/src/UndoHistory.cxx @@ -395,6 +395,18 @@ bool UndoHistory::AfterSavePoint() const noexcept { return (savePoint >= 0) && (savePoint <= currentAction); } +void UndoHistory::SetDetachPoint(int action) noexcept { + if (action == -1) { + detach = {}; + } else { + detach = action; + } +} + +int UndoHistory::DetachPoint() const noexcept { + return detach.value_or(-1); +} + bool UndoHistory::AfterDetachPoint() const noexcept { return detach && (*detach < currentAction); } diff --git a/src/UndoHistory.h b/src/UndoHistory.h index 13aaca98c..10660a195 100644 --- a/src/UndoHistory.h +++ b/src/UndoHistory.h @@ -110,6 +110,10 @@ public: bool BeforeOrAtSavePoint() const noexcept; bool BeforeReachableSavePoint() const noexcept; bool AfterSavePoint() const noexcept; + + /// The detach point is the last action that was before an inaccessible missing save point. + void SetDetachPoint(int action) noexcept; + [[nodiscard]] int DetachPoint() const noexcept; bool AfterDetachPoint() const noexcept; bool AfterOrAtDetachPoint() const noexcept; |