1 // Scintilla source code edit control
3 ** Text document that handles notifications, DBCS, styling, words and end of line.
5 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
16 * A Position is a position within a document between two characters or at the beginning or end.
17 * Sometimes used as a character index where it identifies the character after the position.
20 const Position invalidPosition
= -1;
23 * The range class represents a range of text in a document.
24 * The two values are not sorted as one end may be more significant than the other
25 * as is the case for the selection where the end position is the position of the caret.
26 * If either position is invalidPosition then the range is invalid and most operations will fail.
33 Range(Position pos
=0) :
34 start(pos
), end(pos
) {
36 Range(Position start_
, Position end_
) :
37 start(start_
), end(end_
) {
41 return (start
!= invalidPosition
) && (end
!= invalidPosition
);
44 // Is the position within the range?
45 bool Contains(Position pos
) const {
47 return (pos
>= start
&& pos
<= end
);
49 return (pos
<= start
&& pos
>= end
);
53 // Is the character after pos within the range?
54 bool ContainsCharacter(Position pos
) const {
56 return (pos
>= start
&& pos
< end
);
58 return (pos
< start
&& pos
>= end
);
62 bool Contains(Range other
) const {
63 return Contains(other
.start
) && Contains(other
.end
);
66 bool Overlaps(Range other
) const {
68 Contains(other
.start
) ||
69 Contains(other
.end
) ||
70 other
.Contains(start
) ||
76 class DocModification
;
84 /** Used to pair watcher pointer with user data. */
85 class WatcherWithUserData
{
89 WatcherWithUserData() {
95 enum charClassification
{ ccSpace
, ccNewLine
, ccWord
, ccPunctuation
};
100 CharClassify charClass
;
104 int enteredModification
;
106 int enteredReadOnlyCount
;
108 WatcherWithUserData
*watchers
;
120 /// Can also be SC_CP_UTF8 to enable UTF-8 mode
124 int actualIndentInChars
;
127 bool backspaceUnindents
;
129 DecorationList decorations
;
137 int LineFromPosition(int pos
);
138 int ClampPositionIntoDocument(int pos
);
139 bool IsCrLf(int pos
);
140 int LenChar(int pos
);
141 bool InGoodUTF8(int pos
, int &start
, int &end
);
142 int MovePositionOutsideChar(int pos
, int moveDir
, bool checkLineEnd
=true);
144 // Gateways to modifying document
145 void ModifiedAt(int pos
);
146 void CheckReadOnly();
147 bool DeleteChars(int pos
, int len
);
148 bool InsertString(int position
, const char *s
, int insertLength
);
151 bool CanUndo() { return cb
.CanUndo(); }
152 bool CanRedo() { return cb
.CanRedo(); }
153 void DeleteUndoHistory() { cb
.DeleteUndoHistory(); }
154 bool SetUndoCollection(bool collectUndo
) {
155 return cb
.SetUndoCollection(collectUndo
);
157 bool IsCollectingUndo() { return cb
.IsCollectingUndo(); }
158 void BeginUndoAction() { cb
.BeginUndoAction(); }
159 void EndUndoAction() { cb
.EndUndoAction(); }
161 bool IsSavePoint() { return cb
.IsSavePoint(); }
163 int GetLineIndentation(int line
);
164 void SetLineIndentation(int line
, int indent
);
165 int GetLineIndentPosition(int line
) const;
166 int GetColumn(int position
);
167 int FindColumn(int line
, int column
);
168 void Indent(bool forwards
, int lineBottom
, int lineTop
);
169 static char *TransformLineEnds(int *pLenOut
, const char *s
, size_t len
, int eolMode
);
170 void ConvertLineEnds(int eolModeSet
);
171 void SetReadOnly(bool set
) { cb
.SetReadOnly(set
); }
172 bool IsReadOnly() { return cb
.IsReadOnly(); }
174 bool InsertChar(int pos
, char ch
);
175 bool InsertCString(int position
, const char *s
);
176 void ChangeChar(int pos
, char ch
);
177 void DelChar(int pos
);
178 void DelCharBack(int pos
);
180 char CharAt(int position
) { return cb
.CharAt(position
); }
181 void GetCharRange(char *buffer
, int position
, int lengthRetrieve
) {
182 cb
.GetCharRange(buffer
, position
, lengthRetrieve
);
184 char StyleAt(int position
) { return cb
.StyleAt(position
); }
185 int GetMark(int line
) { return cb
.GetMark(line
); }
186 int AddMark(int line
, int markerNum
);
187 void AddMarkSet(int line
, int valueSet
);
188 void DeleteMark(int line
, int markerNum
);
189 void DeleteMarkFromHandle(int markerHandle
);
190 void DeleteAllMarks(int markerNum
);
191 int LineFromHandle(int markerHandle
) { return cb
.LineFromHandle(markerHandle
); }
192 int LineStart(int line
) const;
193 int LineEnd(int line
) const;
194 int LineEndPosition(int position
);
195 int VCHomePosition(int position
);
197 int SetLevel(int line
, int level
);
198 int GetLevel(int line
) { return cb
.GetLevel(line
); }
199 void ClearLevels() { cb
.ClearLevels(); }
200 int GetLastChild(int lineParent
, int level
=-1);
201 int GetFoldParent(int line
);
203 void Indent(bool forwards
);
204 int ExtendWordSelect(int pos
, int delta
, bool onlyWordCharacters
=false);
205 int NextWordStart(int pos
, int delta
);
206 int NextWordEnd(int pos
, int delta
);
207 int Length() const { return cb
.Length(); }
208 void Allocate(int newSize
) { cb
.Allocate(newSize
); }
209 long FindText(int minPos
, int maxPos
, const char *s
,
210 bool caseSensitive
, bool word
, bool wordStart
, bool regExp
, bool posix
, int *length
);
211 long FindText(int iMessage
, unsigned long wParam
, long lParam
);
212 const char *SubstituteByPosition(const char *text
, int *length
);
213 int LinesTotal() const;
215 void ChangeCase(Range r
, bool makeUpperCase
);
217 void SetDefaultCharClasses(bool includeWordClass
);
218 void SetCharClasses(const unsigned char *chars
, CharClassify::cc newCharClass
);
219 void SetStylingBits(int bits
);
220 void StartStyling(int position
, char mask
);
221 bool SetStyleFor(int length
, char style
);
222 bool SetStyles(int length
, char *styles
);
223 int GetEndStyled() { return endStyled
; }
224 void EnsureStyledTo(int pos
);
225 int GetStyleClock() { return styleClock
; }
226 void IncrementStyleClock();
227 void DecorationFillRange(int position
, int value
, int fillLength
);
229 int SetLineState(int line
, int state
);
230 int GetLineState(int line
) { return cb
.GetLineState(line
); }
231 int GetMaxLineState() { return cb
.GetMaxLineState(); }
233 bool AddWatcher(DocWatcher
*watcher
, void *userData
);
234 bool RemoveWatcher(DocWatcher
*watcher
, void *userData
);
235 const WatcherWithUserData
*GetWatchers() const { return watchers
; }
236 int GetLenWatchers() const { return lenWatchers
; }
238 bool IsWordPartSeparator(char ch
);
239 int WordPartLeft(int pos
);
240 int WordPartRight(int pos
);
241 int ExtendStyleRange(int pos
, int delta
, bool singleLine
= false);
242 bool IsWhiteLine(int line
) const;
244 int ParaDown(int pos
);
245 int IndentSize() { return actualIndentInChars
; }
246 int BraceMatch(int position
, int maxReStyle
);
249 CharClassify::cc
WordCharClass(unsigned char ch
);
250 bool IsWordStartAt(int pos
);
251 bool IsWordEndAt(int pos
);
252 bool IsWordAt(int start
, int end
);
254 void NotifyModifyAttempt();
255 void NotifySavePoint(bool atSavePoint
);
256 void NotifyModified(DocModification mh
);
260 * To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
261 * scope of the change.
262 * If the DocWatcher is a document view then this can be used to optimise screen updating.
264 class DocModification
{
266 int modificationType
;
269 int linesAdded
; /**< Negative if lines deleted. */
270 const char *text
; /**< Only valid for changes to text, not for changes to style. */
275 DocModification(int modificationType_
, int position_
=0, int length_
=0,
276 int linesAdded_
=0, const char *text_
=0, int line_
=0) :
277 modificationType(modificationType_
),
280 linesAdded(linesAdded_
),
286 DocModification(int modificationType_
, const Action
&act
, int linesAdded_
=0) :
287 modificationType(modificationType_
),
288 position(act
.position
),
290 linesAdded(linesAdded_
),
298 * A class that wants to receive notifications from a Document must be derived from DocWatcher
299 * and implement the notification methods. It can then be added to the watcher list with AddWatcher.
303 virtual ~DocWatcher() {}
305 virtual void NotifyModifyAttempt(Document
*doc
, void *userData
) = 0;
306 virtual void NotifySavePoint(Document
*doc
, void *userData
, bool atSavePoint
) = 0;
307 virtual void NotifyModified(Document
*doc
, DocModification mh
, void *userData
) = 0;
308 virtual void NotifyDeleted(Document
*doc
, void *userData
) = 0;
309 virtual void NotifyStyleNeeded(Document
*doc
, void *userData
, int endPos
) = 0;