diff options
author | nyamatongwe <unknown> | 2001-09-19 07:36:23 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2001-09-19 07:36:23 +0000 |
commit | 0260c07c4f3b9d55e28c21f6ba400c570df6afe8 (patch) | |
tree | a8e31993ad19b626231610f83a2e69afc4419b4c /src/LexPython.cxx | |
parent | e9da3dad7b71caf6ead01bf0ca10438bc822cf87 (diff) | |
download | scintilla-mirror-0260c07c4f3b9d55e28c21f6ba400c570df6afe8.tar.gz |
Patch from Stephan to improve folding.
Added a few consts.
Diffstat (limited to 'src/LexPython.cxx')
-rw-r--r-- | src/LexPython.cxx | 81 |
1 files changed, 51 insertions, 30 deletions
diff --git a/src/LexPython.cxx b/src/LexPython.cxx index ae5836b0b..221859035 100644 --- a/src/LexPython.cxx +++ b/src/LexPython.cxx @@ -270,14 +270,15 @@ static bool IsQuoteLine(int line, Accessor &styler) { return ((style == SCE_P_TRIPLE) || (style== SCE_P_TRIPLEDOUBLE)); } + static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unused*/, WordList *[], Accessor &styler) { - int maxPos = startPos + length; - int maxLines = styler.GetLine(maxPos-1); - - bool foldComment = styler.GetPropertyInt("fold.comment.python"); - bool foldQuotes = styler.GetPropertyInt("fold.quotes.python"); - + 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.python"); + const bool foldQuotes = styler.GetPropertyInt("fold.quotes.python"); + // Backtrack to previous non-blank line so we can determine indent level // for any white space lines (needed esp. within triple quoted strings) // and so we can fix any preceding fold level (which is why we go back @@ -295,8 +296,8 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse } int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; + // Set up initial loop state startPos = styler.LineStart(lineCurrent); - // Set up initial state int prev_state = SCE_P_DEFAULT & 31; if (lineCurrent >= 1) prev_state = styler.StyleAt(startPos-1) & 31; @@ -306,21 +307,27 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler); // Process all characters to end of requested range or end of any triple quote - // or comment that hangs over the end of the range - while ((lineCurrent <= maxLines) || prevQuote || prevComment) { + // or comment that hangs over the end of the range. Cap processing in all cases + // to end of document (in case of unclosed quote or comment at end). + while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote || prevComment)) { // Gather info int lev = indentCurrent; int lineNext = lineCurrent + 1; - int style = styler.StyleAt(styler.LineStart(lineNext)) & 31; - int indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); - int quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style== SCE_P_TRIPLEDOUBLE)); - int quote_start = (quote && !prevQuote); - int quote_continue = (quote && prevQuote); - int comment = foldComment && IsCommentLine(lineCurrent, styler); - int comment_start = (comment && !prevComment && + int indentNext = indentCurrent; + int quote = false; + if (lineNext <= docLines) { + // Information about next line is only available if not at end of document + indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); + int style = styler.StyleAt(styler.LineStart(lineNext)) & 31; + quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style== SCE_P_TRIPLEDOUBLE)); + } + const int quote_start = (quote && !prevQuote); + const int quote_continue = (quote && prevQuote); + const int comment = foldComment && IsCommentLine(lineCurrent, styler); + const int comment_start = (comment && !prevComment && (lineNext <= docLines) && IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE)); - int comment_continue = (comment && prevComment); + const int comment_continue = (comment && prevComment); if ((!quote || !prevQuote) && !comment) indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; if (quote) @@ -343,22 +350,35 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse } // Skip past any blank lines for next indent level info; we skip also comments - // starting in column 0 which effectively folds them into surrounding code - // rather than screwing up folding. Then set indent level on the lines - // we skipped to be same as maximum of current and next indent. This approach - // does a reasonable job of collapsing white space into surrounding code - // without getting confused by white space at the start of an indented level. + // starting in column 0 which effectively folds them into surrounding code rather + // than screwing up folding. + const int saveIndentNext = indentNext; while (!quote && - ((indentNext & SC_FOLDLEVELWHITEFLAG) || styler[styler.LineStart(lineNext)] == '#') && - (lineNext < maxLines)) { - int level = Platform::Maximum(indentCurrent, indentNext); - if (indentNext & SC_FOLDLEVELWHITEFLAG) - level = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel; - styler.SetLevel(lineNext, level); + (lineNext < docLines) && + ((indentNext & SC_FOLDLEVELWHITEFLAG) || + (lineNext <= docLines && styler[styler.LineStart(lineNext)] == '#'))) { + lineNext++; indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } + // Next compute max indent level of current line and next non-blank line. + // This is the level to which we set all the intervening blank or comment lines. + const int skip_level = Platform::Maximum(indentCurrentLevel, + indentNext & SC_FOLDLEVELNUMBERMASK); + + // Now set all the indent levels on the lines we skipped + int skipLine = lineCurrent + 1; + int skipIndentNext = saveIndentNext; + while (skipLine < lineNext) { + int skipLineLevel = skip_level; + if (skipIndentNext & SC_FOLDLEVELWHITEFLAG) + skipLineLevel = SC_FOLDLEVELWHITEFLAG | skipLineLevel; + styler.SetLevel(skipLine, skipLineLevel); + skipLine++; + skipIndentNext = styler.IndentAmount(skipLine, &spaceFlags, NULL); + } + // Set fold header on non-quote/non-comment line if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) { if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) @@ -375,8 +395,9 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse lineCurrent = lineNext; } - // Make sure last line indent level is set too - styler.SetLevel(lineCurrent, indentCurrent); + // 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); } LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc); |