OSDN Git Service

Commit DialogBox compile Okay
[tortoisegit/TortoiseGitJp.git] / ext / scintilla / src / LexNsis.cxx
diff --git a/ext/scintilla/src/LexNsis.cxx b/ext/scintilla/src/LexNsis.cxx
new file mode 100644 (file)
index 0000000..6079a63
--- /dev/null
@@ -0,0 +1,654 @@
+// Scintilla source code edit control\r
+/** @file LexNsis.cxx\r
+ ** Lexer for NSIS\r
+ **/\r
+// Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>\r
+// Last Updated: 03/13/2005\r
+// The License.txt file describes the conditions under which this software may be distributed.\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+\r
+#include "Platform.h"\r
+\r
+#include "PropSet.h"\r
+#include "Accessor.h"\r
+#include "KeyWords.h"\r
+#include "Scintilla.h"\r
+#include "SciLexer.h"\r
+\r
+#ifdef SCI_NAMESPACE\r
+using namespace Scintilla;\r
+#endif\r
+\r
+/*\r
+// located in SciLexer.h\r
+#define SCLEX_NSIS 43\r
+\r
+#define SCE_NSIS_DEFAULT 0\r
+#define SCE_NSIS_COMMENT 1\r
+#define SCE_NSIS_STRINGDQ 2\r
+#define SCE_NSIS_STRINGLQ 3\r
+#define SCE_NSIS_STRINGRQ 4\r
+#define SCE_NSIS_FUNCTION 5\r
+#define SCE_NSIS_VARIABLE 6\r
+#define SCE_NSIS_LABEL 7\r
+#define SCE_NSIS_USERDEFINED 8\r
+#define SCE_NSIS_SECTIONDEF 9\r
+#define SCE_NSIS_SUBSECTIONDEF 10\r
+#define SCE_NSIS_IFDEFINEDEF 11\r
+#define SCE_NSIS_MACRODEF 12\r
+#define SCE_NSIS_STRINGVAR 13\r
+#define SCE_NSIS_NUMBER 14\r
+// ADDED for Scintilla v1.63\r
+#define SCE_NSIS_SECTIONGROUP 15\r
+#define SCE_NSIS_PAGEEX 16\r
+#define SCE_NSIS_FUNCTIONDEF 17\r
+#define SCE_NSIS_COMMENTBOX 18\r
+*/\r
+\r
+static bool isNsisNumber(char ch)\r
+{\r
+  return (ch >= '0' && ch <= '9');\r
+}\r
+\r
+static bool isNsisChar(char ch)\r
+{\r
+  return (ch == '.' ) || (ch == '_' ) || isNsisNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');\r
+}\r
+\r
+static bool isNsisLetter(char ch)\r
+{\r
+  return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');\r
+}\r
+\r
+static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)\r
+{\r
+  int nNextLine = -1;\r
+  for( unsigned int i = start; i < end; i++ )\r
+  {\r
+    char cNext = styler.SafeGetCharAt( i );\r
+    if( cNext == '\n' )\r
+    {\r
+      nNextLine = i+1;\r
+      break;\r
+    }\r
+  }\r
+\r
+  if( nNextLine == -1 ) // We never foudn the next line...\r
+    return false;\r
+\r
+  for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )\r
+  {\r
+    char cNext = styler.SafeGetCharAt( firstChar );\r
+    if( cNext == ' ' )\r
+      continue;\r
+    if( cNext == '\t' )\r
+      continue;\r
+    if( cNext == '!' )\r
+    {\r
+      if( styler.Match(firstChar, "!else") )\r
+        return true;\r
+    }\r
+    break;\r
+  }\r
+\r
+  return false;\r
+}\r
+\r
+static int NsisCmp( const char *s1, const char *s2, bool bIgnoreCase )\r
+{\r
+  if( bIgnoreCase )\r
+     return CompareCaseInsensitive( s1, s2);\r
+\r
+  return strcmp( s1, s2 );\r
+}\r
+\r
+static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd )\r
+{\r
+  int style = styler.StyleAt(end);\r
+\r
+  // If the word is too long, it is not what we are looking for\r
+  if( end - start > 20 )\r
+    return foldlevel;\r
+\r
+  if( foldUtilityCmd )\r
+  {\r
+    // Check the style at this point, if it is not valid, then return zero\r
+    if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&\r
+        style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&\r
+        style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&\r
+        style != SCE_NSIS_PAGEEX )\r
+          return foldlevel;\r
+  }\r
+  else\r
+  {\r
+    if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&\r
+        style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP &&\r
+        style != SCE_NSIS_PAGEEX )\r
+          return foldlevel;\r
+  }\r
+\r
+  int newFoldlevel = foldlevel;\r
+  bool bIgnoreCase = false;\r
+  if( styler.GetPropertyInt("nsis.ignorecase") == 1 )\r
+    bIgnoreCase = true;\r
+\r
+  char s[20]; // The key word we are looking for has atmost 13 characters\r
+  for (unsigned int i = 0; i < end - start + 1 && i < 19; i++)\r
+       {\r
+               s[i] = static_cast<char>( styler[ start + i ] );\r
+               s[i + 1] = '\0';\r
+       }\r
+\r
+  if( s[0] == '!' )\r
+  {\r
+    if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )\r
+      newFoldlevel++;\r
+    else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )\r
+      newFoldlevel--;\r
+    else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 )\r
+      newFoldlevel++;\r
+  }\r
+  else\r
+  {\r
+    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 )\r
+      newFoldlevel++;\r
+    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 )\r
+      newFoldlevel--;\r
+  }\r
+\r
+  return newFoldlevel;\r
+}\r
+\r
+static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler )\r
+{\r
+  bool bIgnoreCase = false;\r
+  if( styler.GetPropertyInt("nsis.ignorecase") == 1 )\r
+    bIgnoreCase = true;\r
+\r
+  bool bUserVars = false;\r
+  if( styler.GetPropertyInt("nsis.uservars") == 1 )\r
+    bUserVars = true;\r
+\r
+       char s[100];\r
+\r
+       WordList &Functions = *keywordLists[0];\r
+       WordList &Variables = *keywordLists[1];\r
+       WordList &Lables = *keywordLists[2];\r
+       WordList &UserDefined = *keywordLists[3];\r
+\r
+       for (unsigned int i = 0; i < end - start + 1 && i < 99; i++)\r
+       {\r
+    if( bIgnoreCase )\r
+      s[i] = static_cast<char>( tolower(styler[ start + i ] ) );\r
+    else\r
+                 s[i] = static_cast<char>( styler[ start + i ] );\r
+               s[i + 1] = '\0';\r
+       }\r
+\r
+       // Check for special words...\r
+       if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !micro and !microend\r
+               return SCE_NSIS_MACRODEF;\r
+\r
+       if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 ||  NsisCmp(s, "!ifndef", bIgnoreCase) == 0 ||  NsisCmp(s, "!endif", bIgnoreCase) == 0 )\r
+               return SCE_NSIS_IFDEFINEDEF;\r
+\r
+  if( NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // ||  NsisCmp(s, "!ifndef", bIgnoreCase) == 0 ||  NsisCmp(s, "!endif", bIgnoreCase) == 0 )\r
+               return SCE_NSIS_IFDEFINEDEF;\r
+\r
+  if( NsisCmp(s, "!if", bIgnoreCase ) == 0 )\r
+               return SCE_NSIS_IFDEFINEDEF;\r
+\r
+  if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd\r
+    return SCE_NSIS_SECTIONGROUP;\r
+\r
+       if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd\r
+               return SCE_NSIS_SECTIONDEF;\r
+\r
+       if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd\r
+               return SCE_NSIS_SUBSECTIONDEF;\r
+\r
+  if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd\r
+    return SCE_NSIS_PAGEEX;\r
+\r
+       if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd\r
+               return SCE_NSIS_FUNCTIONDEF;\r
+\r
+       if ( Functions.InList(s) )\r
+               return SCE_NSIS_FUNCTION;\r
+\r
+       if ( Variables.InList(s) )\r
+               return SCE_NSIS_VARIABLE;\r
+\r
+       if ( Lables.InList(s) )\r
+               return SCE_NSIS_LABEL;\r
+\r
+       if( UserDefined.InList(s) )\r
+               return SCE_NSIS_USERDEFINED;\r
+\r
+       if( strlen(s) > 3 )\r
+       {\r
+               if( s[1] == '{' && s[strlen(s)-1] == '}' )\r
+                       return SCE_NSIS_VARIABLE;\r
+       }\r
+\r
+  // See if the variable is a user defined variable\r
+  if( s[0] == '$' && bUserVars )\r
+  {\r
+    bool bHasSimpleNsisChars = true;\r
+    for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)\r
+         {\r
+      if( !isNsisChar( s[j] ) )\r
+      {\r
+        bHasSimpleNsisChars = false;\r
+        break;\r
+      }\r
+         }\r
+\r
+    if( bHasSimpleNsisChars )\r
+      return SCE_NSIS_VARIABLE;\r
+  }\r
+\r
+  // To check for numbers\r
+  if( isNsisNumber( s[0] ) )\r
+  {\r
+    bool bHasSimpleNsisNumber = true;\r
+    for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)\r
+         {\r
+      if( !isNsisNumber( s[j] ) )\r
+      {\r
+        bHasSimpleNsisNumber = false;\r
+        break;\r
+      }\r
+         }\r
+\r
+    if( bHasSimpleNsisNumber )\r
+      return SCE_NSIS_NUMBER;\r
+  }\r
+\r
+       return SCE_NSIS_DEFAULT;\r
+}\r
+\r
+static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)\r
+{\r
+       int state = SCE_NSIS_DEFAULT;\r
+  if( startPos > 0 )\r
+    state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox\r
+\r
+       styler.StartAt( startPos );\r
+       styler.GetLine( startPos );\r
+\r
+       unsigned int nLengthDoc = startPos + length;\r
+       styler.StartSegment( startPos );\r
+\r
+       char cCurrChar;\r
+       bool bVarInString = false;\r
+  bool bClassicVarInString = false;\r
+\r
+       unsigned int i;\r
+       for( i = startPos; i < nLengthDoc; i++ )\r
+       {\r
+               cCurrChar = styler.SafeGetCharAt( i );\r
+               char cNextChar = styler.SafeGetCharAt(i+1);\r
+\r
+               switch(state)\r
+               {\r
+                       case SCE_NSIS_DEFAULT:\r
+                               if( cCurrChar == ';' || cCurrChar == '#' ) // we have a comment line\r
+                               {\r
+                                       styler.ColourTo(i-1, state );\r
+                                       state = SCE_NSIS_COMMENT;\r
+                                       break;\r
+                               }\r
+                               if( cCurrChar == '"' )\r
+                               {\r
+                                       styler.ColourTo(i-1, state );\r
+                                       state = SCE_NSIS_STRINGDQ;\r
+                                       bVarInString = false;\r
+          bClassicVarInString = false;\r
+                                       break;\r
+                               }\r
+                               if( cCurrChar == '\'' )\r
+                               {\r
+                                       styler.ColourTo(i-1, state );\r
+                                       state = SCE_NSIS_STRINGRQ;\r
+                                       bVarInString = false;\r
+          bClassicVarInString = false;\r
+                                       break;\r
+                               }\r
+                               if( cCurrChar == '`' )\r
+                               {\r
+                                       styler.ColourTo(i-1, state );\r
+                                       state = SCE_NSIS_STRINGLQ;\r
+                                       bVarInString = false;\r
+          bClassicVarInString = false;\r
+                                       break;\r
+                               }\r
+\r
+                               // NSIS KeyWord,Function, Variable, UserDefined:\r
+                               if( cCurrChar == '$' || isNsisChar(cCurrChar) || cCurrChar == '!' )\r
+                               {\r
+                                       styler.ColourTo(i-1,state);\r
+                                 state = SCE_NSIS_FUNCTION;\r
+\r
+          // If it is a number, we must check and set style here first...\r
+          if( isNsisNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )\r
+              styler.ColourTo( i, SCE_NSIS_NUMBER);\r
+\r
+                                       break;\r
+                               }\r
+\r
+        if( cCurrChar == '/' && cNextChar == '*' )\r
+        {\r
+          styler.ColourTo(i-1,state);\r
+          state = SCE_NSIS_COMMENTBOX;\r
+          break;\r
+        }\r
+\r
+                               break;\r
+                       case SCE_NSIS_COMMENT:\r
+                               if( cNextChar == '\n' || cNextChar == '\r' )\r
+        {\r
+          // Special case:\r
+          if( cCurrChar == '\\' )\r
+          {\r
+            styler.ColourTo(i-2,state);\r
+            styler.ColourTo(i,SCE_NSIS_DEFAULT);\r
+          }\r
+          else\r
+          {\r
+                                   styler.ColourTo(i,state);\r
+            state = SCE_NSIS_DEFAULT;\r
+          }\r
+        }\r
+                               break;\r
+                       case SCE_NSIS_STRINGDQ:\r
+      case SCE_NSIS_STRINGLQ:\r
+      case SCE_NSIS_STRINGRQ:\r
+\r
+        if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )\r
+          break; // Ignore the next character, even if it is a quote of some sort\r
+\r
+        if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ )\r
+                               {\r
+                                       styler.ColourTo(i,state);\r
+                                 state = SCE_NSIS_DEFAULT;\r
+          break;\r
+                               }\r
+\r
+        if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )\r
+        {\r
+                                       styler.ColourTo(i,state);\r
+                                 state = SCE_NSIS_DEFAULT;\r
+          break;\r
+                               }\r
+\r
+        if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ )\r
+                               {\r
+                                       styler.ColourTo(i,state);\r
+                                 state = SCE_NSIS_DEFAULT;\r
+          break;\r
+                               }\r
+\r
+        if( cNextChar == '\r' || cNextChar == '\n' )\r
+        {\r
+          int nCurLine = styler.GetLine(i+1);\r
+          int nBack = i;\r
+          // We need to check if the previous line has a \ in it...\r
+          bool bNextLine = false;\r
+\r
+          while( nBack > 0 )\r
+          {\r
+            if( styler.GetLine(nBack) != nCurLine )\r
+              break;\r
+\r
+            char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here\r
+\r
+            if( cTemp == '\\' )\r
+            {\r
+              bNextLine = true;\r
+              break;\r
+            }\r
+            if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )\r
+              break;\r
+\r
+            nBack--;\r
+          }\r
+\r
+          if( bNextLine )\r
+          {\r
+            styler.ColourTo(i+1,state);\r
+          }\r
+          if( bNextLine == false )\r
+          {\r
+            styler.ColourTo(i,state);\r
+                                   state = SCE_NSIS_DEFAULT;\r
+          }\r
+        }\r
+                               break;\r
+\r
+                       case SCE_NSIS_FUNCTION:\r
+\r
+                               // NSIS KeyWord:\r
+        if( cCurrChar == '$' )\r
+          state = SCE_NSIS_DEFAULT;\r
+        else if( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )\r
+          state = SCE_NSIS_DEFAULT;\r
+                               else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )\r
+                               {\r
+                                       state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );\r
+                                       styler.ColourTo( i, state);\r
+                                       state = SCE_NSIS_DEFAULT;\r
+                               }\r
+                               else if( !isNsisChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' )\r
+                               {\r
+          if( classifyWordNsis( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_NSIS_NUMBER )\r
+             styler.ColourTo( i-1, SCE_NSIS_NUMBER );\r
+\r
+                                       state = SCE_NSIS_DEFAULT;\r
+\r
+                                       if( cCurrChar == '"' )\r
+                                       {\r
+                                               state = SCE_NSIS_STRINGDQ;\r
+                                               bVarInString = false;\r
+            bClassicVarInString = false;\r
+                                       }\r
+                                       else if( cCurrChar == '`' )\r
+                                       {\r
+                                               state = SCE_NSIS_STRINGLQ;\r
+                                               bVarInString = false;\r
+            bClassicVarInString = false;\r
+                                       }\r
+                                       else if( cCurrChar == '\'' )\r
+                                       {\r
+                                               state = SCE_NSIS_STRINGRQ;\r
+                                               bVarInString = false;\r
+            bClassicVarInString = false;\r
+                                       }\r
+                                       else if( cCurrChar == '#' || cCurrChar == ';' )\r
+          {\r
+                                               state = SCE_NSIS_COMMENT;\r
+          }\r
+                               }\r
+                               break;\r
+      case SCE_NSIS_COMMENTBOX:\r
+\r
+        if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )\r
+        {\r
+          styler.ColourTo(i,state);\r
+          state = SCE_NSIS_DEFAULT;\r
+        }\r
+        break;\r
+               }\r
+\r
+               if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )\r
+               {\r
+                       styler.ColourTo(i,state);\r
+               }\r
+               else if( state == SCE_NSIS_STRINGDQ || state == SCE_NSIS_STRINGLQ || state == SCE_NSIS_STRINGRQ )\r
+               {\r
+      bool bIngoreNextDollarSign = false;\r
+      bool bUserVars = false;\r
+      if( styler.GetPropertyInt("nsis.uservars") == 1 )\r
+        bUserVars = true;\r
+\r
+      if( bVarInString && cCurrChar == '$' )\r
+      {\r
+        bVarInString = false;\r
+        bIngoreNextDollarSign = true;\r
+      }\r
+      else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) )\r
+      {\r
+        styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);\r
+        bVarInString = false;\r
+        bIngoreNextDollarSign = false;\r
+      }\r
+\r
+      // Covers "$INSTDIR and user vars like $MYVAR"\r
+      else if( bVarInString && !isNsisChar(cNextChar) )\r
+      {\r
+        int nWordState = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);\r
+                               if( nWordState == SCE_NSIS_VARIABLE )\r
+                                       styler.ColourTo( i, SCE_NSIS_STRINGVAR);\r
+        else if( bUserVars )\r
+          styler.ColourTo( i, SCE_NSIS_STRINGVAR);\r
+        bVarInString = false;\r
+      }\r
+      // Covers "${TEST}..."\r
+      else if( bClassicVarInString && cNextChar == '}' )\r
+      {\r
+        styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);\r
+                               bClassicVarInString = false;\r
+      }\r
+\r
+      // Start of var in string\r
+                       if( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' )\r
+                       {\r
+                               styler.ColourTo( i-1, state);\r
+                               bClassicVarInString = true;\r
+        bVarInString = false;\r
+                       }\r
+      else if( !bIngoreNextDollarSign && cCurrChar == '$' )\r
+      {\r
+        styler.ColourTo( i-1, state);\r
+        bVarInString = true;\r
+        bClassicVarInString = false;\r
+      }\r
+               }\r
+       }\r
+\r
+  // Colourise remaining document\r
+       styler.ColourTo(nLengthDoc-1,state);\r
+}\r
+\r
+static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)\r
+{\r
+       // No folding enabled, no reason to continue...\r
+       if( styler.GetPropertyInt("fold") == 0 )\r
+               return;\r
+\r
+  bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;\r
+  bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1;\r
+  bool blockComment = false;\r
+\r
+  int lineCurrent = styler.GetLine(startPos);\r
+  unsigned int safeStartPos = styler.LineStart( lineCurrent );\r
+\r
+  bool bArg1 = true;\r
+  int nWordStart = -1;\r
+\r
+  int levelCurrent = SC_FOLDLEVELBASE;\r
+       if (lineCurrent > 0)\r
+               levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\r
+       int levelNext = levelCurrent;\r
+  int style = styler.StyleAt(safeStartPos);\r
+  if( style == SCE_NSIS_COMMENTBOX )\r
+  {\r
+    if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )\r
+      levelNext++;\r
+    blockComment = true;\r
+  }\r
+\r
+  for (unsigned int i = safeStartPos; i < startPos + length; i++)\r
+       {\r
+    char chCurr = styler.SafeGetCharAt(i);\r
+    style = styler.StyleAt(i);\r
+    if( blockComment && style != SCE_NSIS_COMMENTBOX )\r
+    {\r
+      levelNext--;\r
+      blockComment = false;\r
+    }\r
+    else if( !blockComment && style == SCE_NSIS_COMMENTBOX )\r
+    {\r
+      levelNext++;\r
+      blockComment = true;\r
+    }\r
+\r
+    if( bArg1 && !blockComment)\r
+    {\r
+      if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )\r
+      {\r
+        nWordStart = i;\r
+      }\r
+      else if( isNsisLetter(chCurr) == false && nWordStart > -1 )\r
+      {\r
+        int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd );\r
+\r
+        if( newLevel == levelNext )\r
+        {\r
+          if( foldAtElse && foldUtilityCmd )\r
+          {\r
+            if( NsisNextLineHasElse(i, startPos + length, styler) )\r
+              levelNext--;\r
+          }\r
+        }\r
+        else\r
+          levelNext = newLevel;\r
+        bArg1 = false;\r
+      }\r
+    }\r
+\r
+    if( chCurr == '\n' )\r
+    {\r
+      if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment )\r
+      {\r
+        if( NsisNextLineHasElse(i, startPos + length, styler) )\r
+          levelNext--;\r
+      }\r
+\r
+      // If we are on a new line...\r
+      int levelUse = levelCurrent;\r
+                       int lev = levelUse | levelNext << 16;\r
+      if (levelUse < levelNext )\r
+                               lev |= SC_FOLDLEVELHEADERFLAG;\r
+                       if (lev != styler.LevelAt(lineCurrent))\r
+                               styler.SetLevel(lineCurrent, lev);\r
+\r
+                       lineCurrent++;\r
+                       levelCurrent = levelNext;\r
+      bArg1 = true; // New line, lets look at first argument again\r
+      nWordStart = -1;\r
+    }\r
+  }\r
+\r
+       int levelUse = levelCurrent;\r
+       int lev = levelUse | levelNext << 16;\r
+       if (levelUse < levelNext)\r
+               lev |= SC_FOLDLEVELHEADERFLAG;\r
+       if (lev != styler.LevelAt(lineCurrent))\r
+               styler.SetLevel(lineCurrent, lev);\r
+}\r
+\r
+static const char * const nsisWordLists[] = {\r
+       "Functions",\r
+       "Variables",\r
+       "Lables",\r
+       "UserDefined",\r
+       0, };\r
+\r
+\r
+LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists);\r
+\r