diff options
author | Iain Clarke <unknown> | 2018-12-12 09:26:18 +1100 |
---|---|---|
committer | Iain Clarke <unknown> | 2018-12-12 09:26:18 +1100 |
commit | a402d41e20e8fa48ee20bc4a4b5f866ace0c5d32 (patch) | |
tree | b8f2bb59ac39734a5e8fe3f5228f6177f28f7ee4 | |
parent | 197bc747b2561b3bd342d5426a2493246d488db1 (diff) | |
download | scintilla-mirror-a402d41e20e8fa48ee20bc4a4b5f866ace0c5d32.tar.gz |
Backport: Feature [feature-requests:#1247]. Handles message groups as well as messages.
Backport of changeset 7186:8849447859eb.
-rw-r--r-- | doc/ScintillaHistory.html | 5 | ||||
-rw-r--r-- | lexers/LexEDIFACT.cxx | 109 |
2 files changed, 83 insertions, 31 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 1cc91e184..540a4e4d1 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -568,6 +568,11 @@ operators correctly by following operator precedence rules. <a href="https://sourceforge.net/p/scintilla/bugs/2069/">Bug #2069</a>. </li> + <li> + The EDIFACT lexer handles message groups as well as messages. + <a href="https://sourceforge.net/p/scintilla/feature-requests/1247/">Feature #1247</a>. + </li> + </li> <li> Notify with SC_UPDATE_SELECTION when user performs a multiple selection add. </li> diff --git a/lexers/LexEDIFACT.cxx b/lexers/LexEDIFACT.cxx index 6da0759a0..1e0becab2 100644 --- a/lexers/LexEDIFACT.cxx +++ b/lexers/LexEDIFACT.cxx @@ -80,8 +80,8 @@ public: { return -1; } - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; + void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override; + void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override; void * SCI_METHOD PrivateCall(int, void *) override { return NULL; @@ -125,9 +125,9 @@ LexerEDIFACT::LexerEDIFACT() m_chSegment = '\''; } -void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int, IDocument *pAccess) +void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess) { - Sci_PositionU posFinish = startPos + lengthDoc; + Sci_PositionU posFinish = startPos + length; InitialiseFromUNA(pAccess, posFinish); // Look backwards for a ' or a document beginning @@ -205,40 +205,85 @@ void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int, IDoc pAccess->SetStyleFor(posFinish - posSegmentStart, SCE_EDI_BADSEGMENT); } -void LexerEDIFACT::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int, IDocument *pAccess) +void LexerEDIFACT::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess) { if (!m_bFold) return; - // Fold at UNx lines. ie, UNx segments = 0, other segments = 1. - // There's no sub folding, so we can be quite simple. - Sci_Position endPos = startPos + lengthDoc; + Sci_PositionU endPos = startPos + length; + startPos = FindPreviousEnd(pAccess, startPos); + char c; char SegmentHeader[4] = { 0 }; - int iIndentPrevious = 0; - Sci_Position lineLast = pAccess->LineFromPosition(endPos); + bool AwaitingSegment = true; + Sci_PositionU currLine = pAccess->LineFromPosition(startPos); + int levelCurrentStyle = SC_FOLDLEVELBASE; + if (currLine > 0) + levelCurrentStyle = pAccess->GetLevel(currLine - 1); // bottom 12 bits are level + int indentCurrent = levelCurrentStyle & SC_FOLDLEVELNUMBERMASK; + int indentNext = indentCurrent; - for (Sci_Position lineCurrent = pAccess->LineFromPosition(startPos); lineCurrent <= lineLast; lineCurrent++) + while (startPos < endPos) { - Sci_Position posLineStart = pAccess->LineStart(lineCurrent); - posLineStart = ForwardPastWhitespace(pAccess, posLineStart, endPos); - Sci_Position lineDataStart = pAccess->LineFromPosition(posLineStart); - // Fill in whitespace lines? - for (; lineCurrent < lineDataStart; lineCurrent++) - pAccess->SetLevel(lineCurrent, SC_FOLDLEVELBASE | SC_FOLDLEVELWHITEFLAG | iIndentPrevious); - pAccess->GetCharRange(SegmentHeader, posLineStart, 3); - //if (DetectSegmentHeader(SegmentHeader) == SCE_EDI_BADSEGMENT) // Abort if this is not a proper segment header - - int level = 0; - if (memcmp(SegmentHeader, "UNH", 3) == 0) // UNH starts blocks - level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; - // Check for UNA,B and Z. All others are inside messages - else if (!memcmp(SegmentHeader, "UNA", 3) || !memcmp(SegmentHeader, "UNB", 3) || !memcmp(SegmentHeader, "UNZ", 3)) - level = SC_FOLDLEVELBASE; - else - level = SC_FOLDLEVELBASE | 1; - pAccess->SetLevel(lineCurrent, level); - iIndentPrevious = level & SC_FOLDLEVELNUMBERMASK; + pAccess->GetCharRange(&c, startPos, 1); + switch (c) + { + case '\t': + case '\r': + case ' ': + startPos++; + continue; + case '\n': + currLine = pAccess->LineFromPosition(startPos); + pAccess->SetLevel(currLine, levelCurrentStyle | indentCurrent); + startPos++; + levelCurrentStyle = SC_FOLDLEVELBASE; + indentCurrent = indentNext; + continue; + } + if (c == m_chRelease) + { + startPos += 2; + continue; + } + if (c == m_chSegment) + { + AwaitingSegment = true; + startPos++; + continue; + } + + if (!AwaitingSegment) + { + startPos++; + continue; + } + + // Segment! + pAccess->GetCharRange(SegmentHeader, startPos, 3); + if (SegmentHeader[0] != 'U' || SegmentHeader[1] != 'N') + { + startPos++; + continue; + } + + AwaitingSegment = false; + switch (SegmentHeader[2]) + { + case 'H': + case 'G': + indentNext++; + levelCurrentStyle = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; + break; + + case 'T': + case 'E': + if (indentNext > 0) + indentNext--; + break; + } + + startPos += 3; } } @@ -314,7 +359,9 @@ int LexerEDIFACT::DetectSegmentHeader(char SegmentHeader[3]) const if (m_bHighlightAllUN && !memcmp(SegmentHeader, "UN", 2)) return SCE_EDI_UNH; - else if (memcmp(SegmentHeader, "UNH", 3) == 0) + else if (!memcmp(SegmentHeader, "UNH", 3)) + return SCE_EDI_UNH; + else if (!memcmp(SegmentHeader, "UNG", 3)) return SCE_EDI_UNH; return SCE_EDI_SEGMENTSTART; |