1 // Scintilla source code edit control
3 ** Text document that handles notifications, DBCS, styling, words and end of line.
5 // Copyright 1998-2011 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
{
14 class DocModification
;
21 enum class EncodingFamily
{ eightBit
, unicode
, dbcs
};
24 * The range class represents a range of text in a document.
25 * The two values are not sorted as one end may be more significant than the other
26 * as is the case for the selection where the end position is the position of the caret.
27 * If either position is invalidPosition then the range is invalid and most operations will fail.
34 explicit Range(Sci::Position pos
=0) noexcept
:
35 start(pos
), end(pos
) {
37 Range(Sci::Position start_
, Sci::Position end_
) noexcept
:
38 start(start_
), end(end_
) {
41 bool operator==(const Range
&other
) const noexcept
{
42 return (start
== other
.start
) && (end
== other
.end
);
45 bool Valid() const noexcept
{
46 return (start
!= Sci::invalidPosition
) && (end
!= Sci::invalidPosition
);
49 [[nodiscard
]] bool Empty() const noexcept
{
53 [[nodiscard
]] Sci::Position
Length() const noexcept
{
54 return (start
<= end
) ? (end
- start
) : (start
- end
);
57 Sci::Position
First() const noexcept
{
58 return (start
<= end
) ? start
: end
;
61 Sci::Position
Last() const noexcept
{
62 return (start
> end
) ? start
: end
;
65 // Is the position within the range?
66 bool Contains(Sci::Position pos
) const noexcept
{
68 return (pos
>= start
&& pos
<= end
);
70 return (pos
<= start
&& pos
>= end
);
74 // Is the character after pos within the range?
75 bool ContainsCharacter(Sci::Position pos
) const noexcept
{
77 return (pos
>= start
&& pos
< end
);
79 return (pos
< start
&& pos
>= end
);
83 bool Contains(Range other
) const noexcept
{
84 return Contains(other
.start
) && Contains(other
.end
);
87 bool Overlaps(Range other
) const noexcept
{
89 Contains(other
.start
) ||
90 Contains(other
.end
) ||
91 other
.Contains(start
) ||
97 * Interface class for regular expression searching
99 class RegexSearchBase
{
101 virtual ~RegexSearchBase() = default;
103 virtual Sci::Position
FindText(Document
*doc
, Sci::Position minPos
, Sci::Position maxPos
, const char *s
,
104 bool caseSensitive
, bool word
, bool wordStart
, Scintilla::FindOption flags
, Sci::Position
*length
) = 0;
106 ///@return String with the substitutions, must remain valid until the next call or destruction
107 virtual const char *SubstituteByPosition(Document
*doc
, const char *text
, Sci::Position
*length
) = 0;
110 /// Factory function for RegexSearchBase
111 extern RegexSearchBase
*CreateRegexSearch(CharClassify
*charClassTable
);
118 const unsigned char *styles
;
119 StyledText(size_t length_
, const char *text_
, bool multipleStyles_
, int style_
, const unsigned char *styles_
) noexcept
:
120 length(length_
), text(text_
), multipleStyles(multipleStyles_
), style(style_
), styles(styles_
) {
122 // Return number of bytes from start to before '\n' or end of text.
123 // Return 1 when start is outside text
124 size_t LineLength(size_t start
) const noexcept
{
126 while ((cur
< length
) && (text
[cur
] != '\n'))
130 size_t StyleAt(size_t i
) const noexcept
{
131 return multipleStyles
? styles
[i
] : style
;
135 class HighlightDelimiter
{
137 HighlightDelimiter() noexcept
: isEnabled(false) {
141 void Clear() noexcept
{
144 firstChangeableLineBefore
= -1;
145 firstChangeableLineAfter
= -1;
148 bool NeedsDrawing(Sci::Line line
) const noexcept
{
149 return isEnabled
&& (line
<= firstChangeableLineBefore
|| line
>= firstChangeableLineAfter
);
152 bool IsFoldBlockHighlighted(Sci::Line line
) const noexcept
{
153 return isEnabled
&& beginFoldBlock
!= -1 && beginFoldBlock
<= line
&& line
<= endFoldBlock
;
156 bool IsHeadOfFoldBlock(Sci::Line line
) const noexcept
{
157 return beginFoldBlock
== line
&& line
< endFoldBlock
;
160 bool IsBodyOfFoldBlock(Sci::Line line
) const noexcept
{
161 return beginFoldBlock
!= -1 && beginFoldBlock
< line
&& line
< endFoldBlock
;
164 bool IsTailOfFoldBlock(Sci::Line line
) const noexcept
{
165 return beginFoldBlock
!= -1 && beginFoldBlock
< line
&& line
== endFoldBlock
;
168 Sci::Line beginFoldBlock
; // Begin of current fold block
169 Sci::Line endFoldBlock
; // End of current fold block
170 Sci::Line firstChangeableLineBefore
; // First line that triggers repaint before starting line that determined current fold block
171 Sci::Line firstChangeableLineAfter
; // First line that triggers repaint after starting line that determined current fold block
175 struct LexerReleaser
{
176 // Called by unique_ptr to destroy/free the Resource
177 void operator()(Scintilla::ILexer5
*pLexer
) noexcept
{
182 // ILexer5::Release must not throw, ignore if it does.
188 using LexerInstance
= std::unique_ptr
<Scintilla::ILexer5
, LexerReleaser
>;
190 // LexInterface defines the interface to ILexer used in Document.
191 // The LexState subclass is actually created and that is used within ScintillaBase
192 // to provide more methods that are exposed through Scintilla's external API.
196 LexerInstance instance
;
197 bool performingStyle
; ///< Prevent reentrance
199 explicit LexInterface(Document
*pdoc_
) noexcept
;
200 // Deleted so LexInterface objects can not be copied.
201 LexInterface(const LexInterface
&) = delete;
202 LexInterface(LexInterface
&&) = delete;
203 LexInterface
&operator=(const LexInterface
&) = delete;
204 LexInterface
&operator=(LexInterface
&&) = delete;
205 virtual ~LexInterface() noexcept
;
206 void SetInstance(ILexer5
*instance_
) noexcept
;
207 void Colourise(Sci::Position start
, Sci::Position end
);
208 virtual Scintilla::LineEndType
LineEndTypesSupported();
209 bool UseContainerLexing() const noexcept
;
212 struct RegexError
: public std::runtime_error
{
213 RegexError() : std::runtime_error("regex failure") {}
217 * The ActionDuration class stores the average time taken for some action such as styling or
218 * wrapping a line. It is used to decide how many repetitions of that action can be performed
219 * on idle to maximize efficiency without affecting application responsiveness.
220 * The duration changes if the time for the action changes. For example, if a simple lexer is
221 * changed to a complex lexer. Changes are damped and clamped to avoid short periods of easy
222 * or difficult processing moving the value too far leading to inefficiency or poor user
226 class ActionDuration
{
228 const double minDuration
;
229 const double maxDuration
;
231 ActionDuration(double duration_
, double minDuration_
, double maxDuration_
) noexcept
;
232 void AddSample(size_t numberActions
, double durationOfActions
) noexcept
;
233 double Duration() const noexcept
;
234 size_t ActionsInAllowedTime(double secondsAllowed
) const noexcept
;
238 * A whole character (code point) with a value and width in bytes.
239 * For UTF-8, the value is the code point value.
240 * For DBCS, its jamming the lead and trail bytes together.
241 * For 8 bit encodings, is just the byte value.
243 struct CharacterExtracted
{
244 unsigned int character
;
245 unsigned int widthBytes
;
247 CharacterExtracted(unsigned int character_
, unsigned int widthBytes_
) noexcept
:
248 character(character_
), widthBytes(widthBytes_
) {
252 CharacterExtracted(const unsigned char *charBytes
, size_t widthCharBytes
) noexcept
;
254 // For DBCS characters turn 2 bytes into an int
255 static CharacterExtracted
DBCS(unsigned char lead
, unsigned char trail
) noexcept
{
256 return CharacterExtracted((lead
<< 8) | trail
, 2);
262 class Document
: PerLine
, public Scintilla::IDocument
, public Scintilla::ILoader
, public Scintilla::IDocumentEditable
{
265 /** Used to pair watcher pointer with user data. */
266 struct WatcherWithUserData
{
269 WatcherWithUserData(DocWatcher
*watcher_
=nullptr, void *userData_
=nullptr) noexcept
:
270 watcher(watcher_
), userData(userData_
) {
272 bool operator==(const WatcherWithUserData
&other
) const noexcept
{
273 return (watcher
== other
.watcher
) && (userData
== other
.userData
);
280 CharClassify charClass
;
281 CharacterCategoryMap charMap
;
282 std::unique_ptr
<CaseFolder
> pcf
;
283 Sci::Position endStyled
;
285 int enteredModification
;
287 int enteredReadOnlyCount
;
290 std::string insertion
;
292 std::vector
<WatcherWithUserData
> watchers
;
294 // ldSize is not real data - it is for dimensions and loops
295 enum lineData
{ ldMarkers
, ldLevels
, ldState
, ldMargin
, ldAnnotation
, ldEOLAnnotation
, ldSize
};
296 std::unique_ptr
<PerLine
> perLineData
[ldSize
];
297 LineMarkers
*Markers() const noexcept
;
298 LineLevels
*Levels() const noexcept
;
299 LineState
*States() const noexcept
;
300 LineAnnotation
*Margins() const noexcept
;
301 LineAnnotation
*Annotations() const noexcept
;
302 LineAnnotation
*EOLAnnotations() const noexcept
;
305 std::unique_ptr
<RegexSearchBase
> regex
;
306 std::unique_ptr
<LexInterface
> pli
;
310 Scintilla::EndOfLine eolMode
;
311 /// Can also be SC_CP_UTF8 to enable UTF-8 mode
313 Scintilla::LineEndType lineEndBitSet
;
316 int actualIndentInChars
;
319 bool backspaceUnindents
;
320 ActionDuration durationStyleOneByte
;
322 std::unique_ptr
<IDecorationList
> decorations
;
324 Document(Scintilla::DocumentOption options
);
325 // Deleted so Document objects can not be copied.
326 Document(const Document
&) = delete;
327 Document(Document
&&) = delete;
328 void operator=(const Document
&) = delete;
329 Document
&operator=(Document
&&) = delete;
330 ~Document() override
;
332 int SCI_METHOD
AddRef() noexcept override
;
333 int SCI_METHOD
Release() override
;
336 void Init() override
;
337 void InsertLine(Sci::Line line
) override
;
338 void InsertLines(Sci::Line line
, Sci::Line lines
) override
;
339 void RemoveLine(Sci::Line line
) override
;
341 Scintilla::LineEndType
LineEndTypesSupported() const;
342 bool SetDBCSCodePage(int dbcsCodePage_
);
343 Scintilla::LineEndType
GetLineEndTypesAllowed() const noexcept
{ return cb
.GetLineEndTypes(); }
344 bool SetLineEndTypesAllowed(Scintilla::LineEndType lineEndBitSet_
);
345 Scintilla::LineEndType
GetLineEndTypesActive() const noexcept
{ return cb
.GetLineEndTypes(); }
347 int SCI_METHOD
Version() const override
{
348 return Scintilla::dvRelease4
;
350 int SCI_METHOD
DEVersion() const noexcept override
;
352 void SCI_METHOD
SetErrorStatus(int status
) override
;
354 Sci_Position SCI_METHOD
LineFromPosition(Sci_Position pos
) const override
;
355 Sci::Line
SciLineFromPosition(Sci::Position pos
) const noexcept
; // Avoids casting LineFromPosition
356 Sci::Position
ClampPositionIntoDocument(Sci::Position pos
) const noexcept
;
357 bool ContainsLineEnd(const char *s
, Sci::Position length
) const noexcept
{ return cb
.ContainsLineEnd(s
, length
); }
358 bool IsCrLf(Sci::Position pos
) const noexcept
;
359 int LenChar(Sci::Position pos
) const noexcept
;
360 bool InGoodUTF8(Sci::Position pos
, Sci::Position
&start
, Sci::Position
&end
) const noexcept
;
361 Sci::Position
MovePositionOutsideChar(Sci::Position pos
, Sci::Position moveDir
, bool checkLineEnd
=true) const noexcept
;
362 Sci::Position
NextPosition(Sci::Position pos
, int moveDir
) const noexcept
;
363 bool NextCharacter(Sci::Position
&pos
, int moveDir
) const noexcept
; // Returns true if pos changed
364 CharacterExtracted
CharacterAfter(Sci::Position position
) const noexcept
;
365 CharacterExtracted
CharacterBefore(Sci::Position position
) const noexcept
;
366 Sci_Position SCI_METHOD
GetRelativePosition(Sci_Position positionStart
, Sci_Position characterOffset
) const override
;
367 Sci::Position
GetRelativePositionUTF16(Sci::Position positionStart
, Sci::Position characterOffset
) const noexcept
;
368 int SCI_METHOD
GetCharacterAndWidth(Sci_Position position
, Sci_Position
*pWidth
) const override
;
369 int SCI_METHOD
CodePage() const override
;
370 bool SCI_METHOD
IsDBCSLeadByte(char ch
) const override
;
371 bool IsDBCSLeadByteNoExcept(char ch
) const noexcept
;
372 bool IsDBCSTrailByteNoExcept(char ch
) const noexcept
;
373 int DBCSDrawBytes(std::string_view text
) const noexcept
;
374 bool IsDBCSDualByteAt(Sci::Position pos
) const noexcept
;
375 size_t SafeSegment(std::string_view text
) const noexcept
;
376 EncodingFamily
CodePageFamily() const noexcept
;
378 // Gateways to modifying document
379 void ModifiedAt(Sci::Position pos
) noexcept
;
380 void CheckReadOnly();
381 void TrimReplacement(std::string_view
&text
, Range
&range
) const noexcept
;
382 bool DeleteChars(Sci::Position pos
, Sci::Position len
);
383 Sci::Position
InsertString(Sci::Position position
, const char *s
, Sci::Position insertLength
);
384 Sci::Position
InsertString(Sci::Position position
, std::string_view sv
);
385 void ChangeInsertion(const char *s
, Sci::Position length
);
386 int SCI_METHOD
AddData(const char *data
, Sci_Position length
) override
;
387 IDocumentEditable
*AsDocumentEditable() noexcept
;
388 void *SCI_METHOD
ConvertToDocument() override
;
389 Sci::Position
Undo();
390 Sci::Position
Redo();
391 bool CanUndo() const noexcept
{ return cb
.CanUndo(); }
392 bool CanRedo() const noexcept
{ return cb
.CanRedo(); }
393 void DeleteUndoHistory() noexcept
{ cb
.DeleteUndoHistory(); }
394 bool SetUndoCollection(bool collectUndo
) noexcept
{
395 return cb
.SetUndoCollection(collectUndo
);
397 bool IsCollectingUndo() const noexcept
{ return cb
.IsCollectingUndo(); }
398 void BeginUndoAction(bool coalesceWithPrior
=false) noexcept
{ cb
.BeginUndoAction(coalesceWithPrior
); }
399 void EndUndoAction() noexcept
{ cb
.EndUndoAction(); }
400 void AddUndoAction(Sci::Position token
, bool mayCoalesce
) { cb
.AddUndoAction(token
, mayCoalesce
); }
402 bool IsSavePoint() const noexcept
{ return cb
.IsSavePoint(); }
404 void TentativeStart() noexcept
{ cb
.TentativeStart(); }
405 void TentativeCommit() noexcept
{ cb
.TentativeCommit(); }
406 void TentativeUndo();
407 bool TentativeActive() const noexcept
{ return cb
.TentativeActive(); }
409 int UndoActions() const noexcept
;
410 void SetUndoSavePoint(int action
) noexcept
;
411 int UndoSavePoint() const noexcept
;
412 void SetUndoDetach(int action
) noexcept
;
413 int UndoDetach() const noexcept
;
414 void SetUndoTentative(int action
) noexcept
;
415 int UndoTentative() const noexcept
;
416 void SetUndoCurrent(int action
);
417 int UndoCurrent() const noexcept
;
418 int UndoActionType(int action
) const noexcept
;
419 Sci::Position
UndoActionPosition(int action
) const noexcept
;
420 std::string_view
UndoActionText(int action
) const noexcept
;
421 void PushUndoActionType(int type
, Sci::Position position
);
422 void ChangeLastUndoActionText(size_t length
, const char *text
);
424 void ChangeHistorySet(bool set
) { cb
.ChangeHistorySet(set
); }
425 [[nodiscard
]] int EditionAt(Sci::Position pos
) const noexcept
{ return cb
.EditionAt(pos
); }
426 [[nodiscard
]] Sci::Position
EditionEndRun(Sci::Position pos
) const noexcept
{ return cb
.EditionEndRun(pos
); }
427 [[nodiscard
]] unsigned int EditionDeletesAt(Sci::Position pos
) const noexcept
{ return cb
.EditionDeletesAt(pos
); }
428 [[nodiscard
]] Sci::Position
EditionNextDelete(Sci::Position pos
) const noexcept
{ return cb
.EditionNextDelete(pos
); }
430 const char *SCI_METHOD
BufferPointer() override
{ return cb
.BufferPointer(); }
431 const char *RangePointer(Sci::Position position
, Sci::Position rangeLength
) noexcept
{ return cb
.RangePointer(position
, rangeLength
); }
432 Sci::Position
GapPosition() const noexcept
{ return cb
.GapPosition(); }
434 int SCI_METHOD
GetLineIndentation(Sci_Position line
) override
;
435 Sci::Position
SetLineIndentation(Sci::Line line
, Sci::Position indent
);
436 Sci::Position
GetLineIndentPosition(Sci::Line line
) const;
437 Sci::Position
GetColumn(Sci::Position pos
) const;
438 Sci::Position
CountCharacters(Sci::Position startPos
, Sci::Position endPos
) const noexcept
;
439 Sci::Position
CountUTF16(Sci::Position startPos
, Sci::Position endPos
) const noexcept
;
440 Sci::Position
FindColumn(Sci::Line line
, Sci::Position column
);
441 void Indent(bool forwards
, Sci::Line lineBottom
, Sci::Line lineTop
);
442 static std::string
TransformLineEnds(const char *s
, size_t len
, Scintilla::EndOfLine eolModeWanted
);
443 void ConvertLineEnds(Scintilla::EndOfLine eolModeSet
);
444 std::string_view
EOLString() const noexcept
;
445 void SetReadOnly(bool set
) noexcept
{ cb
.SetReadOnly(set
); }
446 bool IsReadOnly() const noexcept
{ return cb
.IsReadOnly(); }
447 bool IsLarge() const noexcept
{ return cb
.IsLarge(); }
448 Scintilla::DocumentOption
Options() const noexcept
;
450 void DelChar(Sci::Position pos
);
451 void DelCharBack(Sci::Position pos
);
453 char CharAt(Sci::Position position
) const noexcept
{ return cb
.CharAt(position
); }
454 void SCI_METHOD
GetCharRange(char *buffer
, Sci_Position position
, Sci_Position lengthRetrieve
) const override
{
455 cb
.GetCharRange(buffer
, position
, lengthRetrieve
);
457 char SCI_METHOD
StyleAt(Sci_Position position
) const override
{ return cb
.StyleAt(position
); }
458 char StyleAtNoExcept(Sci_Position position
) const noexcept
{ return cb
.StyleAt(position
); }
459 int StyleIndexAt(Sci_Position position
) const noexcept
{ return static_cast<unsigned char>(cb
.StyleAt(position
)); }
460 void GetStyleRange(unsigned char *buffer
, Sci::Position position
, Sci::Position lengthRetrieve
) const {
461 cb
.GetStyleRange(buffer
, position
, lengthRetrieve
);
463 int GetMark(Sci::Line line
, bool includeChangeHistory
) const;
464 Sci::Line
MarkerNext(Sci::Line lineStart
, int mask
) const noexcept
;
465 int AddMark(Sci::Line line
, int markerNum
);
466 void AddMarkSet(Sci::Line line
, int valueSet
);
467 void DeleteMark(Sci::Line line
, int markerNum
);
468 void DeleteMarkFromHandle(int markerHandle
);
469 void DeleteAllMarks(int markerNum
);
470 Sci::Line
LineFromHandle(int markerHandle
) const noexcept
;
471 int MarkerNumberFromLine(Sci::Line line
, int which
) const noexcept
;
472 int MarkerHandleFromLine(Sci::Line line
, int which
) const noexcept
;
473 Sci_Position SCI_METHOD
LineStart(Sci_Position line
) const override
;
474 [[nodiscard
]] Range
LineRange(Sci::Line line
) const noexcept
;
475 bool IsLineStartPosition(Sci::Position position
) const noexcept
;
476 Sci_Position SCI_METHOD
LineEnd(Sci_Position line
) const override
;
477 Sci::Position
LineStartPosition(Sci::Position position
) const noexcept
;
478 Sci::Position
LineEndPosition(Sci::Position position
) const noexcept
;
479 bool IsLineEndPosition(Sci::Position position
) const noexcept
;
480 bool IsPositionInLineEnd(Sci::Position position
) const noexcept
;
481 Sci::Position
VCHomePosition(Sci::Position position
) const;
482 Sci::Position
IndexLineStart(Sci::Line line
, Scintilla::LineCharacterIndexType lineCharacterIndex
) const noexcept
;
483 Sci::Line
LineFromPositionIndex(Sci::Position pos
, Scintilla::LineCharacterIndexType lineCharacterIndex
) const noexcept
;
484 Sci::Line
LineFromPositionAfter(Sci::Line line
, Sci::Position length
) const noexcept
;
486 int SCI_METHOD
SetLevel(Sci_Position line
, int level
) override
;
487 int SCI_METHOD
GetLevel(Sci_Position line
) const override
;
488 Scintilla::FoldLevel
GetFoldLevel(Sci_Position line
) const noexcept
;
490 Sci::Line
GetLastChild(Sci::Line lineParent
, std::optional
<Scintilla::FoldLevel
> level
= {}, Sci::Line lastLine
= -1);
491 Sci::Line
GetFoldParent(Sci::Line line
) const noexcept
;
492 void GetHighlightDelimiters(HighlightDelimiter
&highlightDelimiter
, Sci::Line line
, Sci::Line lastLine
);
494 Sci::Position
ExtendWordSelect(Sci::Position pos
, int delta
, bool onlyWordCharacters
=false) const;
495 Sci::Position
NextWordStart(Sci::Position pos
, int delta
) const;
496 Sci::Position
NextWordEnd(Sci::Position pos
, int delta
) const;
497 Sci_Position SCI_METHOD
Length() const override
{ return cb
.Length(); }
498 Sci::Position
LengthNoExcept() const noexcept
{ return cb
.Length(); }
499 void Allocate(Sci::Position newSize
) { cb
.Allocate(newSize
); }
501 CharacterExtracted
ExtractCharacter(Sci::Position position
) const noexcept
;
503 bool IsWordStartAt(Sci::Position pos
) const;
504 bool IsWordEndAt(Sci::Position pos
) const;
505 bool IsWordAt(Sci::Position start
, Sci::Position end
) const;
507 bool MatchesWordOptions(bool word
, bool wordStart
, Sci::Position pos
, Sci::Position length
) const;
508 bool HasCaseFolder() const noexcept
;
509 void SetCaseFolder(std::unique_ptr
<CaseFolder
> pcf_
) noexcept
;
510 Sci::Position
FindText(Sci::Position minPos
, Sci::Position maxPos
, const char *search
, Scintilla::FindOption flags
, Sci::Position
*length
);
511 const char *SubstituteByPosition(const char *text
, Sci::Position
*length
);
512 Scintilla::LineCharacterIndexType
LineCharacterIndex() const noexcept
;
513 void AllocateLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex
);
514 void ReleaseLineCharacterIndex(Scintilla::LineCharacterIndexType lineCharacterIndex
);
515 Sci::Line
LinesTotal() const noexcept
;
516 void AllocateLines(Sci::Line lines
);
518 void SetDefaultCharClasses(bool includeWordClass
);
519 void SetCharClasses(const unsigned char *chars
, CharacterClass newCharClass
);
520 int GetCharsOfClass(CharacterClass characterClass
, unsigned char *buffer
) const;
521 void SetCharacterCategoryOptimization(int countCharacters
);
522 int CharacterCategoryOptimization() const noexcept
;
523 void SCI_METHOD
StartStyling(Sci_Position position
) override
;
524 bool SCI_METHOD
SetStyleFor(Sci_Position length
, char style
) override
;
525 bool SCI_METHOD
SetStyles(Sci_Position length
, const char *styles
) override
;
526 Sci::Position
GetEndStyled() const noexcept
{ return endStyled
; }
527 void EnsureStyledTo(Sci::Position pos
);
528 void StyleToAdjustingLineDuration(Sci::Position pos
);
529 int GetStyleClock() const noexcept
{ return styleClock
; }
530 void IncrementStyleClock() noexcept
;
531 void SCI_METHOD
DecorationSetCurrentIndicator(int indicator
) override
;
532 void SCI_METHOD
DecorationFillRange(Sci_Position position
, int value
, Sci_Position fillLength
) override
;
533 LexInterface
*GetLexInterface() const noexcept
;
534 void SetLexInterface(std::unique_ptr
<LexInterface
> pLexInterface
) noexcept
;
536 int SCI_METHOD
SetLineState(Sci_Position line
, int state
) override
;
537 int SCI_METHOD
GetLineState(Sci_Position line
) const override
;
538 Sci::Line
GetMaxLineState() const noexcept
;
539 void SCI_METHOD
ChangeLexerState(Sci_Position start
, Sci_Position end
) override
;
541 StyledText
MarginStyledText(Sci::Line line
) const noexcept
;
542 void MarginSetStyle(Sci::Line line
, int style
);
543 void MarginSetStyles(Sci::Line line
, const unsigned char *styles
);
544 void MarginSetText(Sci::Line line
, const char *text
);
545 void MarginClearAll();
547 StyledText
AnnotationStyledText(Sci::Line line
) const noexcept
;
548 void AnnotationSetText(Sci::Line line
, const char *text
);
549 void AnnotationSetStyle(Sci::Line line
, int style
);
550 void AnnotationSetStyles(Sci::Line line
, const unsigned char *styles
);
551 int AnnotationLines(Sci::Line line
) const noexcept
;
552 void AnnotationClearAll();
554 StyledText
EOLAnnotationStyledText(Sci::Line line
) const noexcept
;
555 void EOLAnnotationSetStyle(Sci::Line line
, int style
);
556 void EOLAnnotationSetText(Sci::Line line
, const char *text
);
557 void EOLAnnotationClearAll();
559 bool AddWatcher(DocWatcher
*watcher
, void *userData
);
560 bool RemoveWatcher(DocWatcher
*watcher
, void *userData
) noexcept
;
562 CharacterClass
WordCharacterClass(unsigned int ch
) const;
563 bool IsWordPartSeparator(unsigned int ch
) const;
564 Sci::Position
WordPartLeft(Sci::Position pos
) const;
565 Sci::Position
WordPartRight(Sci::Position pos
) const;
566 Sci::Position
ExtendStyleRange(Sci::Position pos
, int delta
, bool singleLine
) noexcept
;
567 bool IsWhiteLine(Sci::Line line
) const;
568 Sci::Position
ParaUp(Sci::Position pos
) const;
569 Sci::Position
ParaDown(Sci::Position pos
) const;
570 int IndentSize() const noexcept
{ return actualIndentInChars
; }
571 Sci::Position
BraceMatch(Sci::Position position
, Sci::Position maxReStyle
, Sci::Position startPos
, bool useStartPos
) noexcept
;
574 void NotifyModifyAttempt();
575 void NotifySavePoint(bool atSavePoint
);
576 void NotifyModified(DocModification mh
);
583 UndoGroup(Document
*pdoc_
, bool groupNeeded_
=true) noexcept
:
584 pdoc(pdoc_
), groupNeeded(groupNeeded_
) {
586 pdoc
->BeginUndoAction();
589 // Deleted so UndoGroup objects can not be copied.
590 UndoGroup(const UndoGroup
&) = delete;
591 UndoGroup(UndoGroup
&&) = delete;
592 void operator=(const UndoGroup
&) = delete;
593 UndoGroup
&operator=(UndoGroup
&&) = delete;
596 // EndUndoAction can throw as it allocates but throw in destructor is fatal.
597 // To fix this UndoHistory should allocate any memory needed by EndUndoAction
598 // beforehand or change EndUndoAction to not require allocation.
599 pdoc
->EndUndoAction();
602 bool Needed() const noexcept
{
609 * To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
610 * scope of the change.
611 * If the DocWatcher is a document view then this can be used to optimise screen updating.
613 class DocModification
{
615 Scintilla::ModificationFlags modificationType
;
616 Sci::Position position
;
617 Sci::Position length
;
618 Sci::Line linesAdded
; /**< Negative if lines deleted. */
619 const char *text
; /**< Only valid for changes to text, not for changes to style. */
621 Scintilla::FoldLevel foldLevelNow
;
622 Scintilla::FoldLevel foldLevelPrev
;
623 Sci::Line annotationLinesAdded
;
626 DocModification(Scintilla::ModificationFlags modificationType_
, Sci::Position position_
=0, Sci::Position length_
=0,
627 Sci::Line linesAdded_
=0, const char *text_
=nullptr, Sci::Line line_
=0) noexcept
:
628 modificationType(modificationType_
),
631 linesAdded(linesAdded_
),
634 foldLevelNow(Scintilla::FoldLevel::None
),
635 foldLevelPrev(Scintilla::FoldLevel::None
),
636 annotationLinesAdded(0),
639 DocModification(Scintilla::ModificationFlags modificationType_
, const Action
&act
, Sci::Line linesAdded_
=0) noexcept
:
640 modificationType(modificationType_
),
641 position(act
.position
),
643 linesAdded(linesAdded_
),
646 foldLevelNow(Scintilla::FoldLevel::None
),
647 foldLevelPrev(Scintilla::FoldLevel::None
),
648 annotationLinesAdded(0),
653 * A class that wants to receive notifications from a Document must be derived from DocWatcher
654 * and implement the notification methods. It can then be added to the watcher list with AddWatcher.
658 virtual ~DocWatcher() {}
660 virtual void NotifyModifyAttempt(Document
*doc
, void *userData
) = 0;
661 virtual void NotifySavePoint(Document
*doc
, void *userData
, bool atSavePoint
) = 0;
662 virtual void NotifyModified(Document
*doc
, DocModification mh
, void *userData
) = 0;
663 virtual void NotifyDeleted(Document
*doc
, void *userData
) noexcept
= 0;
664 virtual void NotifyStyleNeeded(Document
*doc
, void *userData
, Sci::Position endPos
) = 0;
665 virtual void NotifyErrorOccurred(Document
*doc
, void *userData
, Scintilla::Status status
) = 0;