diff options
author | nyamatongwe <devnull@localhost> | 2002-09-06 04:03:42 +0000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2002-09-06 04:03:42 +0000 |
commit | 628d0ff80c403d6ed5c6ec98af6c9ce327d5721b (patch) | |
tree | f5f39c5bb8918ed12c1bc8300be03b9167b512be | |
parent | 7a764a5da22523306237b69e5007ceeba77e73aa (diff) | |
download | scintilla-mirror-628d0ff80c403d6ed5c6ec98af6c9ce327d5721b.tar.gz |
Upgraded by Simon with some words only being keywords in class definitions
and fold comments.
-rw-r--r-- | src/LexPascal.cxx | 240 |
1 files changed, 179 insertions, 61 deletions
diff --git a/src/LexPascal.cxx b/src/LexPascal.cxx index 2f2be32e4..37e5e995f 100644 --- a/src/LexPascal.cxx +++ b/src/LexPascal.cxx @@ -2,6 +2,7 @@ /** @file LexPascal.cxx ** Lexer for Pascal. ** Written by Laurent le Tynevez + ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002 **/ #include <stdlib.h> @@ -17,45 +18,86 @@ #include "KeyWords.h" #include "Scintilla.h" #include "SciLexer.h" +#include "StyleContext.h" -static int classifyWordPascal(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { - char s[100]; - for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { +static void getRange(unsigned int start, + unsigned int end, + Accessor &styler, + char *s, + unsigned int len) { + unsigned int i = 0; + while ((i < end - start + 1) && (i < len-1)) { s[i] = static_cast<char>(tolower(styler[start + i])); - s[i + 1] = '\0'; + i++; } - int lev= 0; + s[i] = '\0'; +} + +static bool IsStreamCommentStyle(int style) { + return style == SCE_C_COMMENT || + style == SCE_C_COMMENTDOC || + style == SCE_C_COMMENTDOCKEYWORD || + style == SCE_C_COMMENTDOCKEYWORDERROR; +} + +static inline bool IsAWordChar(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); +} + +// returns 1 if the item starts a class definition, and -1 if the word is "end". +static int classifyWordPascal(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInClass) { + int ret = 0; + + WordList& keywords = *keywordlists[0]; + WordList& classwords = *keywordlists[1]; + + char s[100]; + getRange(start, end, styler, s, sizeof(s)); + char chAttr = SCE_C_IDENTIFIER; - if (isdigit(s[0]) || (s[0] == '.')){ + if (isdigit(s[0]) || (s[0] == '.')) { chAttr = SCE_C_NUMBER; } else { if (keywords.InList(s)) { chAttr = SCE_C_WORD; - if (strcmp(s, "begin") == 0 || - strcmp(s, "object") == 0 || - strcmp(s,"case") == 0) { - lev=1; - } else if (strcmp(s, "end") == 0) { - lev=-1; + + if(strcmp(s, "class") == 0) + ret = 1; + else if(strcmp(s, "end") == 0) + ret = -1; + } else if (bInClass) { + if (classwords.InList(s)) { + chAttr = SCE_C_WORD; } } } styler.ColourTo(end, chAttr); + return ret; +} + +static int classifyFoldPointPascal(const char* s) { + int lev = 0; + if (!(isdigit(s[0]) || (s[0] == '.'))) { + if (strcmp(s, "begin") == 0 || + strcmp(s, "object") == 0 || + strcmp(s, "case") == 0 || + strcmp(s, "class") == 0 || + strcmp(s, "record") == 0 || + strcmp(s, "try") == 0) { + lev=1; + } else if (strcmp(s, "end") == 0) { + lev=-1; + } + } return lev; } static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { - WordList &keywords = *keywordlists[0]; styler.StartAt(startPos); - bool fold = styler.GetPropertyInt("fold") != 0; - int lineCurrent = styler.GetLine(startPos); - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; - int state = initStyle; if (state == SCE_C_STRINGEOL) // Does not leak onto next line state = SCE_C_DEFAULT; @@ -63,9 +105,21 @@ static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; int visibleChars = 0; + + bool bInClassDefinition; + int currentLine = styler.GetLine(startPos); + if (currentLine > 0) { + styler.SetLineState(currentLine, styler.GetLineState(currentLine-1)); + bInClassDefinition = (styler.GetLineState(currentLine) == 1); + } else { + styler.SetLineState(currentLine, 0); + bInClassDefinition = false; + } + styler.StartSegment(startPos); for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { @@ -76,17 +130,9 @@ static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, styler.ColourTo(i, state); state = SCE_C_DEFAULT; } - if (fold) { - int lev = levelPrev; - if (visibleChars == 0) - lev |= SC_FOLDLEVELWHITEFLAG; - if ((levelCurrent > levelPrev) && (visibleChars > 0)) - lev |= SC_FOLDLEVELHEADERFLAG; - styler.SetLevel(lineCurrent, lev); - lineCurrent++; - levelPrev = levelCurrent; - } visibleChars = 0; + currentLine++; + styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0)); } if (!isspacechar(ch)) visibleChars++; @@ -113,9 +159,6 @@ static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, } else if (ch == '/' && chNext == '/') { styler.ColourTo(i-1, state); state = SCE_C_COMMENTLINE; - } else if (ch == '\"') { - styler.ColourTo(i-1, state); - state = SCE_C_STRING; } else if (ch == '\'') { styler.ColourTo(i-1, state); state = SCE_C_CHARACTER; @@ -129,7 +172,16 @@ static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, } } else if (state == SCE_C_IDENTIFIER) { if (!iswordchar(ch)) { - int levelChange = classifyWordPascal(styler.GetStartSegment(), i - 1, keywords, styler); + int lStateChange = classifyWordPascal(styler.GetStartSegment(), i - 1, keywordlists, styler, bInClassDefinition); + + if(lStateChange == 1) { + styler.SetLineState(currentLine, 1); + bInClassDefinition = true; + } else if(lStateChange == -1) { + styler.SetLineState(currentLine, 0); + bInClassDefinition = false; + } + state = SCE_C_DEFAULT; chNext = styler.SafeGetCharAt(i + 1); if (ch == '{' && chNext != '$' && chNext != '&') { @@ -141,14 +193,11 @@ static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, state = SCE_C_COMMENTDOC; } else if (ch == '/' && chNext == '/') { state = SCE_C_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_C_STRING; } else if (ch == '\'') { state = SCE_C_CHARACTER; } else if (isoperator(ch)) { styler.ColourTo(i, SCE_C_OPERATOR); } - levelCurrent+=levelChange; } } else { if (state == SCE_C_PREPROCESSOR) { @@ -180,30 +229,10 @@ static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, styler.ColourTo(i-1, state); state = SCE_C_DEFAULT; } - } else if (state == SCE_C_STRING) { - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } - } else if (ch == '\"') { - styler.ColourTo(i, state); - state = SCE_C_DEFAULT; - } else if (chNext == '\r' || chNext == '\n') { - styler.ColourTo(i-1, SCE_C_STRINGEOL); - state = SCE_C_STRINGEOL; - } } else if (state == SCE_C_CHARACTER) { - if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + if ((ch == '\r' || ch == '\n')) { styler.ColourTo(i-1, SCE_C_STRINGEOL); state = SCE_C_STRINGEOL; - } else if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } } else if (ch == '\'') { styler.ColourTo(i, state); state = SCE_C_DEFAULT; @@ -213,12 +242,101 @@ static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, chPrev = ch; } styler.ColourTo(lengthDoc - 1, state); +} - // Fill in the real level of the next line, keeping the current flags as they will be filled in later - if (fold) { - int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; - styler.SetLevel(lineCurrent, levelPrev | flagsNext); +static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, WordList *[], + Accessor &styler) { + bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + unsigned int endPos = startPos + length; + int visibleChars = 0; + int lineCurrent = styler.GetLine(startPos); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + int style = initStyle; + + int lastStart = 0; + + for (unsigned int i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + int stylePrev = style; + style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + + if (stylePrev == SCE_C_DEFAULT && style == SCE_C_WORD) + { + // Store last word start point. + lastStart = i; + } + + if (stylePrev == SCE_C_WORD) { + if(iswordchar(ch) && !iswordchar(chNext)) { + char s[100]; + getRange(lastStart, i, styler, s, sizeof(s)); + levelCurrent += classifyFoldPointPascal(s); + } + } + + if (foldComment && (style == SCE_C_COMMENTLINE)) { + if ((ch == '/') && (chNext == '/')) { + char chNext2 = styler.SafeGetCharAt(i + 2); + if (chNext2 == '{') { + levelCurrent++; + } else if (chNext2 == '}') { + levelCurrent--; + } + } + } + + if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) { + if (ch == '{' && chNext == '$') { + unsigned int j=i+2; // skip {$ + while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { + j++; + } + if (styler.Match(j, "region") || styler.Match(j, "if")) { + levelCurrent++; + } else if (styler.Match(j, "end")) { + levelCurrent--; + } + } + } + + if (foldComment && IsStreamCommentStyle(style)) { + if (!IsStreamCommentStyle(stylePrev)) { + levelCurrent++; + } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { + // Comments don't end at end of line and the next character may be unstyled. + levelCurrent--; + } + } + + if (atEOL) { + int lev = levelPrev; + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + if ((levelCurrent > levelPrev) && (visibleChars > 0)) + lev |= SC_FOLDLEVELHEADERFLAG; + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + levelPrev = levelCurrent; + visibleChars = 0; + } + + 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); } -LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal"); +LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc); |