diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/LexFortran.cxx | 78 |
1 files changed, 49 insertions, 29 deletions
diff --git a/src/LexFortran.cxx b/src/LexFortran.cxx index 85e84c58a..60544dd48 100644 --- a/src/LexFortran.cxx +++ b/src/LexFortran.cxx @@ -29,6 +29,9 @@ static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch)); } +inline bool IsABlank(unsigned int ch) { + return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ; +} static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler, bool isFixFormat) { @@ -36,32 +39,51 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; - int posLineStart = 0; + unsigned int posLineStart = 0, currentState; + int endPos = startPos + length; + + // backtrack to the beginning of the document, this may be slow for big documents. + // initStyle = SCE_F_DEFAULT; + // StyleContext sc(0, startPos+length, initStyle, styler); - StyleContext sc(startPos, length, initStyle, styler); + // backtrack to the nearest keyword + while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) { + startPos--; + } + startPos = styler.LineStart(styler.GetLine(startPos)); + initStyle = styler.StyleAt(startPos - 1); + StyleContext sc(startPos, endPos-startPos, initStyle, styler); for (; sc.More(); sc.Forward()) { - if (sc.atLineStart) { - posLineStart = sc.currentPos; - if (sc.state == SCE_F_STRING1) { - // Prevent SCE_F_STRINGEOL from leaking back to previous line - sc.SetState(SCE_F_STRING1); - } - else if(sc.state == SCE_F_STRING2) { - sc.SetState(SCE_F_STRING2); - } - } + // remember the position of the line + if (sc.atLineStart) posLineStart = sc.currentPos; // Handle line continuation generically. if (sc.ch == '&') { - if (sc.chNext == '\n' || sc.chNext == '\r') { - sc.Forward(); - if (sc.ch == '\r' && sc.chNext == '\n') { - sc.Forward(); + int chTemp = ' '; + int j = 1; + while (IsABlank(chTemp) && j<132) { + chTemp = sc.GetRelative(j); + j ++; + } + if (chTemp == '!') { + sc.SetState(SCE_F_CONTINUATION); + if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT); + } else if (chTemp == '\r' || chTemp == '\n') { + currentState = sc.state; + sc.SetState(SCE_F_CONTINUATION); + if (currentState == SCE_F_STRING1 || currentState == SCE_F_STRING2) { + sc.ForwardSetState(SCE_F_DEFAULT); + while (IsASpace(sc.ch) && sc.More()) sc.Forward(); + if (sc.ch == '&') { + sc.SetState(SCE_F_CONTINUATION); + sc.Forward(); + } + sc.SetState(currentState); } - continue; } + continue; } // Determine if the current state should terminate. @@ -89,14 +111,11 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle sc.SetState(SCE_F_DEFAULT); } } else if (sc.state == SCE_F_STRING1) { - if (sc.ch == '&') { - sc.Forward(); - } else if (sc.ch == '\'') { - sc.Forward(); + if (sc.ch == '\'') { if (sc.chNext == '\'') { sc.Forward(); } else { - sc.SetState(SCE_F_DEFAULT); + sc.ForwardSetState(SCE_F_DEFAULT); } } else if (sc.atLineEnd) { sc.ChangeState(SCE_F_STRINGEOL); @@ -106,14 +125,11 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle if (sc.atLineEnd) { sc.ChangeState(SCE_F_STRINGEOL); sc.ForwardSetState(SCE_F_DEFAULT); - } else if (sc.ch == '&') { - sc.Forward(); } else if (sc.ch == '\"') { - sc.Forward(); if (sc.chNext == '\"') { sc.Forward(); } else { - sc.SetState(SCE_F_DEFAULT); + sc.ForwardSetState(SCE_F_DEFAULT); } } } else if (sc.state == SCE_F_OPERATOR2) { @@ -138,7 +154,7 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle sc.SetState(SCE_F_COMMENT); } else if (toLineStart < 5 && !IsASpace(sc.ch)) { sc.SetState(SCE_F_LABEL); - } else if (toLineStart == 5 && (sc.ch != ' ' || sc.ch != '0')) { + } else if (toLineStart == 5 && (!IsASpace(sc.ch) && sc.ch != '0')) { sc.SetState(SCE_F_CONTINUATION); } } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { @@ -161,9 +177,12 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle sc.Complete(); } +// The folding depends on the mercy of the programer. static int classifyFoldPointFortran(const char* s, const char* prevWord) { int lev = 0; if (strcmp(prevWord, "end") == 0) return lev; + if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0) + return -1; if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0 || strcmp(s, "blockdata") == 0 || strcmp(s, "case") == 0 || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0 @@ -173,7 +192,7 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord) { || strcmp(s, "then") == 0 || strcmp(s, "type") == 0 || strcmp(s, "where") == 0) { lev = 1; - } else if (strcmp(s, "end") == 0 + } else if (strcmp(s, "end") == 0 || strcmp(s, "continue") == 0 || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0 || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0 || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0 @@ -181,7 +200,8 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord) { || strcmp(s, "endforall") == 0 || strcmp(s, "endfunction") == 0 || strcmp(s, "endinterface") == 0 || strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0 || strcmp(s, "endsubroutine") == 0 - || strcmp(s, "endtype") == 0 || strcmp(s, "endwhere") == 0) { + || strcmp(s, "endtype") == 0 || strcmp(s, "endwhere") == 0 + || strcmp(s, "procedure") == 0 ) { lev = -1; } return lev; |