1 // Scintilla source code edit control
2 /** @file LexNsis.cxx
3 ** Lexer for NSIS
4 **/
5 // Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>
6 // Last Updated: 03/13/2005
7 // The License.txt file describes the conditions under which this software may be distributed.
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <stdio.h>
12 #include <stdarg.h>
13
14 #include "Platform.h"
15
16 #include "PropSet.h"
17 #include "Accessor.h"
18 #include "KeyWords.h"
19 #include "Scintilla.h"
20 #include "SciLexer.h"
21
22 /*
23 // located in SciLexer.h
24 #define SCLEX_NSIS 43
25
26 #define SCE_NSIS_DEFAULT 0
27 #define SCE_NSIS_COMMENT 1
28 #define SCE_NSIS_STRINGDQ 2
29 #define SCE_NSIS_STRINGLQ 3
30 #define SCE_NSIS_STRINGRQ 4
31 #define SCE_NSIS_FUNCTION 5
32 #define SCE_NSIS_VARIABLE 6
33 #define SCE_NSIS_LABEL 7
34 #define SCE_NSIS_USERDEFINED 8
35 #define SCE_NSIS_SECTIONDEF 9
36 #define SCE_NSIS_SUBSECTIONDEF 10
37 #define SCE_NSIS_IFDEFINEDEF 11
38 #define SCE_NSIS_MACRODEF 12
39 #define SCE_NSIS_STRINGVAR 13
40 #define SCE_NSIS_NUMBER 14
41 // ADDED for Scintilla v1.63
42 #define SCE_NSIS_SECTIONGROUP 15
43 #define SCE_NSIS_PAGEEX 16
44 #define SCE_NSIS_FUNCTIONDEF 17
45 #define SCE_NSIS_COMMENTBOX 18
46 */
47
isNsisNumber(char ch)48 static bool isNsisNumber(char ch)
49 {
50 return (ch >= '0' && ch <= '9');
51 }
52
isNsisChar(char ch)53 static bool isNsisChar(char ch)
54 {
55 return (ch == '.' ) || (ch == '_' ) || isNsisNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
56 }
57
isNsisLetter(char ch)58 static bool isNsisLetter(char ch)
59 {
60 return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
61 }
62
NsisNextLineHasElse(unsigned int start,unsigned int end,Accessor & styler)63 static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
64 {
65 int nNextLine = -1;
66 for( unsigned int i = start; i < end; i++ )
67 {
68 char cNext = styler.SafeGetCharAt( i );
69 if( cNext == '\n' )
70 {
71 nNextLine = i+1;
72 break;
73 }
74 }
75
76 if( nNextLine == -1 ) // We never foudn the next line...
77 return false;
78
79 for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
80 {
81 char cNext = styler.SafeGetCharAt( firstChar );
82 if( cNext == ' ' )
83 continue;
84 if( cNext == '\t' )
85 continue;
86 if( cNext == '!' )
87 {
88 if( styler.Match(firstChar, "!else") )
89 return true;
90 }
91 break;
92 }
93
94 return false;
95 }
96
NsisCmp(char * s1,char * s2,bool bIgnoreCase)97 static int NsisCmp( char *s1, char *s2, bool bIgnoreCase )
98 {
99 if( bIgnoreCase )
100 return CompareCaseInsensitive( s1, s2);
101
102 return strcmp( s1, s2 );
103 }
104
calculateFoldNsis(unsigned int start,unsigned int end,int foldlevel,Accessor & styler,bool bElse,bool foldUtilityCmd)105 static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd )
106 {
107 int style = styler.StyleAt(end);
108
109 // If the word is too long, it is not what we are looking for
110 if( end - start > 20 )
111 return foldlevel;
112
113 if( foldUtilityCmd )
114 {
115 // Check the style at this point, if it is not valid, then return zero
116 if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
117 style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&
118 style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&
119 style != SCE_NSIS_PAGEEX )
120 return foldlevel;
121 }
122 else
123 {
124 if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
125 style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP &&
126 style != SCE_NSIS_PAGEEX )
127 return foldlevel;
128 }
129
130 int newFoldlevel = foldlevel;
131 bool bIgnoreCase = false;
132 if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
133 bIgnoreCase = true;
134
135 char s[20]; // The key word we are looking for has atmost 13 characters
136 for (unsigned int i = 0; i < end - start + 1 && i < 19; i++)
137 {
138 s[i] = static_cast<char>( styler[ start + i ] );
139 s[i + 1] = '\0';
140 }
141
142 if( s[0] == '!' )
143 {
144 if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )
145 newFoldlevel++;
146 else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
147 newFoldlevel--;
148 else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 )
149 newFoldlevel++;
150 }
151 else
152 {
153 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 )
154 newFoldlevel++;
155 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 )
156 newFoldlevel--;
157 }
158
159 return newFoldlevel;
160 }
161
classifyWordNsis(unsigned int start,unsigned int end,WordList * keywordLists[],Accessor & styler)162 static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler )
163 {
164 bool bIgnoreCase = false;
165 if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
166 bIgnoreCase = true;
167
168 bool bUserVars = false;
169 if( styler.GetPropertyInt("nsis.uservars") == 1 )
170 bUserVars = true;
171
172 char s[100];
173
174 WordList &Functions = *keywordLists[0];
175 WordList &Variables = *keywordLists[1];
176 WordList &Lables = *keywordLists[2];
177 WordList &UserDefined = *keywordLists[3];
178
179 for (unsigned int i = 0; i < end - start + 1 && i < 99; i++)
180 {
181 if( bIgnoreCase )
182 s[i] = static_cast<char>( tolower(styler[ start + i ] ) );
183 else
184 s[i] = static_cast<char>( styler[ start + i ] );
185 s[i + 1] = '\0';
186 }
187
188 // Check for special words...
189 if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !micro and !microend
190 return SCE_NSIS_MACRODEF;
191
192 if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 )
193 return SCE_NSIS_IFDEFINEDEF;
194
195 if( NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 )
196 return SCE_NSIS_IFDEFINEDEF;
197
198 if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd
199 return SCE_NSIS_SECTIONGROUP;
200
201 if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd
202 return SCE_NSIS_SECTIONDEF;
203
204 if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
205 return SCE_NSIS_SUBSECTIONDEF;
206
207 if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd
208 return SCE_NSIS_PAGEEX;
209
210 if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd
211 return SCE_NSIS_FUNCTIONDEF;
212
213 if ( Functions.InList(s) )
214 return SCE_NSIS_FUNCTION;
215
216 if ( Variables.InList(s) )
217 return SCE_NSIS_VARIABLE;
218
219 if ( Lables.InList(s) )
220 return SCE_NSIS_LABEL;
221
222 if( UserDefined.InList(s) )
223 return SCE_NSIS_USERDEFINED;
224
225 if( strlen(s) > 3 )
226 {
227 if( s[1] == '{' && s[strlen(s)-1] == '}' )
228 return SCE_NSIS_VARIABLE;
229 }
230
231 // See if the variable is a user defined variable
232 if( s[0] == '$' && bUserVars )
233 {
234 bool bHasSimpleNsisChars = true;
235 for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
236 {
237 if( !isNsisChar( s[j] ) )
238 {
239 bHasSimpleNsisChars = false;
240 break;
241 }
242 }
243
244 if( bHasSimpleNsisChars )
245 return SCE_NSIS_VARIABLE;
246 }
247
248 // To check for numbers
249 if( isNsisNumber( s[0] ) )
250 {
251 bool bHasSimpleNsisNumber = true;
252 for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
253 {
254 if( !isNsisNumber( s[j] ) )
255 {
256 bHasSimpleNsisNumber = false;
257 break;
258 }
259 }
260
261 if( bHasSimpleNsisNumber )
262 return SCE_NSIS_NUMBER;
263 }
264
265 return SCE_NSIS_DEFAULT;
266 }
267
ColouriseNsisDoc(unsigned int startPos,int length,int,WordList * keywordLists[],Accessor & styler)268 static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
269 {
270 int state = SCE_NSIS_DEFAULT;
271 if( startPos > 0 )
272 state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
273
274 styler.StartAt( startPos );
275 styler.GetLine( startPos );
276
277 unsigned int nLengthDoc = startPos + length;
278 styler.StartSegment( startPos );
279
280 char cCurrChar;
281 bool bVarInString = false;
282 bool bClassicVarInString = false;
283
284 unsigned int i;
285 for( i = startPos; i < nLengthDoc; i++ )
286 {
287 cCurrChar = styler.SafeGetCharAt( i );
288 char cNextChar = styler.SafeGetCharAt(i+1);
289
290 switch(state)
291 {
292 case SCE_NSIS_DEFAULT:
293 if( cCurrChar == ';' || cCurrChar == '#' ) // we have a comment line
294 {
295 styler.ColourTo(i-1, state );
296 state = SCE_NSIS_COMMENT;
297 break;
298 }
299 if( cCurrChar == '"' )
300 {
301 styler.ColourTo(i-1, state );
302 state = SCE_NSIS_STRINGDQ;
303 bVarInString = false;
304 bClassicVarInString = false;
305 break;
306 }
307 if( cCurrChar == '\'' )
308 {
309 styler.ColourTo(i-1, state );
310 state = SCE_NSIS_STRINGRQ;
311 bVarInString = false;
312 bClassicVarInString = false;
313 break;
314 }
315 if( cCurrChar == '`' )
316 {
317 styler.ColourTo(i-1, state );
318 state = SCE_NSIS_STRINGLQ;
319 bVarInString = false;
320 bClassicVarInString = false;
321 break;
322 }
323
324 // NSIS KeyWord,Function, Variable, UserDefined:
325 if( cCurrChar == '$' || isNsisChar(cCurrChar) || cCurrChar == '!' )
326 {
327 styler.ColourTo(i-1,state);
328 state = SCE_NSIS_FUNCTION;
329
330 // If it is a number, we must check and set style here first...
331 if( isNsisNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) )
332 styler.ColourTo( i, SCE_NSIS_NUMBER);
333
334 break;
335 }
336
337 if( cCurrChar == '/' && cNextChar == '*' )
338 {
339 styler.ColourTo(i-1,state);
340 state = SCE_NSIS_COMMENTBOX;
341 break;
342 }
343
344 break;
345 case SCE_NSIS_COMMENT:
346 if( cNextChar == '\n' || cNextChar == '\r' )
347 {
348 // Special case:
349 if( cCurrChar == '\\' )
350 {
351 styler.ColourTo(i-2,state);
352 styler.ColourTo(i,SCE_NSIS_DEFAULT);
353 }
354 else
355 {
356 styler.ColourTo(i,state);
357 state = SCE_NSIS_DEFAULT;
358 }
359 }
360 break;
361 case SCE_NSIS_STRINGDQ:
362 case SCE_NSIS_STRINGLQ:
363 case SCE_NSIS_STRINGRQ:
364
365 if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
366 break; // Ignore the next character, even if it is a quote of some sort
367
368 if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ )
369 {
370 styler.ColourTo(i,state);
371 state = SCE_NSIS_DEFAULT;
372 break;
373 }
374
375 if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )
376 {
377 styler.ColourTo(i,state);
378 state = SCE_NSIS_DEFAULT;
379 break;
380 }
381
382 if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ )
383 {
384 styler.ColourTo(i,state);
385 state = SCE_NSIS_DEFAULT;
386 break;
387 }
388
389 if( cNextChar == '\r' || cNextChar == '\n' )
390 {
391 int nCurLine = styler.GetLine(i+1);
392 int nBack = i;
393 // We need to check if the previous line has a \ in it...
394 bool bNextLine = false;
395
396 while( nBack > 0 )
397 {
398 if( styler.GetLine(nBack) != nCurLine )
399 break;
400
401 char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
402
403 if( cTemp == '\\' )
404 {
405 bNextLine = true;
406 break;
407 }
408 if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
409 break;
410
411 nBack--;
412 }
413
414 if( bNextLine )
415 {
416 styler.ColourTo(i+1,state);
417 }
418 if( bNextLine == false )
419 {
420 styler.ColourTo(i,state);
421 state = SCE_NSIS_DEFAULT;
422 }
423 }
424 break;
425
426 case SCE_NSIS_FUNCTION:
427
428 // NSIS KeyWord:
429 if( cCurrChar == '$' )
430 state = SCE_NSIS_DEFAULT;
431 else if( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
432 state = SCE_NSIS_DEFAULT;
433 else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )
434 {
435 state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );
436 styler.ColourTo( i, state);
437 state = SCE_NSIS_DEFAULT;
438 }
439 else if( !isNsisChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' )
440 {
441 if( classifyWordNsis( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_NSIS_NUMBER )
442 styler.ColourTo( i-1, SCE_NSIS_NUMBER );
443
444 state = SCE_NSIS_DEFAULT;
445
446 if( cCurrChar == '"' )
447 {
448 state = SCE_NSIS_STRINGDQ;
449 bVarInString = false;
450 bClassicVarInString = false;
451 }
452 else if( cCurrChar == '`' )
453 {
454 state = SCE_NSIS_STRINGLQ;
455 bVarInString = false;
456 bClassicVarInString = false;
457 }
458 else if( cCurrChar == '\'' )
459 {
460 state = SCE_NSIS_STRINGRQ;
461 bVarInString = false;
462 bClassicVarInString = false;
463 }
464 else if( cCurrChar == '#' || cCurrChar == ';' )
465 {
466 state = SCE_NSIS_COMMENT;
467 }
468 }
469 break;
470 case SCE_NSIS_COMMENTBOX:
471
472 if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )
473 {
474 styler.ColourTo(i,state);
475 state = SCE_NSIS_DEFAULT;
476 }
477 break;
478 }
479
480 if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )
481 {
482 styler.ColourTo(i,state);
483 }
484 else if( state == SCE_NSIS_STRINGDQ || state == SCE_NSIS_STRINGLQ || state == SCE_NSIS_STRINGRQ )
485 {
486 bool bIngoreNextDollarSign = false;
487 bool bUserVars = false;
488 if( styler.GetPropertyInt("nsis.uservars") == 1 )
489 bUserVars = true;
490
491 if( bVarInString && cCurrChar == '$' )
492 {
493 bVarInString = false;
494 bIngoreNextDollarSign = true;
495 }
496 else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) )
497 {
498 styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
499 bVarInString = false;
500 bIngoreNextDollarSign = false;
501 }
502
503 // Covers "$INSTDIR and user vars like $MYVAR"
504 else if( bVarInString && !isNsisChar(cNextChar) )
505 {
506 int nWordState = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);
507 if( nWordState == SCE_NSIS_VARIABLE )
508 styler.ColourTo( i, SCE_NSIS_STRINGVAR);
509 else if( bUserVars )
510 styler.ColourTo( i, SCE_NSIS_STRINGVAR);
511 bVarInString = false;
512 }
513 // Covers "${TEST}..."
514 else if( bClassicVarInString && cNextChar == '}' )
515 {
516 styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
517 bClassicVarInString = false;
518 }
519
520 // Start of var in string
521 if( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' )
522 {
523 styler.ColourTo( i-1, state);
524 bClassicVarInString = true;
525 bVarInString = false;
526 }
527 else if( !bIngoreNextDollarSign && cCurrChar == '$' )
528 {
529 styler.ColourTo( i-1, state);
530 bVarInString = true;
531 bClassicVarInString = false;
532 }
533 }
534 }
535
536 // Colourise remaining document
537 styler.ColourTo(nLengthDoc-1,state);
538 }
539
FoldNsisDoc(unsigned int startPos,int length,int,WordList * [],Accessor & styler)540 static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
541 {
542 // No folding enabled, no reason to continue...
543 if( styler.GetPropertyInt("fold") == 0 )
544 return;
545
546 bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
547 bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1;
548 bool blockComment = false;
549
550 int lineCurrent = styler.GetLine(startPos);
551 unsigned int safeStartPos = styler.LineStart( lineCurrent );
552
553 bool bArg1 = true;
554 int nWordStart = -1;
555
556 int levelCurrent = SC_FOLDLEVELBASE;
557 if (lineCurrent > 0)
558 levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
559 int levelNext = levelCurrent;
560 int style = styler.StyleAt(safeStartPos);
561 if( style == SCE_NSIS_COMMENTBOX )
562 {
563 if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )
564 levelNext++;
565 blockComment = true;
566 }
567
568 for (unsigned int i = safeStartPos; i < startPos + length; i++)
569 {
570 char chCurr = styler.SafeGetCharAt(i);
571 style = styler.StyleAt(i);
572 if( blockComment && style != SCE_NSIS_COMMENTBOX )
573 {
574 levelNext--;
575 blockComment = false;
576 }
577 else if( !blockComment && style == SCE_NSIS_COMMENTBOX )
578 {
579 levelNext++;
580 blockComment = true;
581 }
582
583 if( bArg1 && !blockComment)
584 {
585 if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )
586 {
587 nWordStart = i;
588 }
589 else if( isNsisLetter(chCurr) == false && nWordStart > -1 )
590 {
591 int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd );
592
593 if( newLevel == levelNext )
594 {
595 if( foldAtElse && foldUtilityCmd )
596 {
597 if( NsisNextLineHasElse(i, startPos + length, styler) )
598 levelNext--;
599 }
600 }
601 else
602 levelNext = newLevel;
603 bArg1 = false;
604 }
605 }
606
607 if( chCurr == '\n' )
608 {
609 if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment )
610 {
611 if( NsisNextLineHasElse(i, startPos + length, styler) )
612 levelNext--;
613 }
614
615 // If we are on a new line...
616 int levelUse = levelCurrent;
617 int lev = levelUse | levelNext << 16;
618 if (levelUse < levelNext )
619 lev |= SC_FOLDLEVELHEADERFLAG;
620 if (lev != styler.LevelAt(lineCurrent))
621 styler.SetLevel(lineCurrent, lev);
622
623 lineCurrent++;
624 levelCurrent = levelNext;
625 bArg1 = true; // New line, lets look at first argument again
626 nWordStart = -1;
627 }
628 }
629
630 int levelUse = levelCurrent;
631 int lev = levelUse | levelNext << 16;
632 if (levelUse < levelNext)
633 lev |= SC_FOLDLEVELHEADERFLAG;
634 if (lev != styler.LevelAt(lineCurrent))
635 styler.SetLevel(lineCurrent, lev);
636 }
637
638 static const char * const nsisWordLists[] = {
639 "Functions",
640 "Variables",
641 "Lables",
642 "UserDefined",
643 0, };
644
645
646 LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists);
647
648