aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2004-05-29 23:12:23 +0000
committernyamatongwe <devnull@localhost>2004-05-29 23:12:23 +0000
commit8fba478c44b88995042ff64f59bad01ba16703aa (patch)
tree28594ead385a4832365479658037f00fa2ead974 /src
parent9e3117b190798fb5582122a32e0692066628db0e (diff)
downloadscintilla-mirror-8fba478c44b88995042ff64f59bad01ba16703aa.tar.gz
Updated AutoIt3 lexer from Jos.
Handles folding by syntax rathe rthan indentation.
Diffstat (limited to 'src')
-rw-r--r--src/LexAU3.cxx318
1 files changed, 278 insertions, 40 deletions
diff --git a/src/LexAU3.cxx b/src/LexAU3.cxx
index 8bc1f062e..8e0f791d9 100644
--- a/src/LexAU3.cxx
+++ b/src/LexAU3.cxx
@@ -12,9 +12,15 @@
// Fixed "#comments_end" -> "#comments-end"
// Fixed Sendkeys in Strings when not terminated with }
// Added support for Sendkey strings that have second parameter e.g. {UP 5} or {a down}
-// April 26, 2004 Fixed # pre-processor statement inside of comment block would invalidly change the color.
+// April 26, 2004 - Fixed # pre-processor statement inside of comment block would invalidly change the color.
// Added logic for #include <xyz.au3> to treat the <> as string
// Added underscore to IsAOperator.
+// May 17, 2004 - Changed the folding logic from indent to keyword folding.
+// Added Folding logic for blocks of single-commentlines or commentblock.
+// triggered by: fold.comment=1
+// Added Folding logic for preprocessor blocks triggered by fold.preprocessor=1
+// Added Special for #region - #endregion syntax highlight and folding.
+//
// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// Scintilla source code edit control
@@ -34,17 +40,13 @@
#include "Scintilla.h"
#include "SciLexer.h"
-static bool IsAU3Comment(Accessor &styler, int pos, int len) {
- return len>0 && styler[pos]==';';
-}
-
static inline bool IsTypeCharacter(const int ch)
{
return ch == '$';
}
static inline bool IsAWordChar(const int ch)
{
- return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '-');
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static inline bool IsAWordStart(const int ch)
@@ -57,7 +59,7 @@ static inline bool IsAOperator(char ch) {
return false;
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
ch == '&' || ch == '^' || ch == '=' || ch == '<' || ch == '>' ||
- ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '_' )
+ ch == '(' || ch == ')' || ch == '[' || ch == ']' )
return true;
return false;
}
@@ -111,9 +113,9 @@ static int GetSendKey(const char *szLine, char *szKey)
// Check if the second portion is either a number or one of these keywords
szKey[nKeyPos] = '\0';
szSpecial[nSpecPos] = '\0';
- if (strcmp(szSpecial,"down")==0 || strcmp(szSpecial,"up")==0 ||
- strcmp(szSpecial,"on")==0 || strcmp(szSpecial,"off")==0 ||
- strcmp(szSpecial,"toggle")==0 || nSpecNum == 1 )
+ if (strcmp(szSpecial,"down")== 0 || strcmp(szSpecial,"up")== 0 ||
+ strcmp(szSpecial,"on")== 0 || strcmp(szSpecial,"off")== 0 ||
+ strcmp(szSpecial,"toggle")== 0 || nSpecNum == 1 )
{
nFlag = 0;
}
@@ -121,9 +123,9 @@ static int GetSendKey(const char *szLine, char *szKey)
{
nFlag = 1;
}
- return nFlag; // 1 is bad, 0 is good
+ return nFlag; // 1 is bad, 0 is good
-} // GetSendKey()
+} // GetSendKey()
static void ColouriseAU3Doc(unsigned int startPos,
int length, int initStyle,
@@ -135,6 +137,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];
+ WordList &keywords6 = *keywordlists[5];
styler.StartAt(startPos);
StyleContext sc(startPos, length, initStyle, styler);
@@ -148,9 +151,9 @@ static void ColouriseAU3Doc(unsigned int startPos,
{
case SCE_AU3_COMMENTBLOCK:
{
- if (!IsAWordChar(sc.ch))
+ if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0)))
{
- if ((strcmp(s, "#ce")==0 || strcmp(s, "#comments-end")==0))
+ if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
{sc.SetState(SCE_AU3_COMMENT);} // set to comment line for the rest of the line
else
{sc.SetState(SCE_AU3_COMMENTBLOCK);}
@@ -167,13 +170,18 @@ static void ColouriseAU3Doc(unsigned int startPos,
sc.SetState(SCE_AU3_DEFAULT);
break;
}
+ case SCE_AU3_SPECIAL:
+ {
+ if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
+ break;
+ }
case SCE_AU3_KEYWORD:
{
- if (!IsAWordChar(sc.ch))
+ if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && (strcmp(s, "#comments") == 0 || strcmp(s, "#include") == 0))))
{
if (!IsTypeCharacter(sc.ch))
{
- if (strcmp(s, "#cs")==0 || strcmp(s, "#comments-start")==0 )
+ if (strcmp(s, "#cs")== 0 || strcmp(s, "#comments-start")== 0 )
{
sc.ChangeState(SCE_AU3_COMMENTBLOCK);
sc.SetState(SCE_AU3_COMMENTBLOCK);
@@ -193,11 +201,19 @@ static void ColouriseAU3Doc(unsigned int startPos,
else if (keywords5.InList(s)) {
sc.ChangeState(SCE_AU3_PREPROCESSOR);
sc.SetState(SCE_AU3_DEFAULT);
- if (strcmp(s, "#include")==0)
+ if (strcmp(s, "#include")== 0)
{
si = 3; // use to determine string start for #inlude <>
}
}
+ else if (keywords6.InList(s)) {
+ sc.ChangeState(SCE_AU3_SPECIAL);
+ sc.SetState(SCE_AU3_SPECIAL);
+ }
+ else if (strcmp(s, "_") == 0) {
+ sc.ChangeState(SCE_AU3_OPERATOR);
+ sc.SetState(SCE_AU3_DEFAULT);
+ }
else if (!IsAWordChar(sc.ch)) {
sc.ChangeState(SCE_AU3_DEFAULT);
sc.SetState(SCE_AU3_DEFAULT);
@@ -302,8 +318,8 @@ static void ColouriseAU3Doc(unsigned int startPos,
sc.SetState(SCE_AU3_STRING);
si = 2; }
else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {sc.SetState(SCE_AU3_NUMBER);}
- else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);}
else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
+ else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);}
else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
}
} //for (; sc.More(); sc.Forward())
@@ -311,11 +327,60 @@ static void ColouriseAU3Doc(unsigned int startPos,
}
//
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_AU3_COMMENT || style == SCE_AU3_COMMENTBLOCK;
+}
+
//
-static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+// Routine to find first none space on the current line and return its Style
+// needed for comment lines not starting on pos 1
+static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
+{
+ int nsPos = styler.LineStart(szLine);
+ int nePos = styler.LineStart(szLine+1) - 1;
+ while (isspacechar(styler.SafeGetCharAt(nsPos)) && nsPos < nePos)
+ {
+ nsPos++; // skip to next char
+
+ } // End While
+ return styler.StyleAt(nsPos);
+
+} // GetStyleFirstWord()
+
+//
+// Routine to check the last not comment charater on a line to see if its a continuation
+//
+static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
{
- int endPos = startPos + length;
+ int nsPos = styler.LineStart(szLine);
+ int nePos = styler.LineStart(szLine+1) - 2;
+ //int stylech = styler.StyleAt(nsPos);
+ while (nsPos < nePos)
+ {
+ //stylech = styler.StyleAt(nePos);
+ int stylech = styler.StyleAt(nsPos);
+ if (!(stylech == SCE_AU3_COMMENT)) {
+ char ch = styler.SafeGetCharAt(nePos);
+ if (!isspacechar(ch)) {
+ if (ch == '_')
+ return true;
+ else
+ return false;
+ }
+ }
+ nePos--; // skip to next char
+ } // End While
+ return false;
+} // IsContinuationLine()
+
+//
+static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+{
+ int endPos = startPos + length;
+ // get settings from the config files for folding comments and preprocessor lines
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+ bool foldpreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
// Backtrack to previous line in case need to fix its fold status
int lineCurrent = styler.GetLine(startPos);
if (startPos > 0) {
@@ -324,35 +389,207 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
startPos = styler.LineStart(lineCurrent);
}
}
- int spaceFlags = 0;
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsAU3Comment);
- char chNext = styler[startPos];
+ // vars for style of previous/current/next lines
+ //### int stylech = GetStyleFirstWord(lineCurrent,styler);
+ int style = GetStyleFirstWord(lineCurrent,styler);
+ //### int styleNext = 0;
+ int stylePrev = 0;
+ // find the first previous line without continuation character at the end
+ while (lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ if (lineCurrent > 0) {
+ stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
+ }
+ // vars for getting first word to check for keywords
+ bool FirstWordStart = false;
+ bool FirstWordEnd = false;
+ char szKeyword[10]="";
+ int szKeywordlen = 0;
+ char szThen[5]="";
+ int szThenlen = 0;
+ bool ThenFoundLast = false;
+ // var for indentlevel
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelNext = levelCurrent;
+ //### int levelPrev = 0;
+ //
+ int visibleChars = 0;
+ char chNext = styler.SafeGetCharAt(startPos);
+ char chPrev = ' ';
+ //
for (int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
- int lev = indentCurrent;
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsAU3Comment);
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
- // Line after is blank so check the next - maybe should continue further?
- int spaceFlags2 = 0;
- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsAU3Comment);
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
+ if (IsAWordChar(ch)) {
+ visibleChars++;
+ }
+ // get the syle for the current character neede to check in comment
+ //### stylech = styler.StyleAt(i);
+ int stylech = GetStyleFirstWord(lineCurrent,styler);
+ // get first word for the line for indent check max 9 characters
+ if (FirstWordStart && (!(FirstWordEnd))) {
+ if (!IsAWordChar(ch)) {
+ FirstWordEnd = true;
+ szKeyword[szKeywordlen] = '\0';
+ }
+ else {
+ if (szKeywordlen < 10) {
+ szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
+ }
+ }
+ }
+ // start the capture of the first word
+ if (!(FirstWordStart)) {
+ if (IsAWordChar(ch) || IsAWordStart(ch) || ch == ';') {
+ FirstWordStart = true;
+ szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
+ }
+ }
+ // only process this logic when not in comment section
+ if (!(stylech == SCE_AU3_COMMENT)) {
+ if (ThenFoundLast) {
+ if (IsAWordChar(ch)) {
+ ThenFoundLast = false;
+ }
+ }
+ // find out if the word "then" is the last on a "if" line
+ if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
+ if (szThenlen == 4) {
+ szThen[0] = szThen[1];
+ szThen[1] = szThen[2];
+ szThen[2] = szThen[3];
+ szThen[3] = static_cast<char>(tolower(ch));
+ if (strcmp(szThen,"then") == 0 ) {
+ ThenFoundLast = true;
+ }
+ }
+ else {
+ szThen[szThenlen++] = static_cast<char>(tolower(ch));
+ if (szThenlen == 5) {
+ szThen[4] = '\0';
}
}
}
- indentCurrent = indentNext;
- styler.SetLevel(lineCurrent, lev);
+ }
+ // End of Line found so process the information
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
+ // **************************
+ // Folding logic for Keywords
+ // **************************
+ // if a keyword is found on the current line and the line doesn't end with _ (continuation)
+ if (szKeywordlen > 0 && (!(chPrev == '_'))) {
+ szKeyword[szKeywordlen] = '\0';
+ // only fold "if" last keyword is "then" (else its a one line if)
+ if (strcmp(szKeyword,"if") == 0 && ThenFoundLast) {
+ levelNext++;
+ }
+ // create new fold for these words
+ if (strcmp(szKeyword,"do") == 0 || strcmp(szKeyword,"for") == 0 ||
+ strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
+ strcmp(szKeyword,"#region") == 0 ) {
+ levelNext++;
+ }
+ // create double Fold for select because Case will subtract one of the current level
+ if (strcmp(szKeyword,"select") == 0) {
+ levelNext++;
+ levelNext++;
+ }
+ // end the fold for these words before the current line
+ if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
+ strcmp(szKeyword,"next") == 0 || strcmp(szKeyword,"until") == 0 ||
+ strcmp(szKeyword,"wend") == 0){
+ levelNext--;
+ levelCurrent--;
+ }
+ // end the fold for these words before the current line and Start new fold
+ if (strcmp(szKeyword,"case") == 0 || strcmp(szKeyword,"else") == 0 ||
+ strcmp(szKeyword,"elseif") == 0 ) {
+ levelCurrent--;
+ }
+ // end the double fold for this word before the current line
+ if (strcmp(szKeyword,"endselect") == 0 ) {
+ levelNext--;
+ levelNext--;
+ levelCurrent--;
+ levelCurrent--;
+ }
+ // end the fold for these words on the current line
+ if (strcmp(szKeyword,"#endregion") == 0 ) {
+ levelNext--;
+ }
+ }
+ // Preprocessor and Comment folding
+ int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
+ // *************************************
+ // Folding logic for preprocessor blocks
+ // *************************************
+ // process preprosessor line
+ if (foldpreprocessor && style == SCE_AU3_PREPROCESSOR) {
+ if (!(stylePrev == SCE_AU3_PREPROCESSOR) && (styleNext == SCE_AU3_PREPROCESSOR)) {
+ levelNext++;
+ }
+ // fold till the last line for normal comment lines
+ else if (stylePrev == SCE_AU3_PREPROCESSOR && !(styleNext == SCE_AU3_PREPROCESSOR)) {
+ levelNext--;
+ }
+ }
+ // *********************************
+ // Folding logic for Comment blocks
+ // *********************************
+ if (foldComment && IsStreamCommentStyle(style)) {
+ // Start of a comment block
+ if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
+ levelNext++;
+ }
+ // fold till the last line for normal comment lines
+ else if (IsStreamCommentStyle(stylePrev)
+ && !(styleNext == SCE_AU3_COMMENT)
+ && stylePrev == SCE_AU3_COMMENT
+ && style == SCE_AU3_COMMENT) {
+ levelNext--;
+ }
+ // fold till the one but last line for Blockcomment lines
+ else if (IsStreamCommentStyle(stylePrev)
+ && !(styleNext == SCE_AU3_COMMENTBLOCK)
+ && style == SCE_AU3_COMMENTBLOCK) {
+ levelNext--;
+ levelCurrent--;
+ }
+ }
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ //if (visibleChars == 0)
+ // lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext) {
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ }
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ // reset values for the next line
lineCurrent++;
+ stylePrev = style;
+ style = styleNext;
+ levelCurrent = levelNext;
+ //###levelPrev = levelCurrent;
+ visibleChars = 0;
+ // if the last character is an Underscore then don't reset since the line continues on the next line.
+ if (!(chPrev == '_')) {
+ szKeywordlen = 0;
+ szThenlen = 0;
+ FirstWordStart = false;
+ FirstWordEnd = false;
+ ThenFoundLast = false;
+ }
}
+ // save the last processed character
+ if (!isspacechar(ch))
+ chPrev = ch;
}
-
}
@@ -364,6 +601,7 @@ static const char * const AU3WordLists[] = {
"#autoit macros",
"#autoit Sent keys",
"#autoit Pre-processors",
+ "#autoit Special",
0
};
LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists);