diff options
author | nyamatongwe <devnull@localhost> | 2009-01-01 00:26:08 +0000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2009-01-01 00:26:08 +0000 |
commit | bdc69f9158adb55ec1af6dc8578655e2c88ad434 (patch) | |
tree | 496931982706e296af21b5524fedd4fac7502652 | |
parent | 4f3d781c4b929847fbd7c6f6c145eb903e3dba65 (diff) | |
download | scintilla-mirror-bdc69f9158adb55ec1af6dc8578655e2c88ad434.tar.gz |
Lexer for PowerPro from Christopher Bean.
-rw-r--r-- | gtk/makefile | 8 | ||||
-rw-r--r-- | gtk/scintilla.mak | 3 | ||||
-rw-r--r-- | include/SciLexer.h | 18 | ||||
-rw-r--r-- | include/Scintilla.iface | 19 | ||||
-rw-r--r-- | macosx/makefile | 8 | ||||
-rw-r--r-- | src/KeyWords.cxx | 1 | ||||
-rw-r--r-- | src/LexPowerPro.cxx | 597 | ||||
-rw-r--r-- | vcbuild/SciLexer.dsp | 4 | ||||
-rw-r--r-- | win32/makefile | 8 | ||||
-rw-r--r-- | win32/scintilla.mak | 3 | ||||
-rw-r--r-- | win32/scintilla_vc6.mak | 3 |
11 files changed, 660 insertions, 12 deletions
diff --git a/gtk/makefile b/gtk/makefile index a0d0f1bb6..f6fde6c66 100644 --- a/gtk/makefile +++ b/gtk/makefile @@ -70,10 +70,10 @@ LexEiffel.o LexErlang.o LexEScript.o LexFlagship.o LexForth.o LexFortran.o \ LexGAP.o LexGui4Cli.o LexHaskell.o LexHTML.o LexInno.o LexKix.o LexLisp.o \ LexLout.o LexLua.o LexMagik.o LexMatlab.o LexMetapost.o LexMMIXAL.o LexMPT.o \ LexMSSQL.o LexMySQL.o LexNsis.o LexOpal.o LexOthers.o LexPascal.o LexPB.o \ -LexPerl.o LexPLM.o LexPOV.o LexPowerShell.o LexProgress.o LexPS.o LexPython.o \ -LexR.o LexRebol.o LexRuby.o LexScriptol.o LexSmalltalk.o LexSorcus.o \ -LexSpecman.o LexSpice.o LexSQL.o LexTACL.o LexTADS3.o LexTAL.o LexTCL.o \ -LexTeX.o LexVB.o LexVerilog.o LexVHDL.o LexYAML.o +LexPerl.o LexPLM.o LexPOV.o LexPowerPro.o LexPowerShell.o LexProgress.o \ +LexPS.o LexPython.o LexR.o LexRebol.o LexRuby.o LexScriptol.o LexSmalltalk.o \ +LexSorcus.o LexSpecman.o LexSpice.o LexSQL.o LexTACL.o LexTADS3.o LexTAL.o \ +LexTCL.o LexTeX.o LexVB.o LexVerilog.o LexVHDL.o LexYAML.o #--Autogenerated -- end of automatically generated section all: $(COMPLIB) diff --git a/gtk/scintilla.mak b/gtk/scintilla.mak index 20d82d334..537a2a503 100644 --- a/gtk/scintilla.mak +++ b/gtk/scintilla.mak @@ -195,6 +195,7 @@ LEXOBJS=\ $(DIR_O)\LexPerl.obj \ $(DIR_O)\LexPLM.obj \ $(DIR_O)\LexPOV.obj \ + $(DIR_O)\LexPowerPro.obj \ $(DIR_O)\LexPowerShell.obj \ $(DIR_O)\LexProgress.obj \ $(DIR_O)\LexPS.obj \ @@ -463,6 +464,8 @@ $(DIR_O)\LexPLM.obj: ..\src\LexPLM.cxx $(LEX_HEADERS) $(DIR_O)\LexPOV.obj: ..\src\LexPOV.cxx $(LEX_HEADERS) +$(DIR_O)\LexPowerPro.obj: ..\src\LexPowerPro.cxx $(LEX_HEADERS) + $(DIR_O)\LexPowerShell.obj: ..\src\LexPowerShell.cxx $(LEX_HEADERS) $(DIR_O)\LexProgress.obj: ..\src\LexProgress.cxx $(LEX_HEADERS) diff --git a/include/SciLexer.h b/include/SciLexer.h index f842c2aee..946f2affb 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -107,6 +107,7 @@ #define SCLEX_COBOL 92 #define SCLEX_TACL 93 #define SCLEX_SORCUS 94 +#define SCLEX_POWERPRO 95 #define SCLEX_AUTOMATIC 1000 #define SCE_P_DEFAULT 0 #define SCE_P_COMMENTLINE 1 @@ -1300,6 +1301,23 @@ #define SCE_SORCUS_OPERATOR 7 #define SCE_SORCUS_NUMBER 8 #define SCE_SORCUS_CONSTANT 9 +#define SCE_POWERPRO_DEFAULT 0 +#define SCE_POWERPRO_COMMENTBLOCK 1 +#define SCE_POWERPRO_COMMENTLINE 2 +#define SCE_POWERPRO_NUMBER 3 +#define SCE_POWERPRO_WORD 4 +#define SCE_POWERPRO_WORD2 5 +#define SCE_POWERPRO_WORD3 6 +#define SCE_POWERPRO_WORD4 7 +#define SCE_POWERPRO_DOUBLEQUOTEDSTRING 8 +#define SCE_POWERPRO_SINGLEQUOTEDSTRING 9 +#define SCE_POWERPRO_LINECONTINUE 10 +#define SCE_POWERPRO_OPERATOR 11 +#define SCE_POWERPRO_IDENTIFIER 12 +#define SCE_POWERPRO_STRINGEOL 13 +#define SCE_POWERPRO_VERBATIM 14 +#define SCE_POWERPRO_ALTQUOTE 15 +#define SCE_POWERPRO_FUNCTION 16 #define SCLEX_ASP 29 #define SCLEX_PHP 30 //--Autogenerated -- end of section automatically generated from Scintilla.iface diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 9d0459f48..76e46e9db 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2013,6 +2013,7 @@ val SCLEX_TAL=91 val SCLEX_COBOL=92 val SCLEX_TACL=93 val SCLEX_SORCUS=94 +val SCLEX_POWERPRO=95 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -3378,6 +3379,24 @@ val SCE_SORCUS_IDENTIFIER=6 val SCE_SORCUS_OPERATOR=7 val SCE_SORCUS_NUMBER=8 val SCE_SORCUS_CONSTANT=9 +# Lexical state for SCLEX_POWERPRO +val SCE_POWERPRO_DEFAULT=0 +val SCE_POWERPRO_COMMENTBLOCK=1 +val SCE_POWERPRO_COMMENTLINE=2 +val SCE_POWERPRO_NUMBER=3 +val SCE_POWERPRO_WORD=4 +val SCE_POWERPRO_WORD2=5 +val SCE_POWERPRO_WORD3=6 +val SCE_POWERPRO_WORD4=7 +val SCE_POWERPRO_DOUBLEQUOTEDSTRING=8 +val SCE_POWERPRO_SINGLEQUOTEDSTRING=9 +val SCE_POWERPRO_LINECONTINUE=10 +val SCE_POWERPRO_OPERATOR=11 +val SCE_POWERPRO_IDENTIFIER=12 +val SCE_POWERPRO_STRINGEOL=13 +val SCE_POWERPRO_VERBATIM=14 +val SCE_POWERPRO_ALTQUOTE=15 +val SCE_POWERPRO_FUNCTION=16 # Events diff --git a/macosx/makefile b/macosx/makefile index 69fd0032d..342021ba8 100644 --- a/macosx/makefile +++ b/macosx/makefile @@ -70,10 +70,10 @@ LexEiffel.o LexErlang.o LexEScript.o LexFlagship.o LexForth.o LexFortran.o \ LexGAP.o LexGui4Cli.o LexHaskell.o LexHTML.o LexInno.o LexKix.o LexLisp.o \ LexLout.o LexLua.o LexMagik.o LexMatlab.o LexMetapost.o LexMMIXAL.o LexMPT.o \ LexMSSQL.o LexMySQL.o LexNsis.o LexOpal.o LexOthers.o LexPascal.o LexPB.o \ -LexPerl.o LexPLM.o LexPOV.o LexPowerShell.o LexProgress.o LexPS.o LexPython.o \ -LexR.o LexRebol.o LexRuby.o LexScriptol.o LexSmalltalk.o LexSorcus.o \ -LexSpecman.o LexSpice.o LexSQL.o LexTACL.o LexTADS3.o LexTAL.o LexTCL.o \ -LexTeX.o LexVB.o LexVerilog.o LexVHDL.o LexYAML.o +LexPerl.o LexPLM.o LexPOV.o LexPowerPro.o LexPowerShell.o LexProgress.o \ +LexPS.o LexPython.o LexR.o LexRebol.o LexRuby.o LexScriptol.o LexSmalltalk.o \ +LexSorcus.o LexSpecman.o LexSpice.o LexSQL.o LexTACL.o LexTADS3.o LexTAL.o \ +LexTCL.o LexTeX.o LexVB.o LexVerilog.o LexVHDL.o LexYAML.o #--Autogenerated -- end of automatically generated section # The LEXOBJS have to be treated specially as the functions in them are not called from external code diff --git a/src/KeyWords.cxx b/src/KeyWords.cxx index 0b495d1e5..d5d7499df 100644 --- a/src/KeyWords.cxx +++ b/src/KeyWords.cxx @@ -208,6 +208,7 @@ int Scintilla_LinkLexers() { LINK_LEXER(lmPLM); LINK_LEXER(lmPo); LINK_LEXER(lmPOV); + LINK_LEXER(lmPowerPro); LINK_LEXER(lmPowerShell); LINK_LEXER(lmProgress); LINK_LEXER(lmProps); diff --git a/src/LexPowerPro.cxx b/src/LexPowerPro.cxx new file mode 100644 index 000000000..095a6af1c --- /dev/null +++ b/src/LexPowerPro.cxx @@ -0,0 +1,597 @@ +// Scintilla source code edit control +// @file LexPowerPro.cxx +// PowerPro utility, written by Bruce Switzer, is available from http://powerpro.webeddie.com +// PowerPro lexer is written by Christopher Bean (cbean@cb-software.net) +// +// Lexer code heavily borrowed from: +// LexAU3.cxx by Jos van der Zande +// LexCPP.cxx by Neil Hodgson +// LexVB.cxx by Neil Hodgson +// +// Changes: +// 2008-10-25 - Initial release +// 2008-10-26 - Changed how <name> is hilighted in 'function <name>' so that +// local isFunction = "" and local functions = "" don't get falsely highlighted +// 2008-12-14 - Added bounds checking for szKeyword and szDo +// - Replaced SetOfCharacters with CharacterSet +// - Made sure that CharacterSet::Contains is passed only positive values +// - Made sure that the return value of Accessor::SafeGetCharAt is positive before +// passsing to functions that require positive values like isspacechar() +// - Removed unused visibleChars processing from ColourisePowerProDoc() +// - Fixed bug with folding logic where line continuations didn't end where +// they were supposed to +// - Moved all helper functions to the top of the file +// +// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#include <ctype.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "Platform.h" +#include "PropSet.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" +#include "CharacterSet.h" + + +static inline bool IsStreamCommentStyle(int style) { + return style == SCE_POWERPRO_COMMENTBLOCK; +} + +static bool IsContinuationLine(unsigned int szLine, Accessor &styler) +{ + int nsPos = styler.LineStart(szLine); + int nePos = styler.LineStart(szLine + 1) - 2; + while (nsPos < nePos) + { + int stylech = styler.StyleAt(nsPos); + if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) { + char ch = styler.SafeGetCharAt(nePos); + char chPrev = styler.SafeGetCharAt(nePos-1); + char chPrevPrev = styler.SafeGetCharAt(nePos-2); + if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) ) { + if (chPrevPrev == ';' && chPrev == ';' && ch == '+') + return true; + else + return false; + } + } + nePos--; // skip to next char + } + return false; +} + +// Routine to find first none space on the current line and return its Style +// needed for comment lines not starting on pos 1 +static int GetStyleFirstWord(unsigned int szLine, Accessor &styler) +{ + int nsPos = styler.LineStart(szLine); + int nePos = styler.LineStart(szLine+1) - 1; + char ch = styler.SafeGetCharAt(nsPos); + + while (ch > 0 && isspacechar(ch) && nsPos < nePos) + { + nsPos++; // skip to next char + ch = styler.SafeGetCharAt(nsPos); + + } + return styler.StyleAt(nsPos); +} + +//returns true if there is a function to highlight +//used to highlight <name> in 'function <name>' +static bool HasFunction(Accessor &styler, unsigned int currentPos) { + + //check for presence of 'function ' + return (styler.SafeGetCharAt(currentPos) == ' ' + && tolower(styler.SafeGetCharAt(currentPos-1)) == 'n' + && tolower(styler.SafeGetCharAt(currentPos-2)) == 'o' + && tolower(styler.SafeGetCharAt(currentPos-3)) == 'i' + && tolower(styler.SafeGetCharAt(currentPos-4)) == 't' + && tolower(styler.SafeGetCharAt(currentPos-5)) == 'c' + && tolower(styler.SafeGetCharAt(currentPos-6)) == 'n' + && tolower(styler.SafeGetCharAt(currentPos-7)) == 'u' + && tolower(styler.SafeGetCharAt(currentPos-8)) == 'f' + //only allow 'function ' to appear at the beginning of a line + && (styler.SafeGetCharAt(currentPos-9) == '\n' + || styler.SafeGetCharAt(currentPos-9) == '\r' + || (styler.SafeGetCharAt(currentPos -9, '\0')) == '\0') //is the first line + ); +} + +static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler, bool caseSensitive) { + + WordList &keywords = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + WordList &keywords3 = *keywordlists[2]; + WordList &keywords4 = *keywordlists[3]; + + //define the character sets + CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true); + CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); + + StyleContext sc(startPos, length, initStyle, styler); + char s_save[100]; //for last line highlighting + + for (; sc.More(); sc.Forward()) { + + // ********************************************** + // save the total current word for eof processing + char s[100]; + sc.GetCurrentLowered(s, sizeof(s)); + + if ((sc.ch > 0) && setWord.Contains(sc.ch)) + { + strcpy(s_save,s); + int tp = strlen(s_save); + if (tp < 99) { + s_save[tp] = static_cast<char>(tolower(sc.ch)); + s_save[tp+1] = '\0'; + } + } + // ********************************************** + // + + if (sc.atLineStart) { + if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) { + // Prevent SCE_POWERPRO_STRINGEOL from leaking back to previous line which + // ends with a line continuation by locking in the state upto this position. + sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING); + } + } + + // Determine if the current state should terminate. + switch (sc.state) { + case SCE_POWERPRO_OPERATOR: + sc.SetState(SCE_POWERPRO_DEFAULT); + break; + + case SCE_POWERPRO_NUMBER: + + if (!IsADigit(sc.ch)) + sc.SetState(SCE_POWERPRO_DEFAULT); + + break; + + case SCE_POWERPRO_IDENTIFIER: + //if ((sc.ch > 0) && !setWord.Contains(sc.ch) || (sc.ch == '.')) { // use this line if don't want to match keywords with . in them. ie: win.debug will match both win and debug so win debug will also be colorized + if ((sc.ch > 0) && !setWord.Contains(sc.ch)){ // || (sc.ch == '.')) { // use this line if you want to match keywords with a . ie: win.debug will only match win.debug neither win nor debug will be colorized separately + char s[1000]; + if (caseSensitive) { + sc.GetCurrent(s, sizeof(s)); + } else { + sc.GetCurrentLowered(s, sizeof(s)); + } + if (keywords.InList(s)) { + sc.ChangeState(SCE_POWERPRO_WORD); + } else if (keywords2.InList(s)) { + sc.ChangeState(SCE_POWERPRO_WORD2); + } else if (keywords3.InList(s)) { + sc.ChangeState(SCE_POWERPRO_WORD3); + } else if (keywords4.InList(s)) { + sc.ChangeState(SCE_POWERPRO_WORD4); + } + sc.SetState(SCE_POWERPRO_DEFAULT); + } + break; + + case SCE_POWERPRO_LINECONTINUE: + if (sc.atLineStart) { + sc.SetState(SCE_POWERPRO_DEFAULT); + } else if (sc.Match('/', '*') || sc.Match('/', '/')) { + sc.SetState(SCE_POWERPRO_DEFAULT); + } + break; + + case SCE_POWERPRO_COMMENTBLOCK: + if (sc.Match('*', '/')) { + sc.Forward(); + sc.ForwardSetState(SCE_POWERPRO_DEFAULT); + } + break; + + case SCE_POWERPRO_COMMENTLINE: + if (sc.atLineStart) { + sc.SetState(SCE_POWERPRO_DEFAULT); + } + break; + + case SCE_POWERPRO_DOUBLEQUOTEDSTRING: + if (sc.atLineEnd) { + sc.ChangeState(SCE_POWERPRO_STRINGEOL); + } else if (sc.ch == '\\') { + if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { + sc.Forward(); + } + } else if (sc.ch == '\"') { + sc.ForwardSetState(SCE_POWERPRO_DEFAULT); + } + break; + + case SCE_POWERPRO_SINGLEQUOTEDSTRING: + if (sc.atLineEnd) { + sc.ChangeState(SCE_POWERPRO_STRINGEOL); + } else if (sc.ch == '\\') { + if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { + sc.Forward(); + } + } else if (sc.ch == '\'') { + sc.ForwardSetState(SCE_POWERPRO_DEFAULT); + } + break; + + case SCE_POWERPRO_STRINGEOL: + if (sc.atLineStart) { + sc.SetState(SCE_POWERPRO_DEFAULT); + } + break; + + case SCE_POWERPRO_VERBATIM: + if (sc.ch == '\"') { + if (sc.chNext == '\"') { + sc.Forward(); + } else { + sc.ForwardSetState(SCE_POWERPRO_DEFAULT); + } + } + break; + + case SCE_POWERPRO_ALTQUOTE: + if (sc.ch == '#') { + if (sc.chNext == '#') { + sc.Forward(); + } else { + sc.ForwardSetState(SCE_POWERPRO_DEFAULT); + } + } + break; + + case SCE_POWERPRO_FUNCTION: + if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ' ' || sc.ch == '(') { + sc.SetState(SCE_POWERPRO_DEFAULT); + } + break; + } + + // Determine if a new state should be entered. + if (sc.state == SCE_POWERPRO_DEFAULT) { + if (sc.Match('?', '\"')) { + sc.SetState(SCE_POWERPRO_VERBATIM); + sc.Forward(); + } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_POWERPRO_NUMBER); + }else if (sc.Match('?','#')) { + if (sc.ch == '?' && sc.chNext == '#') { + sc.SetState(SCE_POWERPRO_ALTQUOTE); + sc.Forward(); + } + } else if (HasFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>' + sc.SetState(SCE_POWERPRO_FUNCTION); + } else if (sc.ch == '@' && sc.atLineStart) { //alternate function definition [label] + sc.SetState(SCE_POWERPRO_FUNCTION); + } else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) { + sc.SetState(SCE_POWERPRO_IDENTIFIER); + } else if (sc.Match(";;+")) { + sc.SetState(SCE_POWERPRO_LINECONTINUE); + } else if (sc.Match('/', '*')) { + sc.SetState(SCE_POWERPRO_COMMENTBLOCK); + sc.Forward(); // Eat the * so it isn't used for the end of the comment + } else if (sc.Match('/', '/')) { + sc.SetState(SCE_POWERPRO_COMMENTLINE); + } else if (sc.atLineStart && sc.ch == ';') { //legacy comment that can only appear at the beginning of a line + sc.SetState(SCE_POWERPRO_COMMENTLINE); + } else if (sc.Match(";;")) { + sc.SetState(SCE_POWERPRO_COMMENTLINE); + } else if (sc.ch == '\"') { + sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING); + } else if (sc.ch == '\'') { + sc.SetState(SCE_POWERPRO_SINGLEQUOTEDSTRING); + } else if (isoperator(static_cast<char>(sc.ch))) { + sc.SetState(SCE_POWERPRO_OPERATOR); + } + } + } + + //************************************* + // Colourize the last word correctly + //************************************* + if (sc.state == SCE_POWERPRO_IDENTIFIER) + { + if (keywords.InList(s_save)) { + sc.ChangeState(SCE_POWERPRO_WORD); + sc.SetState(SCE_POWERPRO_DEFAULT); + } + else if (keywords2.InList(s_save)) { + sc.ChangeState(SCE_POWERPRO_WORD2); + sc.SetState(SCE_POWERPRO_DEFAULT); + } + else if (keywords3.InList(s_save)) { + sc.ChangeState(SCE_POWERPRO_WORD3); + sc.SetState(SCE_POWERPRO_DEFAULT); + } + else if (keywords4.InList(s_save)) { + sc.ChangeState(SCE_POWERPRO_WORD4); + sc.SetState(SCE_POWERPRO_DEFAULT); + } + else { + sc.SetState(SCE_POWERPRO_DEFAULT); + } + } + sc.Complete(); +} + +static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) +{ + //define the character sets + CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true); + CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); + + bool isFoldingAll = true; //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function) + int endPos = startPos + length; + int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly + + // get settings from the config files for folding comments and preprocessor lines + bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + bool foldInComment = styler.GetPropertyInt("fold.comment") == 2; + bool foldCompact = true; + + // Backtrack to previous line in case need to fix its fold status + int lineCurrent = styler.GetLine(startPos); + if (startPos > 0) { + isFoldingAll = false; + if (lineCurrent > 0) { + lineCurrent--; + startPos = styler.LineStart(lineCurrent); + } + } + // vars for style of previous/current/next lines + int style = GetStyleFirstWord(lineCurrent,styler); + int stylePrev = 0; + + // find the first previous line without continuation character at the end + while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) || + (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) { + lineCurrent--; + startPos = styler.LineStart(lineCurrent); + } + if (lineCurrent > 0) { + stylePrev = GetStyleFirstWord(lineCurrent-1,styler); + } + // vars for getting first word to check for keywords + bool FirstWordStart = false; + bool FirstWordEnd = false; + + const unsigned int KEYWORD_MAX = 10; + char szKeyword[KEYWORD_MAX]=""; + unsigned int szKeywordlen = 0; + + char szDo[3]=""; + int szDolen = 0; + bool DoFoundLast = false; + + // var for indentlevel + int levelCurrent = SC_FOLDLEVELBASE; + if (lineCurrent > 0) { + levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; + } + int levelNext = levelCurrent; + + int visibleChars = 0; + int functionCount = 0; + + char chNext = styler.SafeGetCharAt(startPos); + char chPrev = '\0'; + char chPrevPrev = '\0'; + char chPrevPrevPrev = '\0'; + + for (int i = startPos; i < endPos; i++) { + + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + + if ((ch > 0) && setWord.Contains(ch)) { + visibleChars++; + } + + // get the syle for the current character neede to check in comment + int stylech = styler.StyleAt(i); + + // get first word for the line for indent check max 9 characters + if (FirstWordStart && (!(FirstWordEnd))) { + if ((ch > 0) && !setWord.Contains(ch)) { + FirstWordEnd = true; + } + else if (szKeywordlen < KEYWORD_MAX - 1) { + szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch)); + szKeyword[szKeywordlen] = '\0'; + } + } + + // start the capture of the first word + if (!(FirstWordStart)) { + if ((ch > 0) && (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/')) { + FirstWordStart = true; + if (szKeywordlen < KEYWORD_MAX - 1) { + szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch)); + szKeyword[szKeywordlen] = '\0'; + } + } + } + // only process this logic when not in comment section + if (stylech != SCE_POWERPRO_COMMENTLINE) { + if (DoFoundLast) { + if (DoFoundLast && (ch > 0) && setWord.Contains(ch)) { + DoFoundLast = false; + } + } + // find out if the word "do" is the last on a "if" line + if (FirstWordEnd && strcmp(szKeyword,"if") == 0) { + if (szDolen == 2) { + szDo[0] = szDo[1]; + szDo[1] = static_cast<char>(tolower(ch)); + szDo[2] = '\0'; + if (strcmp(szDo,"do") == 0 ) { + DoFoundLast = true; + } + } + else if (szDolen < 2) { + szDo[szDolen++] = static_cast<char>(tolower(ch)); + szDo[szDolen] = '\0'; + } + } + } + + // End of Line found so process the information + if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) { + + // ************************** + // Folding logic for Keywords + // ************************** + + // if a keyword is found on the current line and the line doesn't end with ;;+ (continuation) + // and we are not inside a commentblock. + if (szKeywordlen > 0 && + (!(chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev ==';')) && + ((!(IsStreamCommentStyle(style)) || foldInComment)) ) { + + // only fold "if" last keyword is "then" (else its a one line if) + if (strcmp(szKeyword,"if") == 0 && DoFoundLast) { + levelNext++; + } + // create new fold for these words + if (strcmp(szKeyword,"for") == 0) { + levelNext++; + } + + //handle folding for functions/labels + //Note: Functions and labels don't have an explicit end like [end function] + // 1. functions/labels end at the start of another function + // 2. functions/labels end at the end of the file + if ((strcmp(szKeyword,"function") == 0) || (szKeywordlen > 0 && szKeyword[0] == '@')) { + if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script) + + if (functionCount > 0) { + levelCurrent--; + } else { + levelNext++; + } + functionCount++; + + } else { //if just folding a small piece (by clicking on the minus sign next to the word) + levelCurrent--; + } + } + + // end the fold for these words before the current line + if (strcmp(szKeyword,"endif") == 0 || strcmp(szKeyword,"endfor") == 0) { + levelNext--; + levelCurrent--; + } + // end the fold for these words before the current line and Start new fold + if (strcmp(szKeyword,"else") == 0 || strcmp(szKeyword,"elseif") == 0 ) { + levelCurrent--; + } + } + // Preprocessor and Comment folding + int styleNext = GetStyleFirstWord(lineCurrent + 1,styler); + + // ********************************* + // Folding logic for Comment blocks + // ********************************* + if (foldComment && IsStreamCommentStyle(style)) { + // Start of a comment block + if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) { + levelNext++; + } + // fold till the last line for normal comment lines + else if (IsStreamCommentStyle(stylePrev) + && !(styleNext == SCE_POWERPRO_COMMENTLINE) + && stylePrev == SCE_POWERPRO_COMMENTLINE + && style == SCE_POWERPRO_COMMENTLINE) { + levelNext--; + } + // fold till the one but last line for Blockcomment lines + else if (IsStreamCommentStyle(stylePrev) + && !(styleNext == SCE_POWERPRO_COMMENTBLOCK) + && style == SCE_POWERPRO_COMMENTBLOCK) { + levelNext--; + levelCurrent--; + } + } + + int levelUse = levelCurrent; + int lev = levelUse | levelNext << 16; + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + if (levelUse < levelNext) { + lev |= SC_FOLDLEVELHEADERFLAG; + } + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + + // reset values for the next line + lineCurrent++; + stylePrev = style; + style = styleNext; + levelCurrent = levelNext; + visibleChars = 0; + + // if the last characters are ;;+ then don't reset since the line continues on the next line. + if (chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev == ';') { + //do nothing + } else { + szKeywordlen = 0; + szDolen = 0; + FirstWordStart = false; + FirstWordEnd = false; + DoFoundLast = false; + //blank out keyword + for (unsigned int i = 0; i < KEYWORD_MAX; i++) { + szKeyword[i] = '\0'; + } + } + } + + // save the last processed characters + if ((ch > 0) && !isspacechar(ch)) { + chPrevPrevPrev = chPrevPrev; + chPrevPrev = chPrev; + chPrev = ch; + visibleChars++; + } + } + + //close folds on the last line - without this a 'phantom' + //fold can appear when an open fold is on the last line + //this can occur because functions and labels don't have an explicit end + if (lineCurrent >= lastLine) { + int lev = 0; + lev |= SC_FOLDLEVELWHITEFLAG; + styler.SetLevel(lineCurrent, lev); + } + +} + +static const char * const powerProWordLists[] = { + "Keyword list 1", + "Keyword list 2", + "Keyword list 3", + "Keyword list 4", + 0, + }; + +static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + ColourisePowerProDoc(startPos, length, initStyle, keywordlists, styler, false); +} + +LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists); diff --git a/vcbuild/SciLexer.dsp b/vcbuild/SciLexer.dsp index 7458486a0..2d21a9e27 100644 --- a/vcbuild/SciLexer.dsp +++ b/vcbuild/SciLexer.dsp @@ -354,6 +354,10 @@ SOURCE=..\src\LexPOV.cxx # End Source File # Begin Source File +SOURCE=..\src\LexPowerPro.cxx +# End Source File +# Begin Source File + SOURCE=..\src\LexPowerShell.cxx # End Source File # Begin Source File diff --git a/win32/makefile b/win32/makefile index adb48fdf4..d0f2eec4f 100644 --- a/win32/makefile +++ b/win32/makefile @@ -58,10 +58,10 @@ LexEiffel.o LexErlang.o LexEScript.o LexFlagship.o LexForth.o LexFortran.o \ LexGAP.o LexGui4Cli.o LexHaskell.o LexHTML.o LexInno.o LexKix.o LexLisp.o \ LexLout.o LexLua.o LexMagik.o LexMatlab.o LexMetapost.o LexMMIXAL.o LexMPT.o \ LexMSSQL.o LexMySQL.o LexNsis.o LexOpal.o LexOthers.o LexPascal.o LexPB.o \ -LexPerl.o LexPLM.o LexPOV.o LexPowerShell.o LexProgress.o LexPS.o LexPython.o \ -LexR.o LexRebol.o LexRuby.o LexScriptol.o LexSmalltalk.o LexSorcus.o \ -LexSpecman.o LexSpice.o LexSQL.o LexTACL.o LexTADS3.o LexTAL.o LexTCL.o \ -LexTeX.o LexVB.o LexVerilog.o LexVHDL.o LexYAML.o +LexPerl.o LexPLM.o LexPOV.o LexPowerPro.o LexPowerShell.o LexProgress.o \ +LexPS.o LexPython.o LexR.o LexRebol.o LexRuby.o LexScriptol.o LexSmalltalk.o \ +LexSorcus.o LexSpecman.o LexSpice.o LexSQL.o LexTACL.o LexTADS3.o LexTAL.o \ +LexTCL.o LexTeX.o LexVB.o LexVerilog.o LexVHDL.o LexYAML.o #--Autogenerated -- end of automatically generated section SOBJS = ScintillaWin.o ScintillaBase.o Editor.o CharClassify.o Decoration.o \ diff --git a/win32/scintilla.mak b/win32/scintilla.mak index 6edc26c20..2dad3609e 100644 --- a/win32/scintilla.mak +++ b/win32/scintilla.mak @@ -165,6 +165,7 @@ LEXOBJS=\ $(DIR_O)\LexPerl.obj \ $(DIR_O)\LexPLM.obj \ $(DIR_O)\LexPOV.obj \ + $(DIR_O)\LexPowerPro.obj \ $(DIR_O)\LexPowerShell.obj \ $(DIR_O)\LexProgress.obj \ $(DIR_O)\LexPS.obj \ @@ -414,6 +415,8 @@ $(DIR_O)\LexPLM.obj: ..\src\LexPLM.cxx $(LEX_HEADERS) $(DIR_O)\LexPOV.obj: ..\src\LexPOV.cxx $(LEX_HEADERS) +$(DIR_O)\LexPowerPro.obj: ..\src\LexPowerPro.cxx $(LEX_HEADERS) + $(DIR_O)\LexPowerShell.obj: ..\src\LexPowerShell.cxx $(LEX_HEADERS) $(DIR_O)\LexProgress.obj: ..\src\LexProgress.cxx $(LEX_HEADERS) diff --git a/win32/scintilla_vc6.mak b/win32/scintilla_vc6.mak index cbd1f270d..8c6e55f90 100644 --- a/win32/scintilla_vc6.mak +++ b/win32/scintilla_vc6.mak @@ -167,6 +167,7 @@ LEXOBJS=\ $(DIR_O)\LexPerl.obj \ $(DIR_O)\LexPLM.obj \ $(DIR_O)\LexPOV.obj \ + $(DIR_O)\LexPowerPro.obj \ $(DIR_O)\LexPowerShell.obj \ $(DIR_O)\LexProgress.obj \ $(DIR_O)\LexPS.obj \ @@ -416,6 +417,8 @@ $(DIR_O)\LexPLM.obj: ..\src\LexPLM.cxx $(LEX_HEADERS) $(DIR_O)\LexPOV.obj: ..\src\LexPOV.cxx $(LEX_HEADERS) +$(DIR_O)\LexPowerPro.obj: ..\src\LexPowerPro.cxx $(LEX_HEADERS) + $(DIR_O)\LexPowerShell.obj: ..\src\LexPowerShell.cxx $(LEX_HEADERS) $(DIR_O)\LexProgress.obj: ..\src\LexProgress.cxx $(LEX_HEADERS) |