diff options
| author | nyamatongwe <unknown> | 2013-01-10 10:51:04 +1100 | 
|---|---|---|
| committer | nyamatongwe <unknown> | 2013-01-10 10:51:04 +1100 | 
| commit | f18347dd8b4dbbaaccb038e00db883e4d074e538 (patch) | |
| tree | 2f9e9646cf5771a159b973d8a08901eccc3b595e | |
| parent | afbd9cb251631e473247477c7798cd9ff69fa408 (diff) | |
| download | scintilla-mirror-f18347dd8b4dbbaaccb038e00db883e4d074e538.tar.gz | |
Updated to style hidden commands differently.
From Mike Lischke.
| -rw-r--r-- | include/SciLexer.h | 1 | ||||
| -rw-r--r-- | include/Scintilla.iface | 1 | ||||
| -rw-r--r-- | lexers/LexMySQL.cxx | 185 | 
3 files changed, 118 insertions, 69 deletions
| diff --git a/include/SciLexer.h b/include/SciLexer.h index 85ba2a1cc..88d02a6f9 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -1345,6 +1345,7 @@  #define SCE_MYSQL_USER2 19  #define SCE_MYSQL_USER3 20  #define SCE_MYSQL_HIDDENCOMMAND 21 +#define SCE_MYSQL_PLACEHOLDER 22  #define SCE_PO_DEFAULT 0  #define SCE_PO_COMMENT 1  #define SCE_PO_MSGID 2 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index d6df3cc9d..ac0b78781 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -3920,6 +3920,7 @@ val SCE_MYSQL_USER1=18  val SCE_MYSQL_USER2=19  val SCE_MYSQL_USER3=20  val SCE_MYSQL_HIDDENCOMMAND=21 +val SCE_MYSQL_PLACEHOLDER=22  # Lexical state for SCLEX_PO  lex Po=SCLEX_PO SCE_PO_  val SCE_PO_DEFAULT=0 diff --git a/lexers/LexMySQL.cxx b/lexers/LexMySQL.cxx index 305fa7451..f4823f822 100644 --- a/lexers/LexMySQL.cxx +++ b/lexers/LexMySQL.cxx @@ -3,7 +3,7 @@   * @file LexMySQL.cxx   * Lexer for MySQL   * - * Improved by Mike Lischke <mike.lischke@sun.com> + * Improved by Mike Lischke <mike.lischke@oracle.com>   * Adopted from LexSQL.cxx by Anders Karlsson <anders@mysql.com>   * Original work by Neil Hodgson <neilh@scintilla.org>   * Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> @@ -60,74 +60,99 @@ static inline bool IsANumberChar(int ch) {  /**   * Check if the current content context represent a keyword and set the context state if so.   */ -static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[]) +static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[], int activeState)  {    int length = sc.LengthCurrent() + 1; // +1 for the next char    char* s = new char[length];    sc.GetCurrentLowered(s, length);    if (keywordlists[0]->InList(s)) -    sc.ChangeState(SCE_MYSQL_MAJORKEYWORD); +    sc.ChangeState(SCE_MYSQL_MAJORKEYWORD | activeState);    else      if (keywordlists[1]->InList(s)) -      sc.ChangeState(SCE_MYSQL_KEYWORD); +      sc.ChangeState(SCE_MYSQL_KEYWORD | activeState);      else        if (keywordlists[2]->InList(s)) -        sc.ChangeState(SCE_MYSQL_DATABASEOBJECT); +        sc.ChangeState(SCE_MYSQL_DATABASEOBJECT | activeState);        else          if (keywordlists[3]->InList(s)) -          sc.ChangeState(SCE_MYSQL_FUNCTION); +          sc.ChangeState(SCE_MYSQL_FUNCTION | activeState);          else            if (keywordlists[5]->InList(s)) -            sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD); +            sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD | activeState);            else              if (keywordlists[6]->InList(s)) -              sc.ChangeState(SCE_MYSQL_USER1); +              sc.ChangeState(SCE_MYSQL_USER1 | activeState);              else                if (keywordlists[7]->InList(s)) -                sc.ChangeState(SCE_MYSQL_USER2); +                sc.ChangeState(SCE_MYSQL_USER2 | activeState);                else                  if (keywordlists[8]->InList(s)) -                  sc.ChangeState(SCE_MYSQL_USER3); +                  sc.ChangeState(SCE_MYSQL_USER3 | activeState);    delete [] s;  }  //-------------------------------------------------------------------------------------------------- +#define HIDDENCOMMAND_STATE 0x40 // Offset for states within a hidden command. +#define MASKACTIVE(style) (style & ~HIDDENCOMMAND_STATE) + +static void SetDefaultState(StyleContext& sc, int activeState) +{ +  if (activeState == 0) +    sc.SetState(SCE_MYSQL_DEFAULT); +  else +    sc.SetState(SCE_MYSQL_HIDDENCOMMAND); +} + +static void ForwardDefaultState(StyleContext& sc, int activeState) +{ +  if (activeState == 0) +    sc.ForwardSetState(SCE_MYSQL_DEFAULT); +  else +    sc.ForwardSetState(SCE_MYSQL_HIDDENCOMMAND); +} +  static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],                              Accessor &styler)  { -	StyleContext sc(startPos, length, initStyle, styler); +	StyleContext sc(startPos, length, initStyle, styler, 127); +  int activeState = (initStyle == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : initStyle & HIDDENCOMMAND_STATE;  	for (; sc.More(); sc.Forward())    {  		// Determine if the current state should terminate. -		switch (sc.state) +		switch (MASKACTIVE(sc.state))      {        case SCE_MYSQL_OPERATOR: -        sc.SetState(SCE_MYSQL_DEFAULT); +        SetDefaultState(sc, activeState);          break;        case SCE_MYSQL_NUMBER:          // We stop the number definition on non-numerical non-dot non-eE non-sign char.          if (!IsANumberChar(sc.ch)) -          sc.SetState(SCE_MYSQL_DEFAULT); +          SetDefaultState(sc, activeState);          break;        case SCE_MYSQL_IDENTIFIER:          // Switch from identifier to keyword state and open a new state for the new char.          if (!IsAWordChar(sc.ch))          { -          CheckForKeyword(sc, keywordlists); +          CheckForKeyword(sc, keywordlists, activeState);            // Additional check for function keywords needed.            // A function name must be followed by an opening parenthesis. -          if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(') -            sc.ChangeState(SCE_MYSQL_DEFAULT); +          if (MASKACTIVE(sc.state) == SCE_MYSQL_FUNCTION && sc.ch != '(') +          { +            if (activeState > 0) +              sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND); +            else +              sc.ChangeState(SCE_MYSQL_DEFAULT); +          } -          sc.SetState(SCE_MYSQL_DEFAULT); +          SetDefaultState(sc, activeState);          }          break;        case SCE_MYSQL_VARIABLE:          if (!IsAWordChar(sc.ch)) -          sc.SetState(SCE_MYSQL_DEFAULT); +          SetDefaultState(sc, activeState);          break;        case SCE_MYSQL_SYSTEMVARIABLE:          if (!IsAWordChar(sc.ch)) @@ -138,10 +163,10 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,            // Check for known system variables here.            if (keywordlists[4]->InList(&s[2])) -            sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE); +            sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE | activeState);            delete [] s; -          sc.SetState(SCE_MYSQL_DEFAULT); +          SetDefaultState(sc, activeState);          }          break;        case SCE_MYSQL_QUOTEDIDENTIFIER: @@ -150,20 +175,19 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,            if (sc.chNext == '`')              sc.Forward();	// Ignore it            else -            sc.ForwardSetState(SCE_MYSQL_DEFAULT); +            ForwardDefaultState(sc, activeState);  				}    			break;        case SCE_MYSQL_COMMENT: -      case SCE_MYSQL_HIDDENCOMMAND:          if (sc.Match('*', '/'))          {            sc.Forward(); -          sc.ForwardSetState(SCE_MYSQL_DEFAULT); +          ForwardDefaultState(sc, activeState);          }          break;        case SCE_MYSQL_COMMENTLINE:          if (sc.atLineStart) -          sc.SetState(SCE_MYSQL_DEFAULT); +          SetDefaultState(sc, activeState);          break;        case SCE_MYSQL_SQSTRING:          if (sc.ch == '\\') @@ -175,7 +199,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,              if (sc.chNext == '\'')                sc.Forward();              else -              sc.ForwardSetState(SCE_MYSQL_DEFAULT); +              ForwardDefaultState(sc, activeState);            }          break;        case SCE_MYSQL_DQSTRING: @@ -188,76 +212,94 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,              if (sc.chNext == '\"')                sc.Forward();              else -              sc.ForwardSetState(SCE_MYSQL_DEFAULT); +              ForwardDefaultState(sc, activeState);            }          break; +      case SCE_MYSQL_PLACEHOLDER: +        if (sc.Match('}', '>')) +        { +          sc.Forward(); +          ForwardDefaultState(sc, activeState); +        } +        break; +    } + +    if (sc.state == SCE_MYSQL_HIDDENCOMMAND && sc.Match('*', '/')) +    { +      activeState = 0; +      sc.Forward(); +      ForwardDefaultState(sc, activeState);      }      // Determine if a new state should be entered. -    if (sc.state == SCE_MYSQL_DEFAULT) +    if (sc.state == SCE_MYSQL_DEFAULT || sc.state == SCE_MYSQL_HIDDENCOMMAND)      {        switch (sc.ch)        {          case '@':            if (sc.chNext == '@')            { -            sc.SetState(SCE_MYSQL_SYSTEMVARIABLE); +            sc.SetState(SCE_MYSQL_SYSTEMVARIABLE | activeState);              sc.Forward(2); // Skip past @@.            }            else              if (IsAWordStart(sc.ch))              { -              sc.SetState(SCE_MYSQL_VARIABLE); +              sc.SetState(SCE_MYSQL_VARIABLE | activeState);                sc.Forward(); // Skip past @.              }              else -              sc.SetState(SCE_MYSQL_OPERATOR); +              sc.SetState(SCE_MYSQL_OPERATOR | activeState);            break;          case '`': -          sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER); +          sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER | activeState);            break;          case '#': -          sc.SetState(SCE_MYSQL_COMMENTLINE); +          sc.SetState(SCE_MYSQL_COMMENTLINE | activeState);            break;          case '\'': -          sc.SetState(SCE_MYSQL_SQSTRING); +          sc.SetState(SCE_MYSQL_SQSTRING | activeState);            break;          case '\"': -          sc.SetState(SCE_MYSQL_DQSTRING); +          sc.SetState(SCE_MYSQL_DQSTRING | activeState);            break;          default:            if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) -            sc.SetState(SCE_MYSQL_NUMBER); +            sc.SetState(SCE_MYSQL_NUMBER | activeState);            else              if (IsAWordStart(sc.ch)) -              sc.SetState(SCE_MYSQL_IDENTIFIER); +              sc.SetState(SCE_MYSQL_IDENTIFIER | activeState);              else                if (sc.Match('/', '*'))                { -                sc.SetState(SCE_MYSQL_COMMENT); +                sc.SetState(SCE_MYSQL_COMMENT | activeState);                  // Skip comment introducer and check for hidden command.                  sc.Forward(2);                  if (sc.ch == '!')                  { +                  activeState = HIDDENCOMMAND_STATE;                    sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND); -                  sc.Forward();                  }                } +              else if (sc.Match('<', '{')) +              { +                sc.SetState(SCE_MYSQL_PLACEHOLDER | activeState); +              }                else                  if (sc.Match("--"))                  {                    // Special MySQL single line comment. -                  sc.SetState(SCE_MYSQL_COMMENTLINE); +                  sc.SetState(SCE_MYSQL_COMMENTLINE | activeState);                    sc.Forward(2);                    // Check the third character too. It must be a space or EOL.                    if (sc.ch != ' ' && sc.ch != '\n' && sc.ch != '\r') -                    sc.ChangeState(SCE_MYSQL_OPERATOR); +                    sc.ChangeState(SCE_MYSQL_OPERATOR | activeState);                  }                  else                    if (isoperator(static_cast<char>(sc.ch))) -                    sc.SetState(SCE_MYSQL_OPERATOR); +                    sc.SetState(SCE_MYSQL_OPERATOR | activeState);        }      }    } @@ -266,12 +308,12 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,    // also at the end of a line.    if (sc.state == SCE_MYSQL_IDENTIFIER)    { -    CheckForKeyword(sc, keywordlists); +    CheckForKeyword(sc, keywordlists, activeState);      // Additional check for function keywords needed.      // A function name must be followed by an opening parenthesis.      if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(') -      sc.ChangeState(SCE_MYSQL_DEFAULT); +      SetDefaultState(sc, activeState);    }    sc.Complete(); @@ -284,7 +326,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,   */  static bool IsStreamCommentStyle(int style)  { -	return style == SCE_MYSQL_COMMENT; +	return MASKACTIVE(style) == SCE_MYSQL_COMMENT;  }  //-------------------------------------------------------------------------------------------------- @@ -323,6 +365,7 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL  	int styleNext = styler.StyleAt(startPos);  	int style = initStyle; +  int activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE;    bool endPending = false;  	bool whenPending = false; @@ -332,30 +375,23 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL    for (unsigned int i = startPos; length > 0; i++, length--)    {  		int stylePrev = style; +    int lastActiveState = activeState;  		style = styleNext;  		styleNext = styler.StyleAt(i + 1); +    activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE;      char currentChar = nextChar;      nextChar = styler.SafeGetCharAt(i + 1);  		bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n'); -    switch (style) +    switch (MASKACTIVE(style))      {        case SCE_MYSQL_COMMENT:          if (foldComment)          { -          // Multiline comment style /* .. */. -          if (IsStreamCommentStyle(style)) -          { -            // Increase level if we just start a foldable comment. -            if (!IsStreamCommentStyle(stylePrev)) -              levelNext++; -            else -              // If we are in the middle of a foldable comment check if it ends now. -              // Don't end at the line end, though. -              if (!IsStreamCommentStyle(styleNext) && !atEOL) -                levelNext--; -          } +          // Multiline comment style /* .. */ just started or is still in progress. +          if (IsStreamCommentStyle(style) && !IsStreamCommentStyle(stylePrev)) +            levelNext++;          }          break;        case SCE_MYSQL_COMMENTLINE: @@ -377,6 +413,7 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL          }          break;        case SCE_MYSQL_HIDDENCOMMAND: +        /*          if (endPending)          {            // A conditional command is not a white space so it should end the current block @@ -386,15 +423,9 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL            if (levelNext < SC_FOLDLEVELBASE)              levelNext = SC_FOLDLEVELBASE;          } -        if (style != stylePrev) +        }*/ +        if (activeState != lastActiveState)            levelNext++; -        else -          if (style != styleNext) -          { -            levelNext--; -            if (levelNext < SC_FOLDLEVELBASE) -              levelNext = SC_FOLDLEVELBASE; -          }          break;        case SCE_MYSQL_OPERATOR:          if (endPending) @@ -480,7 +511,7 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL          break;        default: -        if (!isspace(currentChar) && endPending) +        if (!isspacechar(currentChar) && endPending)          {            // END followed by a non-whitespace character (not covered by other cases like identifiers)            // also should end a folding block. Typical case: END followed by self defined delimiter. @@ -490,7 +521,23 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL          }          break;      } -     + +    // Go up one level if we just ended a multi line comment. +    if (IsStreamCommentStyle(stylePrev) && !IsStreamCommentStyle(style)) +    { +      levelNext--; +      if (levelNext < SC_FOLDLEVELBASE) +        levelNext = SC_FOLDLEVELBASE; +    } + +    if (activeState == 0 && lastActiveState != 0) +    { +      // Decrease fold level when we left a hidden command. +      levelNext--; +      if (levelNext < SC_FOLDLEVELBASE) +        levelNext = SC_FOLDLEVELBASE; +    } +      if (atEOL)      {        // Apply the new folding level to this line. @@ -530,4 +577,4 @@ static const char * const mysqlWordListDesc[] = {  	0  }; -LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc); +LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc, 7); | 
