aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/AutoComplete.cxx3
-rw-r--r--src/CharClassify.cxx38
-rw-r--r--src/CharClassify.h15
-rw-r--r--src/Document.cxx97
-rw-r--r--src/Document.h61
-rw-r--r--src/Editor.cxx21
-rw-r--r--src/Editor.h2
-rw-r--r--src/ExternalLexer.cxx93
-rw-r--r--src/ExternalLexer.h19
-rw-r--r--src/PositionCache.cxx1
-rw-r--r--src/ScintillaBase.cxx283
-rw-r--r--src/ScintillaBase.h15
12 files changed, 388 insertions, 260 deletions
diff --git a/src/AutoComplete.cxx b/src/AutoComplete.cxx
index cd58f6172..32cf7b2ed 100644
--- a/src/AutoComplete.cxx
+++ b/src/AutoComplete.cxx
@@ -8,10 +8,11 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <assert.h>
#include "Platform.h"
-#include "CharClassify.h"
+#include "CharacterSet.h"
#include "AutoComplete.h"
#ifdef SCI_NAMESPACE
diff --git a/src/CharClassify.cxx b/src/CharClassify.cxx
index bbd25a0f8..c16af4547 100644
--- a/src/CharClassify.cxx
+++ b/src/CharClassify.cxx
@@ -10,6 +10,10 @@
#include "CharClassify.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// Shut up annoying Visual C++ warnings:
#ifdef _MSC_VER
#pragma warning(disable: 4514)
@@ -42,37 +46,3 @@ void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) {
}
}
}
-
-int CompareCaseInsensitive(const char *a, const char *b) {
- while (*a && *b) {
- if (*a != *b) {
- char upperA = MakeUpperCase(*a);
- char upperB = MakeUpperCase(*b);
- if (upperA != upperB)
- return upperA - upperB;
- }
- a++;
- b++;
- }
- // Either *a or *b is nul
- return *a - *b;
-}
-
-int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
- while (*a && *b && len) {
- if (*a != *b) {
- char upperA = MakeUpperCase(*a);
- char upperB = MakeUpperCase(*b);
- if (upperA != upperB)
- return upperA - upperB;
- }
- a++;
- b++;
- len--;
- }
- if (len == 0)
- return 0;
- else
- // Either *a or *b is nul
- return *a - *b;
-}
diff --git a/src/CharClassify.h b/src/CharClassify.h
index d746fe02d..e8b798ecb 100644
--- a/src/CharClassify.h
+++ b/src/CharClassify.h
@@ -8,6 +8,10 @@
#ifndef CHARCLASSIFY_H
#define CHARCLASSIFY_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
class CharClassify {
public:
CharClassify();
@@ -23,15 +27,8 @@ private:
unsigned char charClass[maxChar]; // not type cc to save space
};
-// These functions are implemented because each platform calls them something different.
-int CompareCaseInsensitive(const char *a, const char *b);
-int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
-
-inline char MakeUpperCase(char ch) {
- if (ch < 'a' || ch > 'z')
- return ch;
- else
- return static_cast<char>(ch - 'a' + 'A');
+#ifdef SCI_NAMESPACE
}
+#endif
#endif
diff --git a/src/Document.cxx b/src/Document.cxx
index 08d35a893..0d9b8baa3 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -9,6 +9,7 @@
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <assert.h>
#include <string>
#include <vector>
@@ -23,13 +24,16 @@
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
+
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
#include "CellBuffer.h"
#include "PerLine.h"
#include "CharClassify.h"
+#include "CharacterSet.h"
#include "Decoration.h"
#include "Document.h"
#include "RESearch.h"
@@ -60,6 +64,36 @@ static inline bool IsUpperCase(char ch) {
return isascii(ch) && isupper(ch);
}
+void LexInterface::Colourise(int start, int end) {
+ ElapsedTime et;
+ if (pdoc && instance && !performingStyle) {
+ // Protect against reentrance, which may occur, for example, when
+ // fold points are discovered while performing styling and the folding
+ // code looks for child lines which may trigger styling.
+ performingStyle = true;
+
+ int lengthDoc = pdoc->Length();
+ if (end == -1)
+ end = lengthDoc;
+ int len = end - start;
+
+ PLATFORM_ASSERT(len >= 0);
+ PLATFORM_ASSERT(start + len <= lengthDoc);
+
+ int styleStart = 0;
+ if (start > 0)
+ styleStart = pdoc->StyleAt(start - 1) & pdoc->stylingBitsMask;
+
+ if (len > 0) {
+ instance->Lex(start, len, styleStart, pdoc);
+ instance->Fold(start, len, styleStart, pdoc);
+ }
+
+ performingStyle = false;
+ }
+ Platform::DebugPrintf("Style:%d %9.6g \n", performingStyle, et.Duration());
+}
+
Document::Document() {
refCount = 0;
#ifdef unix
@@ -95,6 +129,8 @@ Document::Document() {
perLineData[ldAnnotation] = new LineAnnotation();
cb.SetPerLine(this);
+
+ pli = 0;
}
Document::~Document() {
@@ -110,6 +146,8 @@ Document::~Document() {
lenWatchers = 0;
delete regex;
regex = 0;
+ delete pli;
+ pli = 0;
}
void Document::Init() {
@@ -208,7 +246,7 @@ int Document::LineFromHandle(int markerHandle) {
return static_cast<LineMarkers *>(perLineData[ldMarkers])->LineFromHandle(markerHandle);
}
-int Document::LineStart(int line) const {
+int SCI_METHOD Document::LineStart(int line) const {
return cb.LineStart(line);
}
@@ -225,7 +263,14 @@ int Document::LineEnd(int line) const {
}
}
-int Document::LineFromPosition(int pos) const {
+void SCI_METHOD Document::SetErrorStatus(int status) {
+ // Tell the watchers the lexer has changed.
+ for (int i = 0; i < lenWatchers; i++) {
+ watchers[i].watcher->NotifyErrorOccurred(this, watchers[i].userData, status);
+ }
+}
+
+int SCI_METHOD Document::LineFromPosition(int pos) const {
return cb.LineFromPosition(pos);
}
@@ -250,7 +295,7 @@ int Document::VCHomePosition(int position) const {
return startText;
}
-int Document::SetLevel(int line, int level) {
+int SCI_METHOD Document::SetLevel(int line, int level) {
int prev = static_cast<LineLevels *>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal());
if (prev != level) {
DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER,
@@ -262,7 +307,7 @@ int Document::SetLevel(int line, int level) {
return prev;
}
-int Document::GetLevel(int line) const {
+int SCI_METHOD Document::GetLevel(int line) const {
return static_cast<LineLevels *>(perLineData[ldLevels])->GetLevel(line);
}
@@ -476,6 +521,14 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
return pos;
}
+int SCI_METHOD Document::CodePage() const {
+ return dbcsCodePage;
+}
+
+bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
+ return Platform::IsDBCSLeadByte(dbcsCodePage, ch);
+}
+
void Document::ModifiedAt(int pos) {
if (endStyled > pos)
endStyled = pos;
@@ -1303,12 +1356,12 @@ void Document::SetStylingBits(int bits) {
stylingBitsMask = (1 << stylingBits) - 1;
}
-void Document::StartStyling(int position, char mask) {
+void SCI_METHOD Document::StartStyling(int position, char mask) {
stylingMask = mask;
endStyled = position;
}
-bool Document::SetStyleFor(int length, char style) {
+bool SCI_METHOD Document::SetStyleFor(int length, char style) {
if (enteredStyling != 0) {
return false;
} else {
@@ -1326,7 +1379,7 @@ bool Document::SetStyleFor(int length, char style) {
}
}
-bool Document::SetStyles(int length, const char *styles) {
+bool SCI_METHOD Document::SetStyles(int length, const char *styles) {
if (enteredStyling != 0) {
return false;
} else {
@@ -1357,14 +1410,27 @@ bool Document::SetStyles(int length, const char *styles) {
void Document::EnsureStyledTo(int pos) {
if ((enteredStyling == 0) && (pos > GetEndStyled())) {
IncrementStyleClock();
- // Ask the watchers to style, and stop as soon as one responds.
- for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
- watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos);
+ if (pli) {
+ int lineEndStyled = LineFromPosition(GetEndStyled());
+ int endStyled = LineStart(lineEndStyled);
+ pli->Colourise(endStyled, pos);
+ } else {
+ // Ask the watchers to style, and stop as soon as one responds.
+ for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
+ watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos);
+ }
}
}
}
-int Document::SetLineState(int line, int state) {
+void Document::LexerChanged() {
+ // Tell the watchers the lexer has changed.
+ for (int i = 0; i < lenWatchers; i++) {
+ watchers[i].watcher->NotifyLexerChanged(this, watchers[i].userData);
+ }
+}
+
+int SCI_METHOD Document::SetLineState(int line, int state) {
int statePrevious = static_cast<LineState *>(perLineData[ldState])->SetLineState(line, state);
if (state != statePrevious) {
DocModification mh(SC_MOD_CHANGELINESTATE, 0, 0, 0, 0, line);
@@ -1373,7 +1439,7 @@ int Document::SetLineState(int line, int state) {
return statePrevious;
}
-int Document::GetLineState(int line) const {
+int SCI_METHOD Document::GetLineState(int line) const {
return static_cast<LineState *>(perLineData[ldState])->GetLineState(line);
}
@@ -1381,6 +1447,11 @@ int Document::GetMaxLineState() {
return static_cast<LineState *>(perLineData[ldState])->GetMaxLineState();
}
+void SCI_METHOD Document::ChangeLexerState(int start, int end) {
+ DocModification mh(SC_MOD_LEXERSTATE, start, end-start, 0, 0, 0);
+ NotifyModified(mh);
+}
+
StyledText Document::MarginStyledText(int line) {
LineAnnotation *pla = static_cast<LineAnnotation *>(perLineData[ldMargin]);
return StyledText(pla->Length(line), pla->Text(line),
@@ -1462,7 +1533,7 @@ void Document::IncrementStyleClock() {
styleClock = (styleClock + 1) % 0x100000;
}
-void Document::DecorationFillRange(int position, int value, int fillLength) {
+void SCI_METHOD Document::DecorationFillRange(int position, int value, int fillLength) {
if (decorations.FillRange(position, value, fillLength)) {
DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER,
position, fillLength);
diff --git a/src/Document.h b/src/Document.h
index 1c270a556..a765c6299 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -133,9 +133,24 @@ public:
void StandardASCII();
};
+class Document;
+
+class LexInterface {
+protected:
+ Document *pdoc;
+ ILexer *instance;
+ bool performingStyle; ///< Prevent reentrance
+public:
+ LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(0), performingStyle(false) {
+ }
+ virtual ~LexInterface() {
+ }
+ void Colourise(int start, int end);
+};
+
/**
*/
-class Document : PerLine {
+class Document : PerLine, public IDocument {
public:
/** Used to pair watcher pointer with user data. */
@@ -172,6 +187,9 @@ private:
RegexSearchBase *regex;
public:
+
+ LexInterface *pli;
+
int stylingBits;
int stylingBitsMask;
@@ -197,12 +215,20 @@ public:
virtual void InsertLine(int line);
virtual void RemoveLine(int line);
- int LineFromPosition(int pos) const;
+ int SCI_METHOD Version() const {
+ return dvOriginal;
+ }
+
+ void SCI_METHOD SetErrorStatus(int status);
+
+ int SCI_METHOD LineFromPosition(int pos) const;
int ClampPositionIntoDocument(int pos);
bool IsCrLf(int pos);
int LenChar(int pos);
bool InGoodUTF8(int pos, int &start, int &end);
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
+ int SCI_METHOD CodePage() const;
+ bool SCI_METHOD IsDBCSLeadByte(char ch) const;
// Gateways to modifying document
void ModifiedAt(int pos);
@@ -243,10 +269,10 @@ public:
void DelCharBack(int pos);
char CharAt(int position) { return cb.CharAt(position); }
- void GetCharRange(char *buffer, int position, int lengthRetrieve) const {
+ void SCI_METHOD GetCharRange(char *buffer, int position, int lengthRetrieve) const {
cb.GetCharRange(buffer, position, lengthRetrieve);
}
- char StyleAt(int position) const { return cb.StyleAt(position); }
+ char SCI_METHOD StyleAt(int position) const { return cb.StyleAt(position); }
int GetMark(int line);
int AddMark(int line, int markerNum);
void AddMarkSet(int line, int valueSet);
@@ -254,14 +280,14 @@ public:
void DeleteMarkFromHandle(int markerHandle);
void DeleteAllMarks(int markerNum);
int LineFromHandle(int markerHandle);
- int LineStart(int line) const;
+ int SCI_METHOD LineStart(int line) const;
int LineEnd(int line) const;
int LineEndPosition(int position) const;
bool IsLineEndPosition(int position) const;
int VCHomePosition(int position) const;
- int SetLevel(int line, int level);
- int GetLevel(int line) const;
+ int SCI_METHOD SetLevel(int line, int level);
+ int SCI_METHOD GetLevel(int line) const;
void ClearLevels();
int GetLastChild(int lineParent, int level=-1);
int GetFoldParent(int line);
@@ -270,7 +296,7 @@ public:
int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);
int NextWordStart(int pos, int delta);
int NextWordEnd(int pos, int delta);
- int Length() const { return cb.Length(); }
+ int SCI_METHOD Length() const { return cb.Length(); }
void Allocate(int newSize) { cb.Allocate(newSize); }
size_t ExtractChar(int pos, char *bytes);
bool MatchesWordOptions(bool word, bool wordStart, int pos, int length);
@@ -284,18 +310,23 @@ public:
void SetDefaultCharClasses(bool includeWordClass);
void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass);
void SetStylingBits(int bits);
- void StartStyling(int position, char mask);
- bool SetStyleFor(int length, char style);
- bool SetStyles(int length, const char *styles);
+ void SCI_METHOD StartStyling(int position, char mask);
+ bool SCI_METHOD SetStyleFor(int length, char style);
+ bool SCI_METHOD SetStyles(int length, const char *styles);
int GetEndStyled() { return endStyled; }
void EnsureStyledTo(int pos);
+ void LexerChanged();
int GetStyleClock() { return styleClock; }
void IncrementStyleClock();
- void DecorationFillRange(int position, int value, int fillLength);
+ void SCI_METHOD DecorationSetCurrentIndicator(int indicator) {
+ decorations.SetCurrentIndicator(indicator);
+ }
+ void SCI_METHOD DecorationFillRange(int position, int value, int fillLength);
- int SetLineState(int line, int state);
- int GetLineState(int line) const;
+ int SCI_METHOD SetLineState(int line, int state);
+ int SCI_METHOD GetLineState(int line) const;
int GetMaxLineState();
+ void SCI_METHOD ChangeLexerState(int start, int end);
StyledText MarginStyledText(int line);
void MarginSetStyle(int line, int style);
@@ -417,6 +448,8 @@ public:
virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0;
virtual void NotifyDeleted(Document *doc, void *userData) = 0;
virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0;
+ virtual void NotifyLexerChanged(Document *doc, void *userData) = 0;
+ virtual void NotifyErrorOccurred(Document *doc, void *userData, int status) = 0;
};
#ifdef SCI_NAMESPACE
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 6119944c3..be63ea839 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -9,6 +9,7 @@
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <assert.h>
#include <string>
#include <vector>
@@ -25,6 +26,7 @@
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
#include "SplitVector.h"
@@ -4132,6 +4134,13 @@ void Editor::NotifyStyleNeeded(Document *, void *, int endStyleNeeded) {
NotifyStyleToNeeded(endStyleNeeded);
}
+void Editor::NotifyLexerChanged(Document *, void *) {
+}
+
+void Editor::NotifyErrorOccurred(Document *, void *, int status) {
+ errorStatus = status;
+}
+
void Editor::NotifyChar(int ch) {
SCNotification scn = {0};
scn.nmhdr.code = SCN_CHARADDED;
@@ -4315,6 +4324,14 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) {
Redraw();
}
}
+ if (mh.modificationType & SC_MOD_LEXERSTATE) {
+ if (paintState == painting) {
+ CheckForChangeOutsidePaint(
+ Range(mh.position, mh.position + mh.length));
+ } else {
+ Redraw();
+ }
+ }
if (mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) {
if (mh.modificationType & SC_MOD_CHANGESTYLE) {
pdoc->IncrementStyleClock();
@@ -8711,6 +8728,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
sel.RangeMain() = SelectionRange(sel.RangeMain().anchor, sel.RangeMain().caret);
break;
+ case SCI_CHANGELEXERSTATE:
+ pdoc->ChangeLexerState(wParam, lParam);
+ break;
+
default:
return DefWndProc(iMessage, wParam, lParam);
}
diff --git a/src/Editor.h b/src/Editor.h
index e7aa2e6ce..aa4fc9236 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -431,6 +431,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
void NotifyModified(Document *document, DocModification mh, void *userData);
void NotifyDeleted(Document *document, void *userData);
void NotifyStyleNeeded(Document *doc, void *userData, int endPos);
+ void NotifyLexerChanged(Document *doc, void *userData);
+ void NotifyErrorOccurred(Document *doc, void *userData, int status);
void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false);
diff --git a/src/ExternalLexer.cxx b/src/ExternalLexer.cxx
index 1c00ec02e..ba0f52ab3 100644
--- a/src/ExternalLexer.cxx
+++ b/src/ExternalLexer.cxx
@@ -9,18 +9,18 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#include <assert.h>
#include <string>
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
-
#include "SciLexer.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "DocumentAccessor.h"
-#include "KeyWords.h"
+
+#include "LexerModule.h"
+#include "Catalogue.h"
#include "ExternalLexer.h"
#ifdef SCI_NAMESPACE
@@ -35,76 +35,9 @@ LexerManager *LexerManager::theInstance = NULL;
//
//------------------------------------------
-char **WordListsToStrings(WordList *val[]) {
- int dim = 0;
- while (val[dim])
- dim++;
- char **wls = new char * [dim + 1];
- for (int i = 0; i < dim; i++) {
- std::string words;
- words = "";
- for (int n = 0; n < val[i]->len; n++) {
- words += val[i]->words[n];
- if (n != val[i]->len - 1)
- words += " ";
- }
- wls[i] = new char[words.length() + 1];
- strcpy(wls[i], words.c_str());
- }
- wls[dim] = 0;
- return wls;
-}
-
-void DeleteWLStrings(char *strs[]) {
- int dim = 0;
- while (strs[dim]) {
- delete strs[dim];
- dim++;
- }
- delete [] strs;
-}
-
-void ExternalLexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const {
- if (!fneLexer)
- return ;
-
- char **kwds = WordListsToStrings(keywordlists);
- char *ps = styler.GetProperties();
-
- // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
- // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
- DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
- WindowID wID = da.GetWindow();
-
- fneLexer(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
-
- delete ps;
- DeleteWLStrings(kwds);
-}
-
-void ExternalLexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const {
- if (!fneFolder)
- return ;
-
- char **kwds = WordListsToStrings(keywordlists);
- char *ps = styler.GetProperties();
-
- // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
- // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
- DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
- WindowID wID = da.GetWindow();
-
- fneFolder(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
-
- delete ps;
- DeleteWLStrings(kwds);
-}
-
-void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index) {
- fneLexer = fLexer;
- fneFolder = fFolder;
+void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
+ fneFactory = fFactory;
+ fnFactory = fFactory(index);
externalLanguage = index;
}
@@ -132,8 +65,9 @@ LexerLibrary::LexerLibrary(const char *ModuleName) {
// Find functions in the DLL
GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
- ExtLexerFunction Lexer = (ExtLexerFunction)(sptr_t)lib->FindFunction("Lex");
- ExtFoldFunction Folder = (ExtFoldFunction)(sptr_t)lib->FindFunction("Fold");
+ //ExtLexerFunction fnLexer = (ExtLexerFunction)(sptr_t)lib->FindFunction("Lex");
+ //ExtFoldFunction fnFolder = (ExtFoldFunction)(sptr_t)lib->FindFunction("Fold");
+ GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory");
// Assign a buffer for the lexer name.
char lexname[100];
@@ -144,6 +78,7 @@ LexerLibrary::LexerLibrary(const char *ModuleName) {
for (int i = 0; i < nl; i++) {
GetLexerName(i, lexname, 100);
lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
+ Catalogue::AddLexerModule(lex);
// Create a LexerMinder so we don't leak the ExternalLexerModule...
lm = new LexerMinder;
@@ -158,8 +93,8 @@ LexerLibrary::LexerLibrary(const char *ModuleName) {
}
// The external lexer needs to know how to call into its DLL to
- // do its lexing and folding, we tell it here. Folder may be null.
- lex->SetExternal(Lexer, Folder, i);
+ // do its lexing and folding, we tell it here.
+ lex->SetExternal(fnFactory, i);
}
}
}
diff --git a/src/ExternalLexer.h b/src/ExternalLexer.h
index eb2bad5d1..98d543ef1 100644
--- a/src/ExternalLexer.h
+++ b/src/ExternalLexer.h
@@ -18,22 +18,15 @@
namespace Scintilla {
#endif
-// External Lexer function definitions...
-typedef void (EXT_LEXER_DECL *ExtLexerFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
- char *words[], WindowID window, char *props);
-typedef void (EXT_LEXER_DECL *ExtFoldFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
- char *words[], WindowID window, char *props);
typedef void*(EXT_LEXER_DECL *GetLexerFunction)(unsigned int Index);
typedef int (EXT_LEXER_DECL *GetLexerCountFn)();
typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength);
-
-//class DynamicLibrary;
+typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index);
/// Sub-class of LexerModule to use an external lexer.
-class ExternalLexerModule : protected LexerModule {
+class ExternalLexerModule : public LexerModule {
protected:
- ExtLexerFunction fneLexer;
- ExtFoldFunction fneFolder;
+ GetLexerFactoryFunction fneFactory;
int externalLanguage;
char name[100];
public:
@@ -43,11 +36,7 @@ public:
name[sizeof(name)-1] = '\0';
languageName = name;
}
- virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const;
- virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const;
- virtual void SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index);
+ virtual void SetExternal(GetLexerFactoryFunction fFactory, int index);
};
/// LexerMinder points to an ExternalLexerModule - so we don't leak them.
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx
index d27205b5f..548b4d940 100644
--- a/src/PositionCache.cxx
+++ b/src/PositionCache.cxx
@@ -30,6 +30,7 @@
#include "ViewStyle.h"
#include "CharClassify.h"
#include "Decoration.h"
+#include "ILexer.h"
#include "Document.h"
#include "Selection.h"
#include "PositionCache.h"
diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx
index cecfc0952..2f84db7cd 100644
--- a/src/ScintillaBase.cxx
+++ b/src/ScintillaBase.cxx
@@ -9,20 +9,21 @@
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <assert.h>
#include <string>
#include <vector>
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
-#include "PropSet.h"
+
#include "PropSetSimple.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
-#include "Accessor.h"
-#include "DocumentAccessor.h"
-#include "KeyWords.h"
+#include "LexerModule.h"
+#include "Catalogue.h"
#endif
#include "SplitVector.h"
#include "Partitioning.h"
@@ -53,21 +54,9 @@ ScintillaBase::ScintillaBase() {
displayPopupMenu = true;
listType = 0;
maxListWidth = 0;
-#ifdef SCI_LEXER
- lexLanguage = SCLEX_CONTAINER;
- performingStyle = false;
- lexCurrent = 0;
- for (int wl = 0; wl < numWordLists; wl++)
- keyWordLists[wl] = new WordList;
- keyWordLists[numWordLists] = 0;
-#endif
}
ScintillaBase::~ScintillaBase() {
-#ifdef SCI_LEXER
- for (int wl = 0; wl < numWordLists; wl++)
- delete keyWordLists[wl];
-#endif
}
void ScintillaBase::Finalise() {
@@ -477,76 +466,189 @@ 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);
- int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
- vs.EnsureStyle((1 << bits) - 1);
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class LexState : public LexInterface {
+ const LexerModule *lexCurrent;
+ void SetLexerModule(const LexerModule *lex);
+ PropSetSimple props;
+public:
+ int lexLanguage;
+
+ LexState(Document *pdoc_);
+ virtual ~LexState();
+ void SetLexer(uptr_t wParam);
+ void SetLexerLanguage(const char *languageName);
+ const char *DescribeWordListSets();
+ void SetWordList(int n, const char *wl);
+ int GetStyleBitsNeeded() const;
+ const char *GetName() const;
+ void *PrivateCall(int operation, void *pointer);
+ const char *PropertyNames();
+ int PropertyType(const char *name);
+ const char *DescribeProperty(const char *name);
+ void PropSet(const char *key, const char *val);
+ const char *PropGet(const char *key) const;
+ int PropGetInt(const char *key, int defaultValue=0) const;
+ int PropGetExpanded(const char *key, char *result) const;
+};
+
+#ifdef SCI_NAMESPACE
}
+#endif
-void ScintillaBase::SetLexerLanguage(const char *languageName) {
+LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) {
+ lexCurrent = 0;
+ performingStyle = false;
lexLanguage = SCLEX_CONTAINER;
- lexCurrent = LexerModule::Find(languageName);
- if (!lexCurrent)
- lexCurrent = LexerModule::Find(SCLEX_NULL);
- if (lexCurrent)
- lexLanguage = lexCurrent->GetLanguage();
- int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
- vs.EnsureStyle((1 << bits) - 1);
}
-void ScintillaBase::Colourise(int start, int end) {
- if (!performingStyle) {
- // Protect against reentrance, which may occur, for example, when
- // fold points are discovered while performing styling and the folding
- // code looks for child lines which may trigger styling.
- performingStyle = true;
+LexState::~LexState() {
+ if (instance) {
+ instance->Release();
+ instance = 0;
+ }
+}
+
+LexState *ScintillaBase::DocumentLexState() {
+ if (!pdoc->pli) {
+ pdoc->pli = new LexState(pdoc);
+ }
+ return static_cast<LexState *>(pdoc->pli);
+}
- int lengthDoc = pdoc->Length();
- if (end == -1)
- end = lengthDoc;
- int len = end - start;
+void LexState::SetLexerModule(const LexerModule *lex) {
+ if (lex != lexCurrent) {
+ if (instance) {
+ instance->Release();
+ instance = 0;
+ }
+ lexCurrent = lex;
+ instance = lexCurrent->Create();
+ pdoc->LexerChanged();
+ }
+}
- PLATFORM_ASSERT(len >= 0);
- PLATFORM_ASSERT(start + len <= lengthDoc);
+void LexState::SetLexer(uptr_t wParam) {
+ lexLanguage = wParam;
+ const LexerModule *lex = Catalogue::Find(lexLanguage);
+ if (!lex)
+ lex = Catalogue::Find(SCLEX_NULL);
+ SetLexerModule(lex);
+}
- //WindowAccessor styler(wMain.GetID(), props);
- DocumentAccessor styler(pdoc, props, wMain.GetID());
+void LexState::SetLexerLanguage(const char *languageName) {
+ const LexerModule *lex = Catalogue::Find(languageName);
+ if (!lex)
+ lex = Catalogue::Find(SCLEX_NULL);
+ if (lex)
+ lexLanguage = lex->GetLanguage();
+ SetLexerModule(lex);
+}
- int styleStart = 0;
- if (start > 0)
- styleStart = styler.StyleAt(start - 1) & pdoc->stylingBitsMask;
- styler.SetCodePage(pdoc->dbcsCodePage);
+const char *LexState::DescribeWordListSets() {
+ if (instance) {
+ return instance->DescribeWordListSets();
+ } else {
+ return 0;
+ }
+}
- if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available
- lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
- styler.Flush();
- if (styler.GetPropertyInt("fold")) {
- lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
- styler.Flush();
- }
+void LexState::SetWordList(int n, const char *wl) {
+ if (instance) {
+ int firstModification = instance->WordListSet(n, wl);
+ if (firstModification >= 0) {
+ pdoc->ModifiedAt(firstModification);
}
+ }
+}
- performingStyle = false;
+int LexState::GetStyleBitsNeeded() const {
+ return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+}
+
+const char *LexState::GetName() const {
+ return lexCurrent ? lexCurrent->languageName : "";
+}
+
+void *LexState::PrivateCall(int operation, void *pointer) {
+ if (pdoc && instance) {
+ return instance->PrivateCall(operation, pointer);
+ } else {
+ return 0;
+ }
+}
+
+const char *LexState::PropertyNames() {
+ if (instance) {
+ return instance->PropertyNames();
+ } else {
+ return 0;
+ }
+}
+
+int LexState::PropertyType(const char *name) {
+ if (instance) {
+ return instance->PropertyType(name);
+ } else {
+ return SC_TYPE_BOOLEAN;
}
}
+
+const char *LexState::DescribeProperty(const char *name) {
+ if (instance) {
+ return instance->DescribeProperty(name);
+ } else {
+ return 0;
+ }
+}
+
+void LexState::PropSet(const char *key, const char *val) {
+ props.Set(key, val);
+ if (instance) {
+ int firstModification = instance->PropertySet(key, val);
+ if (firstModification >= 0) {
+ pdoc->ModifiedAt(firstModification);
+ }
+ }
+}
+
+const char *LexState::PropGet(const char *key) const {
+ return props.Get(key);
+}
+
+int LexState::PropGetInt(const char *key, int defaultValue) const {
+ return props.GetInt(key, defaultValue);
+}
+
+int LexState::PropGetExpanded(const char *key, char *result) const {
+ return props.GetExpanded(key, result);
+}
+
#endif
void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
#ifdef SCI_LEXER
- if (lexLanguage != SCLEX_CONTAINER) {
- int endStyled = WndProc(SCI_GETENDSTYLED, 0, 0);
- int lineEndStyled = WndProc(SCI_LINEFROMPOSITION, endStyled, 0);
- endStyled = WndProc(SCI_POSITIONFROMLINE, lineEndStyled, 0);
- Colourise(endStyled, endStyleNeeded);
+ if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) {
+ int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled());
+ int endStyled = pdoc->LineStart(lineEndStyled);
+ DocumentLexState()->Colourise(endStyled, endStyleNeeded);
return;
}
#endif
Editor::NotifyStyleToNeeded(endStyleNeeded);
}
+void ScintillaBase::NotifyLexerChanged(Document *, void *) {
+#ifdef SCI_LEXER
+ int bits = DocumentLexState()->GetStyleBitsNeeded();
+ vs.EnsureStyle((1 << bits) - 1);
+#endif
+}
+
sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
switch (iMessage) {
case SCI_AUTOCSHOW:
@@ -709,61 +811,66 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
#ifdef SCI_LEXER
case SCI_SETLEXER:
- SetLexer(wParam);
- lexLanguage = wParam;
+ DocumentLexState()->SetLexer(wParam);
break;
case SCI_GETLEXER:
- return lexLanguage;
+ return DocumentLexState()->lexLanguage;
case SCI_COLOURISE:
- if (lexLanguage == SCLEX_CONTAINER) {
+ if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) {
pdoc->ModifiedAt(wParam);
NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam);
} else {
- Colourise(wParam, lParam);
+ DocumentLexState()->Colourise(wParam, lParam);
}
Redraw();
break;
case SCI_SETPROPERTY:
- props.Set(reinterpret_cast<const char *>(wParam),
+ DocumentLexState()->PropSet(reinterpret_cast<const char *>(wParam),
reinterpret_cast<const char *>(lParam));
break;
case SCI_GETPROPERTY:
- return StringResult(lParam, props.Get(reinterpret_cast<const char *>(wParam)));
-
- case SCI_GETPROPERTYEXPANDED: {
- char *val = props.Expanded(reinterpret_cast<const char *>(wParam));
- const int n = strlen(val);
- if (lParam != 0) {
- char *ptr = reinterpret_cast<char *>(lParam);
- strcpy(ptr, val);
- }
- delete []val;
- return n; // Not including NUL
- }
+ return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast<const char *>(wParam)));
+
+ case SCI_GETPROPERTYEXPANDED:
+ return DocumentLexState()->PropGetExpanded(reinterpret_cast<const char *>(wParam),
+ reinterpret_cast<char *>(lParam));
case SCI_GETPROPERTYINT:
- return props.GetInt(reinterpret_cast<const char *>(wParam), lParam);
+ return DocumentLexState()->PropGetInt(reinterpret_cast<const char *>(wParam), lParam);
case SCI_SETKEYWORDS:
- if (wParam < numWordLists) {
- keyWordLists[wParam]->Clear();
- keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam));
- }
+ DocumentLexState()->SetWordList(wParam, reinterpret_cast<const char *>(lParam));
break;
case SCI_SETLEXERLANGUAGE:
- SetLexerLanguage(reinterpret_cast<const char *>(lParam));
+ DocumentLexState()->SetLexerLanguage(reinterpret_cast<const char *>(lParam));
break;
case SCI_GETLEXERLANGUAGE:
- return StringResult(lParam, lexCurrent ? lexCurrent->languageName : "");
+ return StringResult(lParam, DocumentLexState()->GetName());
+
+ case SCI_PRIVATELEXERCALL:
+ return reinterpret_cast<sptr_t>(
+ DocumentLexState()->PrivateCall(wParam, reinterpret_cast<void *>(lParam)));
case SCI_GETSTYLEBITSNEEDED:
- return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+ return DocumentLexState()->GetStyleBitsNeeded();
+
+ case SCI_PROPERTYNAMES:
+ return StringResult(lParam, DocumentLexState()->PropertyNames());
+
+ case SCI_PROPERTYTYPE:
+ return DocumentLexState()->PropertyType(reinterpret_cast<const char *>(wParam));
+
+ case SCI_DESCRIBEPROPERTY:
+ return StringResult(lParam, DocumentLexState()->DescribeProperty(reinterpret_cast<const char *>(wParam)));
+
+ case SCI_DESCRIBEKEYWORDSETS:
+ return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
#endif
diff --git a/src/ScintillaBase.h b/src/ScintillaBase.h
index 704ca88f8..203510844 100644
--- a/src/ScintillaBase.h
+++ b/src/ScintillaBase.h
@@ -12,6 +12,10 @@
namespace Scintilla {
#endif
+#ifdef SCI_LEXER
+class LexState;
+#endif
+
/**
*/
class ScintillaBase : public Editor {
@@ -44,12 +48,7 @@ protected:
int maxListWidth; /// Maximum width of list, in average character widths
#ifdef SCI_LEXER
- bool performingStyle; ///< Prevent reentrance
- int lexLanguage;
- const LexerModule *lexCurrent;
- PropSetSimple props;
- enum {numWordLists=KEYWORDSET_MAX+1};
- WordList *keyWordLists[numWordLists+1];
+ LexState *DocumentLexState();
void SetLexer(uptr_t wParam);
void SetLexerLanguage(const char *languageName);
void Colourise(int start, int end);
@@ -87,7 +86,9 @@ protected:
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
- virtual void NotifyStyleToNeeded(int endStyleNeeded);
+ void NotifyStyleToNeeded(int endStyleNeeded);
+ void NotifyLexerChanged(Document *doc, void *userData);
+
public:
// Public so scintilla_send_message can use it
virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);