aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJohn Donoghue <john.donoghue@ieee.org>2016-11-24 13:46:26 -0500
committerJohn Donoghue <john.donoghue@ieee.org>2016-11-24 13:46:26 -0500
commit7ac968971d5cc25e4a15707ff238e52c1d1faab4 (patch)
tree3c9405bdf421be1cc70c741c2cdf55b0d614a753
parent7e1135d056a9adbd38d712caeebc20d4f55f8090 (diff)
downloadscintilla-mirror-7ac968971d5cc25e4a15707ff238e52c1d1faab4.tar.gz
Bug [#1692]. LexMatlab: update fold functions to use keywords instead of indenting.
* lexers/LexMatlab.cxx (IsMatlabComment): removed unused function. (IsOctaveComment): removed unused function. (LowerCase): Added inline function. (CheckKeywordFoldPoint): New function. (FoldMatlabOctaveDoc): use style and keyword to identify fold points. (FoldMatlabDoc): Use IsMatlabCommentChar. (FoldOctaveDoc): Use IsOctaveCommentChar.
-rw-r--r--doc/ScintillaHistory.html4
-rw-r--r--lexers/LexMatlab.cxx117
2 files changed, 83 insertions, 38 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index f29b7b86e..40201af00 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -561,6 +561,10 @@
JSON folder fixed where it didn't resume folding with the correct fold level.
</li>
<li>
+ Matlab folder based on syntax instead of indentation so more accurate.
+ <a href="http://sourceforge.net/p/scintilla/bugs/1692/">Bug #1692</a>.
+ </li>
+ <li>
YAML lexer fixed style of references and keywords when followed by a comment.
<a href="http://sourceforge.net/p/scintilla/bugs/1872/">Bug #1872</a>.
</li>
diff --git a/lexers/LexMatlab.cxx b/lexers/LexMatlab.cxx
index 6b4b2a92a..ca5e4d908 100644
--- a/lexers/LexMatlab.cxx
+++ b/lexers/LexMatlab.cxx
@@ -15,6 +15,9 @@
**
** Changes by John Donoghue 2014/08/01
** - fix allowed transpose ' after {} operator
+ **
+ ** Changes by John Donoghue 2016/11/15
+ ** - update matlab code folding
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
@@ -49,14 +52,28 @@ static bool IsOctaveCommentChar(int c) {
return (c == '%' || c == '#') ;
}
-static bool IsMatlabComment(Accessor &styler, Sci_Position pos, Sci_Position len) {
- return len > 0 && IsMatlabCommentChar(styler[pos]) ;
+static inline int LowerCase(int c) {
+ if (c >= 'A' && c <= 'Z')
+ return 'a' + c - 'A';
+ return c;
}
-static bool IsOctaveComment(Accessor &styler, Sci_Position pos, Sci_Position len) {
- return len > 0 && IsOctaveCommentChar(styler[pos]) ;
+static int CheckKeywordFoldPoint(char *str) {
+ if (strcmp ("if", str) == 0 ||
+ strcmp ("for", str) == 0 ||
+ strcmp ("switch", str) == 0 ||
+ strcmp ("try", str) == 0 ||
+ strcmp ("do", str) == 0 ||
+ strcmp ("parfor", str) == 0 ||
+ strcmp ("function", str) == 0)
+ return 1;
+ if (strncmp("end", str, 3) == 0 ||
+ strcmp("until", str) == 0)
+ return -1;
+ return 0;
}
+
static void ColouriseMatlabOctaveDoc(
Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler,
@@ -245,58 +262,82 @@ static void ColouriseOctaveDoc(Sci_PositionU startPos, Sci_Position length, int
ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar, false);
}
-static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int,
+static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *[], Accessor &styler,
- bool (*IsComment)(Accessor&, Sci_Position, Sci_Position)) {
-
- Sci_Position endPos = startPos + length;
+ bool (*IsComment)(int ch)) {
- // Backtrack to previous line in case need to fix its fold status
+ Sci_PositionU endPos = startPos + length;
+ int visibleChars = 0;
Sci_Position 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);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelNext = levelCurrent;
char chNext = styler[startPos];
- for (Sci_Position i = startPos; i < endPos; i++) {
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ char word[100];
+ int wordlen = 0;
+ for (Sci_PositionU 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;
- }
- }
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ // a line that starts with a comment
+ if (style == SCE_MATLAB_COMMENT && IsComment(ch) && visibleChars == 0) {
+ // start/end of block comment
+ if (chNext == '{')
+ levelNext ++;
+ if (chNext == '}')
+ levelNext --;
+ }
+ // keyword
+ if(style == SCE_MATLAB_KEYWORD) {
+ word[wordlen++] = static_cast<char>(LowerCase(ch));
+ if (wordlen == 100) { // prevent overflow
+ word[0] = '\0';
+ wordlen = 1;
+ }
+ if (styleNext != SCE_MATLAB_KEYWORD) {
+ word[wordlen] = '\0';
+ wordlen = 0;
+
+ levelNext += CheckKeywordFoldPoint(word);
+ }
+ }
+ if (!IsASpace(ch))
+ visibleChars++;
+ if (atEOL || (i == endPos-1)) {
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
}
- indentCurrent = indentNext;
- styler.SetLevel(lineCurrent, lev);
lineCurrent++;
+ levelCurrent = levelNext;
+ 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;
}
}
}
static void FoldMatlabDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
- FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
+ FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
}
static void FoldOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
- FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
+ FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
}
static const char * const matlabWordListDesc[] = {