diff options
| -rw-r--r-- | include/SciLexer.h | 16 | ||||
| -rw-r--r-- | include/Scintilla.iface | 18 | ||||
| -rw-r--r-- | lexers/LexAVS.cxx | 293 | ||||
| -rw-r--r-- | src/Catalogue.cxx | 1 | ||||
| -rw-r--r-- | win32/scintilla.mak | 3 | ||||
| -rw-r--r-- | win32/scintilla_vc6.mak | 3 | 
6 files changed, 334 insertions, 0 deletions
| diff --git a/include/SciLexer.h b/include/SciLexer.h index 6878c0e5a..2758b92bf 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -116,6 +116,7 @@  #define SCLEX_MODULA 101  #define SCLEX_COFFEESCRIPT 102  #define SCLEX_TCMD 103 +#define SCLEX_AVS 104  #define SCLEX_AUTOMATIC 1000  #define SCE_P_DEFAULT 0  #define SCE_P_COMMENTLINE 1 @@ -1517,6 +1518,21 @@  #define SCE_COFFEESCRIPT_COMMENTBLOCK 22  #define SCE_COFFEESCRIPT_VERBOSE_REGEX 23  #define SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT 24 +#define SCE_AVS_DEFAULT 0 +#define SCE_AVS_COMMENTBLOCK 1 +#define SCE_AVS_COMMENTBLOCKN 2 +#define SCE_AVS_COMMENTLINE 3 +#define SCE_AVS_NUMBER 4 +#define SCE_AVS_OPERATOR 5 +#define SCE_AVS_IDENTIFIER 6 +#define SCE_AVS_STRING 7 +#define SCE_AVS_TRIPLESTRING 8 +#define SCE_AVS_KEYWORD 9 +#define SCE_AVS_FILTER 10 +#define SCE_AVS_PLUGIN 11 +#define SCE_AVS_FUNCTION 12 +#define SCE_AVS_CLIPPROP 13 +#define SCE_AVS_USERDFN 14  /* --Autogenerated -- end of section automatically generated from Scintilla.iface */  #endif diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 226e175ae..f70266eae 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2455,6 +2455,7 @@ val SCLEX_A68K=100  val SCLEX_MODULA=101  val SCLEX_COFFEESCRIPT=102  val SCLEX_TCMD=103 +val SCLEX_AVS=104  # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a  # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -4045,6 +4046,23 @@ val SCE_COFFEESCRIPT_HASHQUOTEDSTRING=22  val SCE_COFFEESCRIPT_COMMENTBLOCK=22  val SCE_COFFEESCRIPT_VERBOSE_REGEX=23  val SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT=24 +# Lexical states for SCLEX_AVS +lex AVS=SCLEX_AVS SCE_AVS_ +val SCE_AVS_DEFAULT=0 +val SCE_AVS_COMMENTBLOCK=1 +val SCE_AVS_COMMENTBLOCKN=2 +val SCE_AVS_COMMENTLINE=3 +val SCE_AVS_NUMBER=4 +val SCE_AVS_OPERATOR=5 +val SCE_AVS_IDENTIFIER=6 +val SCE_AVS_STRING=7 +val SCE_AVS_TRIPLESTRING=8 +val SCE_AVS_KEYWORD=9 +val SCE_AVS_FILTER=10 +val SCE_AVS_PLUGIN=11 +val SCE_AVS_FUNCTION=12 +val SCE_AVS_CLIPPROP=13 +val SCE_AVS_USERDFN=14  # Events diff --git a/lexers/LexAVS.cxx b/lexers/LexAVS.cxx new file mode 100644 index 000000000..82e434579 --- /dev/null +++ b/lexers/LexAVS.cxx @@ -0,0 +1,293 @@ +// Scintilla source code edit control +/** @file LexAVS.cxx + ** Lexer for AviSynth. + **/ +// Copyright 2012 by Bruno Barbieri <brunorex@gmail.com> +// Heavily based on LexPOV by Neil Hodgson +// 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 + +static inline bool IsAWordChar(const int ch) { +	return (ch < 0x80) && (isalnum(ch) || ch == '_'); +} + +static inline bool IsAWordStart(int ch) { +	return isalpha(ch) || (ch != ' ' && ch != '\n' && ch != '(' && ch != '.' && ch != ','); +} + +static inline bool IsANumberChar(int ch) { +	// Not exactly following number definition (several dots are seen as OK, etc.) +	// but probably enough in most cases. +	return (ch < 0x80) && +			(isdigit(ch) || ch == '.' || ch == '-' || ch == '+'); +} + +static void ColouriseAvsDoc( +	unsigned int startPos, +	int length, +	int initStyle, +	WordList *keywordlists[], +	Accessor &styler) { + +	WordList &keywords = *keywordlists[0]; +	WordList &filters = *keywordlists[1]; +	WordList &plugins = *keywordlists[2]; +	WordList &functions = *keywordlists[3]; +	WordList &clipProperties = *keywordlists[4]; +	WordList &userDefined = *keywordlists[5]; + +	int currentLine = styler.GetLine(startPos); +	// Initialize the block comment nesting level, if we are inside such a comment. +	int blockCommentLevel = 0; +	if (initStyle == SCE_AVS_COMMENTBLOCK || initStyle == SCE_AVS_COMMENTBLOCKN) { +		blockCommentLevel = styler.GetLineState(currentLine - 1); +	} + +	// Do not leak onto next line +	if (initStyle == SCE_AVS_COMMENTLINE) { +		initStyle = SCE_AVS_DEFAULT; +	} + +	StyleContext sc(startPos, length, initStyle, styler); + +	for (; sc.More(); sc.Forward()) { +		if (sc.atLineEnd) { +			// Update the line state, so it can be seen by next line +			currentLine = styler.GetLine(sc.currentPos); +			if (sc.state == SCE_AVS_COMMENTBLOCK || sc.state == SCE_AVS_COMMENTBLOCKN) { +				// Inside a block comment, we set the line state +				styler.SetLineState(currentLine, blockCommentLevel); +			} else { +				// Reset the line state +				styler.SetLineState(currentLine, 0); +			} +		} +		 +		// Determine if the current state should terminate. +		if (sc.state == SCE_AVS_OPERATOR) { +			sc.SetState(SCE_AVS_DEFAULT); +		} else if (sc.state == SCE_AVS_NUMBER) { +			// We stop the number definition on non-numerical non-dot non-sign char +			if (!IsANumberChar(sc.ch)) { +				sc.SetState(SCE_AVS_DEFAULT); +			} +		} else if (sc.state == SCE_AVS_IDENTIFIER) { +			if (!IsAWordChar(sc.ch)) { +				char s[100]; +				sc.GetCurrentLowered(s, sizeof(s)); + +				if (keywords.InList(s)) { +					sc.ChangeState(SCE_AVS_KEYWORD); +				} else if (filters.InList(s)) { +					sc.ChangeState(SCE_AVS_FILTER); +				} else if (plugins.InList(s)) { +					sc.ChangeState(SCE_AVS_PLUGIN); +				} else if (functions.InList(s)) { +					sc.ChangeState(SCE_AVS_FUNCTION); +				} else if (clipProperties.InList(s)) { +					sc.ChangeState(SCE_AVS_CLIPPROP); +				} else if (userDefined.InList(s)) { +					sc.ChangeState(SCE_AVS_USERDFN); +				} +				sc.SetState(SCE_AVS_DEFAULT); +			} +		} else if (sc.state == SCE_AVS_COMMENTBLOCK) { +			if (sc.Match('/', '*')) { +				blockCommentLevel++; +				sc.Forward(); +			} else if (sc.Match('*', '/') && blockCommentLevel > 0) { +				blockCommentLevel--; +				sc.Forward(); +				if (blockCommentLevel == 0) { +					sc.ForwardSetState(SCE_AVS_DEFAULT); +				} +			} +		} else if (sc.state == SCE_AVS_COMMENTBLOCKN) { +			if (sc.Match('[', '*')) { +				blockCommentLevel++; +				sc.Forward(); +			} else if (sc.Match('*', ']') && blockCommentLevel > 0) { +				blockCommentLevel--; +				sc.Forward(); +				if (blockCommentLevel == 0) { +					sc.ForwardSetState(SCE_AVS_DEFAULT); +				} +			} +		} else if (sc.state == SCE_AVS_COMMENTLINE) { +			if (sc.atLineEnd) { +				sc.ForwardSetState(SCE_AVS_DEFAULT); +			} +		} else if (sc.state == SCE_AVS_STRING) { +			if (sc.ch == '\"') { +				sc.ForwardSetState(SCE_AVS_DEFAULT); +			} +		} else if (sc.state == SCE_AVS_TRIPLESTRING) { +			if (sc.Match("\"\"\"")) { +				sc.Forward(); +				sc.Forward(); +				sc.ForwardSetState(SCE_AVS_DEFAULT); +			} +		} + +		// Determine if a new state should be entered. +		if (sc.state == SCE_AVS_DEFAULT) { +			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { +				sc.SetState(SCE_AVS_NUMBER); +			} else 	if (IsADigit(sc.ch) || (sc.ch == ',' && IsADigit(sc.chNext))) { +				sc.Forward(); +				sc.SetState(SCE_AVS_NUMBER); +			} else if (sc.Match('/', '*')) { +				blockCommentLevel = 1; +				sc.SetState(SCE_AVS_COMMENTBLOCK); +				sc.Forward();	// Eat the * so it isn't used for the end of the comment +			} else if (sc.Match('[', '*')) { +				blockCommentLevel = 1; +				sc.SetState(SCE_AVS_COMMENTBLOCKN); +				sc.Forward();	// Eat the * so it isn't used for the end of the comment +			} else if (sc.ch == '#') { +				sc.SetState(SCE_AVS_COMMENTLINE); +			} else if (sc.ch == '\"') { +				if (sc.Match("\"\"\"")) { +					sc.SetState(SCE_AVS_TRIPLESTRING); +				} else { +					sc.SetState(SCE_AVS_STRING); +				} +			} else if (isoperator(static_cast<char>(sc.ch))) { +				sc.SetState(SCE_AVS_OPERATOR); +			} else if (IsAWordStart(sc.ch)) { +				sc.SetState(SCE_AVS_IDENTIFIER); +			} +		} +	} + +	// End of file: complete any pending changeState +	if (sc.state == SCE_AVS_IDENTIFIER) { +		if (!IsAWordChar(sc.ch)) { +			char s[100]; +			sc.GetCurrentLowered(s, sizeof(s)); + +			if (keywords.InList(s)) { +				sc.ChangeState(SCE_AVS_KEYWORD); +			} else if (filters.InList(s)) { +				sc.ChangeState(SCE_AVS_FILTER); +			} else if (plugins.InList(s)) { +				sc.ChangeState(SCE_AVS_PLUGIN); +			} else if (functions.InList(s)) { +				sc.ChangeState(SCE_AVS_FUNCTION); +			} else if (clipProperties.InList(s)) { +				sc.ChangeState(SCE_AVS_CLIPPROP); +			} else if (userDefined.InList(s)) { +				sc.ChangeState(SCE_AVS_USERDFN); +			} +			sc.SetState(SCE_AVS_DEFAULT); +		} +	} + +	sc.Complete(); +} + +static void FoldAvsDoc( +	unsigned int startPos, +	int length, +	int initStyle, +	WordList *[], +	Accessor &styler) { + +	bool foldComment = styler.GetPropertyInt("fold.comment") != 0; +	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; +	unsigned int endPos = startPos + length; +	int visibleChars = 0; +	int lineCurrent = styler.GetLine(startPos); +	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; +	int levelCurrent = levelPrev; +	char chNext = styler[startPos]; +	int styleNext = styler.StyleAt(startPos); +	int style = initStyle; + +	for (unsigned int i = startPos; i < endPos; i++) { +		char ch = chNext; +		chNext = styler.SafeGetCharAt(i + 1); +		int stylePrev = style; +		style = styleNext; +		styleNext = styler.StyleAt(i + 1); +		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); +		if (foldComment && style == SCE_AVS_COMMENTBLOCK) { +			if (stylePrev != SCE_AVS_COMMENTBLOCK) { +				levelCurrent++; +			} else if ((styleNext != SCE_AVS_COMMENTBLOCK) && !atEOL) { +				// Comments don't end at end of line and the next character may be unstyled. +				levelCurrent--; +			} +		} + +		if (foldComment && style == SCE_AVS_COMMENTBLOCKN) { +			if (stylePrev != SCE_AVS_COMMENTBLOCKN) { +				levelCurrent++; +			} else if ((styleNext != SCE_AVS_COMMENTBLOCKN) && !atEOL) { +				// Comments don't end at end of line and the next character may be unstyled. +				levelCurrent--; +			} +		} + +		if (style == SCE_AVS_OPERATOR) { +			if (ch == '{') { +				levelCurrent++; +			} else if (ch == '}') { +				levelCurrent--; +			} +		} + +		if (atEOL) { +			int lev = levelPrev; +			if (visibleChars == 0 && foldCompact) +				lev |= SC_FOLDLEVELWHITEFLAG; +			if ((levelCurrent > levelPrev) && (visibleChars > 0)) +				lev |= SC_FOLDLEVELHEADERFLAG; +			if (lev != styler.LevelAt(lineCurrent)) { +				styler.SetLevel(lineCurrent, lev); +			} +			lineCurrent++; +			levelPrev = levelCurrent; +			visibleChars = 0; +		} + +		if (!isspacechar(ch)) +			visibleChars++; +	} +	// Fill in the real level of the next line, keeping the current flags as they will be filled in later +	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; +	styler.SetLevel(lineCurrent, levelPrev | flagsNext); +} + +static const char * const avsWordLists[] = { +	"Keywords", +	"Filters", +	"Plugins", +	"Functions", +	"Clip properties", +	"User defined functions", +	0, +}; + +LexerModule lmAVS(SCLEX_AVS, ColouriseAvsDoc, "avs", FoldAvsDoc, avsWordLists); diff --git a/src/Catalogue.cxx b/src/Catalogue.cxx index 9c47eb4ea..4773fffc0 100644 --- a/src/Catalogue.cxx +++ b/src/Catalogue.cxx @@ -90,6 +90,7 @@ int Scintilla_LinkLexers() {  	LINK_LEXER(lmASY);  	LINK_LEXER(lmAU3);  	LINK_LEXER(lmAVE); +	LINK_LEXER(lmAVS);  	LINK_LEXER(lmBaan);  	LINK_LEXER(lmBash);  	LINK_LEXER(lmBatch); diff --git a/win32/scintilla.mak b/win32/scintilla.mak index 48908916e..db0614889 100644 --- a/win32/scintilla.mak +++ b/win32/scintilla.mak @@ -92,6 +92,7 @@ LEXOBJS=\  	$(DIR_O)\LexASY.obj \  	$(DIR_O)\LexAU3.obj \  	$(DIR_O)\LexAVE.obj \ +	$(DIR_O)\LexAVS.obj \  	$(DIR_O)\LexBaan.obj \  	$(DIR_O)\LexBash.obj \  	$(DIR_O)\LexBasic.obj \ @@ -300,6 +301,8 @@ $(DIR_O)\LexAU3.obj: ..\lexers\LexAU3.cxx $(LEX_HEADERS)  $(DIR_O)\LexAVE.obj: ..\lexers\LexAVE.cxx $(LEX_HEADERS) +$(DIR_O)\LexAVS.obj: ..\lexers\LexAVS.cxx $(LEX_HEADERS) +  $(DIR_O)\LexBaan.obj: ..\lexers\LexBaan.cxx $(LEX_HEADERS)  $(DIR_O)\LexBash.obj: ..\lexers\LexBash.cxx $(LEX_HEADERS) diff --git a/win32/scintilla_vc6.mak b/win32/scintilla_vc6.mak index d1ef864ab..387e1fcb0 100644 --- a/win32/scintilla_vc6.mak +++ b/win32/scintilla_vc6.mak @@ -93,6 +93,7 @@ LEXOBJS=\  	$(DIR_O)\LexASY.obj \  	$(DIR_O)\LexAU3.obj \  	$(DIR_O)\LexAVE.obj \ +	$(DIR_O)\LexAVS.obj \  	$(DIR_O)\LexBaan.obj \  	$(DIR_O)\LexBash.obj \  	$(DIR_O)\LexBasic.obj \ @@ -298,6 +299,8 @@ $(DIR_O)\LexAU3.obj: ..\lexers\LexAU3.cxx $(LEX_HEADERS)  $(DIR_O)\LexAVE.obj: ..\lexers\LexAVE.cxx $(LEX_HEADERS) +$(DIR_O)\LexAVS.obj: ..\lexers\LexAVS.cxx $(LEX_HEADERS) +  $(DIR_O)\LexBaan.obj: ..\lexers\LexBaan.cxx $(LEX_HEADERS)  $(DIR_O)\LexBash.obj: ..\lexers\LexBash.cxx $(LEX_HEADERS) | 
