1 // Scintilla source code edit control
3 ** Manages the text of the document.
5 // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
11 namespace Scintilla::Internal
{
13 // Interface to per-line data that wants to see each line insertion and deletion
17 virtual void Init()=0;
18 virtual void InsertLine(Sci::Line line
)=0;
19 virtual void InsertLines(Sci::Line line
, Sci::Line lines
) = 0;
20 virtual void RemoveLine(Sci::Line line
)=0;
25 * The line vector contains information about each of the lines in a cell buffer.
29 enum class ActionType
{ insert
, remove
, start
, container
};
32 * Actions are used to store all the information required to perform one undo/redo step.
37 Sci::Position position
;
38 std::unique_ptr
<char[]> data
;
39 Sci::Position lenData
;
43 void Create(ActionType at_
, Sci::Position position_
=0, const char *data_
=nullptr, Sci::Position lenData_
=0, bool mayCoalesce_
=true);
44 void Clear() noexcept
;
51 std::vector
<Action
> actions
;
54 int undoSequenceDepth
;
57 std::optional
<int> detach
;
59 void EnsureUndoRoom();
64 const char *AppendAction(ActionType at
, Sci::Position position
, const char *data
, Sci::Position lengthData
, bool &startSequence
, bool mayCoalesce
=true);
66 void BeginUndoAction();
68 void DropUndoSequence();
69 void DeleteUndoHistory();
71 /// The save point is a marker in the undo stack where the container has stated that
72 /// the buffer was saved. Undo and redo can move over the save point.
73 void SetSavePoint() noexcept
;
74 bool IsSavePoint() const noexcept
;
75 bool BeforeSavePoint() const noexcept
;
76 bool BeforeReachableSavePoint() const noexcept
;
77 bool AfterSavePoint() const noexcept
;
78 bool AfterDetachPoint() const noexcept
;
80 // Tentative actions are used for input composition so that it can be undone cleanly
81 void TentativeStart();
82 void TentativeCommit();
83 bool TentativeActive() const noexcept
;
84 int TentativeSteps() noexcept
;
86 /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is
87 /// called that many times. Similarly for redo.
88 bool CanUndo() const noexcept
;
90 const Action
&GetUndoStep() const;
91 void CompletedUndoStep();
92 bool CanRedo() const noexcept
;
94 const Action
&GetRedoStep() const;
95 void CompletedRedoStep();
99 const char *segment1
= nullptr;
101 const char *segment2
= nullptr;
104 bool operator==(const SplitView
&other
) const noexcept
{
105 return segment1
== other
.segment1
&& length1
== other
.length1
&&
106 segment2
== other
.segment2
&& length
== other
.length
;
108 bool operator!=(const SplitView
&other
) const noexcept
{
109 return !(*this == other
);
112 char CharAt(size_t position
) const noexcept
{
113 if (position
< length1
) {
114 return segment1
[position
];
116 if (position
< length
) {
117 return segment2
[position
];
125 * Holder for an expandable array of characters that supports undo and line markers.
126 * Based on article "Data Structures in a Bit-Mapped Text Editor"
127 * by Wilfred J. Hansen, Byte January 1987, page 183.
133 SplitVector
<char> substance
;
134 SplitVector
<char> style
;
137 Scintilla::LineEndType utf8LineEnds
;
142 std::unique_ptr
<ChangeHistory
> changeHistory
;
144 std::unique_ptr
<ILineVector
> plv
;
146 bool UTF8LineEndOverlaps(Sci::Position position
) const noexcept
;
147 bool UTF8IsCharacterBoundary(Sci::Position position
) const;
148 void ResetLineEnds();
149 void RecalculateIndexLineStarts(Sci::Line lineFirst
, Sci::Line lineLast
);
150 bool MaintainingLineCharacterIndex() const noexcept
;
151 /// Actions without undo
152 void BasicInsertString(Sci::Position position
, const char *s
, Sci::Position insertLength
);
153 void BasicDeleteChars(Sci::Position position
, Sci::Position deleteLength
);
157 CellBuffer(bool hasStyles_
, bool largeDocument_
);
158 // Deleted so CellBuffer objects can not be copied.
159 CellBuffer(const CellBuffer
&) = delete;
160 CellBuffer(CellBuffer
&&) = delete;
161 CellBuffer
&operator=(const CellBuffer
&) = delete;
162 CellBuffer
&operator=(CellBuffer
&&) = delete;
163 ~CellBuffer() noexcept
;
165 /// Retrieving positions outside the range of the buffer works and returns 0
166 char CharAt(Sci::Position position
) const noexcept
;
167 unsigned char UCharAt(Sci::Position position
) const noexcept
;
168 void GetCharRange(char *buffer
, Sci::Position position
, Sci::Position lengthRetrieve
) const;
169 char StyleAt(Sci::Position position
) const noexcept
;
170 void GetStyleRange(unsigned char *buffer
, Sci::Position position
, Sci::Position lengthRetrieve
) const;
171 const char *BufferPointer();
172 const char *RangePointer(Sci::Position position
, Sci::Position rangeLength
) noexcept
;
173 Sci::Position
GapPosition() const noexcept
;
174 SplitView
AllView() const noexcept
;
176 Sci::Position
Length() const noexcept
;
177 void Allocate(Sci::Position newSize
);
178 void SetUTF8Substance(bool utf8Substance_
) noexcept
;
179 Scintilla::LineEndType
GetLineEndTypes() const noexcept
{ return utf8LineEnds
; }
180 void SetLineEndTypes(Scintilla::LineEndType utf8LineEnds_
);
181 bool ContainsLineEnd(const char *s
, Sci::Position length
) const noexcept
;
182 void SetPerLine(PerLine
*pl
) noexcept
;
183 Scintilla::LineCharacterIndexType
LineCharacterIndex() const noexcept
;
184 void AllocateLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex
);
185 void ReleaseLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex
);
186 Sci::Line
Lines() const noexcept
;
187 void AllocateLines(Sci::Line lines
);
188 Sci::Position
LineStart(Sci::Line line
) const noexcept
;
189 Sci::Position
IndexLineStart(Sci::Line line
, Scintilla::LineCharacterIndexType lineCharacterIndex
) const noexcept
;
190 Sci::Line
LineFromPosition(Sci::Position pos
) const noexcept
;
191 Sci::Line
LineFromPositionIndex(Sci::Position pos
, Scintilla::LineCharacterIndexType lineCharacterIndex
) const noexcept
;
192 void InsertLine(Sci::Line line
, Sci::Position position
, bool lineStart
);
193 void RemoveLine(Sci::Line line
);
194 const char *InsertString(Sci::Position position
, const char *s
, Sci::Position insertLength
, bool &startSequence
);
196 /// Setting styles for positions outside the range of the buffer is safe and has no effect.
197 /// @return true if the style of a character is changed.
198 bool SetStyleAt(Sci::Position position
, char styleValue
) noexcept
;
199 bool SetStyleFor(Sci::Position position
, Sci::Position lengthStyle
, char styleValue
) noexcept
;
201 const char *DeleteChars(Sci::Position position
, Sci::Position deleteLength
, bool &startSequence
);
203 bool IsReadOnly() const noexcept
;
204 void SetReadOnly(bool set
) noexcept
;
205 bool IsLarge() const noexcept
;
206 bool HasStyles() const noexcept
;
208 /// The save point is a marker in the undo stack where the container has stated that
209 /// the buffer was saved. Undo and redo can move over the save point.
211 bool IsSavePoint() const noexcept
;
213 void TentativeStart();
214 void TentativeCommit();
215 bool TentativeActive() const noexcept
;
216 int TentativeSteps() noexcept
;
218 bool SetUndoCollection(bool collectUndo
);
219 bool IsCollectingUndo() const noexcept
;
220 void BeginUndoAction();
221 void EndUndoAction();
222 void AddUndoAction(Sci::Position token
, bool mayCoalesce
);
223 void DeleteUndoHistory();
225 /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is
226 /// called that many times. Similarly for redo.
227 bool CanUndo() const noexcept
;
229 const Action
&GetUndoStep() const;
230 void PerformUndoStep();
231 bool CanRedo() const noexcept
;
233 const Action
&GetRedoStep() const;
234 void PerformRedoStep();
236 void ChangeHistorySet(bool set
);
237 [[nodiscard
]] int EditionAt(Sci::Position pos
) const noexcept
;
238 [[nodiscard
]] Sci::Position
EditionEndRun(Sci::Position pos
) const noexcept
;
239 [[nodiscard
]] unsigned int EditionDeletesAt(Sci::Position pos
) const noexcept
;
240 [[nodiscard
]] Sci::Position
EditionNextDelete(Sci::Position pos
) const noexcept
;