static void ColouriseNsisDoc()

in ext/scintilla/lexers/LexNsis.cxx [281:551]


static void ColouriseNsisDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordLists[], Accessor &styler)
{
	int state = SCE_NSIS_DEFAULT;
  if( startPos > 0 )
    state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox

	styler.StartAt( startPos );
	styler.GetLine( startPos );

	Sci_PositionU nLengthDoc = startPos + length;
	styler.StartSegment( startPos );

	char cCurrChar;
	bool bVarInString = false;
  bool bClassicVarInString = false;

	Sci_PositionU i;
	for( i = startPos; i < nLengthDoc; i++ )
	{
		cCurrChar = styler.SafeGetCharAt( i );
		char cNextChar = styler.SafeGetCharAt(i+1);

		switch(state)
		{
			case SCE_NSIS_DEFAULT:
				if( cCurrChar == ';' || cCurrChar == '#' ) // we have a comment line
				{
					styler.ColourTo(i-1, state );
					state = SCE_NSIS_COMMENT;
					break;
				}
				if( cCurrChar == '"' )
				{
					styler.ColourTo(i-1, state );
					state = SCE_NSIS_STRINGDQ;
					bVarInString = false;
          bClassicVarInString = false;
					break;
				}
				if( cCurrChar == '\'' )
				{
					styler.ColourTo(i-1, state );
					state = SCE_NSIS_STRINGRQ;
					bVarInString = false;
          bClassicVarInString = false;
					break;
				}
				if( cCurrChar == '`' )
				{
					styler.ColourTo(i-1, state );
					state = SCE_NSIS_STRINGLQ;
					bVarInString = false;
          bClassicVarInString = false;
					break;
				}

				// NSIS KeyWord,Function, Variable, UserDefined:
				if( cCurrChar == '$' || isNsisChar(cCurrChar) || cCurrChar == '!' )
				{
					styler.ColourTo(i-1,state);
				  state = SCE_NSIS_FUNCTION;

          // If it is a number, we must check and set style here first...
          if( isNsisNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )
              styler.ColourTo( i, SCE_NSIS_NUMBER);

					break;
				}

        if( cCurrChar == '/' && cNextChar == '*' )
        {
          styler.ColourTo(i-1,state);
          state = SCE_NSIS_COMMENTBOX;
          break;
        }

				break;
			case SCE_NSIS_COMMENT:
				if( cNextChar == '\n' || cNextChar == '\r' )
        {
          // Special case:
          if( cCurrChar == '\\' )
          {
            styler.ColourTo(i-2,state);
            styler.ColourTo(i,SCE_NSIS_DEFAULT);
          }
          else
          {
				    styler.ColourTo(i,state);
            state = SCE_NSIS_DEFAULT;
          }
        }
				break;
			case SCE_NSIS_STRINGDQ:
      case SCE_NSIS_STRINGLQ:
      case SCE_NSIS_STRINGRQ:

        if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
          break; // Ignore the next character, even if it is a quote of some sort

        if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ )
				{
					styler.ColourTo(i,state);
				  state = SCE_NSIS_DEFAULT;
          break;
				}

        if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )
        {
					styler.ColourTo(i,state);
				  state = SCE_NSIS_DEFAULT;
          break;
				}

        if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ )
				{
					styler.ColourTo(i,state);
				  state = SCE_NSIS_DEFAULT;
          break;
				}

        if( cNextChar == '\r' || cNextChar == '\n' )
        {
          Sci_Position nCurLine = styler.GetLine(i+1);
          Sci_Position nBack = i;
          // We need to check if the previous line has a \ in it...
          bool bNextLine = false;

          while( nBack > 0 )
          {
            if( styler.GetLine(nBack) != nCurLine )
              break;

            char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here

            if( cTemp == '\\' )
            {
              bNextLine = true;
              break;
            }
            if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
              break;

            nBack--;
          }

          if( bNextLine )
          {
            styler.ColourTo(i+1,state);
          }
          if( bNextLine == false )
          {
            styler.ColourTo(i,state);
				    state = SCE_NSIS_DEFAULT;
          }
        }
				break;

			case SCE_NSIS_FUNCTION:

				// NSIS KeyWord:
        if( cCurrChar == '$' )
          state = SCE_NSIS_DEFAULT;
        else if( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
          state = SCE_NSIS_DEFAULT;
				else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )
				{
					state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );
					styler.ColourTo( i, state);
					state = SCE_NSIS_DEFAULT;
				}
				else if( !isNsisChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' )
				{
          if( classifyWordNsis( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_NSIS_NUMBER )
             styler.ColourTo( i-1, SCE_NSIS_NUMBER );

					state = SCE_NSIS_DEFAULT;

					if( cCurrChar == '"' )
					{
						state = SCE_NSIS_STRINGDQ;
						bVarInString = false;
            bClassicVarInString = false;
					}
					else if( cCurrChar == '`' )
					{
						state = SCE_NSIS_STRINGLQ;
						bVarInString = false;
            bClassicVarInString = false;
					}
					else if( cCurrChar == '\'' )
					{
						state = SCE_NSIS_STRINGRQ;
						bVarInString = false;
            bClassicVarInString = false;
					}
					else if( cCurrChar == '#' || cCurrChar == ';' )
          {
						state = SCE_NSIS_COMMENT;
          }
				}
				break;
      case SCE_NSIS_COMMENTBOX:

        if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )
        {
          styler.ColourTo(i,state);
          state = SCE_NSIS_DEFAULT;
        }
        break;
		}

		if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )
		{
			styler.ColourTo(i,state);
		}
		else if( state == SCE_NSIS_STRINGDQ || state == SCE_NSIS_STRINGLQ || state == SCE_NSIS_STRINGRQ )
		{
      bool bIngoreNextDollarSign = false;
      bool bUserVars = false;
      if( styler.GetPropertyInt("nsis.uservars") == 1 )
        bUserVars = true;

      if( bVarInString && cCurrChar == '$' )
      {
        bVarInString = false;
        bIngoreNextDollarSign = true;
      }
      else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) )
      {
        styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
        bVarInString = false;
        bIngoreNextDollarSign = false;
      }

      // Covers "$INSTDIR and user vars like $MYVAR"
      else if( bVarInString && !isNsisChar(cNextChar) )
      {
        int nWordState = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);
				if( nWordState == SCE_NSIS_VARIABLE )
					styler.ColourTo( i, SCE_NSIS_STRINGVAR);
        else if( bUserVars )
          styler.ColourTo( i, SCE_NSIS_STRINGVAR);
        bVarInString = false;
      }
      // Covers "${TEST}..."
      else if( bClassicVarInString && cNextChar == '}' )
      {
        styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
				bClassicVarInString = false;
      }

      // Start of var in string
			if( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' )
			{
				styler.ColourTo( i-1, state);
				bClassicVarInString = true;
        bVarInString = false;
			}
      else if( !bIngoreNextDollarSign && cCurrChar == '$' )
      {
        styler.ColourTo( i-1, state);
        bVarInString = true;
        bClassicVarInString = false;
      }
		}
	}

  // Colourise remaining document
	styler.ColourTo(nLengthDoc-1,state);
}