From a5b8fca36a7a050edfa1c4bb9e91f7722e12f3f6 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Tue, 9 Sep 2025 20:50:07 +0300 Subject: added SC_LINE_END_TYPE_NONE: allows ignoring all line ends This can help when using Scintilla views as command line widgets. It can also help when using Scintilla to edit binary files as you don't want to attach special meaning to CR and LF. --- src/CellBuffer.cxx | 86 ++++++++++++++++++++++++++++++--------------------- src/Document.cxx | 4 +-- src/ScintillaBase.cxx | 2 +- 3 files changed, 54 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx index 3e9deb934..28141e2cd 100644 --- a/src/CellBuffer.cxx +++ b/src/CellBuffer.cxx @@ -521,6 +521,9 @@ void CellBuffer::SetLineEndTypes(LineEndType utf8LineEnds_) { } bool CellBuffer::ContainsLineEnd(const char *s, Sci::Position length) const noexcept { + if (utf8LineEnds == LineEndType::None) { + return false; + } unsigned char chBeforePrev = 0; unsigned char chPrev = 0; for (Sci::Position i = 0; i < length; i++) { @@ -572,6 +575,8 @@ Sci::Position CellBuffer::LineStart(Sci::Line line) const noexcept { return 0; else if (line >= Lines()) return Length(); + else if (LineEndType::None == GetLineEndTypes()) + return 0; else return plv->LineStart(line); } @@ -579,6 +584,8 @@ Sci::Position CellBuffer::LineStart(Sci::Line line) const noexcept { Sci::Position CellBuffer::LineEnd(Sci::Line line) const noexcept { if (line >= Lines() - 1) { return LineStart(line + 1); + } else if (LineEndType::None == GetLineEndTypes()) { + return Length(); } else { Sci::Position position = LineStart(line + 1); if (LineEndType::Unicode == GetLineEndTypes()) { @@ -718,6 +725,11 @@ void CellBuffer::ResetLineEnds() { constexpr Sci::Position position = 0; const Sci::Position length = Length(); plv->InsertText(0, length); + + if (LineEndType::None == GetLineEndTypes()) { + return; + } + Sci::Line lineInsert = 1; constexpr bool atLineStart = true; unsigned char chBeforePrev = 0; @@ -819,7 +831,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P plv->InsertText(lineInsert-1, insertLength); unsigned char chBeforePrev = substance.ValueAt(position - 2); unsigned char chPrev = substance.ValueAt(position - 1); - if (chPrev == '\r' && chAfter == '\n') { + if (LineEndType::None != GetLineEndTypes() && chPrev == '\r' && chAfter == '\n') { // Splitting up a crlf pair at position InsertLine(lineInsert, position, false); lineInsert++; @@ -838,7 +850,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P const char *ptr = s; unsigned char ch = 0; - if (chPrev == '\r' && *ptr == '\n') { + if (LineEndType::None != GetLineEndTypes() && chPrev == '\r' && *ptr == '\n') { ++ptr; // Patch up what was end of line plv->SetLineStart(lineInsert - 1, (position + ptr - s)); @@ -847,8 +859,10 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P if (ptr < end) { uint8_t eolTable[256]{}; - eolTable[static_cast('\n')] = 1; - eolTable[static_cast('\r')] = 2; + if (LineEndType::None != GetLineEndTypes()) { + eolTable[static_cast('\n')] = 1; + eolTable[static_cast('\r')] = 2; + } if (utf8LineEnds == LineEndType::Unicode) { // see UniConversion.h for LS, PS and NEL eolTable[0x85] = 4; @@ -906,7 +920,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P ch = *end; if (ptr == end) { ++ptr; - if (ch == '\r' || ch == '\n') { + if (LineEndType::None != GetLineEndTypes() && (ch == '\r' || ch == '\n')) { InsertLine(lineInsert, (position + ptr - s), atLineStart); lineInsert++; } else if (utf8LineEnds == LineEndType::Unicode && !UTF8IsAscii(ch)) { @@ -918,7 +932,7 @@ void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::P } // Joining two lines where last insertion is cr and following substance starts with lf - if (chAfter == '\n') { + if (LineEndType::None != GetLineEndTypes() && chAfter == '\n') { if (ch == '\r') { // End of line already in buffer so drop the newly created one RemoveLine(lineInsert - 1); @@ -999,7 +1013,7 @@ void CellBuffer::BasicDeleteChars(Sci::Position position, Sci::Position deleteLe } bool ignoreNL = false; - if (chPrev == '\r' && chNext == '\n') { + if (LineEndType::None != GetLineEndTypes() && chPrev == '\r' && chNext == '\n') { // Move back one plv->SetLineStart(lineRemove, position); lineRemove++; @@ -1011,38 +1025,40 @@ void CellBuffer::BasicDeleteChars(Sci::Position position, Sci::Position deleteLe } } - unsigned char ch = chNext; - for (Sci::Position i = 0; i < deleteLength; i++) { - chNext = substance.ValueAt(position + i + 1); - if (ch == '\r') { - if (chNext != '\n') { - RemoveLine(lineRemove); - } - } else if (ch == '\n') { - if (ignoreNL) { - ignoreNL = false; // Further \n are real deletions - } else { - RemoveLine(lineRemove); - } - } else if (utf8LineEnds == LineEndType::Unicode) { - if (!UTF8IsAscii(ch)) { - const unsigned char next3[3] = {ch, chNext, - static_cast(substance.ValueAt(position + i + 2))}; - if (UTF8IsSeparator(next3) || UTF8IsNEL(next3)) { + if (LineEndType::None != GetLineEndTypes()) { + unsigned char ch = chNext; + for (Sci::Position i = 0; i < deleteLength; i++) { + chNext = substance.ValueAt(position + i + 1); + if (ch == '\r') { + if (chNext != '\n') { RemoveLine(lineRemove); } + } else if (ch == '\n') { + if (ignoreNL) { + ignoreNL = false; // Further \n are real deletions + } else { + RemoveLine(lineRemove); + } + } else if (utf8LineEnds == LineEndType::Unicode) { + if (!UTF8IsAscii(ch)) { + const unsigned char next3[3] = {ch, chNext, + static_cast(substance.ValueAt(position + i + 2))}; + if (UTF8IsSeparator(next3) || UTF8IsNEL(next3)) { + RemoveLine(lineRemove); + } + } } - } - ch = chNext; - } - // May have to fix up end if last deletion causes cr to be next to lf - // or removes one of a crlf pair - const char chAfter = substance.ValueAt(position + deleteLength); - if (chBefore == '\r' && chAfter == '\n') { - // Using lineRemove-1 as cr ended line before start of deletion - RemoveLine(lineRemove - 1); - plv->SetLineStart(lineRemove - 1, position + 1); + ch = chNext; + } + // May have to fix up end if last deletion causes cr to be next to lf + // or removes one of a crlf pair + const char chAfter = substance.ValueAt(position + deleteLength); + if (chBefore == '\r' && chAfter == '\n') { + // Using lineRemove-1 as cr ended line before start of deletion + RemoveLine(lineRemove - 1); + plv->SetLineStart(lineRemove - 1, position + 1); + } } } substance.DeleteRange(position, deleteLength); diff --git a/src/Document.cxx b/src/Document.cxx index c79c5002b..5025b3fe2 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -100,7 +100,7 @@ LineEndType LexInterface::LineEndTypesSupported() { if (instance) { return static_cast(instance->LineEndTypesSupported()); } - return LineEndType::Default; + return LineEndType::None; } bool LexInterface::UseContainerLexing() const noexcept { @@ -260,7 +260,7 @@ LineAnnotation *Document::EOLAnnotations() const noexcept { LineEndType Document::LineEndTypesSupported() const { if ((CpUtf8 == dbcsCodePage) && pli) return pli->LineEndTypesSupported(); - return LineEndType::Default; + return LineEndType::None; } bool Document::SetDBCSCodePage(int dbcsCodePage_) { diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx index 1f4c360da..90b3d3275 100644 --- a/src/ScintillaBase.cxx +++ b/src/ScintillaBase.cxx @@ -735,7 +735,7 @@ LineEndType LexState::LineEndTypesSupported() { if (instance) { return static_cast(instance->LineEndTypesSupported()); } - return LineEndType::Default; + return LineEndType::None; } int LexState::AllocateSubStyles(int styleBase, int numberStyles) { -- cgit v1.2.3