diff options
-rw-r--r-- | doc/ScintillaHistory.html | 5 | ||||
-rw-r--r-- | include/SciLexer.h | 4 | ||||
-rw-r--r-- | include/Scintilla.iface | 4 | ||||
-rw-r--r-- | lexers/LexBasic.cxx | 88 |
4 files changed, 85 insertions, 16 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 98debdbb5..b0a56bcc7 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -432,6 +432,7 @@ <td>OmegaPhil</td> </tr><tr> <td>SiegeLord</td> + <td>Erik</td> </tr> </table> <p> @@ -451,6 +452,10 @@ Released 15 October 2013. </li> <li> + Basic lexer supports multiline comments in FreeBASIC. + <a href="http://sourceforge.net/p/scintilla/feature-requests/1023/">Feature #1023.</a> + </li> + <li> C++ lexer fixes bug with #include statements without " or > terminating filename. <a href="http://sourceforge.net/p/scintilla/bugs/1538/">Bug #1538</a>. </li> diff --git a/include/SciLexer.h b/include/SciLexer.h index 1378c8ee8..5edbc620c 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -420,6 +420,10 @@ #define SCE_B_ERROR 16 #define SCE_B_HEXNUMBER 17 #define SCE_B_BINNUMBER 18 +#define SCE_B_COMMENTBLOCK 19 +#define SCE_B_DOCLINE 20 +#define SCE_B_DOCBLOCK 21 +#define SCE_B_DOCKEYWORD 22 #define SCE_PROPS_DEFAULT 0 #define SCE_PROPS_COMMENT 1 #define SCE_PROPS_SECTION 2 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index d1cc6afb1..d23e18020 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2935,6 +2935,10 @@ val SCE_B_LABEL=15 val SCE_B_ERROR=16 val SCE_B_HEXNUMBER=17 val SCE_B_BINNUMBER=18 +val SCE_B_COMMENTBLOCK=19 +val SCE_B_DOCLINE=20 +val SCE_B_DOCBLOCK=21 +val SCE_B_DOCKEYWORD=22 # Lexical states for SCLEX_PROPERTIES lex Properties=SCLEX_PROPERTIES SCE_PROPS_ val SCE_PROPS_DEFAULT=0 diff --git a/lexers/LexBasic.cxx b/lexers/LexBasic.cxx index bc8fcee47..55285201f 100644 --- a/lexers/LexBasic.cxx +++ b/lexers/LexBasic.cxx @@ -49,17 +49,18 @@ using namespace Scintilla; * 8 - decimal digit * 16 - hex digit * 32 - bin digit + * 64 - letter */ static int character_classification[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2, - 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2, - 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, - 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2, + 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2, + 2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 2, 2, 2, 68, + 2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 2, 2, 2, 0 }; static bool IsSpace(int c) { @@ -86,6 +87,10 @@ static bool IsBinDigit(int c) { return c < 128 && (character_classification[c] & 32); } +static bool IsLetter(int c) { + return c < 128 && (character_classification[c] & 64); +} + static int LowerCase(int c) { if (c >= 'A' && c <= 'Z') @@ -126,13 +131,23 @@ static int CheckPureFoldPoint(char const *token, int &level) { static int CheckFreeFoldPoint(char const *token, int &level) { if (!strcmp(token, "function") || !strcmp(token, "sub") || - !strcmp(token, "type")) { + !strcmp(token, "enum") || + !strcmp(token, "type") || + !strcmp(token, "union") || + !strcmp(token, "property") || + !strcmp(token, "destructor") || + !strcmp(token, "constructor")) { level |= SC_FOLDLEVELHEADERFLAG; return 1; } if (!strcmp(token, "end function") || !strcmp(token, "end sub") || - !strcmp(token, "end type")) { + !strcmp(token, "end enum") || + !strcmp(token, "end type") || + !strcmp(token, "end union") || + !strcmp(token, "end property") || + !strcmp(token, "end destructor") || + !strcmp(token, "end constructor")) { return -1; } return 0; @@ -219,9 +234,9 @@ class LexerBasic : public ILexer { OptionSetBasic osBasic; public: LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) : - comment_char(comment_char_), - CheckFoldPoint(CheckFoldPoint_), - osBasic(wordListDescriptions) { + comment_char(comment_char_), + CheckFoldPoint(CheckFoldPoint_), + osBasic(wordListDescriptions) { } virtual ~LexerBasic() { } @@ -302,6 +317,7 @@ void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle bool wasfirst = true, isfirst = true; // true if first token in a line styler.StartAt(startPos); + int styleBeforeKeyword = SCE_B_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); @@ -367,14 +383,44 @@ void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle if (sc.atLineEnd) { sc.SetState(SCE_B_DEFAULT); } + } else if (sc.state == SCE_B_DOCLINE) { + if (sc.atLineEnd) { + sc.SetState(SCE_B_DEFAULT); + } else if (sc.ch == '\\' || sc.ch == '@') { + if (IsLetter(sc.chNext) && sc.chPrev != '\\') { + styleBeforeKeyword = sc.state; + sc.SetState(SCE_B_DOCKEYWORD); + }; + } + } else if (sc.state == SCE_B_DOCKEYWORD) { + if (IsSpace(sc.ch)) { + sc.SetState(styleBeforeKeyword); + } else if (sc.atLineEnd && styleBeforeKeyword == SCE_B_DOCLINE) { + sc.SetState(SCE_B_DEFAULT); + } + } else if (sc.state == SCE_B_COMMENTBLOCK) { + if (sc.Match("\'/")) { + sc.Forward(); + sc.ForwardSetState(SCE_B_DEFAULT); + } + } else if (sc.state == SCE_B_DOCBLOCK) { + if (sc.Match("\'/")) { + sc.Forward(); + sc.ForwardSetState(SCE_B_DEFAULT); + } else if (sc.ch == '\\' || sc.ch == '@') { + if (IsLetter(sc.chNext) && sc.chPrev != '\\') { + styleBeforeKeyword = sc.state; + sc.SetState(SCE_B_DOCKEYWORD); + }; + } } if (sc.atLineStart) isfirst = true; if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) { - if (isfirst && sc.Match('.')) { - sc.SetState(SCE_B_LABEL); + if (isfirst && sc.Match('.') && comment_char != '\'') { + sc.SetState(SCE_B_LABEL); } else if (isfirst && sc.Match('#')) { wasfirst = isfirst; sc.SetState(SCE_B_IDENTIFIER); @@ -383,8 +429,18 @@ void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle // up in freebasic with SCE_B_PREPROCESSOR. if (comment_char == '\'' && sc.Match(comment_char, '$')) sc.SetState(SCE_B_PREPROCESSOR); - else + else if (sc.Match("\'*") || sc.Match("\'!")) { + sc.SetState(SCE_B_DOCLINE); + } else { sc.SetState(SCE_B_COMMENT); + } + } else if (sc.Match("/\'")) { + if (sc.Match("/\'*") || sc.Match("/\'!")) { // Support of gtk-doc/Doxygen doc. style + sc.SetState(SCE_B_DOCBLOCK); + } else { + sc.SetState(SCE_B_COMMENTBLOCK); + } + sc.Forward(); // Eat the ' so it isn't used for the end of the comment } else if (sc.Match('"')) { sc.SetState(SCE_B_STRING); } else if (IsDigit(sc.ch)) { |