aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authordarmar <unknown>2017-04-18 10:02:00 +1000
committerdarmar <unknown>2017-04-18 10:02:00 +1000
commite06e7c881753caff472550cf744d5ce10594fe9f (patch)
tree2a78733430495ce797e2cef0fdf5c7d796ad204c
parent4d6694eccc5db0f9748cbda9152cec7b3c916169 (diff)
downloadscintilla-mirror-e06e7c881753caff472550cf744d5ce10594fe9f.tar.gz
Bug [#1936]. Implement comment folding.
-rw-r--r--doc/ScintillaHistory.html4
-rw-r--r--lexers/LexFortran.cxx220
2 files changed, 215 insertions, 9 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index 47ab6305d..6001a4802 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -541,6 +541,10 @@
<a href="http://sourceforge.net/p/scintilla/bugs/1935/">Bug #1935</a>.
</li>
<li>
+ The Fortran folder can fold comments.
+ <a href="http://sourceforge.net/p/scintilla/bugs/1936/">Bug #1936</a>.
+ </li>
+ <li>
The PowerShell lexer recognizes escaped quotes in strings.
<a href="http://sourceforge.net/p/scintilla/bugs/1929/">Bug #1929</a>.
</li>
diff --git a/lexers/LexFortran.cxx b/lexers/LexFortran.cxx
index 641702893..495b00215 100644
--- a/lexers/LexFortran.cxx
+++ b/lexers/LexFortran.cxx
@@ -227,7 +227,7 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
if (sc.state == SCE_F_DEFAULT) {
if (sc.ch == '!') {
if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") ||
- sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
+ sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
sc.SetState(SCE_F_PREPROCESSOR);
} else {
sc.SetState(SCE_F_COMMENT);
@@ -237,7 +237,7 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_F_NUMBER);
} else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' ||
- tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) {
+ tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) {
sc.SetState(SCE_F_NUMBER);
sc.Forward();
} else if (sc.ch == '.' && isalpha(sc.chNext)) {
@@ -256,6 +256,165 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
sc.Complete();
}
/***************************************/
+static void CheckLevelCommentLine(const unsigned int nComL,
+ int nComColB[], int nComColF[], int &nComCur,
+ bool comLineB[], bool comLineF[], bool &comLineCur,
+ int &levelDeltaNext) {
+ levelDeltaNext = 0;
+ if (!comLineCur) {
+ return;
+ }
+
+ if (!comLineF[0] || nComColF[0] != nComCur) {
+ unsigned int i=0;
+ for (; i<nComL; i++) {
+ if (!comLineB[i] || nComColB[i] != nComCur) {
+ break;
+ }
+ }
+ if (i == nComL) {
+ levelDeltaNext = -1;
+ }
+ }
+ else if (!comLineB[0] || nComColB[0] != nComCur) {
+ unsigned int i=0;
+ for (; i<nComL; i++) {
+ if (!comLineF[i] || nComColF[i] != nComCur) {
+ break;
+ }
+ }
+ if (i == nComL) {
+ levelDeltaNext = 1;
+ }
+ }
+}
+/***************************************/
+static void GetIfLineComment(Accessor &styler, bool isFixFormat, const Sci_Position line, bool &isComLine, Sci_Position &comCol) {
+ Sci_Position col = 0;
+ isComLine = false;
+ Sci_Position pos = styler.LineStart(line);
+ Sci_Position len = styler.Length();
+ while(pos<len) {
+ char ch = styler.SafeGetCharAt(pos);
+ if (ch == '!' || (isFixFormat && col == 0 && (tolower(ch) == 'c' || ch == '*'))) {
+ isComLine = true;
+ comCol = col;
+ break;
+ }
+ else if (!IsABlank(ch) || IsALineEnd(ch)) {
+ break;
+ }
+ pos++;
+ col++;
+ }
+}
+/***************************************/
+static void StepCommentLine(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,
+ Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position &nComCur,
+ bool comLineB[], bool comLineF[], bool &comLineCur) {
+ Sci_Position nLineTotal = styler.GetLine(styler.Length()-1) + 1;
+ if (lineCurrent >= nLineTotal) {
+ return;
+ }
+
+ for (int i=nComL-2; i>=0; i--) {
+ nComColB[i+1] = nComColB[i];
+ comLineB[i+1] = comLineB[i];
+ }
+ nComColB[0] = nComCur;
+ comLineB[0] = comLineCur;
+ nComCur = nComColF[0];
+ comLineCur = comLineF[0];
+ for (unsigned int i=0; i+1<nComL; i++) {
+ nComColF[i] = nComColF[i+1];
+ comLineF[i] = comLineF[i+1];
+ }
+ Sci_Position chL = lineCurrent + nComL;
+ if (chL < nLineTotal) {
+ GetIfLineComment(styler, isFixFormat, chL, comLineF[nComL-1], nComColF[nComL-1]);
+ }
+ else {
+ comLineF[nComL-1] = false;
+ }
+}
+/***************************************/
+static void CheckBackComLines(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,
+ Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position nComCur,
+ bool comLineB[], bool comLineF[], bool &comLineCur) {
+ unsigned int nLines = nComL + nComL + 1;
+ bool* comL = new bool[nLines];
+ Sci_Position* nComCol = new Sci_Position[nLines];
+ bool comL0;
+ Sci_Position nComCol0;
+ GetIfLineComment(styler, isFixFormat, lineCurrent-nComL-1, comL0, nComCol0);
+ for (unsigned int i=0; i<nComL; i++) {
+ unsigned copyTo = nComL - i - 1;
+ comL[copyTo] = comLineB[i];
+ nComCol[copyTo] = nComColB[i];
+ }
+ assert(nComL < nLines);
+ comL[nComL] = comLineCur;
+ nComCol[nComL] = nComCur;
+ for (unsigned int i=0; i<nComL; i++) {
+ unsigned copyTo = i + nComL + 1;
+ comL[copyTo] = comLineF[i];
+ nComCol[copyTo] = nComColF[i];
+ }
+
+ Sci_Position lineC = lineCurrent - nComL + 1;
+ unsigned int iStart;
+ if (lineC <= 0) {
+ lineC = 0;
+ iStart = nComL - lineCurrent;
+ }
+ else {
+ iStart = 1;
+ }
+ bool levChanged = false;
+ int lev = styler.LevelAt(lineC) & SC_FOLDLEVELNUMBERMASK;
+
+ for (unsigned int i=iStart; i<=nComL; i++) {
+ if (comL[i] && (!comL[i-1] || nComCol[i] != nComCol[i-1])) {
+ bool increase = true;
+ unsigned int until = i + nComL;
+ for (unsigned int j=i+1; j<=until; j++) {
+ if (!comL[j] || nComCol[j] != nComCol[i]) {
+ increase = false;
+ break;
+ }
+ }
+ lev = styler.LevelAt(lineC) & SC_FOLDLEVELNUMBERMASK;
+ if (increase) {
+ int levH = lev | SC_FOLDLEVELHEADERFLAG;
+ lev += 1;
+ if (levH != styler.LevelAt(lineC)) {
+ styler.SetLevel(lineC, levH);
+ }
+ for (Sci_Position j=lineC+1; j<=lineCurrent; j++) {
+ if (lev != styler.LevelAt(j)) {
+ styler.SetLevel(j, lev);
+ }
+ }
+ break;
+ }
+ else {
+ if (lev != styler.LevelAt(lineC)) {
+ styler.SetLevel(lineC, lev);
+ }
+ }
+ levChanged = true;
+ }
+ else if (levChanged && comL[i]) {
+ if (lev != styler.LevelAt(lineC)) {
+ styler.SetLevel(lineC, lev);
+ }
+ }
+ lineC++;
+ }
+ delete[] comL;
+ delete[] nComCol;
+}
+/***************************************/
// To determine the folding level depending on keywords
static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) {
int lev = 0;
@@ -302,29 +461,62 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
// Folding the code
static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
Accessor &styler, bool isFixFormat) {
- //
- // bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- // Do not know how to fold the comment at the moment.
- //
+
+ bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
Sci_PositionU endPos = startPos + length;
int visibleChars = 0;
Sci_Position lineCurrent = styler.GetLine(startPos);
- int levelCurrent;
bool isPrevLine;
if (lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
- levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
isPrevLine = true;
} else {
- levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
isPrevLine = false;
}
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
int levelDeltaNext = 0;
+
+ const unsigned int nComL = 3; // defines how many comment lines should be before they are folded
+ Sci_Position nComColB[nComL];
+ Sci_Position nComColF[nComL] = {};
+ Sci_Position nComCur;
+ bool comLineB[nComL];
+ bool comLineF[nComL];
+ bool comLineCur;
+ Sci_Position nLineTotal = styler.GetLine(styler.Length()-1) + 1;
+ if (foldComment) {
+ for (unsigned int i=0; i<nComL; i++) {
+ Sci_Position chL = lineCurrent-(i+1);
+ if (chL < 0) {
+ comLineB[i] = false;
+ break;
+ }
+ GetIfLineComment(styler, isFixFormat, chL, comLineB[i], nComColB[i]);
+ if (!comLineB[i]) {
+ for (unsigned int j=i+1; j<nComL; j++) {
+ comLineB[j] = false;
+ }
+ break;
+ }
+ }
+ for (unsigned int i=0; i<nComL; i++) {
+ Sci_Position chL = lineCurrent+i+1;
+ if (chL >= nLineTotal) {
+ comLineF[i] = false;
+ break;
+ }
+ GetIfLineComment(styler, isFixFormat, chL, comLineF[i], nComColF[i]);
+ }
+ GetIfLineComment(styler, isFixFormat, lineCurrent, comLineCur, nComCur);
+ CheckBackComLines(styler, isFixFormat, lineCurrent, nComL, nComColB, nComColF, nComCur,
+ comLineB, comLineF, comLineCur);
+ }
+ int levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+
/***************************************/
Sci_Position lastStart = 0;
char prevWord[32] = "";
@@ -467,6 +659,11 @@ static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int init
}
}
if (atEOL) {
+ if (foldComment) {
+ int ldNext;
+ CheckLevelCommentLine(nComL, nComColB, nComColF, nComCur, comLineB, comLineF, comLineCur, ldNext);
+ levelDeltaNext += ldNext;
+ }
int lev = levelCurrent;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
@@ -481,6 +678,11 @@ static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int init
visibleChars = 0;
strcpy(prevWord, "");
isPrevLine = false;
+
+ if (foldComment) {
+ StepCommentLine(styler, isFixFormat, lineCurrent, nComL, nComColB, nComColF, nComCur,
+ comLineB, comLineF, comLineCur);
+ }
}
/***************************************/
if (!isspacechar(ch)) visibleChars++;