mirror of
				https://github.com/notepad-plus-plus/notepad-plus-plus.git
				synced 2025-10-31 11:34:05 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			663 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			663 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Scintilla source code edit control
 | |
| /** @file LexNsis.cxx
 | |
|  ** Lexer for NSIS
 | |
|  **/
 | |
| // Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>
 | |
| // Last Updated: 03/13/2005
 | |
| // The License.txt file describes the conditions under which this software may be distributed.
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <stdio.h>
 | |
| #include <stdarg.h>
 | |
| #include <assert.h>
 | |
| #include <ctype.h>
 | |
| 
 | |
| #include "ILexer.h"
 | |
| #include "Scintilla.h"
 | |
| #include "SciLexer.h"
 | |
| 
 | |
| #include "WordList.h"
 | |
| #include "LexAccessor.h"
 | |
| #include "Accessor.h"
 | |
| #include "StyleContext.h"
 | |
| #include "CharacterSet.h"
 | |
| #include "LexerModule.h"
 | |
| 
 | |
| #ifdef SCI_NAMESPACE
 | |
| using namespace Scintilla;
 | |
| #endif
 | |
| 
 | |
| /*
 | |
| // located in SciLexer.h
 | |
| #define SCLEX_NSIS 43
 | |
| 
 | |
| #define SCE_NSIS_DEFAULT 0
 | |
| #define SCE_NSIS_COMMENT 1
 | |
| #define SCE_NSIS_STRINGDQ 2
 | |
| #define SCE_NSIS_STRINGLQ 3
 | |
| #define SCE_NSIS_STRINGRQ 4
 | |
| #define SCE_NSIS_FUNCTION 5
 | |
| #define SCE_NSIS_VARIABLE 6
 | |
| #define SCE_NSIS_LABEL 7
 | |
| #define SCE_NSIS_USERDEFINED 8
 | |
| #define SCE_NSIS_SECTIONDEF 9
 | |
| #define SCE_NSIS_SUBSECTIONDEF 10
 | |
| #define SCE_NSIS_IFDEFINEDEF 11
 | |
| #define SCE_NSIS_MACRODEF 12
 | |
| #define SCE_NSIS_STRINGVAR 13
 | |
| #define SCE_NSIS_NUMBER 14
 | |
| // ADDED for Scintilla v1.63
 | |
| #define SCE_NSIS_SECTIONGROUP 15
 | |
| #define SCE_NSIS_PAGEEX 16
 | |
| #define SCE_NSIS_FUNCTIONDEF 17
 | |
| #define SCE_NSIS_COMMENTBOX 18
 | |
| */
 | |
| 
 | |
| static bool isNsisNumber(char ch)
 | |
| {
 | |
|   return (ch >= '0' && ch <= '9');
 | |
| }
 | |
| 
 | |
| static bool isNsisChar(char ch)
 | |
| {
 | |
|   return (ch == '.' ) || (ch == '_' ) || isNsisNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
 | |
| }
 | |
| 
 | |
| static bool isNsisLetter(char ch)
 | |
| {
 | |
|   return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
 | |
| }
 | |
| 
 | |
| static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
 | |
