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);
}