static void ColouriseYAMLDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) { char lineBuffer[1024]; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0; unsigned int startLine = startPos; unsigned int endPos = startPos + length; unsigned int maxPos = styler.Length(); unsigned int lineCurrent = styler.GetLine(startPos); for (unsigned int i = startPos; i < maxPos && i < endPos; i++) { lineBuffer[linePos++] = styler[i]; if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it lineBuffer[linePos] = '\0'; ColouriseYAMLLine(lineBuffer, lineCurrent, linePos, startLine, i, *keywordLists[0], styler); linePos = 0; startLine = i + 1; lineCurrent++; } } if (linePos > 0) { // Last line does not have ending characters ColouriseYAMLLine(lineBuffer, lineCurrent, linePos, startLine, startPos + length - 1, *keywordLists[0], styler); } }
static void FoldSolDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { int lengthDoc = startPos + length; int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { if (lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); if (startPos == 0) initStyle = SCE_SCRIPTOL_DEFAULT; else initStyle = styler.StyleAt(startPos-1); } } int state = initStyle & 31; int spaceFlags = 0; int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment); if ((state == SCE_SCRIPTOL_TRIPLE)) indentCurrent |= SC_FOLDLEVELWHITEFLAG; char chNext = styler[startPos]; for (int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styler.StyleAt(i) & 31; if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) { int lev = indentCurrent; int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsSolComment); if (style == SCE_SCRIPTOL_TRIPLE) indentNext |= SC_FOLDLEVELWHITEFLAG; if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { // Only non whitespace lines can be headers if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } else if (indentNext & SC_FOLDLEVELWHITEFLAG) { // Line after is blank so check the next - maybe should continue further? int spaceFlags2 = 0; int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsSolComment); if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } } } indentCurrent = indentNext; styler.SetLevel(lineCurrent, lev); lineCurrent++; } } }
// Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". static void FoldNoBox4glDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = static_cast<char>(tolower(styler[startPos])); int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1))); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelNext++; } else if (!IsStreamCommentStyle(styleNext)) { // && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } else if ((style & 0xf) == SCE_4GL_BLOCK && !isalnum(chNext)) { levelNext++; } else if ((style & 0xf) == SCE_4GL_END && (ch == 'e' || ch == 'f')) { levelNext--; } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } }
void Fold_Doc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); // Comment folding if (foldComment && atEOL && IsCommentLine(lineCurrent, styler)) { if (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler)) levelCurrent++; else if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent+1, styler)) levelCurrent--; } if (style == sID::OPERATOR) { if ( ch == '<' && chNext != '/' ) { levelCurrent++; } else if (ch == '<' && chNext == '/') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); }
// Main folding function called by Scintilla - (based on props (.ini) files function) static void FoldGui4Cli(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); bool headerPoint = false; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler[i+1]; int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_GC_EVENT || style == SCE_GC_GLOBAL) { headerPoint = true; // fold at events and globals } if (atEOL) { int lev = SC_FOLDLEVELBASE+1; if (headerPoint) lev = SC_FOLDLEVELBASE; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (headerPoint) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) // set level, if not already correct { styler.SetLevel(lineCurrent, lev); } lineCurrent++; // re-initialize our flags visibleChars = 0; headerPoint = false; } if (!(isspacechar(ch))) // || (style == SCE_GC_COMMENTLINE) || (style != SCE_GC_COMMENTBLOCK))) visibleChars++; } int lev = headerPoint ? SC_FOLDLEVELBASE : SC_FOLDLEVELBASE+1; int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, lev | flagsNext); }
static void FoldPSDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); //mac?? if ((style & 31) == SCE_PS_PAREN_PROC) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } }
static int LineEnd(int line, Accessor &styler) { const int docLines = styler.GetLine(styler.Length() - 1); // Available last line int eol_pos ; // if the line is the last line, the eol_pos is styler.Length() // eol will contain a new line, or a virtual new line if ( docLines == line ) eol_pos = styler.Length() ; else eol_pos = styler.LineStart(line + 1) - 1; return eol_pos ; }
static void FoldGAPDoc( unsigned int startPos, int length, int initStyle, WordList** , Accessor &styler) { unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; int lastStart = 0; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (stylePrev != SCE_GAP_KEYWORD && style == SCE_GAP_KEYWORD) { // Store last word start point. lastStart = i; } if (stylePrev == SCE_GAP_KEYWORD) { if(iswordchar(ch) && !iswordchar(chNext)) { char s[100]; GetRange(lastStart, i, styler, s, sizeof(s)); levelCurrent += ClassifyFoldPointGAP(s); } } if (atEOL) { int lev = levelPrev; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); }
// Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment. static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) { levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16; }
static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos+length; int visibleChars=0; int lineCurrent=styler.GetLine(startPos); int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent=levelPrev; char chNext=styler[startPos]; char buffer[100]=""; for (unsigned int i=startPos; i < endPos; i++) { char ch=chNext; chNext=styler.SafeGetCharAt(i+1); char chPrev=styler.SafeGetCharAt(i-1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if(i==0 || chPrev == '\r' || chPrev=='\n'|| chPrev==' '|| chPrev=='(' || chPrev=='$') { ParseMetapostWord(i, styler, buffer); levelCurrent += classifyFoldPointMetapost(buffer,keywordlists); } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); }
void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler) const { if (fnFolder) { int lineCurrent = styler.GetLine(startPos); // Move back one line in case deletion wrecked current line fold state if (lineCurrent > 0) { lineCurrent--; int newStartPos = styler.LineStart(lineCurrent); lengthDoc += startPos - newStartPos; startPos = newStartPos; initStyle = 0; if (startPos > 0) { initStyle = styler.StyleAt(startPos - 1); } } fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler); } }
static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler, bool (*IsComment)(Accessor&, int, int)) { int endPos = startPos + length; // Backtrack to previous line in case need to fix its fold status int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { if (lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } } int spaceFlags = 0; int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment); char chNext = styler[startPos]; for (int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) { int lev = indentCurrent; int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { // Only non whitespace lines can be headers if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } else if (indentNext & SC_FOLDLEVELWHITEFLAG) { // Line after is blank so check the next - maybe should continue further? int spaceFlags2 = 0; int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment); if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } } } indentCurrent = indentNext; styler.SetLevel(lineCurrent, lev); lineCurrent++; } } }
static void FoldRebolDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[], Accessor &styler) { unsigned int lengthDoc = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_REBOL_DEFAULT) { if (ch == '[') { levelCurrent++; } else if (ch == ']') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); }
static void ColouriseLuaDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; WordList &keywords7 = *keywordlists[6]; WordList &keywords8 = *keywordlists[7]; // Accepts accented characters CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. [pP] is for hex floats. CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP"); CharacterSet setExponent(CharacterSet::setNone, "eEpP"); CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#"); CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\"); int currentLine = styler.GetLine(startPos); // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level, // if we are inside such a string. Block comment was introduced in Lua 5.0, // blocks with separators [=[ ... ]=] in Lua 5.1. // Continuation of a string (\z whitespace escaping) is controlled by stringWs. int nestLevel = 0; int sepCount = 0; int stringWs = 0; if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT || initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) { int lineState = styler.GetLineState(currentLine - 1); nestLevel = lineState >> 9; sepCount = lineState & 0xFF; stringWs = lineState & 0x100; }
// // ColouriseDocument // static void ColouriseDocument( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; StyleContext sc(startPos, length, initStyle, styler); int lineCurrent = styler.GetLine(startPos); bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0; while (sc.More()) { if (sc.atLineEnd) { // Go to the next line sc.Forward(); lineCurrent++; // Remember the line state for future incremental lexing styler.SetLineState(lineCurrent, apostropheStartsAttribute); // Don't continue any styles on the next line sc.SetState(SCE_SPICE_DEFAULT); } // Comments if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) { ColouriseComment(sc, apostropheStartsAttribute); // Whitespace } else if (IsASpace(sc.ch)) { ColouriseWhiteSpace(sc, apostropheStartsAttribute); // Delimiters } else if (IsDelimiterCharacter(sc.ch)) { ColouriseDelimiter(sc, apostropheStartsAttribute); // Numbers } else if (IsADigit(sc.ch) || sc.ch == '#') { ColouriseNumber(sc, apostropheStartsAttribute); // Keywords or identifiers } else { ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute); } } sc.Complete(); }
static void FoldFlagShipDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { int endPos = startPos + length; // Backtrack to previous line in case need to fix its fold status int lineCurrent = styler.GetLine(startPos); if (startPos > 0 && lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } int spaceFlags = 0; int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags); char chNext = styler[startPos]; for (int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos-1)) { int lev = indentCurrent; int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } else if (indentNext & SC_FOLDLEVELWHITEFLAG) { int spaceFlags2 = 0; int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2); if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } } } indentCurrent = indentNext; styler.SetLevel(lineCurrent, lev); lineCurrent++; } } }
static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { unsigned int endPos = startPos + length; char chNext = styler[startPos]; int lineCurrent = styler.GetLine(startPos); bool sectionFlag = false; int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE; int level; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler[i+1]; bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); int style = styler.StyleAt(i); if (style == SCE_INNO_SECTION) sectionFlag = true; if (atEOL || i == endPos - 1) { if (sectionFlag) { level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; if (level == levelPrev) styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG); } else { level = levelPrev & SC_FOLDLEVELNUMBERMASK; if (levelPrev & SC_FOLDLEVELHEADERFLAG) level++; } styler.SetLevel(lineCurrent, level); levelPrev = level; lineCurrent++; sectionFlag = false; } } }
static void FoldCmakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { // No folding enabled, no reason to continue... if ( styler.GetPropertyInt("fold") == 0 ) return; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1; int lineCurrent = styler.GetLine(startPos); unsigned int safeStartPos = styler.LineStart( lineCurrent ); bool bArg1 = true; int nWordStart = -1; int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelNext = levelCurrent; for (unsigned int i = safeStartPos; i < startPos + length; i++) { char chCurr = styler.SafeGetCharAt(i); if ( bArg1 ) { if ( nWordStart == -1 && (isCmakeLetter(chCurr)) ) { nWordStart = i; } else if ( isCmakeLetter(chCurr) == false && nWordStart > -1 ) { int newLevel = calculateFoldCmake( nWordStart, i-1, levelNext, styler, foldAtElse); if ( newLevel == levelNext ) { if ( foldAtElse ) { if ( CmakeNextLineHasElse(i, startPos + length, styler) ) levelNext--; } } else levelNext = newLevel; bArg1 = false; } } if ( chCurr == '\n' ) { if ( bArg1 && foldAtElse) { if ( CmakeNextLineHasElse(i, startPos + length, styler) ) levelNext--; } // If we are on a new line... int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (levelUse < levelNext ) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); lineCurrent++; levelCurrent = levelNext; bArg1 = true; // New line, lets look at first argument again nWordStart = -1; } } int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); }
static void ColouriseCmakeDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) { int state = SCE_CMAKE_DEFAULT; if ( startPos > 0 ) state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox styler.StartAt( startPos ); styler.GetLine( startPos ); unsigned int nLengthDoc = startPos + length; styler.StartSegment( startPos ); char cCurrChar; bool bVarInString = false; bool bClassicVarInString = false; unsigned int i; for ( i = startPos; i < nLengthDoc; i++ ) { cCurrChar = styler.SafeGetCharAt( i ); char cNextChar = styler.SafeGetCharAt(i+1); switch (state) { case SCE_CMAKE_DEFAULT: if ( cCurrChar == '#' ) { // we have a comment line styler.ColourTo(i-1, state ); state = SCE_CMAKE_COMMENT; break; } if ( cCurrChar == '"' ) { styler.ColourTo(i-1, state ); state = SCE_CMAKE_STRINGDQ; bVarInString = false; bClassicVarInString = false; break; } if ( cCurrChar == '\'' ) { styler.ColourTo(i-1, state ); state = SCE_CMAKE_STRINGRQ; bVarInString = false; bClassicVarInString = false; break; } if ( cCurrChar == '`' ) { styler.ColourTo(i-1, state ); state = SCE_CMAKE_STRINGLQ; bVarInString = false; bClassicVarInString = false; break; } // CMake Variable if ( cCurrChar == '$' || isCmakeChar(cCurrChar)) { styler.ColourTo(i-1,state); state = SCE_CMAKE_VARIABLE; // If it is a number, we must check and set style here first... if ( isCmakeNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) ) styler.ColourTo( i, SCE_CMAKE_NUMBER); break; } break; case SCE_CMAKE_COMMENT: if ( cNextChar == '\n' || cNextChar == '\r' ) { // Special case: if ( cCurrChar == '\\' ) { styler.ColourTo(i-2,state); styler.ColourTo(i,SCE_CMAKE_DEFAULT); } else { styler.ColourTo(i,state); state = SCE_CMAKE_DEFAULT; } } break; case SCE_CMAKE_STRINGDQ: case SCE_CMAKE_STRINGLQ: case SCE_CMAKE_STRINGRQ: if ( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' ) break; // Ignore the next character, even if it is a quote of some sort if ( cCurrChar == '"' && state == SCE_CMAKE_STRINGDQ ) { styler.ColourTo(i,state); state = SCE_CMAKE_DEFAULT; break; } if ( cCurrChar == '`' && state == SCE_CMAKE_STRINGLQ ) { styler.ColourTo(i,state); state = SCE_CMAKE_DEFAULT; break; } if ( cCurrChar == '\'' && state == SCE_CMAKE_STRINGRQ ) { styler.ColourTo(i,state); state = SCE_CMAKE_DEFAULT; break; } if ( cNextChar == '\r' || cNextChar == '\n' ) { int nCurLine = styler.GetLine(i+1); int nBack = i; // We need to check if the previous line has a \ in it... bool bNextLine = false; while ( nBack > 0 ) { if ( styler.GetLine(nBack) != nCurLine ) break; char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here if ( cTemp == '\\' ) { bNextLine = true; break; } if ( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' ) break; nBack--; } if ( bNextLine ) { styler.ColourTo(i+1,state); } if ( bNextLine == false ) { styler.ColourTo(i,state); state = SCE_CMAKE_DEFAULT; } } break; case SCE_CMAKE_VARIABLE: // CMake Variable: if ( cCurrChar == '$' ) state = SCE_CMAKE_DEFAULT; else if ( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) ) state = SCE_CMAKE_DEFAULT; else if ( (isCmakeChar(cCurrChar) && !isCmakeChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' ) { state = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler ); styler.ColourTo( i, state); state = SCE_CMAKE_DEFAULT; } else if ( !isCmakeChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' ) { if ( classifyWordCmake( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_CMAKE_NUMBER ) styler.ColourTo( i-1, SCE_CMAKE_NUMBER ); state = SCE_CMAKE_DEFAULT; if ( cCurrChar == '"' ) { state = SCE_CMAKE_STRINGDQ; bVarInString = false; bClassicVarInString = false; } else if ( cCurrChar == '`' ) { state = SCE_CMAKE_STRINGLQ; bVarInString = false; bClassicVarInString = false; } else if ( cCurrChar == '\'' ) { state = SCE_CMAKE_STRINGRQ; bVarInString = false; bClassicVarInString = false; } else if ( cCurrChar == '#' ) { state = SCE_CMAKE_COMMENT; } } break; } if ( state == SCE_CMAKE_COMMENT) { styler.ColourTo(i,state); } else if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) { bool bIngoreNextDollarSign = false; if ( bVarInString && cCurrChar == '$' ) { bVarInString = false; bIngoreNextDollarSign = true; } else if ( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) ) { styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR); bVarInString = false; bIngoreNextDollarSign = false; } else if ( bVarInString && !isCmakeChar(cNextChar) ) { int nWordState = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler); if ( nWordState == SCE_CMAKE_VARIABLE ) styler.ColourTo( i, SCE_CMAKE_STRINGVAR); bVarInString = false; } // Covers "${TEST}..." else if ( bClassicVarInString && cNextChar == '}' ) { styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR); bClassicVarInString = false; } // Start of var in string if ( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' ) { styler.ColourTo( i-1, state); bClassicVarInString = true; bVarInString = false; } else if ( !bIngoreNextDollarSign && cCurrChar == '$' ) { styler.ColourTo( i-1, state); bVarInString = true; bClassicVarInString = false; } } } // Colourise remaining document styler.ColourTo(nLengthDoc-1,state); }
static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos+length; int visibleChars=0; int lineCurrent=styler.GetLine(startPos); int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent=levelPrev; char chNext=styler[startPos]; char buffer[100]=""; for (unsigned int i=startPos; i < endPos; i++) { char ch=chNext; chNext=styler.SafeGetCharAt(i+1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if(ch=='\\') { ParseTeXCommand(i, styler, buffer); levelCurrent += classifyFoldPointTeXPaired(buffer)+classifyFoldPointTeXUnpaired(buffer); } if (levelCurrent > SC_FOLDLEVELBASE && ((ch == '\r' || ch=='\n') && (chNext == '\\'))) { ParseTeXCommand(i+1, styler, buffer); levelCurrent -= classifyFoldPointTeXUnpaired(buffer); } char chNext2; char chNext3; char chNext4; char chNext5; chNext2=styler.SafeGetCharAt(i+2); chNext3=styler.SafeGetCharAt(i+3); chNext4=styler.SafeGetCharAt(i+4); chNext5=styler.SafeGetCharAt(i+5); bool atEOfold = (ch == '%') && (chNext == '%') && (chNext2=='}') && (chNext3=='}')&& (chNext4=='-')&& (chNext5=='-'); bool atBOfold = (ch == '%') && (chNext == '%') && (chNext2=='-') && (chNext3=='-')&& (chNext4=='{')&& (chNext5=='{'); if(atBOfold){ levelCurrent+=1; } if(atEOfold){ levelCurrent-=1; } if(ch=='\\' && chNext=='['){ levelCurrent+=1; } if(ch=='\\' && chNext==']'){ levelCurrent-=1; } bool foldComment = styler.GetPropertyInt("fold.comment") != 0; if (foldComment && atEOL && IsTeXCommentLine(lineCurrent, styler)) { if (lineCurrent==0 && IsTeXCommentLine(lineCurrent + 1, styler) ) levelCurrent++; else if (lineCurrent!=0 && !IsTeXCommentLine(lineCurrent - 1, styler) && IsTeXCommentLine(lineCurrent + 1, styler) ) levelCurrent++; else if (lineCurrent!=0 && IsTeXCommentLine(lineCurrent - 1, styler) && !IsTeXCommentLine(lineCurrent+1, styler)) levelCurrent--; } //--------------------------------------------------------------------------------------------- if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); }
// Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; // Verilog specific folding options: // fold_at_module - // Generally used methodology in verilog code is // one module per file, so folding at module definition is useless. // fold_at_brace/parenthese - // Folding of long port lists can be convenient. bool foldAtModule = styler.GetPropertyInt("fold.verilog.flags", 0) != 0; bool foldAtBrace = 1; bool foldAtParenthese = 1; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelNext++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } if (foldComment && atEOL && IsCommentLine(lineCurrent, styler)) { if (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler)) levelNext++; else if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent+1, styler)) levelNext--; } if (foldComment && (style == SCE_V_COMMENTLINE)) { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelNext++; } else if (chNext2 == '}') { levelNext--; } } } if (foldPreprocessor && (style == SCE_V_PREPROCESSOR)) { if (ch == '`') { unsigned int j = i + 1; while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { j++; } if (styler.Match(j, "if")) { levelNext++; } else if (styler.Match(j, "end")) { levelNext--; } } } if (style == SCE_V_OPERATOR) { if (foldAtParenthese) { if (ch == '(') { levelNext++; } else if (ch == ')') { levelNext--; } } } if (style == SCE_V_OPERATOR) { if (foldAtBrace) { if (ch == '{') { levelNext++; } else if (ch == '}') { levelNext--; } } } if (style == SCE_V_WORD && stylePrev != SCE_V_WORD) { unsigned int j = i; if (styler.Match(j, "case") || styler.Match(j, "casex") || styler.Match(j, "casez") || styler.Match(j, "function") || styler.Match(j, "fork") || styler.Match(j, "table") || styler.Match(j, "task") || styler.Match(j, "generate") || styler.Match(j, "specify") || styler.Match(j, "primitive") || (styler.Match(j, "module") && foldAtModule) || styler.Match(j, "begin")) { levelNext++; } else if (styler.Match(j, "endcase") || styler.Match(j, "endfunction") || styler.Match(j, "join") || styler.Match(j, "endtask") || styler.Match(j, "endgenerate") || styler.Match(j, "endtable") || styler.Match(j, "endspecify") || styler.Match(j, "endprimitive") || (styler.Match(j, "endmodule") && foldAtModule) || (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) { levelNext--; } } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } }
static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { // No folding enabled, no reason to continue... if( styler.GetPropertyInt("fold") == 0 ) return; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1; bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1; bool blockComment = false; int lineCurrent = styler.GetLine(startPos); unsigned int safeStartPos = styler.LineStart( lineCurrent ); bool bArg1 = true; int nWordStart = -1; int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelNext = levelCurrent; int style = styler.StyleAt(safeStartPos); if( style == SCE_NSIS_COMMENTBOX ) { if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' ) levelNext++; blockComment = true; } for (unsigned int i = safeStartPos; i < startPos + length; i++) { char chCurr = styler.SafeGetCharAt(i); style = styler.StyleAt(i); if( blockComment && style != SCE_NSIS_COMMENTBOX ) { levelNext--; blockComment = false; } else if( !blockComment && style == SCE_NSIS_COMMENTBOX ) { levelNext++; blockComment = true; } if( bArg1 && !blockComment) { if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') ) { nWordStart = i; } else if( isNsisLetter(chCurr) == false && nWordStart > -1 ) { int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd ); if( newLevel == levelNext ) { if( foldAtElse && foldUtilityCmd ) { if( NsisNextLineHasElse(i, startPos + length, styler) ) levelNext--; } } else levelNext = newLevel; bArg1 = false; } } if( chCurr == '\n' ) { if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment ) { if( NsisNextLineHasElse(i, startPos + length, styler) ) levelNext--; } // If we are on a new line... int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (levelUse < levelNext ) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); lineCurrent++; levelCurrent = levelNext; bArg1 = true; // New line, lets look at first argument again nWordStart = -1; } } int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); }
//The folding routine for PowerBasic toggles SUBs and FUNCTIONs only. This was exactly what I wanted, //nothing more. I had worked with this kind of toggling for several years when I used the great good old //GFA Basic which is dead now. After testing the feature of toggling FOR-NEXT loops, WHILE-WEND loops //and so on too I found this is more disturbing then helping (for me). So if You think in another way //you can (or must) write Your own toggling routine ;-) static void FoldPBDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { // No folding enabled, no reason to continue... if( styler.GetPropertyInt("fold") == 0 ) return; unsigned int endPos = startPos + length; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelNext = levelCurrent; char chNext = styler[startPos]; bool fNewLine=true; bool fMightBeMultiLineMacro=false; bool fBeginOfCommentFound=false; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if (fNewLine) //Begin of a new line (The Sub/Function/Macro keywords may occur at begin of line only) { fNewLine=false; fBeginOfCommentFound=false; switch (ch) { case ' ': //Most lines start with space - so check this first, the code is the same as for 'default:' case '\t': //Handle tab too { int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; styler.SetLevel(lineCurrent, lev); break; } case 'F': case 'f': { switch (chNext) { case 'U': case 'u': { if( MatchUpperCase(styler,i,"FUNCTION") ) { styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } break; } } break; } case 'S': case 's': { switch (chNext) { case 'U': case 'u': { if( MatchUpperCase(styler,i,"SUB") ) { styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } break; } case 'T': case 't': { if( MatchUpperCase(styler,i,"STATIC FUNCTION") ) { styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } else if( MatchUpperCase(styler,i,"STATIC SUB") ) { styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } break; } } break; } case 'C': case 'c': { switch (chNext) { case 'A': case 'a': { if( MatchUpperCase(styler,i,"CALLBACK FUNCTION") ) { styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } break; } } break; } case 'M': case 'm': { switch (chNext) { case 'A': case 'a': { if( MatchUpperCase(styler,i,"MACRO") ) { fMightBeMultiLineMacro=true; //Set folder level at end of line, we have to check for single line macro } break; } } break; } default: { int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; styler.SetLevel(lineCurrent, lev); break; } } //switch (ch) } //if( fNewLine ) switch (ch) { case '=': //To test single line macros { if (fBeginOfCommentFound==false) fMightBeMultiLineMacro=false; //The found macro is a single line macro only; break; } case '\'': //A comment starts { fBeginOfCommentFound=true; break; } case '\n': { if (fMightBeMultiLineMacro) //The current line is the begin of a multi line macro { fMightBeMultiLineMacro=false; styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } lineCurrent++; levelCurrent = levelNext; fNewLine=true; break; } case '\r': { if (chNext != '\n') { lineCurrent++; levelCurrent = levelNext; fNewLine=true; } break; } } //switch (ch) } //for (unsigned int i = startPos; i < endPos; i++) }
static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; styler.StartAt(startPos); bool fold = styler.GetPropertyInt("fold") != 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; int state = initStyle; if (state == SCE_C_STRINGEOL) // Does not leak onto next line state = SCE_C_DEFAULT; char chPrev = ' '; char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; int visibleChars = 0; styler.StartSegment(startPos); int endFoundThisLine = 0; for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) // Avoid triggering two times on Dos/Win // End of line endFoundThisLine = 0; if (state == SCE_C_STRINGEOL) { styler.ColourTo(i, state); state = SCE_C_DEFAULT; } if (fold) { int lev = levelPrev; if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; styler.SetLevel(lineCurrent, lev); lineCurrent++; levelPrev = levelCurrent; } visibleChars = 0; /* int indentBlock = GetLineIndentation(lineCurrent); if (blockChange==1){ lineCurrent++; int pos=SetLineIndentation(lineCurrent, indentBlock + indentSize); } else if (blockChange==-1) { indentBlock -= indentSize; if (indentBlock < 0) indentBlock = 0; SetLineIndentation(lineCurrent, indentBlock); lineCurrent++; } blockChange=0; */ } if (!(IsASCII(ch) && isspace(ch))) visibleChars++; if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); chPrev = ' '; i += 1; continue; } if (state == SCE_C_DEFAULT) { if (iswordstart(ch)) { styler.ColourTo(i-1, state); state = SCE_C_IDENTIFIER; } else if (ch == '@' && chNext == 'o') { if ((styler.SafeGetCharAt(i+2) =='f') && (styler.SafeGetCharAt(i+3) == 'f')) { styler.ColourTo(i-1, state); state = SCE_C_COMMENT; } } else if (ch == '#') { styler.ColourTo(i-1, state); state = SCE_C_COMMENTLINE; } else if (ch == '\"') { styler.ColourTo(i-1, state); state = SCE_C_STRING; } else if (ch == '\'') { styler.ColourTo(i-1, state); state = SCE_C_CHARACTER; } else if (isoperator(ch)) { styler.ColourTo(i-1, state); styler.ColourTo(i, SCE_C_OPERATOR); } } else if (state == SCE_C_IDENTIFIER) { if (!iswordchar(ch)) { int levelChange = classifyWordBullant(styler.GetStartSegment(), i - 1, keywords, styler); state = SCE_C_DEFAULT; chNext = styler.SafeGetCharAt(i + 1); if (ch == '#') { state = SCE_C_COMMENTLINE; } else if (ch == '\"') { state = SCE_C_STRING; } else if (ch == '\'') { state = SCE_C_CHARACTER; } else if (isoperator(ch)) { styler.ColourTo(i, SCE_C_OPERATOR); } if (endFoundThisLine == 0) levelCurrent+=levelChange; if (levelChange == -1) endFoundThisLine=1; } } else if (state == SCE_C_COMMENT) { if (ch == '@' && chNext == 'o') { if (styler.SafeGetCharAt(i+2) == 'n') { styler.ColourTo(i+2, state); state = SCE_C_DEFAULT; i+=2; } } } else if (state == SCE_C_COMMENTLINE) { if (ch == '\r' || ch == '\n') { endFoundThisLine = 0; styler.ColourTo(i-1, state); state = SCE_C_DEFAULT; } } else if (state == SCE_C_STRING) { if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; ch = chNext; chNext = styler.SafeGetCharAt(i + 1); } } else if (ch == '\"') { styler.ColourTo(i, state); state = SCE_C_DEFAULT; } else if (chNext == '\r' || chNext == '\n') { endFoundThisLine = 0; styler.ColourTo(i-1, SCE_C_STRINGEOL); state = SCE_C_STRINGEOL; } } else if (state == SCE_C_CHARACTER) { if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { endFoundThisLine = 0; styler.ColourTo(i-1, SCE_C_STRINGEOL); state = SCE_C_STRINGEOL; } else if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; ch = chNext; chNext = styler.SafeGetCharAt(i + 1); } } else if (ch == '\'') { styler.ColourTo(i, state); state = SCE_C_DEFAULT; } } chPrev = ch; } styler.ColourTo(lengthDoc - 1, state); // Fill in the real level of the next line, keeping the current flags as they will be filled in later if (fold) { int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; //styler.SetLevel(lineCurrent, levelCurrent | flagsNext); styler.SetLevel(lineCurrent, levelPrev | flagsNext); } }
// Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment. static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16; int levelNext = levelCurrent; int styleNext = styler.StyleAt(startPos); int style = initStyle; int activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE; bool endPending = false; bool whenPending = false; bool elseIfPending = false; char nextChar = styler.SafeGetCharAt(startPos); for (unsigned int i = startPos; length > 0; i++, length--) { int stylePrev = style; int lastActiveState = activeState; style = styleNext; styleNext = styler.StyleAt(i + 1); activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE; char currentChar = nextChar; nextChar = styler.SafeGetCharAt(i + 1); bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n'); switch (MASKACTIVE(style)) { case SCE_MYSQL_COMMENT: if (foldComment) { // Multiline comment style /* .. */ just started or is still in progress. if (IsStreamCommentStyle(style) && !IsStreamCommentStyle(stylePrev)) levelNext++; } break; case SCE_MYSQL_COMMENTLINE: if (foldComment) { // Not really a standard, but we add support for single line comments // with special curly braces syntax as foldable comments too. // MySQL needs -- comments to be followed by space or control char if (styler.Match(i, "--")) { char chNext2 = styler.SafeGetCharAt(i + 2); char chNext3 = styler.SafeGetCharAt(i + 3); if (chNext2 == '{' || chNext3 == '{') levelNext++; else if (chNext2 == '}' || chNext3 == '}') levelNext--; } } break; case SCE_MYSQL_HIDDENCOMMAND: /* if (endPending) { // A conditional command is not a white space so it should end the current block // before opening a new one. endPending = false; levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } }*/ if (activeState != lastActiveState) levelNext++; break; case SCE_MYSQL_OPERATOR: if (endPending) { endPending = false; levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } if (currentChar == '(') levelNext++; else if (currentChar == ')') { levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } break; case SCE_MYSQL_MAJORKEYWORD: case SCE_MYSQL_KEYWORD: case SCE_MYSQL_FUNCTION: case SCE_MYSQL_PROCEDUREKEYWORD: // Reserved and other keywords. if (style != stylePrev) { // END decreases the folding level, regardless which keyword follows. bool endFound = MatchIgnoreCase(styler, i, "end"); if (endPending) { levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } else if (!endFound) { if (MatchIgnoreCase(styler, i, "begin")) levelNext++; else { if (!foldOnlyBegin) { bool whileFound = MatchIgnoreCase(styler, i, "while"); bool loopFound = MatchIgnoreCase(styler, i, "loop"); bool repeatFound = MatchIgnoreCase(styler, i, "repeat"); bool caseFound = MatchIgnoreCase(styler, i, "case"); if (whileFound || loopFound || repeatFound || caseFound) levelNext++; else { // IF alone does not increase the fold level as it is also used in non-block'ed // code like DROP PROCEDURE blah IF EXISTS. // Instead THEN opens the new level (if not part of an ELSEIF or WHEN (case) branch). if (MatchIgnoreCase(styler, i, "then")) { if (!elseIfPending && !whenPending) levelNext++; else { elseIfPending = false; whenPending = false; } } else { // Neither of if/then/while/loop/repeat/case, so check for // sub parts of IF and CASE. if (MatchIgnoreCase(styler, i, "elseif")) elseIfPending = true; if (MatchIgnoreCase(styler, i, "when")) whenPending = true; } } } } } // Keep the current end state for the next round. endPending = endFound; } break; default: if (!isspacechar(currentChar) && endPending) { // END followed by a non-whitespace character (not covered by other cases like identifiers) // also should end a folding block. Typical case: END followed by self defined delimiter. levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } break; } // Go up one level if we just ended a multi line comment. if (IsStreamCommentStyle(stylePrev) && !IsStreamCommentStyle(style)) { levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } if (activeState == 0 && lastActiveState != 0) { // Decrease fold level when we left a hidden command. levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } if (atEOL) { // Apply the new folding level to this line. // Leave pending states as they are otherwise a line break will de-sync // code folding and valid syntax. int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); lineCurrent++; levelCurrent = levelNext; visibleChars = 0; } if (!isspacechar(currentChar)) visibleChars++; } }
static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; CharacterSet setWordStart(CharacterSet::setAlpha, "_"); // note that [+-] are often parts of identifiers in shell scripts CharacterSet setWord(CharacterSet::setAlphaNum, "._+-"); CharacterSet setBashOperator(CharacterSet::setNone, "^&\\%()-+=|{}[]:;>,*/<?!.~@"); CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn"); CharacterSet setParam(CharacterSet::setAlphaNum, "$_"); CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!"); CharacterSet setHereDoc2(CharacterSet::setAlphaNum, "_-+!"); CharacterSet setLeftShift(CharacterSet::setDigits, "=$"); class HereDocCls { // Class to manage HERE document elements public: int State; // 0: '<<' encountered // 1: collect the delimiter // 2: here doc text (lines after the delimiter) int Quote; // the char after '<<' bool Quoted; // true if Quote in ('\'','"','`') bool Indent; // indented delimiter (for <<-) int DelimiterLength; // strlen(Delimiter) char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf HereDocCls() { State = 0; Quote = 0; Quoted = false; Indent = 0; DelimiterLength = 0; Delimiter = new char[HERE_DELIM_MAX]; Delimiter[0] = '\0'; } void Append(int ch) { Delimiter[DelimiterLength++] = static_cast<char>(ch); Delimiter[DelimiterLength] = '\0'; } ~HereDocCls() { delete []Delimiter; } }; HereDocCls HereDoc; class QuoteCls { // Class to manage quote pairs (simplified vs LexPerl) public: int Count; int Up, Down; QuoteCls() { Count = 0; Up = '\0'; Down = '\0'; } void Open(int u) { Count++; Up = u; Down = opposite(Up); } void Start(int u) { Count = 0; Open(u); } }; QuoteCls Quote; int numBase = 0; int digit; unsigned int endPos = startPos + length; // Backtrack to beginning of style if required... // If in a long distance lexical state, backtrack to find quote characters if (initStyle == SCE_SH_HERE_Q) { while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_SH_HERE_DELIM)) { startPos--; } startPos = styler.LineStart(styler.GetLine(startPos)); initStyle = styler.StyleAt(startPos - 1); } // Bash strings can be multi-line with embedded newlines, so backtrack. // Bash numbers have additional state during lexing, so backtrack too. if (initStyle == SCE_SH_STRING || initStyle == SCE_SH_BACKTICKS || initStyle == SCE_SH_CHARACTER || initStyle == SCE_SH_NUMBER || initStyle == SCE_SH_IDENTIFIER || initStyle == SCE_SH_COMMENTLINE) { while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) { startPos--; } initStyle = SCE_SH_DEFAULT; } StyleContext sc(startPos, endPos - startPos, initStyle, styler); for (; sc.More(); sc.Forward()) { // Determine if the current state should terminate. switch (sc.state) { case SCE_SH_OPERATOR: sc.SetState(SCE_SH_DEFAULT); break; case SCE_SH_WORD: // "." never used in Bash variable names but used in file names if (!setWord.Contains(sc.ch)) { char s[1000]; sc.GetCurrent(s, sizeof(s)); if (s[0] != '-' && // for file operators !keywords.InList(s)) { sc.ChangeState(SCE_SH_IDENTIFIER); } sc.SetState(SCE_SH_DEFAULT); } break; case SCE_SH_IDENTIFIER: if (sc.chPrev == '\\') { // for escaped chars sc.ForwardSetState(SCE_SH_DEFAULT); } else if (!setWord.Contains(sc.ch)) { sc.SetState(SCE_SH_DEFAULT); } break; case SCE_SH_NUMBER: digit = translateBashDigit(sc.ch); if (numBase == BASH_BASE_DECIMAL) { if (sc.ch == '#') { char s[10]; sc.GetCurrent(s, sizeof(s)); numBase = getBashNumberBase(s); if (numBase != BASH_BASE_ERROR) break; } else if (IsADigit(sc.ch)) break; } else if (numBase == BASH_BASE_HEX) { if (IsADigit(sc.ch, 16)) break; #ifdef PEDANTIC_OCTAL } else if (numBase == BASH_BASE_OCTAL || numBase == BASH_BASE_OCTAL_ERROR) { if (digit <= 7) break; if (digit <= 9) { numBase = BASH_BASE_OCTAL_ERROR; break; } #endif } else if (numBase == BASH_BASE_ERROR) { if (digit <= 9) break; } else { // DD#DDDD number style handling if (digit != BASH_BASE_ERROR) { if (numBase <= 36) { // case-insensitive if base<=36 if (digit >= 36) digit -= 26; } if (digit < numBase) break; if (digit <= 9) { numBase = BASH_BASE_ERROR; break; } } } // fallthrough when number is at an end or error if (numBase == BASH_BASE_ERROR #ifdef PEDANTIC_OCTAL || numBase == BASH_BASE_OCTAL_ERROR #endif ) { sc.ChangeState(SCE_SH_ERROR); } sc.SetState(SCE_SH_DEFAULT); break; case SCE_SH_COMMENTLINE: if (sc.ch == '\\' && (sc.chNext == '\r' || sc.chNext == '\n')) { // comment continuation sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } } else if (sc.atLineEnd) { sc.ForwardSetState(SCE_SH_DEFAULT); } break; case SCE_SH_HERE_DELIM: // From Bash info: // --------------- // Specifier format is: <<[-]WORD // Optional '-' is for removal of leading tabs from here-doc. // Whitespace acceptable after <<[-] operator // if (HereDoc.State == 0) { // '<<' encountered HereDoc.Quote = sc.chNext; HereDoc.Quoted = false; HereDoc.DelimiterLength = 0; HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; if (sc.chNext == '\'' || sc.chNext == '\"') { // a quoted here-doc delimiter (' or ") sc.Forward(); HereDoc.Quoted = true; HereDoc.State = 1; } else if (!HereDoc.Indent && sc.chNext == '-') { // <<- indent case HereDoc.Indent = true; } else if (setHereDoc.Contains(sc.chNext)) { // an unquoted here-doc delimiter, no special handling // TODO check what exactly bash considers part of the delim HereDoc.State = 1; } else if (sc.chNext == '<') { // HERE string <<< sc.Forward(); sc.ForwardSetState(SCE_SH_DEFAULT); } else if (IsASpace(sc.chNext)) { // eat whitespace } else if (setLeftShift.Contains(sc.chNext)) { // left shift << or <<= operator cases sc.ChangeState(SCE_SH_OPERATOR); sc.ForwardSetState(SCE_SH_DEFAULT); } else { // symbols terminates; deprecated zero-length delimiter HereDoc.State = 1; } } else if (HereDoc.State == 1) { // collect the delimiter if (HereDoc.Quoted) { // a quoted here-doc delimiter if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter sc.ForwardSetState(SCE_SH_DEFAULT); } else { if (sc.ch == '\\' && sc.chNext == HereDoc.Quote) { // escaped quote sc.Forward(); } HereDoc.Append(sc.ch); } } else { // an unquoted here-doc delimiter if (setHereDoc2.Contains(sc.ch)) { HereDoc.Append(sc.ch); } else if (sc.ch == '\\') { // skip escape prefix } else { sc.SetState(SCE_SH_DEFAULT); } } if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { // force blowup sc.SetState(SCE_SH_ERROR); HereDoc.State = 0; } } break; case SCE_SH_HERE_Q: // HereDoc.State == 2 if (sc.atLineStart) { sc.SetState(SCE_SH_HERE_Q); int prefixws = 0; while (IsASpace(sc.ch) && !sc.atLineEnd) { // whitespace prefix sc.Forward(); prefixws++; } if (prefixws > 0) sc.SetState(SCE_SH_HERE_Q); while (!sc.atLineEnd) { sc.Forward(); } char s[HERE_DELIM_MAX]; sc.GetCurrent(s, sizeof(s)); if (sc.LengthCurrent() == 0) break; if (s[strlen(s) - 1] == '\r') s[strlen(s) - 1] = '\0'; if (strcmp(HereDoc.Delimiter, s) == 0) { if ((prefixws > 0 && HereDoc.Indent) || // indentation rule (prefixws == 0 && !HereDoc.Indent)) { sc.SetState(SCE_SH_DEFAULT); break; } } } break; case SCE_SH_SCALAR: // variable names if (!setParam.Contains(sc.ch)) { if (sc.LengthCurrent() == 1) { // Special variable: $(, $_ etc. sc.ForwardSetState(SCE_SH_DEFAULT); } else { sc.SetState(SCE_SH_DEFAULT); } } break; case SCE_SH_STRING: // delimited styles case SCE_SH_CHARACTER: case SCE_SH_BACKTICKS: case SCE_SH_PARAM: if (sc.ch == '\\' && Quote.Up != '\\') { sc.Forward(); } else if (sc.ch == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { sc.ForwardSetState(SCE_SH_DEFAULT); } } else if (sc.ch == Quote.Up) { Quote.Count++; } break; } // Must check end of HereDoc state 1 before default state is handled if (HereDoc.State == 1 && sc.atLineEnd) { // Begin of here-doc (the line after the here-doc delimiter): // Lexically, the here-doc starts from the next line after the >>, but the // first line of here-doc seem to follow the style of the last EOL sequence HereDoc.State = 2; if (HereDoc.Quoted) { if (sc.state == SCE_SH_HERE_DELIM) { // Missing quote at end of string! We are stricter than bash. // Colour here-doc anyway while marking this bit as an error. sc.ChangeState(SCE_SH_ERROR); } // HereDoc.Quote always == '\'' } sc.SetState(SCE_SH_HERE_Q); } // Determine if a new state should be entered. if (sc.state == SCE_SH_DEFAULT) { if (sc.ch == '\\') { // escaped character sc.SetState(SCE_SH_IDENTIFIER); } else if (IsADigit(sc.ch)) { sc.SetState(SCE_SH_NUMBER); numBase = BASH_BASE_DECIMAL; if (sc.ch == '0') { // hex,octal if (sc.chNext == 'x' || sc.chNext == 'X') { numBase = BASH_BASE_HEX; sc.Forward(); } else if (IsADigit(sc.chNext)) { #ifdef PEDANTIC_OCTAL numBase = BASH_BASE_OCTAL; #else numBase = BASH_BASE_HEX; #endif } } } else if (setWordStart.Contains(sc.ch)) { sc.SetState(SCE_SH_WORD); } else if (sc.ch == '#') { sc.SetState(SCE_SH_COMMENTLINE); } else if (sc.ch == '\"') { sc.SetState(SCE_SH_STRING); Quote.Start(sc.ch); } else if (sc.ch == '\'') { sc.SetState(SCE_SH_CHARACTER); Quote.Start(sc.ch); } else if (sc.ch == '`') { sc.SetState(SCE_SH_BACKTICKS); Quote.Start(sc.ch); } else if (sc.ch == '$') { sc.SetState(SCE_SH_SCALAR); sc.Forward(); if (sc.ch == '{') { sc.ChangeState(SCE_SH_PARAM); } else if (sc.ch == '\'') { sc.ChangeState(SCE_SH_CHARACTER); } else if (sc.ch == '"') { sc.ChangeState(SCE_SH_STRING); } else if (sc.ch == '(' || sc.ch == '`') { sc.ChangeState(SCE_SH_BACKTICKS); if (sc.chNext == '(') { // $(( is lexed as operator sc.ChangeState(SCE_SH_OPERATOR); } } else { continue; // scalar has no delimiter pair } // fallthrough, open delim for $[{'"(`] Quote.Start(sc.ch); } else if (sc.Match('<', '<')) { sc.SetState(SCE_SH_HERE_DELIM); HereDoc.State = 0; HereDoc.Indent = false; } else if (sc.ch == '-' && // one-char file test operators setSingleCharOp.Contains(sc.chNext) && !setWord.Contains(sc.GetRelative(2)) && IsASpace(sc.chPrev)) { sc.SetState(SCE_SH_WORD); sc.Forward(); } else if (setBashOperator.Contains(sc.ch)) { sc.SetState(SCE_SH_OPERATOR); } } } sc.Complete(); }
static void FoldYAMLDoc(unsigned int startPos, int length, int /*initStyle - unused*/, WordList *[], Accessor &styler) { const int maxPos = startPos + length; const int maxLines = styler.GetLine(maxPos - 1); // Requested last line const int docLines = styler.GetLine(styler.Length() - 1); // Available last line const bool foldComment = styler.GetPropertyInt("fold.comment.yaml") != 0; // Backtrack to previous non-blank line so we can determine indent level // for any white space lines // and so we can fix any preceding fold level (which is why we go back // at least one line in all cases) int spaceFlags = 0; int lineCurrent = styler.GetLine(startPos); int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); while (lineCurrent > 0) { lineCurrent--; indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) && (!IsCommentLine(lineCurrent, styler))) break; } int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; // Set up initial loop state int prevComment = 0; if (lineCurrent >= 1) prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler); // Process all characters to end of requested range // or comment that hangs over the end of the range. Cap processing in all cases // to end of document (in case of unclosed comment at end). while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevComment)) { // Gather info int lev = indentCurrent; int lineNext = lineCurrent + 1; int indentNext = indentCurrent; if (lineNext <= docLines) { // Information about next line is only available if not at end of document indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } const int comment = foldComment && IsCommentLine(lineCurrent, styler); const int comment_start = (comment && !prevComment && (lineNext <= docLines) && IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE)); const int comment_continue = (comment && prevComment); if (!comment) indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; if (indentNext & SC_FOLDLEVELWHITEFLAG) indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel; if (comment_start) { // Place fold point at start of a block of comments lev |= SC_FOLDLEVELHEADERFLAG; } else if (comment_continue) { // Add level to rest of lines in the block lev = lev + 1; } // Skip past any blank lines for next indent level info; we skip also // comments (all comments, not just those starting in column 0) // which effectively folds them into surrounding code rather // than screwing up folding. while ((lineNext < docLines) && ((indentNext & SC_FOLDLEVELWHITEFLAG) || (lineNext <= docLines && IsCommentLine(lineNext, styler)))) { lineNext++; indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK; const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments); // Now set all the indent levels on the lines we skipped // Do this from end to start. Once we encounter one line // which is indented more than the line after the end of // the comment-block, use the level of the block before int skipLine = lineNext; int skipLevel = levelAfterComments; while (--skipLine > lineCurrent) { int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL); if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments) skipLevel = levelBeforeComments; int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG; styler.SetLevel(skipLine, skipLevel | whiteFlag); } // Set fold header on non-comment line if (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) { if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) lev |= SC_FOLDLEVELHEADERFLAG; } // Keep track of block comment state of previous line prevComment = comment_start || comment_continue; // Set fold level for this line and move to next line styler.SetLevel(lineCurrent, lev); indentCurrent = indentNext; lineCurrent = lineNext; } // NOTE: Cannot set level of last line here because indentCurrent doesn't have // header flag set; the loop above is crafted to take care of this case! //styler.SetLevel(lineCurrent, indentCurrent); }
// <--- Colourise ---> void Colourise_Doc(unsigned int startPos, unsigned int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords0 = *keywordlists[0]; WordList &keywords1 = *keywordlists[1]; WordList &keywords2 = *keywordlists[2]; WordList &keywords3 = *keywordlists[3]; WordList &keywords4 = *keywordlists[4]; WordList &keywords5 = *keywordlists[5]; WordList &keywords6 = *keywordlists[6]; WordList &keywords7 = *keywordlists[7]; WordList &keywords8 = *keywordlists[8]; int currentLine = styler.GetLine(startPos); int sepCount = 0; if (initStyle == LITERALSTRING || initStyle == LUA_COMMENT) { sepCount = styler.GetLineState(currentLine - 1) & 0xFF; } // Do not leak onto next line if (initStyle == STRINGEOL || initStyle == LUA_COMMENTLINE || initStyle == CPP_COMMENTLINE) { initStyle = DEFAULT; } StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineEnd) { // Update the line state, so it can be seen by next line currentLine = styler.GetLine(sc.currentPos); switch (sc.state) { case LITERALSTRING: case LUA_COMMENT: // Inside a literal string or block comment, we set the line state styler.SetLineState(currentLine, sepCount); break; default: // Reset the line state styler.SetLineState(currentLine, 0); break; } } // Handle string line continuation if ((sc.state == STRING || sc.state == CHARACTER) && sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continue; } } // Determine if the current state should terminate. if (sc.state == OPERATOR || sc.state == NUMBER) { sc.SetState(DEFAULT); } else if (sc.state == IDENTIFIER) { if (!IsAWordChar(sc.ch) || (sc.currentPos+1 == startPos + length)) { if (IsAWordChar(sc.ch)) { sc.Forward(); // Checks words at the end of the document. } char s[100]; sc.GetCurrent(s, sizeof(s)); if (keywords0.InList(s)) { sc.ChangeState(WORD0); } else if (keywords1.InList(s)) { sc.ChangeState(WORD1); } else if (keywords2.InList(s)) { sc.ChangeState(WORD2); } else if (keywords5.InList(s)) { sc.ChangeState(WORD5); } else if (keywords8.InList(s)) { sc.ChangeState(WORD8); } sc.SetState(DEFAULT); } } else if (sc.state == LUA_COMMENTLINE || sc.state == CPP_COMMENTLINE) { if (sc.atLineEnd) { sc.ForwardSetState(DEFAULT); } } else if (sc.state == STRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(STRINGEOL); sc.ForwardSetState(DEFAULT); } } else if (sc.state == CHARACTER) { if (sc.ch == '\\') { if (sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(STRINGEOL); sc.ForwardSetState(DEFAULT); } } else if (sc.state == LITERALSTRING || sc.state == LUA_COMMENT) { if (sc.ch == ']') { int sep = LongDelimCheck(sc); if (sep == sepCount) { sc.Forward(sep); sc.ForwardSetState(DEFAULT); } } } else if (sc.state == CPP_COMMENT) { if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(DEFAULT); } } else { sc.SetState(DEFAULT); } // Determine if a new state should be entered. if (sc.state == DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(NUMBER); if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) { int j = 1; while (IsADigit(sc.GetRelative(j+1), 16)) { j++; } sc.Forward(j); } else { int j = 0; bool hitDot(false); bool hitE(false); int ch = sc.ch; int chNext = sc.chNext; while (IsADigit(ch) || (ch == '.' && !hitDot && !hitE) || ((ch == 'e' || ch == 'E') && !hitE && (IsADigit(chNext) || ((chNext == '-' || chNext == '+') && IsADigit(sc.GetRelative(j+2)))))) { if (ch == '.') { hitDot = true; } else if (ch == 'e' || ch == 'E') { hitE = true; j++; if (chNext == '-' || chNext == '+') { j++; } chNext = sc.GetRelative(j+1); } j++; ch = chNext; chNext = sc.GetRelative(j+1); } sc.Forward(j-1); } } else if (sc.ch == ':' || sc.ch == '.') { sc.SetState(OPERATOR); if (IsAWordChar(sc.chNext) || isspace(sc.chNext)) { int j = 1; int ch = sc.chNext; while((sc.currentPos + j < startPos + length) && isspace(ch)) { ch = sc.GetRelative(++j); } if (IsAWordChar(ch)) { int i = 0; char s[101]; while (i < 100 && IsAWordChar(ch)) { s[i++] = ch; ch = sc.GetRelative(++j); } s[i++] = '\0'; if (keywords7.InList(s)) { sc.Forward(j-i+1); sc.SetState(WORD7); } if (sc.state != OPERATOR) { sc.Forward(i-2); } } } } else if (IsAWordChar(sc.ch)) { sc.SetState(IDENTIFIER); int j = 0; int i = 0; char s[101]; bool finished = false; int ch = sc.ch; while (i < 100 && (sc.currentPos + j < startPos + length) && !finished && (IsAWordChar(ch) || isspace(ch) || (ch == '.' || ch == ':'))) { if (!IsAWordChar(ch)) { while((sc.currentPos + j < startPos + length) && isspace(ch)) { ch = sc.GetRelative(++j); } if (i < 100 && (ch == '.' || ch == ':')) { s[i++] = ch; ch = sc.GetRelative(++j); while((sc.currentPos + j < startPos + length) && isspace(ch)) { ch = sc.GetRelative(++j); } while(i < 100 && IsAWordChar(ch)) { s[i++] = ch; ch = sc.GetRelative(++j); } s[i++] = '\0'; if (keywords3.InList(s)) { sc.ChangeState(WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(WORD4); } else if (keywords6.InList(s)) { sc.ChangeState(WORD6); } if (sc.state != IDENTIFIER) { sc.Forward(j-1); } } finished = true; } else { s[i++] = ch; ch = sc.GetRelative(++j); } } } else if (sc.ch == '\"') { sc.SetState(STRING); } else if (sc.ch == '\'') { sc.SetState(CHARACTER); } else if (sc.ch == '[') { sepCount = LongDelimCheck(sc); if (sepCount == 0) { sc.SetState(OPERATOR); } else { sc.SetState(LITERALSTRING); sc.Forward(sepCount); } } else if (sc.Match('-', '-')) { sc.SetState(LUA_COMMENTLINE); if (sc.Match("--[")) { sc.Forward(2); sepCount = LongDelimCheck(sc); if (sepCount > 0) { sc.ChangeState(LUA_COMMENT); sc.Forward(sepCount); } } else { sc.Forward(); } } else if (sc.Match('/', '/')) { sc.SetState(CPP_COMMENTLINE); sc.Forward(); } else if (sc.Match('/', '*')) { sc.SetState(CPP_COMMENT); sc.Forward(); } else if (IsLuaOperator(sc.ch)) { sc.SetState(OPERATOR); } } } sc.Complete(); }
// Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". static void FoldPowerShellDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_POWERSHELL_OPERATOR) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} else {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } else if (foldComment && style == SCE_POWERSHELL_COMMENTSTREAM) { if (stylePrev != SCE_POWERSHELL_COMMENTSTREAM) { levelNext++; } else if (styleNext != SCE_POWERSHELL_COMMENTSTREAM) { levelNext--; } } if (!IsASpace(ch)) visibleChars++; if (atEOL || (i == endPos-1)) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } } }
// <--- Fold ---> void Fold_Doc(unsigned int startPos, unsigned int length, int initStyle, WordList *[], Accessor &styler) { unsigned int lengthDoc = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; int styleNext = styler.StyleAt(startPos); int style = initStyle; char s[10]; for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == WORD0 && stylePrev != WORD0) { if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e' || ch == 'r' || ch == 'u') { unsigned int j; for (j = 0; j < 8 && iswordchar(styler.SafeGetCharAt(i + j)); j++) { s[j] = styler[i + j]; } s[j] = '\0'; if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0) || (strcmp(s, "repeat") == 0)) { levelCurrent++; } if ((strcmp(s, "end") == 0) || (strcmp(s, "until") == 0)) { levelCurrent--; } } } else if (style == OPERATOR) { if (ch == '{') { levelCurrent++; } else if (ch == '}') { levelCurrent--; } } else if ((style == LITERALSTRING || style == LUA_COMMENT || style == CPP_COMMENT) && !(stylePrev == LITERALSTRING || stylePrev == LUA_COMMENT || stylePrev == CPP_COMMENT) && (ch == '[' || ch == '/' || ch == '-')) { levelCurrent++; } else if ((style == LITERALSTRING || style == LUA_COMMENT || style == CPP_COMMENT) && !(styleNext == LITERALSTRING || styleNext == LUA_COMMENT || styleNext == CPP_COMMENT) && (ch == ']' || ch == '/')) { levelCurrent--; } else if (style == CPP_COMMENTLINE || style == LUA_COMMENTLINE) { if ((ch == '/' && chNext == '/') || (ch == '-' && chNext == '-')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelCurrent++; } else if (chNext2 == '}') { levelCurrent--; } } } if (!isspacechar(ch)) { visibleChars++; } if (atEOL || (i == lengthDoc-1)) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) { lev |= SC_FOLDLEVELWHITEFLAG; } if (levelCurrent > levelPrev) { lev |= SC_FOLDLEVELHEADERFLAG; } if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } } char lastChar = styler.SafeGetCharAt(lengthDoc-1); if ((unsigned)styler.Length() == lengthDoc && (lastChar == '\n' || lastChar == '\r')) { styler.SetLevel(lineCurrent, levelCurrent); } }