| {
 | |
|   int nNextLine = -1;
 | |
|   for( unsigned int i = start; i < end; i++ )
 | |
|   {
 | |
|     char cNext = styler.SafeGetCharAt( i );
 | |
|     if( cNext == '\n' )
 | |
|     {
 | |
|       nNextLine = i+1;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if( nNextLine == -1 ) // We never found the next line...
 | |
|     return false;
 | |
| 
 | |
|   for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
 | |
|   {
 | |
|     char cNext = styler.SafeGetCharAt( firstChar );
 | |
|     if( cNext == ' ' )
 | |
|       continue;
 | |
|     if( cNext == '\t' )
 | |
|       continue;
 | |
|     if( cNext == '!' )
 | |
|     {
 | |
|       if( styler.Match(firstChar, "!else") )
 | |
|         return true;
 | |
|     }
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| static int NsisCmp( const char *s1, const char *s2, bool bIgnoreCase )
 | |
| {
 | |
|   if( bIgnoreCase )
 | |
|      return CompareCaseInsensitive( s1, s2);
 | |
| 
 | |
|   return strcmp( s1, s2 );
 | |
| }
 | |
| 
 | |
| static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd )
 | |
| {
 | |
|   int style = styler.StyleAt(end);
 | |
| 
 | |
|   // If the word is too long, it is not what we are looking for
 | |
|   if( end - start > 20 )
 | |
|     return foldlevel;
 | |
| 
 | |
|   if( foldUtilityCmd )
 | |
|   {
 | |
|     // Check the style at this point, if it is not valid, then return zero
 | |
|     if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
 | |
|         style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&
 | |
|         style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&
 | |
|         style != SCE_NSIS_PAGEEX )
 | |
|           return foldlevel;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
 | |
|         style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP &&
 | |
|         style != SCE_NSIS_PAGEEX )
 | |
|           return foldlevel;
 | |
|   }
 | |
| 
 | |
|   int newFoldlevel = foldlevel;
 | |
|   bool bIgnoreCase = false;
 | |
|   if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
 | |
|     bIgnoreCase = true;
 | |
| 
 | |
|   char s[20]; // The key word we are looking for has atmost 13 characters
 | |
|   s[0] = '\0';
 | |
|   for (unsigned int i = 0; i < end - start + 1 && i < 19; i++)
 | |
| 	{
 | |
| 		s[i] = static_cast<char>( styler[ start + i ] );
 | |
| 		s[i + 1] = '\0';
 | |
| 	}
 | |
| 
 | |
|   if( s[0] == '!' )
 | |
|   {
 | |
|     if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )
 | |
|       newFoldlevel++;
 | |
|     else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
 | |
|       newFoldlevel--;
 | |
|     else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 )
 | |
|       newFoldlevel++;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionGroup", bIgnoreCase ) == 0 || NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 || NsisCmp(s, "PageEx", bIgnoreCase ) == 0 )
 | |
|       newFoldlevel++;
 | |
|     else if( NsisCmp(s, "SectionGroupEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase ) == 0 )
 | |
|       newFoldlevel--;
 | |
|   }
 | |
| 
 | |
|   return newFoldlevel;
 | |
| }
 | |
| 
 | |
| static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler )
 | |
| {
 | |
|   bool bIgnoreCase = false;
 | |
|   if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
 | |
|     bIgnoreCase = true;
 | |
| 
 | |
|   bool bUserVars = false;
 | |
|   if( styler.GetPropertyInt("nsis.uservars") == 1 )
 | |
|     bUserVars = true;
 | |
| 
 | |
| 	char s[100];
 | |
| 	s[0] = '\0';
 | |
| 	s[1] = '\0';
 | |
| 
 | |
| 	WordList &Functions = *keywordLists[0];
 | |
| 	WordList &Variables = *keywordLists[1];
 | |
| 	WordList &Lables = *keywordLists[2];
 | |
| 	WordList &UserDefined = *keywordLists[3];
 | |
| 
 | |
| 	for (unsigned int i = 0; i < end - start + 1 && i < 99; i++)
 | |
| 	{
 | |
|     if( bIgnoreCase )
 | |
|       s[i] = static_cast<char>( tolower(styler[ start + i ] ) );
 | |
|     else
 | |
| 		  s[i] = static_cast<char>( styler[ start + i ] );
 | |
| 		s[i + 1] = '\0';
 | |
| 	}
 | |
| 
 | |
| 	// Check for special words...
 | |
| 	if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !macro and !macroend
 | |
| 		return SCE_NSIS_MACRODEF;
 | |
| 
 | |
| 	if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 ||  NsisCmp(s, "!ifndef", bIgnoreCase) == 0 ||  NsisCmp(s, "!endif", bIgnoreCase) == 0 ) // Covers !ifdef, !ifndef and !endif
 | |
