aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/LexCPP.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/LexCPP.cxx')
-rw-r--r--src/LexCPP.cxx281
1 files changed, 33 insertions, 248 deletions
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,
};