diff options
-rw-r--r-- | lexers/LexBaan.cxx | 226 |
1 files changed, 150 insertions, 76 deletions
diff --git a/lexers/LexBaan.cxx b/lexers/LexBaan.cxx index 99cdb4907..42a0657ba 100644 --- a/lexers/LexBaan.cxx +++ b/lexers/LexBaan.cxx @@ -39,7 +39,7 @@ using namespace Scintilla; # endif namespace { - // Use an unnamed namespace to protect the functions and classes from name conflicts +// Use an unnamed namespace to protect the functions and classes from name conflicts // Options used for LexerBaan struct OptionsBaan { @@ -49,6 +49,7 @@ struct OptionsBaan { bool foldCompact; bool baanFoldSyntaxBased; bool baanFoldKeywordsBased; + bool baanFoldSections; bool baanStylingWithinPreprocessor; OptionsBaan() { fold = false; @@ -57,6 +58,7 @@ struct OptionsBaan { foldCompact = false; baanFoldSyntaxBased = false; baanFoldKeywordsBased = false; + baanFoldSections = false; baanStylingWithinPreprocessor = false; } }; @@ -85,10 +87,14 @@ struct OptionSetBaan : public OptionSet<OptionsBaan> { DefineProperty("fold.baan.syntax.based", &OptionsBaan::baanFoldSyntaxBased, "Set this property to 0 to disable syntax based folding, which is folding based on '{' & '('."); - + DefineProperty("fold.baan.keywords.based", &OptionsBaan::baanFoldKeywordsBased, "Set this property to 0 to disable keywords based folding, which is folding based on " - " for, if, on (case), repeat, select, while and fold ends based on endfor, endif, endcase, until, endselect, endwhile respectively."); + " for, if, on (case), repeat, select, while and fold ends based on endfor, endif, endcase, until, endselect, endwhile respectively." + "Also folds declarations which are grouped together."); + + DefineProperty("fold.baan.sections", &OptionsBaan::baanFoldSections, + "Set this property to 0 to disable folding of Main Sections."); DefineProperty("lexer.baan.styling.within.preprocessor", &OptionsBaan::baanStylingWithinPreprocessor, "For Baan code, determines whether all preprocessor code is styled in the " @@ -103,10 +109,6 @@ static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$'); } -static inline bool IsAWordStart(const int ch) { - return (ch < 0x80) && (isalnum(ch) || ch == '_'); -} - static inline bool IsAnOperator(int ch) { if (IsAlphaNumeric(ch)) return false; @@ -216,7 +218,16 @@ static bool IsPreProcLine(Sci_Position line, LexAccessor &styler) { Sci_Position eol_pos = styler.LineStart(line + 1) - 1; for (Sci_Position i = pos; i < eol_pos; i++) { char ch = styler[i]; - if (ch == '#' || ch == '|' || ch == '^') + int style = styler.StyleAt(i); + if (ch == '#' && style == SCE_BAAN_PREPROCESSOR) { + if (styler.Match(i, "#elif") || styler.Match(i, "#else") || styler.Match(i, "#endif") + || styler.Match(i, "#if") || styler.Match(i, "#ifdef") || styler.Match(i, "#ifndef")) + // Above PreProcessors has a seperate fold mechanism. + return false; + else + return true; + } + else if (ch == '^') return true; else if (!IsASpaceOrTab(ch)) return false; @@ -238,10 +249,36 @@ static bool IsMainSectionLine(Sci_Position line, LexAccessor &styler) { return false; } -static inline int ToLowerCase(int c) { - if (c >= 'A' && c <= 'Z') - return 'a' + c - 'A'; - return c; +static bool IsDeclarationLine(Sci_Position line, LexAccessor &styler) { + Sci_Position pos = styler.LineStart(line); + Sci_Position eol_pos = styler.LineStart(line + 1) - 1; + for (Sci_Position i = pos; i < eol_pos; i++) { + char ch = styler[i]; + int style = styler.StyleAt(i); + if (style == SCE_BAAN_WORD) { + if (styler.Match(i, "table") || styler.Match(i, "extern") || styler.Match(i, "long") + || styler.Match(i, "double") || styler.Match(i, "boolean") || styler.Match(i, "string") + || styler.Match(i, "domain")) { + for (Sci_Position j = eol_pos; j > pos; j--) { + int styleFromEnd = styler.StyleAt(j); + if (styleFromEnd == SCE_BAAN_COMMENT) + continue; + else if (IsASpace(styler[j])) + continue; + else if (styler[j] != ',') + //Above conditions ensures, Declaration is not part of any function parameters. + return true; + else + return false; + } + } + else + return false; + } + else if (!IsASpaceOrTab(ch)) + return false; + } + return false; } static inline bool wordInArray(const std::string& value, std::string *array, int length) @@ -399,7 +436,12 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int bool lineHasPreProc = false; bool lineIgnoreString = false; bool lineHasDefines = false; + char word[1000]; + int wordlen = 0; + std::string preProcessorTags[11] = { "#define", "#elif", "#else", "#endif", + "#ident", "#if", "#ifdef", "#ifndef", + "#include", "#pragma", "#undef" }; LexAccessor styler(pAccess); StyleContext sc(startPos, length, initStyle, styler); @@ -537,7 +579,7 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int sc.Forward(); } while ((!sc.atLineEnd) && sc.More()); } - else if (IsAWordStart(sc.ch)) { + else if (iswordstart(sc.ch)) { sc.SetState(SCE_BAAN_IDENTIFIER); } else if (sc.Match('|')) { @@ -549,15 +591,26 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int else if (sc.ch == '#' && visibleChars == 0) { // Preprocessor commands are alone on their line sc.SetState(SCE_BAAN_PREPROCESSOR); - // Skip whitespace between # and preprocessor word - do { + word[0] = '\0'; + wordlen = 0; + while (sc.More() && !IsASpace(sc.chNext)) { sc.Forward(); - } while (IsASpace(sc.ch) && sc.More()); - if (sc.MatchIgnoreCase("pragma") || sc.MatchIgnoreCase("include")) { + wordlen++; + } + sc.GetCurrentLowered(word, sizeof(word)); + if (!sc.atLineEnd) { + word[wordlen++] = sc.ch; + word[wordlen++] = '\0'; + } + if (!wordInArray(word, preProcessorTags, 11)) + // Colorise only preprocessor built in Baan. + sc.ChangeState(SCE_BAAN_IDENTIFIER); + if (strcmp(word, "#pragma") == 0 || strcmp(word, "#include") == 0) { lineHasPreProc = true; lineIgnoreString = true; } - else if (sc.MatchIgnoreCase("define") || sc.MatchIgnoreCase("undef")) { + else if (strcmp(word, "#define") == 0 || strcmp(word, "#undef") == 0 || + strcmp(word, "#ifdef") == 0 || strcmp(word, "#if") == 0 || strcmp(word, "#ifndef") == 0) { lineHasDefines = true; lineIgnoreString = false; } @@ -594,7 +647,7 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int bool foldNextSelect = true; bool afterFunctionSection = false; bool beforeDeclarationSection = false; - + std::string startTags[6] = { "for", "if", "on", "repeat", "select", "while" }; std::string endTags[6] = { "endcase", "endfor", "endif", "endselect", "endwhile", "until" }; std::string selectCloseTags[5] = { "selectdo", "selecteos", "selectempty", "selecterror", "endselect" }; @@ -646,13 +699,24 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int levelCurrent--; } // PreProcessor Folding - if (options.foldPreprocessor && atEOL && IsPreProcLine(lineCurrent, styler)) { - if (!IsPreProcLine(lineCurrent - 1, styler) - && IsPreProcLine(lineCurrent + 1, styler)) - levelCurrent++; - else if (IsPreProcLine(lineCurrent - 1, styler) - && !IsPreProcLine(lineCurrent + 1, styler)) - levelCurrent--; + if (options.foldPreprocessor) { + if (atEOL && IsPreProcLine(lineCurrent, styler)) { + if (!IsPreProcLine(lineCurrent - 1, styler) + && IsPreProcLine(lineCurrent + 1, styler)) + levelCurrent++; + else if (IsPreProcLine(lineCurrent - 1, styler) + && !IsPreProcLine(lineCurrent + 1, styler)) + levelCurrent--; + } + else if (style == SCE_BAAN_PREPROCESSOR) { + // folds #ifdef/#if/#ifndef - they are not part of the IsPreProcLine folding. + if (ch == '#') { + if (styler.Match(i, "#ifdef") || styler.Match(i, "#if") || styler.Match(i, "#ifndef")) + levelCurrent++; + else if (styler.Match(i, "#endif")) + levelCurrent--; + } + } } //Syntax Folding if (options.baanFoldSyntaxBased && (style == SCE_BAAN_OPERATOR)) { @@ -664,60 +728,70 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int } } //Keywords Folding - if (options.baanFoldKeywordsBased && style == SCE_BAAN_WORD) { - word[wordlen++] = static_cast<char>(ToLowerCase(ch)); - if (wordlen == 100) { // prevent overflow - word[0] = '\0'; - wordlen = 1; + if (options.baanFoldKeywordsBased) { + if (atEOL && IsDeclarationLine(lineCurrent, styler)) { + if (!IsDeclarationLine(lineCurrent - 1, styler) + && IsDeclarationLine(lineCurrent + 1, styler)) + levelCurrent++; + else if (IsDeclarationLine(lineCurrent - 1, styler) + && !IsDeclarationLine(lineCurrent + 1, styler)) + levelCurrent--; } - if (styleNext != SCE_BAAN_WORD) { - word[wordlen] = '\0'; - wordlen = 0; - if (strcmp(word, "for") == 0) { - Sci_PositionU j = i + 1; - while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { - j++; - } - if (styler.Match(j, "update")) { - // Means this is a "for update" used by Select which is already folded. - foldStart = false; - } + else if (style == SCE_BAAN_WORD) { + word[wordlen++] = static_cast<char>(MakeLowerCase(ch)); + if (wordlen == 100) { // prevent overflow + word[0] = '\0'; + wordlen = 1; } - else if (strcmp(word, "on") == 0) { - Sci_PositionU j = i + 1; - while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { - j++; + if (styleNext != SCE_BAAN_WORD) { + word[wordlen] = '\0'; + wordlen = 0; + if (strcmp(word, "for") == 0) { + Sci_PositionU j = i + 1; + while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { + j++; + } + if (styler.Match(j, "update")) { + // Means this is a "for update" used by Select which is already folded. + foldStart = false; + } } - if (!styler.Match(j, "case")) { - // Means this is not a "on Case" statement... could be "on" used by index. - foldStart = false; + else if (strcmp(word, "on") == 0) { + Sci_PositionU j = i + 1; + while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { + j++; + } + if (!styler.Match(j, "case")) { + // Means this is not a "on Case" statement... could be "on" used by index. + foldStart = false; + } } - } - else if (strcmp(word, "select") == 0) { - if (foldNextSelect) { - // Next Selects are sub-clause till reach of selectCloseTags[] array. - foldNextSelect = false; + else if (strcmp(word, "select") == 0) { + if (foldNextSelect) { + // Next Selects are sub-clause till reach of selectCloseTags[] array. + foldNextSelect = false; + foldStart = true; + } + else { + foldNextSelect = false; + foldStart = false; + } + } + else if (wordInArray(word, selectCloseTags, 5)) { + // select clause ends, next select clause can be folded. + foldNextSelect = true; foldStart = true; } else { - foldNextSelect = false; - foldStart = false; - } - } - else if (wordInArray(word, selectCloseTags, 5)) { - // select clause ends, next select clause can be folded. - foldNextSelect = true; - foldStart = true; - } - else { - foldStart = true; - } - if (foldStart) { - if (wordInArray(word, startTags, 6)) { - levelCurrent++; + foldStart = true; } - else if (wordInArray(word, endTags, 6)) { - levelCurrent--; + if (foldStart) { + if (wordInArray(word, startTags, 6)) { + levelCurrent++; + } + else if (wordInArray(word, endTags, 6)) { + levelCurrent--; + } } } } @@ -726,15 +800,15 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int // One way of implementing Section Foldings, as there is no END markings of sections. // first section ends on the previous line of next section. // Re-written whole folding to accomodate this. - if (options.baanFoldKeywordsBased && atEOL) { + if (options.baanFoldSections && atEOL) { if (IsMainSectionLine(lineCurrent, styler)) { if (levelCurrent < levelPrev) --levelPrev; for (Sci_Position j = styler.LineStart(lineCurrent); j < styler.LineStart(lineCurrent + 1) - 1; j++) { - if (IsASpaceOrTab(styler[j])) + if (IsASpaceOrTab(styler[j])) continue; else if (styler.StyleAt(j) == SCE_BAAN_WORD5) { - if (styler.Match(j, "functions:")) { + if (styler.Match(j, "functions:")) { // Means functions: is the end of MainSections. // Nothing to fold after this. afterFunctionSection = true; @@ -758,7 +832,7 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int if (IsASpaceOrTab(styler[j])) continue; else if (styler.StyleAt(j) == SCE_BAAN_WORD5) { - if (styler.Match(j, "declaration:")) { + if (styler.Match(j, "declaration:")) { // Means declaration: is the start of MainSections. // Nothing to fold before this. beforeDeclarationSection = true; |