| 		return SCE_NSIS_IFDEFINEDEF;
 | |
| 
 | |
| 	if( NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!else", bIgnoreCase )  == 0 ) // Covers !if and else
 | |
| 		return SCE_NSIS_IFDEFINEDEF;
 | |
| 
 | |
| 	if (NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase )  == 0 ) // Covers !ifmacrodef and !ifnmacrodef
 | |
| 		return SCE_NSIS_IFDEFINEDEF;
 | |
| 
 | |
|   if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd
 | |
|     return SCE_NSIS_SECTIONGROUP;
 | |
| 
 | |
| 	if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd
 | |
| 		return SCE_NSIS_SECTIONDEF;
 | |
| 
 | |
| 	if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
 | |
| 		return SCE_NSIS_SUBSECTIONDEF;
 | |
| 
 | |
|   if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd
 | |
|     return SCE_NSIS_PAGEEX;
 | |
| 
 | |
| 	if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd
 | |
| 		return SCE_NSIS_FUNCTIONDEF;
 | |
| 
 | |
| 	if ( Functions.InList(s) )
 | |
| 		return SCE_NSIS_FUNCTION;
 | |
| 
 | |
| 	if ( Variables.InList(s) )
 | |
| 		return SCE_NSIS_VARIABLE;
 | |
| 
 | |
| 	if ( Lables.InList(s) )
 | |
| 		return SCE_NSIS_LABEL;
 | |
| 
 | |
| 	if( UserDefined.InList(s) )
 | |
| 		return SCE_NSIS_USERDEFINED;
 | |
| 
 | |
| 	if( strlen(s) > 3 )
 | |
| 	{
 | |
| 		if( s[1] == '{' && s[strlen(s)-1] == '}' )
 | |
| 			return SCE_NSIS_VARIABLE;
 | |
| 	}
 | |
| 
 | |
|   // See if the variable is a user defined variable
 | |
|   if( s[0] == '$' && bUserVars )
 | |
|   {
 | |
|     bool bHasSimpleNsisChars = true;
 | |
|     for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
 | |
| 	  {
 | |
|       if( !isNsisChar( s[j] ) )
 | |
|       {
 | |
|         bHasSimpleNsisChars = false;
 | |
|         break;
 | |
|       }
 | |
| 	  }
 | |
| 
 | |
|     if( bHasSimpleNsisChars )
 | |
|       return SCE_NSIS_VARIABLE;
 | |
|   }
 | |
| 
 | |
|   // To check for numbers
 | |
|   if( isNsisNumber( s[0] ) )
 | |
|   {
 | |
|     bool bHasSimpleNsisNumber = true;
 | |
|     for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
 | |
| 	  {
 | |
|       if( !isNsisNumber( s[j] ) )
 | |
|       {
 | |
|         bHasSimpleNsisNumber = false;
 | |
|         break;
 | |
|       }
 | |
| 	  }
 | |
| 
 | |
|     if( bHasSimpleNsisNumber )
 | |
|       return SCE_NSIS_NUMBER;
 | |
|   }
 | |
| 
 | |
| 	return SCE_NSIS_DEFAULT;
 | |
| }
 | |
| 
 | |
| static void ColouriseNsisDoc(unsigned int startPos, int 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 );
 | |
| 
 | |
| 	unsigned int nLengthDoc = startPos + length;
 | |
| 	styler.StartSegment( startPos );
 | |
| 
 | |
| 	char cCurrChar;
 | |
| 	bool bVarInString = false;
 | |
|   bool bClassicVarInString = false;
 | |
| 
 | |
| 	unsigned int 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' )
 | |
|         {
 | |
|           int nCurLine = styler.GetLine(i+1);
 | |
|           int 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);
 | |
| }
 | |
| 
 | |
| static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
 | |
