diff options
author | nyamatongwe <devnull@localhost> | 2003-04-21 10:28:26 +0000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2003-04-21 10:28:26 +0000 |
commit | da722dd5c385ed15c09e19bd4b52c00dfb5eaa1a (patch) | |
tree | fabd2641345ba9de8d0307ad98b34bf863b14740 | |
parent | 279f5f7cad53f0f8dabf7dcdd5781a46b0d70b25 (diff) | |
download | scintilla-mirror-da722dd5c385ed15c09e19bd4b52c00dfb5eaa1a.tar.gz |
New folding scheme that allows "} else {" to be a fold header.
-rw-r--r-- | src/Editor.cxx | 13 | ||||
-rw-r--r-- | src/LexCPP.cxx | 281 |
2 files changed, 43 insertions, 251 deletions
diff --git a/src/Editor.cxx b/src/Editor.cxx index 2eba8a471..0cb693ba6 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -1576,8 +1576,15 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { number[0] = '\0'; if (firstSubLine) sprintf(number, "%d", lineDoc + 1); - if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS) - sprintf(number, "%X", pdoc->GetLevel(lineDoc)); + if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS) { + int lev = pdoc->GetLevel(lineDoc); + sprintf(number, "%c%c %03X %03X", + (lev & SC_FOLDLEVELHEADERFLAG) ? 'H' : '_', + (lev & SC_FOLDLEVELWHITEFLAG) ? 'W' : '_', + lev & SC_FOLDLEVELNUMBERMASK, + lev >> 16 + ); + } PRectangle rcNumber = rcMarker; // Right justify int width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, strlen(number)); @@ -2476,7 +2483,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { } else { int FoldLevelCurr = (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE; int FoldLevelPrev = (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE; - int FoldLevelFlags = (pdoc->GetLevel(lineDoc) & ~SC_FOLDLEVELNUMBERMASK); + int FoldLevelFlags = (pdoc->GetLevel(lineDoc) & ~SC_FOLDLEVELNUMBERMASK) & ~(0xFFF0000); int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); // Draw line above fold if ((FoldLevelPrev < FoldLevelCurr) diff --git a/src/LexCPP.cxx b/src/LexCPP.cxx index 3be8c91f1..9c8ea416a 100644 --- a/src/LexCPP.cxx +++ b/src/LexCPP.cxx @@ -282,237 +282,23 @@ static bool IsStreamCommentStyle(int style) { style == SCE_C_COMMENTDOCKEYWORDERROR; } -static bool matchKeyword(unsigned int start, WordList &keywords, Accessor &styler, int keywordtype) { - bool FoundKeyword = false; - - for (unsigned int i = 0; - strlen(keywords[i]) > 0 && !FoundKeyword; - i++) { - if (atoi(keywords[i]) == keywordtype) { - FoundKeyword = styler.Match(start, ((char *)keywords[i]) + 2); - } - } - return FoundKeyword; -} - -static bool IsCommentLine(int line, Accessor &styler) { - unsigned int Pos = styler.LineStart(line); - while (styler.GetLine(Pos) == line) { - int PosStyle = styler.StyleAt(Pos); - - if ( !IsStreamCommentStyle(PosStyle) - && - PosStyle != SCE_C_COMMENTLINEDOC - && - PosStyle != SCE_C_COMMENTLINE - && - !IsASpace(styler.SafeGetCharAt(Pos)) - ) - return false; - Pos++; - } - - return true; -} - -static void FoldBoxCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], - Accessor &styler) { - - WordList &keywords4 = *keywordlists[3]; - - bool foldComment = styler.GetPropertyInt("fold.comment") != 0; - bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; - bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; - bool firstLine = true; - unsigned int endPos = startPos + length; - int visibleChars = 0; - int lineCurrent = styler.GetLine(startPos); - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; - int levelPrevPrev; - int levelFlags = 0; - int levelUnindent = 0; - char chNext = styler[startPos]; - int styleNext = styler.StyleAt(startPos); - int style = initStyle; - - if (lineCurrent == 0) { - levelPrevPrev = levelPrev; - } else { - levelPrevPrev = styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK; - } - - 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 && (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 == '#') { - unsigned int j = i + 1; - 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 (style == SCE_C_OPERATOR - || - style == SCE_C_COMMENT - || - style == SCE_C_COMMENTLINE) { - - if (ch == '{') { - levelCurrent++; - // Special handling if line has closing brace followed by opening brace. - if (levelCurrent == levelPrev) { - if (firstLine) - levelUnindent = 1; - else - levelUnindent = -1; - } - } else if (ch == '}') { - levelCurrent--; - } - } - - /* Check for fold header keyword at beginning of word */ - if ((style == SCE_C_WORD || style == SCE_C_COMMENT || style == SCE_C_COMMENTLINE) - && - (style != stylePrev)) { - if (matchKeyword(i, keywords4, styler, KEYWORD_BOXHEADER)) { - int line; - /* Loop backwards all empty or comment lines */ - for (line = lineCurrent - 1; - line >= 0 - && - levelCurrent == (styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK) - && - (styler.LevelAt(line) & SC_FOLDLEVELBOXFOOTERFLAG) == 0 - && - IsCommentLine(line, styler); - line--) { - /* just loop backwards */; - } - - line++; - /* Set Box header flag (if the previous line has no footer line) */ - if ((styler.LevelAt(line) & SC_FOLDLEVELBOXFOOTERFLAG) == 0) { - if (line == lineCurrent) { - /* in current line */ - levelFlags |= SC_FOLDLEVELBOXHEADERFLAG; - } else { - /* at top of all preceding comment lines */ - styler.SetLevel(line, styler.LevelAt(line) - | SC_FOLDLEVELBOXHEADERFLAG); - } - } - } - } - - if (matchKeyword(i, keywords4, styler, KEYWORD_FOLDCONTRACTED)) { - levelFlags |= SC_FOLDLEVELCONTRACTED; - } - - if (atEOL) { - int lev; - // Compute level correction for special case: '} else {' - if (levelUnindent < 0) { - levelPrev += levelUnindent; - } else { - levelCurrent += levelUnindent; - } - - lev = levelPrev; - if (visibleChars == 0 && foldCompact) - lev |= SC_FOLDLEVELWHITEFLAG; - // Produce additional footer line (e.g. after closed if) - if (visibleChars == 0 - && - (levelPrev < levelPrevPrev)) - lev |= SC_FOLDLEVELBOXFOOTERFLAG; - // Produce footer line at line before (special handling for '} else {' - if (levelPrev < levelPrevPrev) { - styler.SetLevel(lineCurrent - 1, - styler.LevelAt(lineCurrent - 1) | SC_FOLDLEVELBOXFOOTERFLAG); - } - // Mark the fold header (the line that is always visible) - if ((levelCurrent > levelPrev) && (visibleChars > 0)) - lev |= SC_FOLDLEVELHEADERFLAG; - // Show a footer line at end of fold - if (levelCurrent < levelPrev) - lev |= SC_FOLDLEVELBOXFOOTERFLAG; - /* Show a footer line at the end of each procedure (level == SC_FOLDLEVELBASE) */ - if ((levelPrev == SC_FOLDLEVELBASE) - && - (levelPrevPrev > SC_FOLDLEVELBASE) - && - (visibleChars == 0)) { - lev |= SC_FOLDLEVELBOXFOOTERFLAG; - } - - lev |= levelFlags; - if (lev != styler.LevelAt(lineCurrent)) { - styler.SetLevel(lineCurrent, lev); - } - - lineCurrent++; - levelPrevPrev = levelPrev; - levelPrev = levelCurrent; - levelUnindent = 0; - visibleChars = 0; - levelFlags = 0; - firstLine = 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); -} - +// 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 FoldNoBoxCppDoc(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; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; + 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; @@ -525,19 +311,19 @@ static void FoldNoBoxCppDoc(unsigned int startPos, int length, int initStyle, bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { - levelCurrent++; + levelNext++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. - levelCurrent--; + levelNext--; } } if (foldComment && (style == SCE_C_COMMENTLINE)) { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { - levelCurrent++; + levelNext++; } else if (chNext2 == '}') { - levelCurrent--; + levelNext--; } } } @@ -548,58 +334,57 @@ static void FoldNoBoxCppDoc(unsigned int startPos, int length, int initStyle, j++; } if (styler.Match(j, "region") || styler.Match(j, "if")) { - levelCurrent++; + levelNext++; } else if (styler.Match(j, "end")) { - levelCurrent--; + levelNext--; } } } if (style == SCE_C_OPERATOR) { if (ch == '{') { - levelCurrent++; + // Measure the minimum before a '{' to allow + // folding on "} else {" + if (levelMinCurrent > levelNext) { + levelMinCurrent = levelNext; + } + levelNext++; } else if (ch == '}') { - levelCurrent--; + levelNext--; } } if (atEOL) { - int lev = levelPrev; + int levelUse = levelCurrent; + if (foldAtElse) { + levelUse = levelMinCurrent; + } + int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; - if ((levelCurrent > levelPrev) && (visibleChars > 0)) + if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; - levelPrev = levelCurrent; + levelCurrent = levelNext; + levelMinCurrent = 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 FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], +static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { - - int foldFlags = styler.GetPropertyInt("fold.flags") ; - bool foldBox = ((foldFlags & SC_FOLDFLAG_BOX) == SC_FOLDFLAG_BOX); - - if (foldBox) { - FoldBoxCppDoc(startPos, length, initStyle, keywordlists, styler); - } else { - FoldNoBoxCppDoc(startPos, length, initStyle, styler); - } + FoldNoBoxCppDoc(startPos, length, initStyle, styler); } static const char * const cppWordLists[] = { "Primary keywords and identifiers", "Secondary keywords and identifiers", "Documentation comment keywords", - "Fold header keywords", + "Unused", "Global classes and typedefs", 0, }; |