aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2001-09-19 07:36:23 +0000
committernyamatongwe <devnull@localhost>2001-09-19 07:36:23 +0000
commit97eb55b4e3f7ef34bec93e5b4060fb4fc6cc1365 (patch)
treea8e31993ad19b626231610f83a2e69afc4419b4c
parente529721d9530299023cc04787bc0e7612b9c4600 (diff)
downloadscintilla-mirror-97eb55b4e3f7ef34bec93e5b4060fb4fc6cc1365.tar.gz
Patch from Stephan to improve folding.
Added a few consts.
-rw-r--r--src/LexPython.cxx81
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);