changeset 4341:6e4a1de60e8b

qscintilla: add patch for matlab code folding (Bug #42569) * src/qscintilla-2-matlab-fold.patch: new patch file * dist-files.mk: add qscintilla-2-matlab-fold.patch
author John D
date Thu, 19 Jan 2017 08:13:20 -0500
parents c202df909032
children 5eef82cc581c
files dist-files.mk src/qscintilla-2-matlab-fold.patch
diffstat 2 files changed, 170 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/dist-files.mk	Thu Jan 19 07:57:27 2017 -0500
+++ b/dist-files.mk	Thu Jan 19 08:13:20 2017 -0500
@@ -568,6 +568,7 @@
   qrupdate-1-fixes.patch \
   qrupdate.mk \
   qscintilla-1-fixes.patch \
+  qscintilla-2-matlab-fold.patch \
   qscintilla-3-matlab-block-comment.patch \
   qscintilla.mk \
   qt-1-cherrypicks.patch \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/qscintilla-2-matlab-fold.patch	Thu Jan 19 08:13:20 2017 -0500
@@ -0,0 +1,169 @@
+diff -ur QScintilla_gpl-2.9.3.orig/lexers/LexMatlab.cpp QScintilla_gpl-2.9.3/lexers/LexMatlab.cpp
+--- QScintilla_gpl-2.9.3.orig/lexers/LexMatlab.cpp	2016-11-15 10:56:48.705675755 -0500
++++ QScintilla_gpl-2.9.3/lexers/LexMatlab.cpp	2016-11-15 18:03:03.938533646 -0500
+@@ -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.
+@@ -48,15 +51,27 @@
+ static bool IsOctaveCommentChar(int c) {
+ 	return (c == '%' || c == '#') ;
+ }
+-
+-static bool IsMatlabComment(Accessor &styler, int pos, int 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, int pos, int 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(
+             unsigned int startPos, int length, int initStyle,
+             WordList *keywordlists[], Accessor &styler,
+@@ -245,58 +260,83 @@
+ 	ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar, false);
+ }
+ 
+-static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,
++static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int initStyle,
+                                 WordList *[], Accessor &styler,
+-                                bool (*IsComment)(Accessor&, int, int)) {
+-
+-	int endPos = startPos + length;
++                                bool (*IsComment)(int)) {
+ 
+-	// Backtrack to previous line in case need to fix its fold status
+-	int lineCurrent = styler.GetLine(startPos);
+-	if (startPos > 0) {
+-		if (lineCurrent > 0) {
+-			lineCurrent--;
+-			startPos = styler.LineStart(lineCurrent);
++	unsigned int endPos = startPos + length;
++	int visibleChars = 0;
++ 	unsigned int lineCurrent = styler.GetLine(startPos);
++	int levelCurrent = SC_FOLDLEVELBASE;
++	if (lineCurrent > 0)
++		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
++	int levelNext = levelCurrent;
++ 	char chNext = styler[startPos];
++	int styleNext = styler.StyleAt(startPos);
++	int style = initStyle;
++	char word[100];
++	int wordlen = 0;
++	for (unsigned int i = startPos; i < endPos; i++) {
++ 		char ch = chNext;
++ 		chNext = styler.SafeGetCharAt(i + 1);
++
++		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 --;
+ 		}
+-	}
+-	int spaceFlags = 0;
+-	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
+-	char chNext = styler[startPos];
+-	for (int 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;
+-					}
+-				}
++		// 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<unsigned int>(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(unsigned int startPos, int length, int initStyle,
+                           WordList *keywordlists[], Accessor &styler) {
+-	FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
++	FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
+ }
+ 
+ static void FoldOctaveDoc(unsigned int startPos, int 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[] = {