From bc62f2f0c2fec64593a30a5b42f23aeeac398ca9 Mon Sep 17 00:00:00 2001 From: Neil Date: Thu, 7 Nov 2013 10:50:15 +1100 Subject: Feature [feature-requests:#962]. Improvement of folding for Fortran. Treats "else" as fold header. From darmar. --- doc/ScintillaHistory.html | 4 ++ lexers/LexFortran.cxx | 103 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 83 insertions(+), 24 deletions(-) diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 9426de5fb..ca282397b 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -473,6 +473,10 @@ Bug #1538.
  • + Fortran folder improved. Treats "else" as fold header. + Feature #962. +
  • +
  • For DirectWrite, use the GDI ClearType gamma value for SC_EFF_QUALITY_LCD_OPTIMIZED as this results in text that is similar in colour intensity to GDI. For the duller default DirectWrite ClearType text appearance, use SC_EFF_QUALITY_DEFAULT. diff --git a/lexers/LexFortran.cxx b/lexers/LexFortran.cxx index 01caa0b61..3410acb40 100644 --- a/lexers/LexFortran.cxx +++ b/lexers/LexFortran.cxx @@ -254,16 +254,18 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle // To determine the folding level depending on keywords static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) { int lev = 0; - if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0) - return -1; - if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0 + + if ((strcmp(prevWord, "module") == 0 && strcmp(s, "subroutine") == 0) + || (strcmp(prevWord, "module") == 0 && strcmp(s, "function") == 0)) { + lev = 0; + } else if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0 || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0 || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0 || strcmp(s, "function") == 0 || strcmp(s, "interface") == 0 || strcmp(s, "module") == 0 || strcmp(s, "program") == 0 || strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0 || (strcmp(s, "type") == 0 && chNextNonBlank != '(') - || strcmp(s, "critical") == 0){ + || strcmp(s, "critical") == 0 || strcmp(s, "submodule") == 0){ if (strcmp(prevWord, "end") == 0) lev = 0; else @@ -277,15 +279,20 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c || strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0 || strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0 || strcmp(s, "endwhere") == 0 || strcmp(s, "endcritical") == 0 - || (strcmp(s, "procedure") == 0 && strcmp(prevWord, "module") == 0) ) { // Take care of the "module procedure" statement + || (strcmp(prevWord, "module") == 0 && strcmp(s, "procedure") == 0) // Take care of the "module procedure" statement + || strcmp(s, "endsubmodule") == 0) { lev = -1; } else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if lev = 0; } else if (strcmp(prevWord, "type") == 0 && strcmp(s, "is") == 0){ // type is lev = -1; + } else if ((strcmp(prevWord, "end") == 0 && strcmp(s, "procedure") == 0) + || strcmp(s, "endprocedure") == 0) { + lev = 1; // level back to 0, because no folding support for "module procedure" in submodule } return lev; } +/***************************************/ // Folding the code static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, Accessor &styler, bool isFixFormat) { @@ -297,12 +304,22 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; + 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]; char chNextNonBlank; int styleNext = styler.StyleAt(startPos); int style = initStyle; + int levelDeltaNext = 0; /***************************************/ int lastStart = 0; char prevWord[32] = ""; @@ -315,17 +332,28 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); chNextNonBlank = chNext; + bool nextEOL = false; + if (IsALineEnd(chNextNonBlank)) { + nextEOL = true; + } unsigned int j=i+1; while(IsABlank(chNextNonBlank) && j levelPrev) && (visibleChars > 0)) + if ((levelDeltaNext > 0) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; - if (lev != styler.LevelAt(lineCurrent)) { + if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); - } + lineCurrent++; - levelPrev = levelCurrent; + levelCurrent += levelDeltaNext; + levelDeltaNext = 0; visibleChars = 0; strcpy(prevWord, ""); + isPrevLine = false; } /***************************************/ if (!isspacechar(ch)) visibleChars++; } /***************************************/ - // Fill in the real level of the next line, keeping the current flags as they will be filled in later - int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; - styler.SetLevel(lineCurrent, levelPrev | flagsNext); } /***************************************/ static const char * const FortranWordLists[] = { -- cgit v1.2.3