// Scintilla source code edit control /** @file Document.h ** Text document that handles notifications, DBCS, styling, words and end of line. **/ // Copyright 1998-2011 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #ifndef DOCUMENT_H #define DOCUMENT_H namespace Scintilla::Internal { class DocWatcher; class DocModification; class Document; class LineMarkers; class LineLevels; class LineState; class LineAnnotation; enum class EncodingFamily { eightBit, unicode, dbcs }; /** * The range class represents a range of text in a document. * The two values are not sorted as one end may be more significant than the other * as is the case for the selection where the end position is the position of the caret. * If either position is invalidPosition then the range is invalid and most operations will fail. */ class Range { public: Sci::Position start; Sci::Position end; explicit Range(Sci::Position pos=0) noexcept : start(pos), end(pos) { } Range(Sci::Position start_, Sci::Position end_) noexcept : start(start_), end(end_) { } bool operator==(const Range &other) const noexcept { return (start == other.start) && (end == other.end); } bool Valid() const noexcept { return (start != Sci::invalidPosition) && (end != Sci::invalidPosition); } [[nodiscard]] bool Empty() const noexcept { return start == end; } [[nodiscard]] Sci::Position Length() const noexcept { return (start <= end) ? (end - start) : (start - end); } Sci::Position First() const noexcept { return (start <= end) ? start : end; } Sci::Position Last() const noexcept { return (start > end) ? start : end; } // Is the position within the range? bool Contains(Sci::Position pos) const noexcept { if (start < end) { return (pos >= start && pos <= end); } else { return (pos <= start && pos >= end); } } // Is the character after pos within the range? bool ContainsCharacter(Sci::Position pos) const noexcept { if (start < end) { return (pos >= start && pos < end); } else { return (pos < start && pos >= end); } } bool Contains(Range other) const noexcept { return Contains(other.start) && Contains(other.end); } bool Overlaps(Range other) const noexcept { return Contains(other.start) || Contains(other.end) || other.Contains(start) || other.Contains(end); } }; /** * Interface class for regular expression searching */ class RegexSearchBase { public: virtual ~RegexSearchBase() = default; virtual Sci::Position FindText(Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s, bool caseSensitive, bool word, bool wordStart, Scintilla::FindOption flags, Sci::Position *length) = 0; ///@return String with the substitutions, must remain valid until the next call or destruction virtual const char *SubstituteByPosition(Document *doc, const char *text, Sci::Position *length) = 0; }; /// Factory function for RegexSearchBase extern RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable); struct StyledText { size_t length; const char *text; bool multipleStyles; size_t style; const unsigned char *styles; StyledText(size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) noexcept : length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) { } // Return number of bytes from start to before '\n' or end of text. // Return 1 when start is outside text size_t LineLength(size_t start) const noexcept { size_t cur = start; while ((cur < length) && (text[cur] != '\n')) cur++; return cur-start; } size_t StyleAt(size_t i) const noexcept { return multipleStyles ? styles[i] : style; } }; class HighlightDelimiter { public: HighlightDelimiter() noexcept : isEnabled(false) { Clear(); } void Clear() noexcept { beginFoldBlock = -1; endFoldBlock = -1; firstChangeableLineBefore = -1; firstChangeableLineAfter = -1; } bool NeedsDrawing(Sci::Line line) const noexcept { return isEnabled && (line <= firstChangeableLineBefore || line >= firstChangeableLineAfter); } bool IsFoldBlockHighlighted(Sci::Line line) const noexcept { return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock; } bool IsHeadOfFoldBlock(Sci::Line line) const noexcept { return beginFoldBlock == line && line < endFoldBlock; } bool IsBodyOfFoldBlock(Sci::Line line) const noexcept { return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock; } bool IsTailOfFoldBlock(Sci::Line line) const noexcept { return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock; } Sci::Line beginFoldBlock; // Begin of current fold block Sci::Line endFoldBlock; // End of current fold block Sci::Line firstChangeableLineBefore; // First line that triggers repaint before starting line that determined current fold block Sci::Line firstChangeableLineAfter; // First line that triggers repaint after starting line that determined current fold block bool isEnabled; }; struct LexerReleaser { // Called by unique_ptr to destroy/free the Resource void operator()(Scintilla::ILexer5 *pLexer) noexcept { if (pLexer) { try { pLexer->Release(); } catch (...) { // ILexer5::Release must not throw, ignore if it does. } } } }; using LexerInstance = std::unique_ptr; // LexInterface defines the interface to ILexer used in Document. // The LexState subclass is actually created and that is used within ScintillaBase // to provide more methods that are exposed through Scintilla's external API. class LexInterface { protected: Document *pdoc; LexerInstance instance; bool performingStyle; ///< Prevent reentrance public: explicit LexInterface(Document *pdoc_) noexcept; // Deleted so LexInterface objects can not be copied. LexInterface(const LexInterface &) = delete; LexInterface(LexInterface &&) = delete; LexInterface &operator=(const LexInterface &) = delete; LexInterface &operator=(LexInterface &&) = delete; virtual ~LexInterface() noexcept; void SetInstance(ILexer5 *instance_) noexcept; void Colourise(Sci::Position start, Sci::Position end); virtual Scintilla::LineEndType LineEndTypesSupported(); bool UseContainerLexing() const noexcept; }; struct RegexError : public std::runtime_error { RegexError() : std::runtime_error("regex failure") {} }; /** * The ActionDuration class stores the average time taken for some action such as styling or * wrapping a line. It is used to decide how many repetitions of that action can be performed * on idle to maximize efficiency without affecting application responsiveness. * The duration changes if the time for the action changes. For example, if a simple lexer is * changed to a complex lexer. Changes are damped and clamped to avoid short periods of easy * or difficult processing moving the value too far leading to inefficiency or poor user * experience. */ class ActionDuration { double duration; const double minDuration; const double maxDuration; public: ActionDuration(double duration_, double minDuration_, double maxDuration_) noexcept; void AddSample(size_t numberActions, double durationOfActions) noexcept; double Duration() const noexcept; size_t ActionsInAllowedTime(double secondsAllowed) const noexcept; }; /** * A whole character (code point) with a value and width in bytes. * For UTF-8, the value is the code point value. * For DBCS, its jamming the lead and trail bytes together. * For 8 bit encodings, is just the byte value. */ struct CharacterExtracted { unsigned int character; unsigned int widthBytes; CharacterExtracted(unsigned int character_, unsigned int widthBytes_) noexcept : character(character_), widthBytes(widthBytes_) { } // For UTF-8: CharacterExtracted(const unsigned char *charBytes, size_t widthCharBytes) noexcept; // For DBCS characters turn 2 bytes into an int static CharacterExtracted DBCS(unsigned char lead, unsigned char trail) noexcept { return CharacterExtracted((lead << 8) | trail, 2); } }; /** */HTTP/1.1 200 OK Connection: keep-alive Connection: keep-alive Connection: keep-alive Content-Disposition: inline; filename="Document.h" Content-Disposition: inline; filename="Document.h" Content-Disposition: inline; filename="Document.h" Content-Length: 26298 Content-Length: 26298 Content-Length: 26298 Content-Security-Policy: default-src 'none' Content-Security-Policy: default-src 'none' Content-Security-Policy: default-src 'none' Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8 Date: Sat, 18 Oct 2025 08:00:17 UTC ETag: "f7f4eeeddf77bcacd34cf3bb9dd6c9811c9d194e" ETag: "f7f4eeeddf77bcacd34cf3bb9dd6c9811c9d194e" ETag: "f7f4eeeddf77bcacd34cf3bb9dd6c9811c9d194e" Expires: Tue, 16 Oct 2035 08:00:16 GMT Expires: Tue, 16 Oct 2035 08:00:17 GMT Expires: Tue, 16 Oct 2035 08:00:17 GMT Last-Modified: Sat, 18 Oct 2025 08:00:16 GMT Last-Modified: Sat, 18 Oct 2025 08:00:17 GMT Last-Modified: Sat, 18 Oct 2025 08:00:17 GMT Server: OpenBSD httpd Server: OpenBSD httpd Server: OpenBSD httpd X-Content-Type-Options: nosniff X-Content-Type-Options: nosniff X-Content-Type-Options: nosniff // Scintilla source code edit control /** @file Document.h ** Text document that handles notifications, DBCS, styling, words and end of line. **/ // Copyright 1998-2011 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #ifndef DOCUMENT_H #define DOCUMENT_H namespace Scintilla::Internal { class DocWatcher; class DocModification; class Document; class LineMarkers; class LineLevels; class LineState; class LineAnnotation; enum class EncodingFamily { eightBit, unicode, dbcs }; /** * The range class represents a range of text in a document. * The two values are not sorted as one end may be more significant than the other * as is the case for the selection where the end position is the position of the caret. * If either position is invalidPosition then the range is invalid and most operations will fail. */ class Range { public: Sci::Position start; Sci::Position end; explicit Range(Sci::Position pos=0) noexcept : start(pos), end(pos) { } Range(Sci::Position start_, Sci::Position end_) noexcept : start(start_), end(end_) { } bool operator==(const Range &other) const noexcept { return (start == other.start) && (end == other.end); } bool Valid() const noexcept { return (start != Sci::invalidPosition) && (end != Sci::invalidPosition); } [[nodiscard]] bool Empty() const noexcept { return start == end; } [[nodiscard]] Sci::Position Length() const noexcept { return (start <= end) ? (end - start) : (start - end); } Sci::Position First() const noexcept { return (start <= end) ? start : end; } Sci::Position Last() const noexcept { return (start > end) ? start : end; } // Is the position within the range? bool Contains(Sci::Position pos) const noexcept { if (start < end) { return (pos >= start && pos <= end); } else { return (pos <= start && pos >= end); } } // Is the character after pos within the range? bool ContainsCharacter(Sci::Position pos) const noexcept { if (start < end) { return (pos >= start && pos < end); } else { return (pos < start && pos >= end); } } bool Contains(Range other) const noexcept { return Contains(other.start) && Contains(other.end); } bool Overlaps(Range other) const noexcept { return Contains(other.start) || Contains(other.end) || other.Contains(start) || other.Contains(end); } }; /** * Interface class for regular expression searching */ class RegexSearchBase { public: virtual ~RegexSearchBase() = default; virtual Sci::Position FindText(Document *doc, Sci::Position minPos, Sci::Position maxPos, const char *s, bool caseSensitive, bool word, bool wordStart, Scintilla::FindOption flags, Sci::Position *length) = 0; ///@return String with the substitutions, must remain valid until the next call or destruction virtual const char *SubstituteByPosition(Document *doc, const char *text, Sci::Position *length) = 0; }; /// Factory function for RegexSearchBase extern RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable); struct StyledText { size_t length; const char *text; bool multipleStyles; size_t style; const unsigned char *styles; StyledText(size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) noexcept : length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) { } // Return number of bytes from start to before '\n' or end of text. // Return 1 when start is outside text size_t LineLength(size_t start) const noexcept { size_t cur = start; while ((cur < length) && (text[cur] != '\n')) cur++; return cur-start; } size_t StyleAt(size_t i) const noexcept { return multipleStyles ? styles[i] : style; } }; class HighlightDelimiter { public: HighlightDelimiter() noexcept : isEnabled(false) { Clear(); } void Clear() noexcept { beginFoldBlock = -1; endFoldBlock = -1; firstChangeableLineBefore = -1; firstChangeableLineAfter = -1; } bool NeedsDrawing(Sci::Line line) const noexcept { return isEnabled && (line <= firstChangeableLineBefore || line >= firstChangeableLineAfter); } bool IsFoldBlockHighlighted(Sci::Line line) const noexcept { return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock; } bool IsHeadOfFoldBlock(Sci::Line line) const noexcept { return beginFoldBlock == line && line < endFoldBlock; } bool IsBodyOfFoldBlock(Sci::Line line) const noexcept { return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock; } bool IsTailOfFoldBlock(Sci::Line line) const noexcept { return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock; } Sci::Line beginFoldBlock; // Begin of current fold block Sci::Line endFoldBlock; // End of current fold block Sci::Line firstChangeableLineBefore; // First line that triggers repaint before starting line that determined current fold block Sci::Line firstChangeableLineAfter; // First line that triggers repaint after starting line that determined current fold block bool isEnabled; }; struct LexerReleaser { // Called by unique_ptr to destroy/free the Resource void operator()(Scintilla::ILexer5 *pLexer) noexcept { if (pLexer) { try { pLexer->Release(); } catch (...) { // ILexer5::Release must not throw, ignore if it does. } } } }; using LexerInstance = std::unique_ptr; // LexInterface defines the interface to ILexer used in Document. // The LexState subclass is actually created and that is used within ScintillaBase // to provide more methods that are exposed through Scintilla's external API. class LexInterface { protected: Document *pdoc; LexerInstance instance; bool performingStyle; ///< Prevent reentrance public: explicit LexInterface(Document *pdoc_) noexcept; // Deleted so LexInterface objects can not be copied. LexInterface(const LexInterface &) = delete; LexInterface(LexInterface &&) = delete; LexInterface &operator=(const LexInterface &) = delete; LexInterface &operator=(LexInterface &&) = delete; virtual ~LexInterface() noexcept; void SetInstance(ILexer5 *instance_) noexcept; void Colourise(Sci::Position start, Sci::Position end); virtual Scintilla::LineEndType LineEndTypesSupported(); bool UseContainerLexing() const noexcept; }; struct RegexError : public std::runtime_error { RegexError() : std::runtime_error("regex failure") {} }; /** * The ActionDuration class stores the average time taken for some action such as styling or * wrapping a line. It is used to decide how many repetitions of that action can be performed * on idle to maximize efficiency without affecting application responsiveness. * The duration changes if the time for the action changes. For example, if a simple lexer is * changed to a complex lexer. Changes are damped and clamped to avoid short periods of easy * or difficult processing moving the value too far leading to inefficiency or poor user * experience. */ class ActionDuration { double duration; const double minDuration; const double maxDuration; public: ActionDuration(double duration_, double minDuration_, double maxDuration_) noexcept; void AddSample(size_t numberActions, double durationOfActions) noexcept; double Duration() const noexcept; size_t ActionsInAllowedTime(double secondsAllowed) const noexcept; }; /** * A whole character (code point) with a value and width in bytes. * For UTF-8, the value is the code point value. * For DBCS, its jamming the lead and trail bytes together. * For 8 bit encodings, is just the byte value. */ struct CharacterExtracted { unsigned int character; unsigned int widthBytes; CharacterExtracted(unsigned int character_, unsigned int widthBytes_) noexcept : character(character_), widthBytes(widthBytes_) { } // For UTF-8: CharacterExtracted(const unsigned char *charBytes, size_t widthCharBytes) noexcept; // For DBCS characters turn 2 bytes into an int static CharacterExtracted DBCS(unsigned char lead, unsigned char trail) noexcept { return CharacterExtracted((lead << 8) | trail, 2); } }; /** */ class Document : PerLine, public Scintilla::IDocument, public Scintilla::ILoader { public: /** Used to pair watcher pointer with user data. */ struct WatcherWithUserData { DocWatcher *watcher; void *userData; WatcherWithUserData(DocWatcher *watcher_=nullptr, void *userData_=nullptr) noexcept : watcher(watcher_), userData(userData_) { } bool operator==(const WatcherWithUserData &other) const noexcept { return (watcher == other.watcher) && (userData == other.userData); } }; private: int refCount; CellBuffer cb; CharClassify charClass; CharacterCategoryMap charMap; std::unique_ptr pcf; Sci::Position endStyled; int styleClock; int enteredModification; int enteredStyling; int enteredReadOnlyCount; bool insertionSet; std::string insertion; std::vector watchers; // ldSize is not real data - it is for dimensions and loops enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldEOLAnnotation, ldSize }; std::unique_ptr perLineData[ldSize]; LineMarkers *Markers() const noexcept; LineLevels *Levels() const noexcept; LineState *States() const noexcept; LineAnnotation *Margins() const noexcept; LineAnnotation *Annotations() const noexcept; LineAnnotation *EOLAnnotations() const noexcept; bool matchesValid; std::unique_ptr regex; std::unique_ptr pli; public: Scintilla::EndOfLine eolMode; /// Can also be SC_CP_UTF8 to enable UTF-8 mode int dbcsCodePage; Scintilla::LineEndType lineEndBitSet; int tabInChars; int indentInChars; int actualIndentInChars; bool useTabs; bool tabIndents; bool backspaceUnindents; ActionDuration durationStyleOneByte; std::unique_ptr decorations; Document(Scintilla::DocumentOption options); // Deleted so Document objects can not be copied. Document(const Document &) = delete; Document(Document &&) = delete; void operator=(const Document &) = delete; Document &operator=(Document &&) = delete; ~Document() override; int AddRef(); int SCI_METHOD Release() override; // From PerLine void Init() override; void InsertLine(Sci::Line line) override; void InsertLines(Sci::Line line, Sci::Line lines) override; void RemoveLine(Sci::Line line) override; Scintilla::LineEndType LineEndTypesSupported() const; bool SetDBCSCodePage(int dbcsCodePage_); Scintilla::LineEndType GetLineEndTypesAllowed() const noexcept { return cb.GetLineEndTypes(); } bool SetLineEndTypesAllowed(Scintilla::LineEndType lineEndBitSet_); Scintilla::LineEndType GetLineEndTypesActive() const noexcept { return cb.GetLineEndTypes(); } int SCI_METHOD Version() const override { return Scintilla::dvRelease4; } void SCI_METHOD SetErrorStatus(int status) override; Sci_Position SCI_METHOD LineFromPosition(Sci_Position pos) const override; Sci::Line SciLineFromPosition(Sci::Position pos) const noexcept; // Avoids casting LineFromPosition Sci::Position ClampPositionIntoDocument(Sci::Position pos) const noexcept; bool ContainsLineEnd(const char *s, Sci::Position length) const noexcept { return cb.ContainsLineEnd(s, length); } bool IsCrLf(Sci::Position pos) const noexcept; int LenChar(Sci::Position pos) const noexcept; bool InGoodUTF8(Sci::Position pos, Sci::Position &start, Sci::Position &end) const noexcept; Sci::Position MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd=true) const noexcept; Sci::Position NextPosition(Sci::Position pos, int moveDir) const noexcept; bool NextCharacter(Sci::Position &pos, int moveDir) const noexcept; // Returns true if pos changed CharacterExtracted CharacterAfter(Sci::Position position) const noexcept; CharacterExtracted CharacterBefore(Sci::Position position) const noexcept; Sci_Position SCI_METHOD GetRelativePosition(Sci_Position positionStart, Sci_Position characterOffset) const override; Sci::Position GetRelativePositionUTF16(Sci::Position positionStart, Sci::Position characterOffset) const noexcept; int SCI_METHOD GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const override; int SCI_METHOD CodePage() const override; bool SCI_METHOD IsDBCSLeadByte(char ch) const override; bool IsDBCSLeadByteNoExcept(char ch) const noexcept; bool IsDBCSTrailByteNoExcept(char ch) const noexcept; int DBCSDrawBytes(std::string_view text) const noexcept; bool IsDBCSDualByteAt(Sci::Position pos) const noexcept; size_t SafeSegment(std::string_view text) const noexcept; EncodingFamily CodePageFamily() const noexcept; // Gateways to modifying document void ModifiedAt(Sci::Position pos) noexcept; void CheckReadOnly(); void TrimReplacement(std::string_view &text, Range &range) const noexcept; bool DeleteChars(Sci::Position pos, Sci::Position len); Sci::Position InsertString(Sci::Position position, const char *s, Sci::Position insertLength); Sci::Position InsertString(Sci::Position position, std::string_view sv); void ChangeInsertion(const char *s, Sci::Position length); int SCI_METHOD AddData(const char *data, Sci_Position length) override; void * SCI_METHOD ConvertToDocument() override; Sci::Position Undo(); Sci::Position Redo(); bool CanUndo() const noexcept { return cb.CanUndo(); } bool CanRedo() const noexcept { return cb.CanRedo(); } void DeleteUndoHistory() { cb.DeleteUndoHistory(); } bool SetUndoCollection(bool collectUndo) { return cb.SetUndoCollection(collectUndo); } bool IsCollectingUndo() const noexcept { return cb.IsCollectingUndo(); } void BeginUndoAction() { cb.BeginUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); } void AddUndoAction(Sci::Position token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); } void SetSavePoint(); bool IsSavePoint() const noexcept { return cb.IsSavePoint(); } void TentativeStart() { cb.TentativeStart(); } void TentativeCommit() { cb.TentativeCommit(); } void TentativeUndo(); bool TentativeActive() const noexcept { return cb.TentativeActive(); } void ChangeHistorySet(bool set) { cb.ChangeHistorySet(set); } [[nodiscard]] int EditionAt(Sci::Position pos) const noexcept { return cb.EditionAt(pos); } [[nodiscard]] Sci::Position EditionEndRun(Sci::Position pos) const noexcept { return cb.EditionEndRun(pos); } [[nodiscard]] unsigned int EditionDeletesAt(Sci::Position pos) const noexcept { return cb.EditionDeletesAt(pos); } [[nodiscard]] Sci::Position EditionNextDelete(Sci::Position pos) const noexcept { return cb.EditionNextDelete(pos); } const char * SCI_METHOD BufferPointer() override { return cb.BufferPointer(); } const char *RangePointer(Sci::Position position, Sci::Position rangeLength) noexcept { return cb.RangePointer(position, rangeLength); } Sci::Position GapPosition() const noexcept { return cb.GapPosition(); } int SCI_METHOD GetLineIndentation(Sci_Position line) override; Sci::Position SetLineIndentation(Sci::Line line, Sci::Position indent); Sci::Position GetLineIndentPosition(Sci::Line line) const; Sci::Position GetColumn(Sci::Position pos) const; Sci::Position CountCharacters(Sci::Position startPos, Sci::Position endPos) const noexcept; Sci::Position CountUTF16(Sci::Position startPos, Sci::Position endPos) const noexcept; Sci::Position FindColumn(Sci::Line line, Sci::Position column); void Indent(bool forwards, Sci::Line lineBottom, Sci::Line lineTop); static std::string TransformLineEnds(const char *s, size_t len, Scintilla::EndOfLine eolModeWanted); void ConvertLineEnds(Scintilla::EndOfLine eolModeSet); std::string_view EOLString() const noexcept; void SetReadOnly(bool set) { cb.SetReadOnly(set); } bool IsReadOnly() const noexcept { return cb.IsReadOnly(); } bool IsLarge() const noexcept { return cb.IsLarge(); } Scintilla::DocumentOption Options() const noexcept; void DelChar(Sci::Position pos); void DelCharBack(Sci::Position pos); char CharAt(Sci::Position position) const noexcept { return cb.CharAt(position); } void SCI_METHOD GetCharRange(char *buffer, Sci_Position position, Sci_Position lengthRetrieve) const override { cb.GetCharRange(buffer, position, lengthRetrieve); } char SCI_METHOD StyleAt(Sci_Position position) const override { return cb.StyleAt(position); } char StyleAtNoExcept(Sci_Position position) const noexcept { return cb.StyleAt(position); } int StyleIndexAt(Sci_Position position) const noexcept { return static_cast(cb.StyleAt(position)); } void GetStyleRange(unsigned char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const { cb.GetStyleRange(buffer, position, lengthRetrieve); } int GetMark(Sci::Line line, bool includeChangeHistory) const; Sci::Line MarkerNext(Sci::Line lineStart, int mask) const noexcept; int AddMark(Sci::Line lin