aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornyamatongwe <unknown>2001-04-13 04:55:04 +0000
committernyamatongwe <unknown>2001-04-13 04:55:04 +0000
commit3e36fa6f3ea27bb64ce42bdd1a5b50b52dc6bb04 (patch)
tree72f9058f86ae76bf8d6131a4e80d87549b4770ad
parentc9925ce492d3ea61e692769c2733d69eed133993 (diff)
downloadscintilla-mirror-3e36fa6f3ea27bb64ce42bdd1a5b50b52dc6bb04.tar.gz
Start of new lexer infrastructure.
Lexers can have a fold function as well as a lexer function. They can be identified by string name as well as an integer ID and may ask to be automatically assigned that ID.
-rw-r--r--include/KeyWords.h23
-rw-r--r--include/SciLexer.h1
-rw-r--r--include/Scintilla.h1
-rw-r--r--include/Scintilla.iface6
-rw-r--r--src/KeyWords.cxx64
-rw-r--r--src/LexCPP.cxx3
-rw-r--r--src/ScintillaBase.cxx31
-rw-r--r--src/ScintillaBase.h3
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