aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2024-02-16 09:52:43 +1100
committerNeil <nyamatongwe@gmail.com>2024-02-16 09:52:43 +1100
commitf39367fc4c7af72caef8e20b1e9b1a038e242b0a (patch)
treeb5f2fddf5ad5d2b79e72e93ebefa8cf8e7abe4d4
parent1681b7fc9da6d455ab73a96816a47f6ba263017c (diff)
downloadscintilla-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.cxx16
-rw-r--r--doc/ScintillaDoc.html47
-rw-r--r--include/Scintilla.h16
-rw-r--r--include/Scintilla.iface24
-rw-r--r--include/ScintillaCall.h6
-rw-r--r--include/ScintillaMessages.h16
-rw-r--r--src/CellBuffer.cxx16
-rw-r--r--src/CellBuffer.h6
-rw-r--r--src/Document.cxx16
-rw-r--r--src/Document.h6
-rw-r--r--src/Editor.cxx15
-rw-r--r--src/UndoHistory.cxx12
-rw-r--r--src/UndoHistory.h4
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 &rarr; int</a><br />
<a class="message" href="#SCI_SETUNDOSAVEPOINT">SCI_SETUNDOSAVEPOINT(int action)</a><br />
<a class="message" href="#SCI_GETUNDOSAVEPOINT">SCI_GETUNDOSAVEPOINT &rarr; int</a><br />
- <a class="message" href="#SCI_SETUNDOCURRENT">SCI_SETUNDOCURRENT(int action)</a><br />
- <a class="message" href="#SCI_GETUNDOCURRENT">SCI_GETUNDOCURRENT &rarr; int</a><br />
+ <a class="message" href="#SCI_SETUNDODETACH">SCI_SETUNDODETACH(int action)</a><br />
+ <a class="message" href="#SCI_GETUNDODETACH">SCI_GETUNDODETACH &rarr; int</a><br />
<a class="message" href="#SCI_SETUNDOTENTATIVE">SCI_SETUNDOTENTATIVE(int action)</a><br />
<a class="message" href="#SCI_GETUNDOTENTATIVE">SCI_GETUNDOTENTATIVE &rarr; int</a><br />
+ <a class="message" href="#SCI_SETUNDOCURRENT">SCI_SETUNDOCURRENT(int action)</a><br />
+ <a class="message" href="#SCI_GETUNDOCURRENT">SCI_GETUNDOCURRENT &rarr; 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) &rarr; 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;