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 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); }
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++; } }
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); }
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 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 SafeSetLevel(int line, int level, Accessor &styler) { if ( line < 0 ) return ; int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG)); if ( (level & mask) < 0 ) return ; if ( styler.LevelAt(line) != level ) styler.SetLevel(line, level) ; }
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 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 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 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); }
// 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 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); }
//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 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); }
static void FoldTALDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 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); int style = initStyle; bool was_end = false; bool section = false; 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_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_UUID || style == SCE_C_PREPROCESSOR)) { // Store last word start point. lastStart = i; } if (stylePrev == SCE_C_WORD || style == SCE_C_UUID || stylePrev == SCE_C_PREPROCESSOR) { if(isTALwordchar(ch) && !isTALwordchar(chNext)) { char s[100]; getRange(lastStart, i, styler, s, sizeof(s)); if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0) { section = true; levelCurrent = 1; levelPrev = 0; } else if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_UUID) { if (strcmp(s, "block") == 0) { // block keyword is ignored immediately after end keyword if (!was_end) levelCurrent++; } else levelCurrent += classifyFoldPointTAL(s); if (strcmp(s, "end") == 0) { was_end = true; } else { was_end = false; } } } } if (foldComment && (style == SCE_C_COMMENTLINE)) { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelCurrent++; } else if (chNext2 == '}') { levelCurrent--; } } } if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) { if (ch == '{' && chNext == '$') { unsigned int j=i+2; // skip {$ while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { j++; } if (styler.Match(j, "region") || styler.Match(j, "if")) { levelCurrent++; } else if (styler.Match(j, "end")) { levelCurrent--; } } } if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelCurrent++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } if (atEOL) { int lev = levelPrev | SC_FOLDLEVELBASE; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev || section) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; section = false; } 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 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); } }
static void FoldPlmDoc(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); int style = initStyle; int startKeyword = 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_PLM_KEYWORD && style == SCE_PLM_KEYWORD) startKeyword = i; if (style == SCE_PLM_KEYWORD && styleNext != SCE_PLM_KEYWORD) { char word[1024]; GetRange(startKeyword, i, styler, word, sizeof(word)); if (strcmp(word, "procedure") == 0 || strcmp(word, "do") == 0) levelCurrent++; else if (strcmp(word, "end") == 0) levelCurrent--; } if (foldComment) { if (stylePrev != SCE_PLM_COMMENT && style == SCE_PLM_COMMENT) levelCurrent++; else if (stylePrev == SCE_PLM_COMMENT && style != SCE_PLM_COMMENT) 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++; } int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); }
// <--- 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); } }
// 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 FoldPascalDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 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; int lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; int lastStart = 0; CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); 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)) { levelCurrent++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } 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 (foldPreprocessor) { if (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') { ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler); } else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*' && styler.SafeGetCharAt(i + 2) == '$') { ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler); } } if (stylePrev != SCE_PAS_WORD && style == SCE_PAS_WORD) { // Store last word start point. lastStart = i; } if (stylePrev == SCE_PAS_WORD && !(lineFoldStateCurrent & stateFoldInPreprocessor)) { if(setWord.Contains(ch) && !setWord.Contains(chNext)) { ClassifyPascalWordFoldPoint(levelCurrent, lineFoldStateCurrent, startPos, endPos, lastStart, i, styler); } } if (!IsASpace(ch)) visibleChars++; 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); } int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent; styler.SetLineState(lineCurrent, newLineState); lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } } // If we didn't reach the EOL in previous loop, store line level and whitespace information. // The rest will be filled in later... int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; styler.SetLevel(lineCurrent, lev); }
/** * The folding function * * \param startPos Where to start scanning * \param length Where to scan to * \param keywordslists The keywordslists, currently, number 5 is used * \param styler The styler */ static void FoldMagikDoc(unsigned int startPos, int length, int, WordList *keywordslists[], Accessor &styler) { bool compact = styler.GetPropertyInt("fold.compact") != 0; WordList &foldingElements = *keywordslists[5]; int endPos = startPos + length; int line = styler.GetLine(startPos); int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK; int flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK; for( int currentPos = startPos; currentPos < endPos; currentPos++) { char currentState = styler.StyleAt(currentPos); char c = styler.SafeGetCharAt(currentPos, ' '); int prevLine = styler.GetLine(currentPos - 1); line = styler.GetLine(currentPos); // Default situation if(prevLine < line) { styler.SetLevel(line, (level|flags) & ~SC_FOLDLEVELHEADERFLAG); flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK; } if( ( currentState == SCE_MAGIK_CONTAINER || currentState == SCE_MAGIK_FLOW ) && c == '_') { char keyword[50]; memset(keyword, '\0', 50); for( int scanPosition = 0; scanPosition < 50; scanPosition++) { char keywordChar = static_cast<char>( tolower(styler.SafeGetCharAt( scanPosition + currentPos + 1, ' '))); if(IsAlpha(keywordChar)) { keyword[scanPosition] = keywordChar; } else { break; } } if(IsFoldingContainer(foldingElements, keyword) > 0) { styler.SetLevel( line, styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG); level++; } else if(IsFoldingContainer(foldingElements, keyword) < 0) { styler.SetLevel(line, styler.LevelAt(line)); level--; } } if( compact && ( currentState == SCE_MAGIK_BRACE_BLOCK || currentState == SCE_MAGIK_BRACKET_BLOCK || currentState == SCE_MAGIK_SQBRACKET_BLOCK)) { if(c == '{' || c == '[' || c == '(') { styler.SetLevel( line, styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG); level++; } else if(c == '}' || c == ']' || c == ')') { styler.SetLevel(line, styler.LevelAt(line)); level--; } } } }
static void FoldAveDoc(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 = static_cast<char>(tolower(styler[startPos])); bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; int styleNext = styler.StyleAt(startPos); char s[10] = ""; for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = static_cast<char>(tolower(chNext)); chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1))); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_AVE_WORD) { if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') { for (unsigned int j = 0; j < 6; j++) { if (!iswordchar(styler[i + j])) { break; } s[j] = static_cast<char>(tolower(styler[i + j])); s[j + 1] = '\0'; } if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) { levelCurrent++; } if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) { // Normally "elseif" and "then" will be on the same line and will cancel // each other out. // As implemented, this does not support fold.at.else. levelCurrent--; } } } else if (style == SCE_AVE_OPERATOR) { if (ch == '{' || ch == '(') { levelCurrent++; } else if (ch == '}' || ch == ')') { 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 FoldEclDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = true; bool foldPreprocessor = true; bool foldCompact = true; bool foldAtElse = true; Sci_PositionU endPos = startPos + length; int visibleChars = 0; Sci_Position 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 (Sci_PositionU 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) && (stylePrev != SCE_ECL_COMMENTLINEDOC)) { levelNext++; } else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_ECL_COMMENTLINEDOC) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } if (foldComment && (style == SCE_ECL_COMMENTLINE)) { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelNext++; } else if (chNext2 == '}') { levelNext--; } } } if (foldPreprocessor && (style == SCE_ECL_PREPROCESSOR)) { if (ch == '#') { Sci_PositionU j = i + 1; while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { j++; } if (MatchNoCase(styler, j, "region") || MatchNoCase(styler, j, "if")) { levelNext++; } else if (MatchNoCase(styler, j, "endregion") || MatchNoCase(styler, j, "end")) { levelNext--; } } } if (style == SCE_ECL_OPERATOR) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} else {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } if (style == SCE_ECL_WORD2) { if (MatchNoCase(styler, i, "record") || MatchNoCase(styler, i, "transform") || MatchNoCase(styler, i, "type") || MatchNoCase(styler, i, "function") || MatchNoCase(styler, i, "module") || MatchNoCase(styler, i, "service") || MatchNoCase(styler, i, "interface") || MatchNoCase(styler, i, "ifblock") || MatchNoCase(styler, i, "macro") || MatchNoCase(styler, i, "beginc++")) { levelNext++; } else if (MatchNoCase(styler, i, "endmacro") || MatchNoCase(styler, i, "endc++") || MatchNoCase(styler, i, "end")) { levelNext--; } } 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; if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length()-1))) { // There is an empty line at end of file so give it same level and empty styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG); } visibleChars = 0; } if (!IsASpace(ch)) visibleChars++; } }
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); }
static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { //define the character sets CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function) bool isFoldingAll = true; int endPos = startPos + length; int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly // get settings from the config files for folding comments and preprocessor lines bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldInComment = styler.GetPropertyInt("fold.comment") == 2; bool foldCompact = true; // Backtrack to previous line in case need to fix its fold status int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { isFoldingAll = false; if (lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } } // vars for style of previous/current/next lines int style = GetStyleFirstWord(lineCurrent,styler); int stylePrev = 0; // find the first previous line without continuation character at the end while ((lineCurrent > 0 && IsContinuationLine(lineCurrent, styler)) || (lineCurrent > 1 && IsContinuationLine(lineCurrent - 1, styler))) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } if (lineCurrent > 0) { stylePrev = GetStyleFirstWord(lineCurrent-1,styler); } // vars for getting first word to check for keywords bool isFirstWordStarted = false; bool isFirstWordEnded = false; const unsigned int FIRST_WORD_MAX_LEN = 10; char szFirstWord[FIRST_WORD_MAX_LEN] = ""; unsigned int firstWordLen = 0; char szDo[3]=""; int szDolen = 0; bool isDoLastWord = false; // var for indentlevel int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelNext = levelCurrent; int visibleChars = 0; int functionCount = 0; char chNext = styler.SafeGetCharAt(startPos); char chPrev = '\0'; char chPrevPrev = '\0'; char chPrevPrevPrev = '\0'; for (int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch > 0) && setWord.Contains(ch)) visibleChars++; // get the syle for the current character neede to check in comment int stylech = styler.StyleAt(i); // start the capture of the first word if (!isFirstWordStarted && (ch > 0)) { if (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/') { isFirstWordStarted = true; if (firstWordLen < FIRST_WORD_MAX_LEN - 1) { szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch)); szFirstWord[firstWordLen] = '\0'; } } } // continue capture of the first word on the line else if (isFirstWordStarted && !isFirstWordEnded && (ch > 0)) { if (!setWord.Contains(ch)) { isFirstWordEnded = true; } else if (firstWordLen < (FIRST_WORD_MAX_LEN - 1)) { szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch)); szFirstWord[firstWordLen] = '\0'; } } if (stylech != SCE_POWERPRO_COMMENTLINE) { //reset isDoLastWord if we find a character(ignoring spaces) after 'do' if (isDoLastWord && (ch > 0) && setWord.Contains(ch)) isDoLastWord = false; // --find out if the word "do" is the last on a "if" line-- // collect each letter and put it into a buffer 2 chars long // if we end up with "do" in the buffer when we reach the end of // the line, "do" was the last word on the line if ((ch > 0) && isFirstWordEnded && strcmp(szFirstWord, "if") == 0) { if (szDolen == 2) { szDo[0] = szDo[1]; szDo[1] = static_cast<char>(tolower(ch)); szDo[2] = '\0'; if (strcmp(szDo, "do") == 0) isDoLastWord = true; } else if (szDolen < 2) { szDo[szDolen++] = static_cast<char>(tolower(ch)); szDo[szDolen] = '\0'; } } } // End of Line found so process the information if ((ch == '\r' && chNext != '\n') // \r\n || ch == '\n' // \n || i == endPos) { // end of selection // ************************** // Folding logic for Keywords // ************************** // if a keyword is found on the current line and the line doesn't end with ;;+ (continuation) // and we are not inside a commentblock. if (firstWordLen > 0 && chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev !=';' && (!IsStreamCommentStyle(style) || foldInComment) ) { // only fold "if" last keyword is "then" (else its a one line if) if (strcmp(szFirstWord, "if") == 0 && isDoLastWord) levelNext++; // create new fold for these words if (strcmp(szFirstWord, "for") == 0) levelNext++; //handle folding for functions/labels //Note: Functions and labels don't have an explicit end like [end function] // 1. functions/labels end at the start of another function // 2. functions/labels end at the end of the file if ((strcmp(szFirstWord, "function") == 0) || (firstWordLen > 0 && szFirstWord[0] == '@')) { if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script) if (functionCount > 0) { levelCurrent--; } else { levelNext++; } functionCount++; } else { //if just folding a small piece (by clicking on the minus sign next to the word) levelCurrent--; } } // end the fold for these words before the current line if (strcmp(szFirstWord, "endif") == 0 || strcmp(szFirstWord, "endfor") == 0) { levelNext--; levelCurrent--; } // end the fold for these words before the current line and Start new fold if (strcmp(szFirstWord, "else") == 0 || strcmp(szFirstWord, "elseif") == 0 ) levelCurrent--; } // Preprocessor and Comment folding int styleNext = GetStyleFirstWord(lineCurrent + 1,styler); // ********************************* // Folding logic for Comment blocks // ********************************* if (foldComment && IsStreamCommentStyle(style)) { // Start of a comment block if (stylePrev != style && IsStreamCommentStyle(styleNext) && styleNext == style) { levelNext++; } // fold till the last line for normal comment lines else if (IsStreamCommentStyle(stylePrev) && styleNext != SCE_POWERPRO_COMMENTLINE && stylePrev == SCE_POWERPRO_COMMENTLINE && style == SCE_POWERPRO_COMMENTLINE) { levelNext--; } // fold till the one but last line for Blockcomment lines else if (IsStreamCommentStyle(stylePrev) && styleNext != SCE_POWERPRO_COMMENTBLOCK && style == SCE_POWERPRO_COMMENTBLOCK) { levelNext--; levelCurrent--; } } 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); // reset values for the next line lineCurrent++; stylePrev = style; style = styleNext; levelCurrent = levelNext; visibleChars = 0; // if the last characters are ;;+ then don't reset since the line continues on the next line. if (chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev != ';') { firstWordLen = 0; szDolen = 0; isFirstWordStarted = false; isFirstWordEnded = false; isDoLastWord = false; //blank out first word for (unsigned int i = 0; i < FIRST_WORD_MAX_LEN; i++) szFirstWord[i] = '\0'; } } // save the last processed characters if ((ch > 0) && !isspacechar(ch)) { chPrevPrevPrev = chPrevPrev; chPrevPrev = chPrev; chPrev = ch; } } //close folds on the last line - without this a 'phantom' //fold can appear when an open fold is on the last line //this can occur because functions and labels don't have an explicit end if (lineCurrent >= lastLine) { int lev = 0; lev |= SC_FOLDLEVELWHITEFLAG; styler.SetLevel(lineCurrent, lev); } }
// 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; } } }
//============================================================================= // Folding the code static void FoldNoBoxVHDLDoc( unsigned int startPos, int length, int, Accessor &styler) { // Decided it would be smarter to have the lexer have all keywords included. Therefore I // don't check if the style for the keywords that I use to adjust the levels. char words[] = "architecture begin block case component else elsif end entity generate loop package process record then " "procedure function when"; WordList keywords; keywords.Set(words); bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 1) != 0; bool foldAtBegin = styler.GetPropertyInt("fold.at.Begin", 1) != 0; bool foldAtParenthese = styler.GetPropertyInt("fold.at.Parenthese", 1) != 0; //bool foldAtWhen = styler.GetPropertyInt("fold.at.When", 1) != 0; //< fold at when in case statements int visibleChars = 0; unsigned int endPos = startPos + length; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if(lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; //int levelMinCurrent = levelCurrent; int levelMinCurrentElse = levelCurrent; //< Used for folding at 'else' int levelMinCurrentBegin = levelCurrent; //< Used for folding at 'begin' int levelNext = levelCurrent; /***************************************/ int lastStart = 0; char prevWord[32] = ""; /***************************************/ // Find prev word // The logic for going up or down a level depends on a the previous keyword // This code could be cleaned up. int end = 0; unsigned int j; for(j = startPos; j>0; j--) { char ch = styler.SafeGetCharAt(j); char chPrev = styler.SafeGetCharAt(j-1); int style = styler.StyleAt(j); int stylePrev = styler.StyleAt(j-1); if ((!IsCommentStyle(style)) && (stylePrev != SCE_VHDL_STRING)) { if(IsAWordChar(chPrev) && !IsAWordChar(ch)) { end = j-1; } } if ((!IsCommentStyle(style)) && (style != SCE_VHDL_STRING)) { if(!IsAWordChar(chPrev) && IsAWordStart(ch) && (end != 0)) { char s[32]; unsigned int k; for(k=0; (k<31 ) && (k<end-j+1 ); k++) { s[k] = static_cast<char>(tolower(styler[j+k])); } s[k] = '\0'; if(keywords.InList(s)) { strcpy(prevWord, s); break; } } } } for(j=j+static_cast<unsigned int>(strlen(prevWord)); j<endPos; j++) { char ch = styler.SafeGetCharAt(j); int style = styler.StyleAt(j); if ((!IsCommentStyle(style)) && (style != SCE_VHDL_STRING)) { if((ch == ';') && (strcmp(prevWord, "end") == 0)) { strcpy(prevWord, ";"); } } } char chNext = styler[startPos]; char chPrev = '\0'; char chNextNonBlank; int styleNext = styler.StyleAt(startPos); //Platform::DebugPrintf("Line[%04d] Prev[%20s] ************************* Level[%x]\n", lineCurrent+1, prevWord, levelCurrent); /***************************************/ for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); chPrev = styler.SafeGetCharAt(i - 1); chNextNonBlank = chNext; unsigned int j = i+1; while(IsABlank(chNextNonBlank) && j<endPos) { j ++ ; chNextNonBlank = styler.SafeGetCharAt(j); } int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && atEOL) { if(IsCommentLine(lineCurrent, styler)) { if(!IsCommentLine(lineCurrent-1, styler) && IsCommentLine(lineCurrent+1, styler)) { levelNext++; } else if(IsCommentLine(lineCurrent-1, styler) && !IsCommentLine(lineCurrent+1, styler)) { levelNext--; } } else { if (IsCommentBlockStart(lineCurrent, styler) && !IsCommentBlockEnd(lineCurrent, styler)) { levelNext++; } else if (IsCommentBlockEnd(lineCurrent, styler) && !IsCommentBlockStart(lineCurrent, styler)) { levelNext--; } } } if ((style == SCE_VHDL_OPERATOR) && foldAtParenthese) { if(ch == '(') { levelNext++; } else if (ch == ')') { levelNext--; } } if ((!IsCommentStyle(style)) && (style != SCE_VHDL_STRING)) { if((ch == ';') && (strcmp(prevWord, "end") == 0)) { strcpy(prevWord, ";"); } if(!IsAWordChar(chPrev) && IsAWordStart(ch)) { lastStart = i; } if(IsAWordChar(ch) && !IsAWordChar(chNext)) { char s[32]; unsigned int k; for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) { s[k] = static_cast<char>(tolower(styler[lastStart+k])); } s[k] = '\0'; if(keywords.InList(s)) { if ( strcmp(s, "architecture") == 0 || strcmp(s, "case") == 0 || strcmp(s, "generate") == 0 || strcmp(s, "block") == 0 || strcmp(s, "loop") == 0 || strcmp(s, "package") ==0 || strcmp(s, "process") == 0 || strcmp(s, "record") == 0 || strcmp(s, "then") == 0) { if (strcmp(prevWord, "end") != 0) { if (levelMinCurrentElse > levelNext) { levelMinCurrentElse = levelNext; } levelNext++; } } else if ( strcmp(s, "component") == 0 || strcmp(s, "entity") == 0 || strcmp(s, "configuration") == 0 ) { if (strcmp(prevWord, "end") != 0 && lastStart) { // check for instantiated unit by backward searching for the colon. unsigned pos = lastStart; char chAtPos, styleAtPos; do{// skip white spaces pos--; styleAtPos = styler.StyleAt(pos); chAtPos = styler.SafeGetCharAt(pos); }while(pos>0 && (chAtPos == ' ' || chAtPos == '\t' || chAtPos == '\n' || chAtPos == '\r' || IsCommentStyle(styleAtPos))); // check for a colon (':') before the instantiated units "entity", "component" or "configuration". Don't fold thereafter. if (chAtPos != ':') { if (levelMinCurrentElse > levelNext) { levelMinCurrentElse = levelNext; } levelNext++; } } } else if ( strcmp(s, "procedure") == 0 || strcmp(s, "function") == 0) { if (strcmp(prevWord, "end") != 0) // check for "end procedure" etc. { // This code checks to see if the procedure / function is a definition within a "package" // rather than the actual code in the body. int BracketLevel = 0; for(int pos=i+1; pos<styler.Length(); pos++) { int styleAtPos = styler.StyleAt(pos); char chAtPos = styler.SafeGetCharAt(pos); if(chAtPos == '(') BracketLevel++; if(chAtPos == ')') BracketLevel--; if( (BracketLevel == 0) && (!IsCommentStyle(styleAtPos)) && (styleAtPos != SCE_VHDL_STRING) && !iswordchar(styler.SafeGetCharAt(pos-1)) && styler.Match(pos, "is") && !iswordchar(styler.SafeGetCharAt(pos+2))) { if (levelMinCurrentElse > levelNext) { levelMinCurrentElse = levelNext; } levelNext++; break; } if((BracketLevel == 0) && (chAtPos == ';')) { break; } } } } else if (strcmp(s, "end") == 0) { levelNext--; } else if(strcmp(s, "elsif") == 0) { // elsif is followed by then so folding occurs correctly levelNext--; } else if (strcmp(s, "else") == 0) { if(strcmp(prevWord, "when") != 0) // ignore a <= x when y else z; { levelMinCurrentElse = levelNext - 1; // VHDL else is all on its own so just dec. the min level } } else if( ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "architecture") == 0)) || ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "function") == 0)) || ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "procedure") == 0))) { levelMinCurrentBegin = levelNext - 1; } //Platform::DebugPrintf("Line[%04d] Prev[%20s] Cur[%20s] Level[%x]\n", lineCurrent+1, prevWord, s, levelCurrent); strcpy(prevWord, s); } } } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse && (levelMinCurrentElse < levelUse)) { levelUse = levelMinCurrentElse; } if (foldAtBegin && (levelMinCurrentBegin < levelUse)) { levelUse = levelMinCurrentBegin; } 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); } //Platform::DebugPrintf("Line[%04d] ---------------------------------------------------- Level[%x]\n", lineCurrent+1, levelCurrent); lineCurrent++; levelCurrent = levelNext; //levelMinCurrent = levelCurrent; levelMinCurrentElse = levelCurrent; levelMinCurrentBegin = levelCurrent; visibleChars = 0; } /***************************************/ if (!isspacechar(ch)) visibleChars++; } /***************************************/ // Platform::DebugPrintf("Line[%04d] ---------------------------------------------------- Level[%x]\n", lineCurrent+1, levelCurrent); }