| {
 | |
| 	// No folding enabled, no reason to continue...
 | |
| 	if( styler.GetPropertyInt("fold") == 0 )
 | |
| 		return;
 | |
| 
 | |
|   bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
 | |
|   bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1;
 | |
|   bool blockComment = false;
 | |
| 
 | |
|   int lineCurrent = styler.GetLine(startPos);
 | |
|   unsigned int safeStartPos = styler.LineStart( lineCurrent );
 | |
| 
 | |
|   bool bArg1 = true;
 | |
|   int nWordStart = -1;
 | |
| 
 | |
|   int levelCurrent = SC_FOLDLEVELBASE;
 | |
| 	if (lineCurrent > 0)
 | |
| 		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 | |
| 	int levelNext = levelCurrent;
 | |
|   int style = styler.StyleAt(safeStartPos);
 | |
|   if( style == SCE_NSIS_COMMENTBOX )
 | |
|   {
 | |
|     if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )
 | |
|       levelNext++;
 | |
|     blockComment = true;
 | |
|   }
 | |
| 
 | |
|   for (unsigned int i = safeStartPos; i < startPos + length; i++)
 | |
| 	{
 | |
|     char chCurr = styler.SafeGetCharAt(i);
 | |
|     style = styler.StyleAt(i);
 | |
|     if( blockComment && style != SCE_NSIS_COMMENTBOX )
 | |
|     {
 | |
|       levelNext--;
 | |
|       blockComment = false;
 | |
|     }
 | |
|     else if( !blockComment && style == SCE_NSIS_COMMENTBOX )
 | |
|     {
 | |
|       levelNext++;
 | |
|       blockComment = true;
 | |
|     }
 | |
| 
 | |
|     if( bArg1 && !blockComment)
 | |
|     {
 | |
|       if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )
 | |
|       {
 | |
|         nWordStart = i;
 | |
|       }
 | |
|       else if( isNsisLetter(chCurr) == false && nWordStart > -1 )
 | |
|       {
 | |
|         int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd );
 | |
| 
 | |
|         if( newLevel == levelNext )
 | |
|         {
 | |
|           if( foldAtElse && foldUtilityCmd )
 | |
|           {
 | |
|             if( NsisNextLineHasElse(i, startPos + length, styler) )
 | |
|               levelNext--;
 | |
|           }
 | |
|         }
 | |
|         else
 | |
|           levelNext = newLevel;
 | |
|         bArg1 = false;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if( chCurr == '\n' )
 | |
|     {
 | |
|       if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment )
 | |
|       {
 | |
|         if( NsisNextLineHasElse(i, startPos + length, styler) )
 | |
|           levelNext--;
 | |
|       }
 | |
| 
 | |
|       // If we are on a new line...
 | |
|       int levelUse = levelCurrent;
 | |
| 			int lev = levelUse | levelNext << 16;
 | |
|       if (levelUse < levelNext )
 | |
| 				lev |= SC_FOLDLEVELHEADERFLAG;
 | |
| 			if (lev != styler.LevelAt(lineCurrent))
 | |
| 				styler.SetLevel(lineCurrent, lev);
 | |
| 
 | |
| 			lineCurrent++;
 | |
| 			levelCurrent = levelNext;
 | |
|       bArg1 = true; // New line, lets look at first argument again
 | |
|       nWordStart = -1;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| 	int levelUse = levelCurrent;
 | |
| 	int lev = levelUse | levelNext << 16;
 | |
| 	if (levelUse < levelNext)
 | |
| 		lev |= SC_FOLDLEVELHEADERFLAG;
 | |
| 	if (lev != styler.LevelAt(lineCurrent))
 | |
| 		styler.SetLevel(lineCurrent, lev);
 | |
| }
 | |
| 
 | |
| static const char * const nsisWordLists[] = {
 | |
| 	"Functions",
 | |
| 	"Variables",
 | |
| 	"Lables",
 | |
| 	"UserDefined",
 | |
| 	0, };
 | |
| 
 | |
| 
 | |
| LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists);
 | |
| 
 |