diff options
| -rw-r--r-- | include/KeyWords.h | 23 | ||||
| -rw-r--r-- | include/SciLexer.h | 1 | ||||
| -rw-r--r-- | include/Scintilla.h | 1 | ||||
| -rw-r--r-- | include/Scintilla.iface | 6 | ||||
| -rw-r--r-- | src/KeyWords.cxx | 64 | ||||
| -rw-r--r-- | src/LexCPP.cxx | 3 | ||||
| -rw-r--r-- | src/ScintillaBase.cxx | 31 | ||||
| -rw-r--r-- | src/ScintillaBase.h | 3 | 
8 files changed, 111 insertions, 21 deletions
| diff --git a/include/KeyWords.h b/include/KeyWords.h index d589d1228..43de26fe6 100644 --- a/include/KeyWords.h +++ b/include/KeyWords.h @@ -9,17 +9,30 @@ typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyl                    WordList *keywordlists[], Accessor &styler);  /** + * A LexerModule is responsible for lexing and folding a particular language. + * The class maintains a list of LexerModules which can be searched to find a + * module appropriate to a particular language.   */  class LexerModule { -	static LexerModule *base;  	LexerModule *next;  	int language; -	LexerFunction fn; +	const char *languageName; +	LexerFunction fnLexer; +	LexerFunction fnFolder; +	 +	static LexerModule *base; +	static int nextLanguage;  public: -	LexerModule(int language_, LexerFunction fn_); -	static void Colourise(unsigned int startPos, int lengthDoc, int initStyle, -                  int language, WordList *keywordlists[], Accessor &styler); +	LexerModule(int language_, LexerFunction fnLexer_,  +		const char *languageName_=0, LexerFunction fnFolder_=0); +	int GetLanguage() { return language; } +	void Lex(unsigned int startPos, int lengthDoc, int initStyle, +                  WordList *keywordlists[], Accessor &styler); +	void Fold(unsigned int startPos, int lengthDoc, int initStyle, +                  WordList *keywordlists[], Accessor &styler); +	static LexerModule *Find(int language); +	static LexerModule *Find(const char *languageName);  };  /** diff --git a/include/SciLexer.h b/include/SciLexer.h index 88e8b954b..9274b31de 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -35,6 +35,7 @@  #define SCLEX_PASCAL 18  #define SCLEX_AVE 19  #define SCLEX_ADA 20 +#define SCLEX_AUTOMATIC 1000  #define SCE_P_DEFAULT 0  #define SCE_P_COMMENTLINE 1  #define SCE_P_NUMBER 2 diff --git a/include/Scintilla.h b/include/Scintilla.h index fa1003ab4..54c02de47 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -411,6 +411,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,  #define SCI_COLOURISE 4003  #define SCI_SETPROPERTY 4004  #define SCI_SETKEYWORDS 4005 +#define SCI_SETLEXERLANGUAGE 4006  #define SC_MOD_INSERTTEXT 0x1  #define SC_MOD_DELETETEXT 0x2  #define SC_MOD_CHANGESTYLE 0x4 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 97f183ffc..be9468184 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -1102,6 +1102,9 @@ set void SetProperty=4004(string key, string value)  # Set up the key words used by the lexer.  set void SetKeyWords=4005(int keywordSet, string keyWords) +# Set the lexing language of the document based on string name. +set void SetLexerLanguage=4006(, string language) +  # Notifications  # Type of modification and the action which caused the modification  # These are defined as a bit mask to make it easy to specify which notifications are wanted. @@ -1174,6 +1177,9 @@ val SCLEX_CONF=17  val SCLEX_PASCAL=18  val SCLEX_AVE=19  val SCLEX_ADA=20 +# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a  +# value assigned in sequence from SCLEX_AUTOMATIC+1. +val SCLEX_AUTOMATIC=1000  # Lexical states for SCLEX_PYTHON  val SCE_P_DEFAULT=0  val SCE_P_COMMENTLINE=1 diff --git a/src/KeyWords.cxx b/src/KeyWords.cxx index a275c1963..f28fcecfb 100644 --- a/src/KeyWords.cxx +++ b/src/KeyWords.cxx @@ -20,32 +20,70 @@  #include "SciLexer.h"  LexerModule *LexerModule::base = 0; +int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1; -LexerModule::LexerModule(int language_, LexerFunction fn_) : -	language(language_), fn(fn_) { +LexerModule::LexerModule(int language_, LexerFunction fnLexer_, +	const char *languageName_, LexerFunction fnFolder_) : +	language(language_),  +	languageName(languageName_),  +	fnLexer(fnLexer_),  +	fnFolder(fnFolder_) {  	next = base;  	base = this; +	if (language == SCLEX_AUTOMATIC) { +		language = nextLanguage; +		nextLanguage++; +	}  } -void LexerModule::Colourise(unsigned int startPos, int lengthDoc, int initStyle, -		int language, WordList *keywordlists[], Accessor &styler) { +LexerModule *LexerModule::Find(int language) {  	LexerModule *lm = base;  	while (lm) {  		if (lm->language == language) { -			lm->fn(startPos, lengthDoc, initStyle, keywordlists, styler); -			return; +			return lm;  		}  		lm = lm->next;  	} -	// Unknown language +	return 0; +} + +LexerModule *LexerModule::Find(const char *languageName) { +	if (languageName) { +		LexerModule *lm = base; +		while (lm) { +			if (lm->languageName && 0 == strcmp(lm->languageName, languageName)) { +				return lm; +			} +			lm = lm->next; +		} +	} +	return 0; +} + +void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle, +	  WordList *keywordlists[], Accessor &styler) { +	if (fnLexer) +		fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler); +} + +void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle, +	  WordList *keywordlists[], Accessor &styler) { +	if (fnFolder) +		fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler); +} + +static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[], +                            Accessor &styler) {  	// Null language means all style bytes are 0 so just mark the end - no need to fill in. -	if (lengthDoc > 0) { -		styler.StartAt(startPos + lengthDoc - 1); -		styler.StartSegment(startPos + lengthDoc - 1); -		styler.ColourTo(startPos + lengthDoc - 1, 0); +	if (length > 0) { +		styler.StartAt(startPos + length - 1); +		styler.StartSegment(startPos + length - 1); +		styler.ColourTo(startPos + length - 1, 0);  	}  } +LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null"); +  #ifdef __vms  // The following code forces a reference to all of the Scintilla lexers. @@ -55,6 +93,7 @@ void LexerModule::Colourise(unsigned int startPos, int lengthDoc, int initStyle,  // Taken from wxWindow's stc.cpp. Walter.  int wxForceScintillaLexers(void) { +  extern LexerModule lmAda;    extern LexerModule lmCPP;    extern LexerModule lmHTML;    extern LexerModule lmXML; @@ -68,7 +107,8 @@ int wxForceScintillaLexers(void) {    extern LexerModule lmVB;    if ( -      &lmCPP +      &lmAda +      && &lmCPP        && &lmHTML        && &lmXML        && &lmProps diff --git a/src/LexCPP.cxx b/src/LexCPP.cxx index 966601ed3..826ac259f 100644 --- a/src/LexCPP.cxx +++ b/src/LexCPP.cxx @@ -328,7 +328,6 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo  	}  	styler.ColourTo(lengthDoc - 1, state);  	styler.Flush(); -	FoldCppDoc(startPos, length, initStyle, keywordlists, styler);  } -LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc); +LexerModule lmCPP(SCLEX_CPP, ColouriseCppDoc, "cpp", FoldCppDoc); diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx index fd2bef184..4eb0cf7a0 100644 --- a/src/ScintillaBase.cxx +++ b/src/ScintillaBase.cxx @@ -38,6 +38,7 @@ ScintillaBase::ScintillaBase() {  	listType = 0;  #ifdef SCI_LEXER  	lexLanguage = SCLEX_CONTAINER; +	lexCurrent = 0;  	for (int wl = 0;wl < numWordLists;wl++)  		keyWordLists[wl] = new WordList;  #endif @@ -338,6 +339,22 @@ void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool  }  #ifdef SCI_LEXER +void ScintillaBase::SetLexer(uptr_t wParam) { +	lexLanguage = wParam; +	lexCurrent = LexerModule::Find(lexLanguage); +	if (!lexCurrent) +		lexCurrent = LexerModule::Find(SCLEX_NULL); +} + +void ScintillaBase::SetLexerLanguage(const char *languageName) { +	lexLanguage = SCLEX_CONTAINER; +	lexCurrent = LexerModule::Find(languageName); +	if (!lexCurrent) +		lexCurrent = LexerModule::Find(SCLEX_NULL); +	if (lexCurrent) +		lexLanguage = lexCurrent->GetLanguage(); +} +  void ScintillaBase::Colourise(int start, int end) {  	int lengthDoc = pdoc->Length();  	if (end == -1) @@ -352,8 +369,12 @@ void ScintillaBase::Colourise(int start, int end) {  		styleStart = styler.StyleAt(start - 1);  	styler.SetCodePage(pdoc->dbcsCodePage); -	LexerModule::Colourise(start, len, styleStart, lexLanguage, keyWordLists, styler); -	styler.Flush(); +	if (lexCurrent) {	// Should always succeed as null lexer should always be available +		lexCurrent->Lex(start, len, styleStart, keyWordLists, styler); +		styler.Flush(); +		lexCurrent->Fold(start, len, styleStart, keyWordLists, styler); +		styler.Flush(); +	}  }  #endif @@ -482,6 +503,7 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara  #ifdef SCI_LEXER  	case SCI_SETLEXER: +		SetLexer(wParam);  		lexLanguage = wParam;  		break; @@ -504,6 +526,11 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara  			keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam));  		}  		break; + +	case SCI_SETLEXERLANGUAGE: +		SetLexerLanguage(reinterpret_cast<const char *>(lParam)); +		break; +  #endif  	default: diff --git a/src/ScintillaBase.h b/src/ScintillaBase.h index 758f75a4c..13172031a 100644 --- a/src/ScintillaBase.h +++ b/src/ScintillaBase.h @@ -40,9 +40,12 @@ protected:  #ifdef SCI_LEXER  	int lexLanguage; +	LexerModule *lexCurrent;  	PropSet props;  	enum {numWordLists=5};  	WordList *keyWordLists[numWordLists]; +	void SetLexer(uptr_t wParam); +	void SetLexerLanguage(const char *languageName);  	void Colourise(int start, int end);  #endif | 
