SF.net SVN: geany:[3769] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Sun May 3 17:49:34 UTC 2009


Revision: 3769
          http://geany.svn.sourceforge.net/geany/?rev=3769&view=rev
Author:   eht16
Date:     2009-05-03 17:49:33 +0000 (Sun, 03 May 2009)

Log Message:
-----------
Update Scintilla to version 1.78.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/scintilla/CellBuffer.cxx
    trunk/scintilla/CellBuffer.h
    trunk/scintilla/Document.cxx
    trunk/scintilla/Document.h
    trunk/scintilla/Editor.cxx
    trunk/scintilla/Editor.h
    trunk/scintilla/Indicator.cxx
    trunk/scintilla/Indicator.h
    trunk/scintilla/KeyWords.cxx
    trunk/scintilla/LexBash.cxx
    trunk/scintilla/LexCPP.cxx
    trunk/scintilla/LexD.cxx
    trunk/scintilla/LexFortran.cxx
    trunk/scintilla/LexHTML.cxx
    trunk/scintilla/LexOthers.cxx
    trunk/scintilla/LexPascal.cxx
    trunk/scintilla/LexPerl.cxx
    trunk/scintilla/LexPython.cxx
    trunk/scintilla/LexRuby.cxx
    trunk/scintilla/LexSQL.cxx
    trunk/scintilla/LexYAML.cxx
    trunk/scintilla/Makefile.am
    trunk/scintilla/PlatGTK.cxx
    trunk/scintilla/PositionCache.cxx
    trunk/scintilla/RESearch.cxx
    trunk/scintilla/ScintillaBase.cxx
    trunk/scintilla/ScintillaGTK.cxx
    trunk/scintilla/SplitVector.h
    trunk/scintilla/UniConversion.cxx
    trunk/scintilla/ViewStyle.cxx
    trunk/scintilla/ViewStyle.h
    trunk/scintilla/include/Accessor.h
    trunk/scintilla/include/KeyWords.h
    trunk/scintilla/include/Platform.h
    trunk/scintilla/include/PropSet.h
    trunk/scintilla/include/SString.h
    trunk/scintilla/include/SciLexer.h
    trunk/scintilla/include/Scintilla.h
    trunk/scintilla/include/Scintilla.iface
    trunk/scintilla/include/WindowAccessor.h
    trunk/scintilla/makefile.win32
    trunk/scintilla/scintilla_changes.patch
    trunk/src/plugindata.h
    trunk/wscript

Added Paths:
-----------
    trunk/scintilla/PerLine.cxx
    trunk/scintilla/PerLine.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/ChangeLog	2009-05-03 17:49:33 UTC (rev 3769)
@@ -1,3 +1,9 @@
+2009-05-03  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
+
+ * wscript, scintilla/*, scintilla/include/*, src/plugindata.h:
+   Update Scintilla to version 1.78.
+
+
 2009-05-02  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
 
  * src/printing.c:

Modified: trunk/scintilla/CellBuffer.cxx
===================================================================
--- trunk/scintilla/CellBuffer.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/CellBuffer.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -21,183 +21,31 @@
 using namespace Scintilla;
 #endif
 
-MarkerHandleSet::MarkerHandleSet() {
-	root = 0;
-}
-
-MarkerHandleSet::~MarkerHandleSet() {
-	MarkerHandleNumber *mhn = root;
-	while (mhn) {
-		MarkerHandleNumber *mhnToFree = mhn;
-		mhn = mhn->next;
-		delete mhnToFree;
-	}
-	root = 0;
-}
-
-int MarkerHandleSet::Length() const {
-	int c = 0;
-	MarkerHandleNumber *mhn = root;
-	while (mhn) {
-		c++;
-		mhn = mhn->next;
-	}
-	return c;
-}
-
-int MarkerHandleSet::NumberFromHandle(int handle) const {
-	MarkerHandleNumber *mhn = root;
-	while (mhn) {
-		if (mhn->handle == handle) {
-			return mhn->number;
-		}
-		mhn = mhn->next;
-	}
-	return - 1;
-}
-
-int MarkerHandleSet::MarkValue() const {
-	unsigned int m = 0;
-	MarkerHandleNumber *mhn = root;
-	while (mhn) {
-		m |= (1 << mhn->number);
-		mhn = mhn->next;
-	}
-	return m;
-}
-
-bool MarkerHandleSet::Contains(int handle) const {
-	MarkerHandleNumber *mhn = root;
-	while (mhn) {
-		if (mhn->handle == handle) {
-			return true;
-		}
-		mhn = mhn->next;
-	}
-	return false;
-}
-
-bool MarkerHandleSet::InsertHandle(int handle, int markerNum) {
-	MarkerHandleNumber *mhn = new MarkerHandleNumber;
-	if (!mhn)
-		return false;
-	mhn->handle = handle;
-	mhn->number = markerNum;
-	mhn->next = root;
-	root = mhn;
-	return true;
-}
-
-void MarkerHandleSet::RemoveHandle(int handle) {
-	MarkerHandleNumber **pmhn = &root;
-	while (*pmhn) {
-		MarkerHandleNumber *mhn = *pmhn;
-		if (mhn->handle == handle) {
-			*pmhn = mhn->next;
-			delete mhn;
-			return;
-		}
-		pmhn = &((*pmhn)->next);
-	}
-}
-
-bool MarkerHandleSet::RemoveNumber(int markerNum) {
-	bool performedDeletion = false;
-	MarkerHandleNumber **pmhn = &root;
-	while (*pmhn) {
-		MarkerHandleNumber *mhn = *pmhn;
-		if (mhn->number == markerNum) {
-			*pmhn = mhn->next;
-			delete mhn;
-			performedDeletion = true;
-		} else {
-			pmhn = &((*pmhn)->next);
-		}
-	}
-	return performedDeletion;
-}
-
-void MarkerHandleSet::CombineWith(MarkerHandleSet *other) {
-	MarkerHandleNumber **pmhn = &root;
-	while (*pmhn) {
-		pmhn = &((*pmhn)->next);
-	}
-	*pmhn = other->root;
-	other->root = 0;
-}
-
 LineVector::LineVector() : starts(256) {
-	handleCurrent = 1;
-
 	Init();
 }
 
 LineVector::~LineVector() {
 	starts.DeleteAll();
-	for (int line = 0; line < markers.Length(); line++) {
-		delete markers[line];
-		markers[line] = 0;
-	}
-	markers.DeleteAll();
-	levels.DeleteAll();
 }
 
 void LineVector::Init() {
 	starts.DeleteAll();
-	for (int line = 0; line < markers.Length(); line++) {
-		delete markers[line];
-		markers[line] = 0;
-	}
-	markers.DeleteAll();
-	levels.DeleteAll();
 }
 
-void LineVector::ExpandLevels(int sizeNew) {
-	levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE);
+void LineVector::SetPerLine(PerLine *pl) {
+	perLine = pl;
 }
 
-void LineVector::ClearLevels() {
-	levels.DeleteAll();
-}
-
-int LineVector::SetLevel(int line, int level) {
-	int prev = 0;
-	if ((line >= 0) && (line < Lines())) {
-		if (!levels.Length()) {
-			ExpandLevels(Lines() + 1);
-		}
-		prev = levels[line];
-		if (prev != level) {
-			levels[line] = level;
-		}
-	}
-	return prev;
-}
-
-int LineVector::GetLevel(int line) {
-	if (levels.Length() && (line >= 0) && (line < Lines())) {
-		return levels[line];
-	} else {
-		return SC_FOLDLEVELBASE;
-	}
-}
-
 void LineVector::InsertText(int line, int delta) {
 	starts.InsertText(line, delta);
 }
 
 void LineVector::InsertLine(int line, int position) {
 	starts.InsertPartition(line, position);
-	if (markers.Length()) {
-		markers.Insert(line, 0);
+	if (perLine) {
+		perLine->InsertLine(line);
 	}
-	if (levels.Length()) {
-		int level = SC_FOLDLEVELBASE;
-		if ((line > 0) && (line < Lines())) {
-			level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;
-		}
-		levels.InsertValue(line, 1, level);
-	}
 }
 
 void LineVector::SetLineStart(int line, int position) {
@@ -206,103 +54,15 @@
 
 void LineVector::RemoveLine(int line) {
 	starts.RemovePartition(line);
-	// Retain the markers from the deleted line by oring them into the previous line
-	if (markers.Length()) {
-		if (line > 0) {
-			MergeMarkers(line - 1);
-		}
-		markers.Delete(line);
+	if (perLine) {
+		perLine->RemoveLine(line);
 	}
-	if (levels.Length()) {
-		// Move up following lines but merge header flag from this line
-		// to line before to avoid a temporary disappearence causing expansion.
-		int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG;
-		levels.Delete(line);
-		if (line > 0)
-			levels[line-1] |= firstHeader;
-	}
 }
 
 int LineVector::LineFromPosition(int pos) {
 	return starts.PartitionFromPosition(pos);
 }
 
-int LineVector::MarkValue(int line) {
-	if (markers.Length() && markers[line])
-		return markers[line]->MarkValue();
-	else
-		return 0;
-}
-
-int LineVector::AddMark(int line, int markerNum) {
-	handleCurrent++;
-	if (!markers.Length()) {
-		// No existing markers so allocate one element per line
-		markers.InsertValue(0, Lines(), 0);
-	}
-	if (!markers[line]) {
-		// Need new structure to hold marker handle
-		markers[line] = new MarkerHandleSet();
-		if (!markers[line])
-			return - 1;
-	}
-	markers[line]->InsertHandle(handleCurrent, markerNum);
-
-	return handleCurrent;
-}
-
-void LineVector::MergeMarkers(int pos) {
-	if (markers[pos + 1] != NULL) {
-		if (markers[pos] == NULL)
-			markers[pos] = new MarkerHandleSet;
-		markers[pos]->CombineWith(markers[pos + 1]);
-		delete markers[pos + 1];
-		markers[pos + 1] = NULL;
-	}
-}
-
-void LineVector::DeleteMark(int line, int markerNum, bool all) {
-	if (markers.Length() && markers[line]) {
-		if (markerNum == -1) {
-			delete markers[line];
-			markers[line] = NULL;
-		} else {
-			bool performedDeletion = markers[line]->RemoveNumber(markerNum);
-			while (all && performedDeletion) {
-				performedDeletion = markers[line]->RemoveNumber(markerNum);
-			}
-			if (markers[line]->Length() == 0) {
-				delete markers[line];
-				markers[line] = NULL;
-			}
-		}
-	}
-}
-
-void LineVector::DeleteMarkFromHandle(int markerHandle) {
-	int line = LineFromHandle(markerHandle);
-	if (line >= 0) {
-		markers[line]->RemoveHandle(markerHandle);
-		if (markers[line]->Length() == 0) {
-			delete markers[line];
-			markers[line] = NULL;
-		}
-	}
-}
-
-int LineVector::LineFromHandle(int markerHandle) {
-	if (markers.Length()) {
-		for (int line = 0; line < Lines(); line++) {
-			if (markers[line]) {
-				if (markers[line]->Contains(markerHandle)) {
-					return line;
-				}
-			}
-		}
-	}
-	return -1;
-}
-
 Action::Action() {
 	at = startAction;
 	position = 0;
@@ -398,7 +158,7 @@
 }
 
 void UndoHistory::AppendAction(actionType at, int position, char *data, int lengthData,
-	bool &startSequence) {
+	bool &startSequence, bool mayCoalesce) {
 	EnsureUndoRoom();
 	//Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction);
 	//Platform::DebugPrintf("^ %d action %d %d\n", actions[currentAction - 1].at,
@@ -410,25 +170,35 @@
 	if (currentAction >= 1) {
 		if (0 == undoSequenceDepth) {
 			// Top level actions may not always be coalesced
-			Action &actPrevious = actions[currentAction - 1];
+			int targetAct = -1;
+			const Action *actPrevious = &(actions[currentAction + targetAct]);
+			// Container actions may forward the coalesce state of Scintilla Actions.
+			while ((actPrevious->at == containerAction) && actPrevious->mayCoalesce) {
+				targetAct--;
+				actPrevious = &(actions[currentAction + targetAct]);
+			}
 			// See if current action can be coalesced into previous action
 			// Will work if both are inserts or deletes and position is same
-			if (at != actPrevious.at) {
+			if (currentAction == savePoint) {
 				currentAction++;
-			} else if (currentAction == savePoint) {
+			} else if (!actions[currentAction].mayCoalesce) {
+				// Not allowed to coalesce if this set
 				currentAction++;
+			} else if (!mayCoalesce || !actPrevious->mayCoalesce) {
+				currentAction++;
+			} else if (at == containerAction || actions[currentAction].at == containerAction) {
+				;	// A coalescible containerAction
+			} else if ((at != actPrevious->at) && (actPrevious->at != startAction)) {
+				currentAction++;
 			} else if ((at == insertAction) &&
-			           (position != (actPrevious.position + actPrevious.lenData))) {
+			           (position != (actPrevious->position + actPrevious->lenData))) {
 				// Insertions must be immediately after to coalesce
 				currentAction++;
-			} else if (!actions[currentAction].mayCoalesce) {
-				// Not allowed to coalesce if this set
-				currentAction++;
 			} else if (at == removeAction) {
 				if ((lengthData == 1) || (lengthData == 2)){
-					if ((position + lengthData) == actPrevious.position) {
+					if ((position + lengthData) == actPrevious->position) {
 						; // Backspace -> OK
-					} else if (position == actPrevious.position) {
+					} else if (position == actPrevious->position) {
 						; // Delete -> OK
 					} else {
 						// Removals must be at same position to coalesce
@@ -451,7 +221,7 @@
 		currentAction++;
 	}
 	startSequence = oldCurrentAction != currentAction;
-	actions[currentAction].Create(at, position, data, lengthData);
+	actions[currentAction].Create(at, position, data, lengthData, mayCoalesce);
 	currentAction++;
 	actions[currentAction].Create(startAction);
 	maxAction = currentAction;
@@ -666,6 +436,10 @@
 	style.ReAllocate(newSize);
 }
 
+void CellBuffer::SetPerLine(PerLine *pl) {
+	lv.SetPerLine(pl);
+}
+
 int CellBuffer::Lines() const {
 	return lv.Lines();
 }
@@ -695,54 +469,14 @@
 	return uh.IsSavePoint();
 }
 
-int CellBuffer::AddMark(int line, int markerNum) {
-	if ((line >= 0) && (line < Lines())) {
-		return lv.AddMark(line, markerNum);
-	}
-	return - 1;
-}
-
-void CellBuffer::DeleteMark(int line, int markerNum) {
-	if ((line >= 0) && (line < Lines())) {
-		lv.DeleteMark(line, markerNum, false);
-	}
-}
-
-void CellBuffer::DeleteMarkFromHandle(int markerHandle) {
-	lv.DeleteMarkFromHandle(markerHandle);
-}
-
-int CellBuffer::GetMark(int line) {
-	if ((line >= 0) && (line < Lines()))
-		return lv.MarkValue(line);
-	return 0;
-}
-
-void CellBuffer::DeleteAllMarks(int markerNum) {
-	for (int line = 0; line < Lines(); line++) {
-		lv.DeleteMark(line, markerNum, true);
-	}
-}
-
-int CellBuffer::LineFromHandle(int markerHandle) {
-	return lv.LineFromHandle(markerHandle);
-}
-
 // Without undo
 
 void CellBuffer::InsertLine(int line, int position) {
 	lv.InsertLine(line, position);
-	if (lineStates.Length()) {
-		lineStates.EnsureLength(line);
-		lineStates.Insert(line, 0);
-	}
 }
 
 void CellBuffer::RemoveLine(int line) {
 	lv.RemoveLine(line);
-	if (lineStates.Length() > line) {
-		lineStates.Delete(line);
-	}
 }
 
 void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) {
@@ -862,6 +596,11 @@
 	uh.EndUndoAction();
 }
 
+void CellBuffer::AddUndoAction(int token, bool mayCoalesce) {
+	bool startSequence;
+	uh.AppendAction(containerAction, token, 0, 0, startSequence, mayCoalesce);
+}
+
 void CellBuffer::DeleteUndoHistory() {
 	uh.DeleteUndoHistory();
 }
@@ -910,30 +649,3 @@
 	uh.CompletedRedoStep();
 }
 
-int CellBuffer::SetLineState(int line, int state) {
-	lineStates.EnsureLength(line + 1);
-	int stateOld = lineStates[line];
-	lineStates[line] = state;
-	return stateOld;
-}
-
-int CellBuffer::GetLineState(int line) {
-	lineStates.EnsureLength(line + 1);
-	return lineStates[line];
-}
-
-int CellBuffer::GetMaxLineState() {
-	return lineStates.Length();
-}
-
-int CellBuffer::SetLevel(int line, int level) {
-	return lv.SetLevel(line, level);
-}
-
-int CellBuffer::GetLevel(int line) {
-	return lv.GetLevel(line);
-}
-
-void CellBuffer::ClearLevels() {
-	lv.ClearLevels();
-}

Modified: trunk/scintilla/CellBuffer.h
===================================================================
--- trunk/scintilla/CellBuffer.h	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/CellBuffer.h	2009-05-03 17:49:33 UTC (rev 3769)
@@ -12,33 +12,12 @@
 namespace Scintilla {
 #endif
 
-/**
- * This holds the marker identifier and the marker type to display.
- * MarkerHandleNumbers are members of lists.
- */
-struct MarkerHandleNumber {
-	int handle;
-	int number;
-	MarkerHandleNumber *next;
-};
-
-/**
- * A marker handle set contains any number of MarkerHandleNumbers.
- */
-class MarkerHandleSet {
-	MarkerHandleNumber *root;
-
+// Interface to per-line data that wants to see each line insertion and deletion
+class PerLine {
 public:
-	MarkerHandleSet();
-	~MarkerHandleSet();
-	int Length() const;
-	int NumberFromHandle(int handle) const;
-	int MarkValue() const;	///< Bit set of marker numbers.
-	bool Contains(int handle) const;
-	bool InsertHandle(int handle, int markerNum);
-	void RemoveHandle(int handle);
-	bool RemoveNumber(int markerNum);
-	void CombineWith(MarkerHandleSet *other);
+	virtual ~PerLine() {}
+	virtual void InsertLine(int)=0;
+	virtual void RemoveLine(int)=0;
 };
 
 /**
@@ -47,22 +26,15 @@
 class LineVector {
 
 	Partitioning starts;
-	SplitVector<MarkerHandleSet *> markers;
-	SplitVector<int> levels;
-	/// Handles are allocated sequentially and should never have to be reused as 32 bit ints are very big.
-	int handleCurrent;
+	PerLine *perLine;
 
 public:
 
 	LineVector();
 	~LineVector();
 	void Init();
+	void SetPerLine(PerLine *pl);
 
-	void ExpandLevels(int sizeNew=-1);
-	void ClearLevels();
-	int SetLevel(int line, int level);
-	int GetLevel(int line);
-
 	void InsertText(int line, int delta);
 	void InsertLine(int line, int position);
 	void SetLineStart(int line, int position);
@@ -81,9 +53,18 @@
 	void DeleteMark(int line, int markerNum, bool all);
 	void DeleteMarkFromHandle(int markerHandle);
 	int LineFromHandle(int markerHandle);
+
+	void ClearLevels();
+	int SetLevel(int line, int level);
+	int GetLevel(int line);
+
+	int SetLineState(int line, int state);
+	int GetLineState(int line);
+	int GetMaxLineState();
+
 };
 
-enum actionType { insertAction, removeAction, startAction };
+enum actionType { insertAction, removeAction, startAction, containerAction };
 
 /**
  * Actions are used to store all the information required to perform one undo/redo step.
@@ -120,7 +101,7 @@
 	UndoHistory();
 	~UndoHistory();
 
-	void AppendAction(actionType at, int position, char *data, int length, bool &startSequence);
+	void AppendAction(actionType at, int position, char *data, int length, bool &startSequence, bool mayCoalesce=true);
 
 	void BeginUndoAction();
 	void EndUndoAction();
@@ -160,8 +141,6 @@
 
 	LineVector lv;
 
-	SplitVector<int> lineStates;
-
 public:
 
 	CellBuffer();
@@ -175,6 +154,7 @@
 
 	int Length() const;
 	void Allocate(int newSize);
+	void SetPerLine(PerLine *pl);
 	int Lines() const;
 	int LineStart(int line) const;
 	int LineFromPosition(int pos) { return lv.LineFromPosition(pos); }
@@ -197,14 +177,6 @@
 	void SetSavePoint();
 	bool IsSavePoint();
 
-	/// Line marker functions
-	int AddMark(int line, int markerNum);
-	void DeleteMark(int line, int markerNum);
-	void DeleteMarkFromHandle(int markerHandle);
-	int GetMark(int line);
-	void DeleteAllMarks(int markerNum);
-	int LineFromHandle(int markerHandle);
-
 	/// Actions without undo
 	void BasicInsertString(int position, const char *s, int insertLength);
 	void BasicDeleteChars(int position, int deleteLength);
@@ -213,6 +185,7 @@
 	bool IsCollectingUndo();
 	void BeginUndoAction();
 	void EndUndoAction();
+	void AddUndoAction(int token, bool mayCoalesce);
 	void DeleteUndoHistory();
 
 	/// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is
@@ -225,14 +198,6 @@
 	int StartRedo();
 	const Action &GetRedoStep() const;
 	void PerformRedoStep();
-
-	int SetLineState(int line, int state);
-	int GetLineState(int line);
-	int GetMaxLineState();
-
-	int SetLevel(int line, int level);
-	int GetLevel(int line);
-	void ClearLevels();
 };
 
 #ifdef SCI_NAMESPACE

Modified: trunk/scintilla/Document.cxx
===================================================================
--- trunk/scintilla/Document.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/Document.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -17,6 +17,7 @@
 #include "Partitioning.h"
 #include "RunStyles.h"
 #include "CellBuffer.h"
+#include "PerLine.h"
 #include "CharClassify.h"
 #include "Decoration.h"
 #include "Document.h"
@@ -74,6 +75,14 @@
 
 	matchesValid = false;
 	regex = 0;
+
+	perLineData[ldMarkers] = new LineMarkers();
+	perLineData[ldLevels] = new LineLevels();
+	perLineData[ldState] = new LineState();
+	perLineData[ldMargin] = new LineAnnotation();
+	perLineData[ldAnnotation] = new LineAnnotation();
+
+	cb.SetPerLine(this);
 }
 
 Document::~Document() {
@@ -81,12 +90,30 @@
 		watchers[i].watcher->NotifyDeleted(this, watchers[i].userData);
 	}
 	delete []watchers;
+	for (int j=0; j<ldSize; j++) {
+		delete perLineData[j];
+		perLineData[j] = 0;
+	}
 	watchers = 0;
 	lenWatchers = 0;
 	delete regex;
 	regex = 0;
 }
 
+void Document::InsertLine(int line) {
+	for (int j=0; j<ldSize; j++) {
+		if (perLineData[j])
+			perLineData[j]->InsertLine(line);
+	}
+}
+
+void Document::RemoveLine(int line) {
+	for (int j=0; j<ldSize; j++) {
+		if (perLineData[j])
+			perLineData[j]->RemoveLine(line);
+	}
+}
+
 // Increase reference count and return its previous value.
 int Document::AddRef() {
 	return refCount++;
@@ -106,42 +133,58 @@
 	NotifySavePoint(true);
 }
 
+int Document::GetMark(int line) { 
+	return static_cast<LineMarkers*>(perLineData[ldMarkers])->MarkValue(line); 
+}
+
 int Document::AddMark(int line, int markerNum) {
-	int prev = cb.AddMark(line, markerNum);
-	DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
-	NotifyModified(mh);
-	return prev;
+	if (line <= LinesTotal()) {
+		int prev = static_cast<LineMarkers*>(perLineData[ldMarkers])->
+			AddMark(line, markerNum, LinesTotal());
+		DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
+		NotifyModified(mh);
+		return prev;
+	} else {
+		return 0;
+	}
 }
 
 void Document::AddMarkSet(int line, int valueSet) {
 	unsigned int m = valueSet;
 	for (int i = 0; m; i++, m >>= 1)
 		if (m & 1)
-			cb.AddMark(line, i);
+			static_cast<LineMarkers*>(perLineData[ldMarkers])->
+				AddMark(line, i, LinesTotal());
 	DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
 	NotifyModified(mh);
 }
 
 void Document::DeleteMark(int line, int markerNum) {
-	cb.DeleteMark(line, markerNum);
+	static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, false);
 	DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
 	NotifyModified(mh);
 }
 
 void Document::DeleteMarkFromHandle(int markerHandle) {
-	cb.DeleteMarkFromHandle(markerHandle);
+	static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMarkFromHandle(markerHandle);
 	DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
 	mh.line = -1;
 	NotifyModified(mh);
 }
 
 void Document::DeleteAllMarks(int markerNum) {
-	cb.DeleteAllMarks(markerNum);
+	for (int line = 0; line < LinesTotal(); line++) {
+		static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, true);
+	}
 	DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
 	mh.line = -1;
 	NotifyModified(mh);
 }
 
+int Document::LineFromHandle(int markerHandle) { 
+	return static_cast<LineMarkers*>(perLineData[ldMarkers])->LineFromHandle(markerHandle); 
+}
+
 int Document::LineStart(int line) const {
 	return cb.LineStart(line);
 }
@@ -181,7 +224,7 @@
 }
 
 int Document::SetLevel(int line, int level) {
-	int prev = cb.SetLevel(line, level);
+	int prev = static_cast<LineLevels*>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal());
 	if (prev != level) {
 		DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER,
 		                   LineStart(line), 0, 0, 0, line);
@@ -192,6 +235,14 @@
 	return prev;
 }
 
+int Document::GetLevel(int line) { 
+	return static_cast<LineLevels*>(perLineData[ldLevels])->GetLevel(line); 
+}
+
+void Document::ClearLevels() { 
+	static_cast<LineLevels*>(perLineData[ldLevels])->ClearLevels(); 
+}
+
 static bool IsSubordinate(int levelStart, int levelTry) {
 	if (levelTry & SC_FOLDLEVELWHITEFLAG)
 		return true;
@@ -503,21 +554,27 @@
 				if (action.at == removeAction) {
 					NotifyModified(DocModification(
 									SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));
+				} else if (action.at == containerAction) {
+					DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO);
+					dm.token = action.position;
+					NotifyModified(dm);
 				} else {
 					NotifyModified(DocModification(
 									SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
 				}
 				cb.PerformUndoStep();
 				int cellPosition = action.position;
-				ModifiedAt(cellPosition);
-				newPos = cellPosition;
+				if (action.at != containerAction) {
+					ModifiedAt(cellPosition);
+					newPos = cellPosition;
+				}
 
 				int modFlags = SC_PERFORMED_UNDO;
 				// With undo, an insertion action becomes a deletion notification
 				if (action.at == removeAction) {
 					newPos += action.lenData;
 					modFlags |= SC_MOD_INSERTTEXT;
-				} else {
+				} else if (action.at == insertAction) {
 					modFlags |= SC_MOD_DELETETEXT;
 				}
 				if (steps > 1)
@@ -558,19 +615,25 @@
 				if (action.at == insertAction) {
 					NotifyModified(DocModification(
 									SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));
+				} else if (action.at == containerAction) {
+					DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_REDO);
+					dm.token = action.position;
+					NotifyModified(dm);
 				} else {
 					NotifyModified(DocModification(
 									SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
 				}
 				cb.PerformRedoStep();
-				ModifiedAt(action.position);
-				newPos = action.position;
+				if (action.at != containerAction) {
+					ModifiedAt(action.position);
+					newPos = action.position;
+				}
 
 				int modFlags = SC_PERFORMED_REDO;
 				if (action.at == insertAction) {
 					newPos += action.lenData;
 					modFlags |= SC_MOD_INSERTTEXT;
-				} else {
+				} else if (action.at == removeAction) {
 					modFlags |= SC_MOD_DELETETEXT;
 				}
 				if (steps > 1)
@@ -1059,8 +1122,8 @@
 					}
 					if (found) {
 						if ((!word && !wordStart) ||
-						        word && IsWordAt(pos, pos + lengthFind) ||
-						        wordStart && IsWordStartAt(pos))
+						        (word && IsWordAt(pos, pos + lengthFind)) ||
+						        (wordStart && IsWordStartAt(pos)))
 							return pos;
 					}
 				}
@@ -1075,8 +1138,8 @@
 					}
 					if (found) {
 						if ((!word && !wordStart) ||
-						        word && IsWordAt(pos, pos + lengthFind) ||
-						        wordStart && IsWordStartAt(pos))
+						        (word && IsWordAt(pos, pos + lengthFind)) ||
+						        (wordStart && IsWordStartAt(pos)))
 							return pos;
 					}
 				}
@@ -1155,7 +1218,7 @@
 	}
 }
 
-bool Document::SetStyles(int length, char *styles) {
+bool Document::SetStyles(int length, const char *styles) {
 	if (enteredStyling != 0) {
 		return false;
 	} else {
@@ -1194,7 +1257,7 @@
 }
 
 int Document::SetLineState(int line, int state) {
-	int statePrevious = cb.SetLineState(line, state);
+	int statePrevious = static_cast<LineState*>(perLineData[ldState])->SetLineState(line, state);
 	if (state != statePrevious) {
 		DocModification mh(SC_MOD_CHANGELINESTATE, 0, 0, 0, 0, line);
 		NotifyModified(mh);
@@ -1202,6 +1265,89 @@
 	return statePrevious;
 }
 
+int Document::GetLineState(int line) { 
+	return static_cast<LineState*>(perLineData[ldState])->GetLineState(line); 
+}
+
+int Document::GetMaxLineState() { 
+	return static_cast<LineState*>(perLineData[ldState])->GetMaxLineState(); 
+}
+
+StyledText Document::MarginStyledText(int line) {
+	LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldMargin]);
+	return StyledText(pla->Length(line), pla->Text(line), 
+		pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
+}
+
+void Document::MarginSetText(int line, const char *text) {
+	static_cast<LineAnnotation*>(perLineData[ldMargin])->SetText(line, text); 
+	DocModification mh(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line);
+	NotifyModified(mh);
+}
+
+void Document::MarginSetStyle(int line, int style) {
+	static_cast<LineAnnotation*>(perLineData[ldMargin])->SetStyle(line, style); 
+}
+
+void Document::MarginSetStyles(int line, const unsigned char *styles) {
+	static_cast<LineAnnotation*>(perLineData[ldMargin])->SetStyles(line, styles); 
+}
+
+int Document::MarginLength(int line) const {
+	return static_cast<LineAnnotation*>(perLineData[ldMargin])->Length(line);
+}
+
+void Document::MarginClearAll() {
+	int maxEditorLine = LinesTotal();
+	for (int l=0;l<maxEditorLine;l++)
+		MarginSetText(l, 0);
+	// Free remaining data
+	static_cast<LineAnnotation*>(perLineData[ldMargin])->ClearAll();
+}
+
+bool Document::AnnotationAny() const {
+	return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->AnySet(); 
+}
+
+StyledText Document::AnnotationStyledText(int line) {
+	LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldAnnotation]);
+	return StyledText(pla->Length(line), pla->Text(line), 
+		pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
+}
+
+void Document::AnnotationSetText(int line, const char *text) {
+	const int linesBefore = AnnotationLines(line);
+	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetText(line, text); 
+	const int linesAfter = AnnotationLines(line);
+	DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line);
+	mh.annotationLinesAdded = linesAfter - linesBefore;
+	NotifyModified(mh);
+}
+
+void Document::AnnotationSetStyle(int line, int style) {
+	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyle(line, style); 
+}
+
+void Document::AnnotationSetStyles(int line, const unsigned char *styles) {
+	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyles(line, styles); 
+}
+
+int Document::AnnotationLength(int line) const {
+	return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Length(line);
+}
+
+int Document::AnnotationLines(int line) const {
+	return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Lines(line);
+}
+
+void Document::AnnotationClearAll() {
+	int maxEditorLine = LinesTotal();
+	for (int l=0;l<maxEditorLine;l++)
+		AnnotationSetText(l, 0);
+	// Free remaining data
+	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->ClearAll();
+}
+
 void Document::IncrementStyleClock() {
 	styleClock = (styleClock + 1) % 0x100000;
 }
@@ -1657,8 +1803,18 @@
 
 #ifndef SCI_OWNREGEX
 
+#ifdef SCI_NAMESPACE
+
+RegexSearchBase *Scintilla::CreateRegexSearch(CharClassify *charClassTable) {
+	return new BuiltinRegex(charClassTable);
+}
+
+#else
+
 RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable) {
 	return new BuiltinRegex(charClassTable);
 }
 
 #endif
+
+#endif

Modified: trunk/scintilla/Document.h
===================================================================
--- trunk/scintilla/Document.h	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/Document.h	2009-05-03 17:49:33 UTC (rev 3769)
@@ -93,9 +93,31 @@
 /// Factory function for RegexSearchBase
 extern RegexSearchBase* CreateRegexSearch(CharClassify *charClassTable);
 
+struct StyledText {
+	size_t length;
+	const char *text;
+	bool multipleStyles;
+	size_t style;
+	const unsigned char *styles;
+	StyledText(	size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) : 
+		length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) {
+	}
+	// Return number of bytes from start to before '\n' or end of text.
+	// Return 1 when start is outside text
+	size_t LineLength(size_t start) const {
+		size_t cur = start;
+		while ((cur < length) && (text[cur] != '\n'))
+			cur++;
+		return cur-start;
+	}
+	size_t StyleAt(size_t i) const {
+		return multipleStyles ? styles[i] : style;
+	}
+};
+
 /**
  */
-class Document {
+class Document : PerLine {
 
 public:
 	/** Used to pair watcher pointer with user data. */
@@ -110,7 +132,6 @@
 	};
 
 	enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation };
-
 private:
 	int refCount;
 	CellBuffer cb;
@@ -125,6 +146,10 @@
 	WatcherWithUserData *watchers;
 	int lenWatchers;
 
+	// ldSize is not real data - it is for dimensions and loops
+	enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize };	
+	PerLine *perLineData[ldSize];
+
 	bool matchesValid;
 	RegexSearchBase* regex;
 
@@ -150,6 +175,9 @@
 	int AddRef();
 	int Release();
 
+	virtual void InsertLine(int line);
+	virtual void RemoveLine(int line);
+
 	int LineFromPosition(int pos);
 	int ClampPositionIntoDocument(int pos);
 	bool IsCrLf(int pos);
@@ -173,6 +201,7 @@
 	bool IsCollectingUndo() { return cb.IsCollectingUndo(); }
 	void BeginUndoAction() { cb.BeginUndoAction(); }
 	void EndUndoAction() { cb.EndUndoAction(); }
+	void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); }
 	void SetSavePoint();
 	bool IsSavePoint() { return cb.IsSavePoint(); }
 	const char *BufferPointer() { return cb.BufferPointer(); }
@@ -199,21 +228,21 @@
 		cb.GetCharRange(buffer, position, lengthRetrieve);
 	}
 	char StyleAt(int position) { return cb.StyleAt(position); }
-	int GetMark(int line) { return cb.GetMark(line); }
+	int GetMark(int line);
 	int AddMark(int line, int markerNum);
 	void AddMarkSet(int line, int valueSet);
 	void DeleteMark(int line, int markerNum);
 	void DeleteMarkFromHandle(int markerHandle);
 	void DeleteAllMarks(int markerNum);
-	int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); }
+	int LineFromHandle(int markerHandle);
 	int LineStart(int line) const;
 	int LineEnd(int line) const;
 	int LineEndPosition(int position);
 	int VCHomePosition(int position);
 
 	int SetLevel(int line, int level);
-	int GetLevel(int line) { return cb.GetLevel(line); }
-	void ClearLevels() { cb.ClearLevels(); }
+	int GetLevel(int line);
+	void ClearLevels();
 	int GetLastChild(int lineParent, int level=-1);
 	int GetFoldParent(int line);
 
@@ -236,7 +265,7 @@
 	void SetStylingBits(int bits);
 	void StartStyling(int position, char mask);
 	bool SetStyleFor(int length, char style);
-	bool SetStyles(int length, char *styles);
+	bool SetStyles(int length, const char *styles);
 	int GetEndStyled() { return endStyled; }
 	void EnsureStyledTo(int pos);
 	int GetStyleClock() { return styleClock; }
@@ -244,9 +273,25 @@
 	void DecorationFillRange(int position, int value, int fillLength);
 
 	int SetLineState(int line, int state);
-	int GetLineState(int line) { return cb.GetLineState(line); }
-	int GetMaxLineState() { return cb.GetMaxLineState(); }
+	int GetLineState(int line);
+	int GetMaxLineState();
 
+	StyledText MarginStyledText(int line);
+	void MarginSetStyle(int line, int style);
+	void MarginSetStyles(int line, const unsigned char *styles);
+	void MarginSetText(int line, const char *text);
+	int MarginLength(int line) const;
+	void MarginClearAll();
+
+	bool AnnotationAny() const;
+	StyledText AnnotationStyledText(int line);
+	void AnnotationSetText(int line, const char *text);
+	void AnnotationSetStyle(int line, int style);
+	void AnnotationSetStyles(int line, const unsigned char *styles);
+	int AnnotationLength(int line) const;
+	int AnnotationLines(int line) const;
+	void AnnotationClearAll();
+
 	bool AddWatcher(DocWatcher *watcher, void *userData);
 	bool RemoveWatcher(DocWatcher *watcher, void *userData);
 	const WatcherWithUserData *GetWatchers() const { return watchers; }
@@ -288,6 +333,8 @@
  	int line;
 	int foldLevelNow;
 	int foldLevelPrev;
+	int annotationLinesAdded;
+	int token;
 
 	DocModification(int modificationType_, int position_=0, int length_=0,
 		int linesAdded_=0, const char *text_=0, int line_=0) :
@@ -298,7 +345,9 @@
 		text(text_),
 		line(line_),
 		foldLevelNow(0),
-		foldLevelPrev(0) {}
+		foldLevelPrev(0),
+		annotationLinesAdded(0),
+		token(0) {}
 
 	DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
 		modificationType(modificationType_),
@@ -308,7 +357,9 @@
 		text(act.data),
 		line(0),
 		foldLevelNow(0),
-		foldLevelPrev(0) {}
+		foldLevelPrev(0),
+		annotationLinesAdded(0),
+		token(0) {}
 };
 
 /**

Modified: trunk/scintilla/Editor.cxx
===================================================================
--- trunk/scintilla/Editor.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/Editor.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -1277,7 +1277,8 @@
 		LayoutLine(lineToWrap, surface, vs, ll, wrapWidth);
 		linesWrapped = ll->lines;
 	}
-	return cs.SetHeight(lineToWrap, linesWrapped);
+	return cs.SetHeight(lineToWrap, linesWrapped + 
+		(vs.annotationVisible ? pdoc->AnnotationLines(lineToWrap) : 0));
 }
 
 // Check if wrapping needed and perform any needed wrapping.
@@ -1315,7 +1316,8 @@
 			if (wrapWidth != LineLayout::wrapWidthInfinite) {
 				wrapWidth = LineLayout::wrapWidthInfinite;
 				for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) {
-					cs.SetHeight(lineDoc, 1);
+					cs.SetHeight(lineDoc, 1 + 
+						(vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0));
 				}
 				wrapOccurred = true;
 			}
@@ -1457,6 +1459,84 @@
 	return static_cast<int>(strlen(s));
 }
 
+bool ValidStyledText(ViewStyle &vs, size_t styleOffset, const StyledText &st) {
+	if (st.multipleStyles) {
+		for (size_t iStyle=0;iStyle<st.length; iStyle++) {
+			if (!vs.ValidStyle(styleOffset + st.styles[iStyle]))
+				return false;
+		}
+	} else {
+		if (!vs.ValidStyle(styleOffset + st.style))
+			return false;
+	}
+	return true;
+}
+
+static int WidthStyledText(Surface *surface, ViewStyle &vs, int styleOffset,
+	const char *text, const unsigned char *styles, size_t len) {
+	int width = 0;
+	size_t start = 0;
+	while (start < len) {
+		size_t style = styles[start];
+		size_t endSegment = start;
+		while ((endSegment+1 < len) && (static_cast<size_t>(styles[endSegment+1]) == style))
+			endSegment++;
+		width += surface->WidthText(vs.styles[style+styleOffset].font, text + start, endSegment - start + 1);
+		start = endSegment + 1;
+	}
+	return width;
+}
+
+static int WidestLineWidth(Surface *surface, ViewStyle &vs, int styleOffset, const StyledText &st) {
+	int widthMax = 0;
+	size_t start = 0;
+	while (start < st.length) {
+		size_t lenLine = st.LineLength(start);
+		int widthSubLine;
+		if (st.multipleStyles) {
+			widthSubLine = WidthStyledText(surface, vs, styleOffset, st.text + start, st.styles + start, lenLine);
+		} else {
+			widthSubLine = surface->WidthText(vs.styles[styleOffset + st.style].font, st.text + start, lenLine);
+		}
+		if (widthSubLine > widthMax)
+			widthMax = widthSubLine;
+		start += lenLine + 1;
+	}
+	return widthMax;
+}
+
+void DrawStyledText(Surface *surface, ViewStyle &vs, int styleOffset, PRectangle rcText, int ascent, 
+	const StyledText &st, size_t start, size_t length) {
+
+	if (st.multipleStyles) {
+		int x = rcText.left;
+		size_t i = 0;
+		while (i < length) {
+			size_t end = i;
+			int style = st.styles[i + start];
+			while (end < length-1 && st.styles[start+end+1] == style)
+				end++;
+			style += styleOffset;
+			int width = surface->WidthText(vs.styles[style].font, st.text + start + i, end - i + 1);
+			PRectangle rcSegment = rcText;
+			rcSegment.left = x;
+			rcSegment.right = x + width + 1;
+			surface->DrawTextNoClip(rcSegment, vs.styles[style].font,
+					ascent, st.text + start + i, end - i + 1,
+					vs.styles[style].fore.allocated,
+					vs.styles[style].back.allocated);
+			x += width;
+			i = end + 1;
+		}
+	} else {
+		int style = st.style + styleOffset;
+		surface->DrawTextNoClip(rcText, vs.styles[style].font,
+				rcText.top + vs.maxAscent, st.text, st.length,
+				vs.styles[style].fore.allocated,
+				vs.styles[style].back.allocated);
+	}
+}
+
 void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 	if (vs.fixedColumnWidth == 0)
 		return;
@@ -1638,6 +1718,20 @@
 					        rcNumber.top + vs.maxAscent, number, istrlen(number),
 					        vs.styles[STYLE_LINENUMBER].fore.allocated,
 					        vs.styles[STYLE_LINENUMBER].back.allocated);
+				} else if (vs.ms[margin].style == SC_MARGIN_TEXT || vs.ms[margin].style == SC_MARGIN_RTEXT) {
+					if (firstSubLine) {
+						const StyledText stMargin  = pdoc->MarginStyledText(lineDoc);
+						if (stMargin.text && ValidStyledText(vs, vs.marginStyleOffset, stMargin)) {
+							surface->FillRectangle(rcMarker, 
+								vs.styles[stMargin.StyleAt(0)+vs.marginStyleOffset].back.allocated);
+							if (vs.ms[margin].style == SC_MARGIN_RTEXT) {
+								int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin);
+								rcMarker.left = rcMarker.right - width - 3;
+							}
+							DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker, rcMarker.top + vs.maxAscent, 
+								stMargin, 0, stMargin.length);
+						}
+					}
 				}
 
 				if (marks) {
@@ -2221,6 +2315,58 @@
 	        textBack, textFore);
 }
 
+void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
+    PRectangle rcLine, LineLayout *ll, int subLine) {
+	int indent = pdoc->GetLineIndentation(line) * vsDraw.spaceWidth;
+	PRectangle rcSegment = rcLine;
+	int annotationLine = subLine - ll->lines;
+	const StyledText stAnnotation  = pdoc->AnnotationStyledText(line);
+	if (stAnnotation.text && ValidStyledText(vsDraw, vsDraw.annotationStyleOffset, stAnnotation)) {
+		surface->FillRectangle(rcSegment, vsDraw.styles[0].back.allocated);
+		if (vs.annotationVisible == ANNOTATION_BOXED) {
+			// Only care about calculating width if need to draw box
+			int widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset, stAnnotation);
+			widthAnnotation += vsDraw.spaceWidth * 2; // Margins
+			rcSegment.left = xStart + indent;
+			rcSegment.right = rcSegment.left + widthAnnotation;
+			surface->PenColour(vsDraw.styles[vsDraw.annotationStyleOffset].fore.allocated);
+		} else {
+			rcSegment.left = xStart;
+		}
+		const int annotationLines = pdoc->AnnotationLines(line);
+		size_t start = 0;
+		size_t lengthAnnotation = stAnnotation.LineLength(start);
+		int lineInAnnotation = 0;
+		while ((lineInAnnotation < annotationLine) && (start < stAnnotation.length)) {
+			start += lengthAnnotation + 1;
+			lengthAnnotation = stAnnotation.LineLength(start);
+			lineInAnnotation++;
+		}
+		PRectangle rcText = rcSegment;
+		if (vs.annotationVisible == ANNOTATION_BOXED) {
+			surface->FillRectangle(rcText, 
+				vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back.allocated);
+			rcText.left += vsDraw.spaceWidth;
+		}
+		DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, rcText.top + vsDraw.maxAscent, 
+			stAnnotation, start, lengthAnnotation);
+		if (vs.annotationVisible == ANNOTATION_BOXED) {
+			surface->MoveTo(rcSegment.left, rcSegment.top);
+			surface->LineTo(rcSegment.left, rcSegment.bottom);
+			surface->MoveTo(rcSegment.right, rcSegment.top);
+			surface->LineTo(rcSegment.right, rcSegment.bottom);
+			if (subLine == ll->lines){
+				surface->MoveTo(rcSegment.left, rcSegment.top);
+				surface->LineTo(rcSegment.right, rcSegment.top);
+			} 
+			if (subLine == ll->lines+annotationLines-1) {
+				surface->MoveTo(rcSegment.left, rcSegment.bottom - 1);
+				surface->LineTo(rcSegment.right, rcSegment.bottom - 1);
+			}
+		}
+	}
+}
+
 void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
         PRectangle rcLine, LineLayout *ll, int subLine) {
 
@@ -2280,6 +2426,10 @@
 
 	int startseg = ll->LineStart(subLine);
 	int subLineStart = ll->positions[startseg];
+	if (subLine >= ll->lines) {
+		DrawAnnotation(surface, vsDraw, line, xStart, rcLine, ll, subLine);
+		return; // No further drawing
+	}
 	int lineStart = 0;
 	int lineEnd = 0;
 	if (subLine < ll->lines) {
@@ -2693,9 +2843,16 @@
 	}
 
 	// We now know what to draw, update the caret drawing rectangle
-	rcCaret.left = ll->positions[offsetFirstChar] - ll->positions[ll->LineStart(subLine)] + xStart;
-	rcCaret.right = ll->positions[offsetFirstChar+numCharsToDraw] - ll->positions[ll->LineStart(subLine)] + xStart;
+	rcCaret.left = ll->positions[offsetFirstChar] - ll->positions[lineStart] + xStart;
+	rcCaret.right = ll->positions[offsetFirstChar+numCharsToDraw] - ll->positions[lineStart] + xStart;
 
+	// Adjust caret position to take into account any word wrapping symbols.
+	if ((actualWrapVisualStartIndent != 0) && (lineStart != 0)) {
+		int wordWrapCharWidth = actualWrapVisualStartIndent * vs.aveCharWidth;
+		rcCaret.left += wordWrapCharWidth;
+		rcCaret.right += wordWrapCharWidth;
+	}
+
 	// This character is where the caret block is, we override the colours
 	// (inversed) for drawing the caret here.
 	int styleMain = ll->styles[offsetFirstChar];
@@ -2793,7 +2950,7 @@
 	//Platform::DebugPrintf("Paint lines = %d .. %d\n", topLine + screenLinePaintFirst, lineStyleLast);
 	int endPosPaint = pdoc->Length();
 	if (lineStyleLast < cs.LinesDisplayed())
-		endPosPaint = pdoc->LineStart(cs.DocFromDisplay(lineStyleLast + 1));
+		endPosPaint = pdoc->LineStart(cs.DocFromDisplay(lineStyleLast) + 1);
 
 	int xStart = vs.fixedColumnWidth - xOffset;
 	int ypos = 0;
@@ -2945,7 +3102,9 @@
 				ll->RestoreBracesHighlight(rangeLine, braces);
 
 				bool expanded = cs.GetExpanded(lineDoc);
+#ifdef INCLUDE_DEPRECATED_FEATURES
 				if ((foldFlags & SC_FOLDFLAG_BOX) == 0) {
+#endif
 					// Paint the line above the fold
 					if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
 					        ||
@@ -2966,6 +3125,7 @@
 							surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
 						}
 					}
+#ifdef INCLUDE_DEPRECATED_FEATURES
 				} else {
 					int FoldLevelCurr = (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE;
 					int FoldLevelPrev = (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE;
@@ -3001,6 +3161,7 @@
 						surface->FillRectangle(rcBoxLine, vs.styles[STYLE_DEFAULT].fore.allocated);
 					}
 				}
+#endif
 
 				// Draw the Caret
 				if (lineDoc == lineCaret) {
@@ -3512,6 +3673,8 @@
 	}
 	if (!pdoc->IsReadOnly()) {
 		cs.Clear();
+		pdoc->AnnotationClearAll();
+		pdoc->MarginClearAll();
 	}
 	pdoc->EndUndoAction();
 	anchor = 0;
@@ -3885,6 +4048,10 @@
 			int lines = Platform::Maximum(0, mh.linesAdded);
 			NeedWrapping(lineDoc, lineDoc + lines + 1);
 		}
+		// Fix up annotation heights
+		int lineDoc = pdoc->LineFromPosition(mh.position);
+		int lines = Platform::Maximum(0, mh.linesAdded);
+		SetAnnotationHeights(lineDoc, lineDoc + lines + 2);
 	}
 }
 
@@ -3972,6 +4139,12 @@
 				cs.DeleteLines(lineOfPos, -mh.linesAdded);
 			}
 		}
+		if (mh.modificationType & SC_MOD_CHANGEANNOTATION) {
+			int lineDoc = pdoc->LineFromPosition(mh.position);
+			if (vs.annotationVisible) {
+				cs.SetHeight(lineDoc, cs.GetHeight(lineDoc) + mh.annotationLinesAdded);
+			}
+		}
 		CheckModificationForWrap(mh);
 		if (mh.linesAdded != 0) {
 			// Avoid scrolling of display if change before current display
@@ -4002,7 +4175,7 @@
 		SetScrollBars();
 	}
 
-	if (mh.modificationType & SC_MOD_CHANGEMARKER) {
+	if ((mh.modificationType & SC_MOD_CHANGEMARKER) || (mh.modificationType & SC_MOD_CHANGEMARGIN)) {
 		if ((paintState == notPainting) || !PaintContainsMargin()) {
 			if (mh.modificationType & SC_MOD_CHANGEFOLD) {
 				// Fold changes can affect the drawing of following lines so redraw whole margin
@@ -4036,6 +4209,8 @@
 		scn.line = mh.line;
 		scn.foldLevelNow = mh.foldLevelNow;
 		scn.foldLevelPrev = mh.foldLevelPrev;
+		scn.token = mh.token;
+		scn.annotationLinesAdded = mh.annotationLinesAdded;
 		NotifyParent(scn);
 	}
 }
@@ -4305,8 +4480,16 @@
 
 void Editor::CursorUpOrDown(int direction, selTypes sel) {
 	Point pt = LocationFromPosition(currentPos);
+	int lineDoc = pdoc->LineFromPosition(currentPos);
+	Point ptStartLine = LocationFromPosition(pdoc->LineStart(lineDoc));
+	int subLine = (pt.y - ptStartLine.y) / vs.lineHeight;
+	int commentLines = vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0;
 	int posNew = PositionFromLocation(
 	            Point(lastXChosen, pt.y + direction * vs.lineHeight));
+	if ((direction > 0) && (subLine >= (cs.GetHeight(lineDoc) - 1 - commentLines))) {
+		posNew = PositionFromLocation(
+	            Point(lastXChosen, pt.y + (commentLines + 1) * vs.lineHeight));
+	}
 	if (direction < 0) {
 		// Line wrapping may lead to a location on the same line, so
 		// seek back if that is the case.
@@ -4611,6 +4794,7 @@
 			SetLastXChosen();
 		}
 		EnsureCaretVisible();
+		ShowCaretAtCurrentPosition();		// Avoid blinking
 		break;
 	case SCI_BACKTAB:
 		Indent(false);
@@ -4618,6 +4802,7 @@
 			SetLastXChosen();
 		}
 		EnsureCaretVisible();
+		ShowCaretAtCurrentPosition();		// Avoid blinking
 		break;
 	case SCI_NEWLINE:
 		NewLine();
@@ -5740,6 +5925,14 @@
 	}
 }
 
+void Editor::SetAnnotationHeights(int start, int end) {
+	if (vs.annotationVisible) {
+		for (int line=start; line<end; line++) {
+			cs.SetHeight(line, pdoc->AnnotationLines(line) + 1);
+		}
+	}
+}
+
 void Editor::SetDocPointer(Document *document) {
 	//Platform::DebugPrintf("** %x setdoc to %x\n", pdoc, document);
 	pdoc->RemoveWatcher(this, 0);
@@ -5764,6 +5957,7 @@
 	// Reset the contraction state to fully shown.
 	cs.Clear();
 	cs.InsertLines(0, pdoc->LinesTotal() - 1);
+	SetAnnotationHeights(0, pdoc->LinesTotal());
 	llc.Deallocate();
 	NeedWrapping();
 
@@ -5772,6 +5966,22 @@
 	Redraw();
 }
 
+void Editor::SetAnnotationVisible(int visible) {
+	if (vs.annotationVisible != visible) {
+		bool changedFromOrToHidden = ((vs.annotationVisible != 0) != (visible != 0));
+		vs.annotationVisible = visible;
+		if (changedFromOrToHidden) {
+			int dir = vs.annotationVisible ? 1 : -1;
+			for (int line=0; line<pdoc->LinesTotal(); line++) {
+				int annotationLines = pdoc->AnnotationLines(line);
+				if (annotationLines > 0) {
+					cs.SetHeight(line, cs.GetHeight(line) + annotationLines * dir);
+				}
+			}
+		}
+	}
+}
+
 /**
  * Recursively expand a fold, making lines visible except where they have an unexpanded parent.
  */
@@ -6892,6 +7102,13 @@
 		InvalidateStyleData();
 		RedrawSelMargin();
 		break;
+
+	case SCI_MARKERSYMBOLDEFINED:
+		if (wParam <= MARKER_MAX)
+			return vs.markers[wParam].markType;
+		else
+			return 0;
+
 	case SCI_MARKERSETFORE:
 		if (wParam <= MARKER_MAX)
 			vs.markers[wParam].fore.desired = ColourDesired(lParam);
@@ -7304,6 +7521,16 @@
 	case SCI_INDICGETUNDER:
 		return (wParam <= INDIC_MAX) ? vs.indicators[wParam].under : 0;
 
+	case SCI_INDICSETALPHA:
+		if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 100) {
+			vs.indicators[wParam].fillAlpha = lParam;
+			InvalidateStyleRedraw();
+		}
+		break;
+
+	case SCI_INDICGETALPHA:
+		return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fillAlpha : 0;
+
 	case SCI_SETINDICATORCURRENT:
 		pdoc->decorations.SetCurrentIndicator(wParam);
 		break;
@@ -7675,6 +7902,138 @@
 	case SCI_GETCHARACTERPOINTER:
 		return reinterpret_cast<sptr_t>(pdoc->BufferPointer());
 
+	case SCI_SETEXTRAASCENT:
+		vs.extraAscent = wParam;
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_GETEXTRAASCENT:
+		return vs.extraAscent;
+
+	case SCI_SETEXTRADESCENT:
+		vs.extraDescent = wParam;
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_GETEXTRADESCENT:
+		return vs.extraDescent;
+
+	case SCI_MARGINSETSTYLEOFFSET:
+		vs.marginStyleOffset = wParam;
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_MARGINGETSTYLEOFFSET:
+		return vs.marginStyleOffset;
+
+	case SCI_MARGINSETTEXT:
+		pdoc->MarginSetText(wParam, CharPtrFromSPtr(lParam));
+		break;
+
+	case SCI_MARGINGETTEXT: {
+			const StyledText st = pdoc->MarginStyledText(wParam);
+			if (lParam) {
+				if (st.text)
+					memcpy(CharPtrFromSPtr(lParam), st.text, st.length);
+				else
+					strcpy(CharPtrFromSPtr(lParam), "");
+			}
+			return st.length;
+		}
+
+	case SCI_MARGINSETSTYLE:
+		pdoc->MarginSetStyle(wParam, lParam);
+		break;
+
+	case SCI_MARGINGETSTYLE: {
+			const StyledText st = pdoc->MarginStyledText(wParam);
+			return st.style;
+		}
+
+	case SCI_MARGINSETSTYLES:
+		pdoc->MarginSetStyles(wParam, reinterpret_cast<const unsigned char *>(lParam));
+		break;
+
+	case SCI_MARGINGETSTYLES: {
+			const StyledText st = pdoc->MarginStyledText(wParam);
+			if (lParam) {
+				if (st.styles)
+					memcpy(CharPtrFromSPtr(lParam), st.styles, st.length);
+				else
+					strcpy(CharPtrFromSPtr(lParam), "");
+			}
+			return st.styles ? st.length : 0;
+		}
+
+	case SCI_MARGINTEXTCLEARALL:
+		pdoc->MarginClearAll();
+		break;
+
+	case SCI_ANNOTATIONSETTEXT:
+		pdoc->AnnotationSetText(wParam, CharPtrFromSPtr(lParam));
+		break;
+
+	case SCI_ANNOTATIONGETTEXT: {
+			const StyledText st = pdoc->AnnotationStyledText(wParam);
+			if (lParam) {
+				if (st.text)
+					memcpy(CharPtrFromSPtr(lParam), st.text, st.length);
+				else
+					strcpy(CharPtrFromSPtr(lParam), "");
+			}
+			return st.length;
+		}
+
+	case SCI_ANNOTATIONGETSTYLE: {
+			const StyledText st = pdoc->AnnotationStyledText(wParam);
+			return st.style;
+		}
+
+	case SCI_ANNOTATIONSETSTYLE:
+		pdoc->AnnotationSetStyle(wParam, lParam);
+		break;
+
+	case SCI_ANNOTATIONSETSTYLES:
+		pdoc->AnnotationSetStyles(wParam, reinterpret_cast<const unsigned char *>(lParam));
+		break;
+
+	case SCI_ANNOTATIONGETSTYLES: {
+			const StyledText st = pdoc->AnnotationStyledText(wParam);
+			if (lParam) {
+				if (st.styles)
+					memcpy(CharPtrFromSPtr(lParam), st.styles, st.length);
+				else
+					strcpy(CharPtrFromSPtr(lParam), "");
+			}
+			return st.styles ? st.length : 0;
+		}
+
+	case SCI_ANNOTATIONGETLINES:
+		return pdoc->AnnotationLines(wParam);
+
+	case SCI_ANNOTATIONCLEARALL:
+		pdoc->AnnotationClearAll();
+		break;
+
+	case SCI_ANNOTATIONSETVISIBLE:
+		SetAnnotationVisible(wParam);
+		break;
+
+	case SCI_ANNOTATIONGETVISIBLE:
+		return vs.annotationVisible;
+
+	case SCI_ANNOTATIONSETSTYLEOFFSET:
+		vs.annotationStyleOffset = wParam;
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_ANNOTATIONGETSTYLEOFFSET:
+		return vs.annotationStyleOffset;
+
+	case SCI_ADDUNDOACTION:
+		pdoc->AddUndoAction(wParam, lParam & UNDO_MAY_COALESCE);
+		break;
+
 	default:
 		return DefWndProc(iMessage, wParam, lParam);
 	}

Modified: trunk/scintilla/Editor.h
===================================================================
--- trunk/scintilla/Editor.h	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/Editor.h	2009-05-03 17:49:33 UTC (rev 3769)
@@ -322,6 +322,8 @@
 		bool drawWrapMark, ColourAllocated wrapColour);
 	void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
 		PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under);
+	void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
+        PRectangle rcLine, LineLayout *ll, int subLine);
 	void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
 		PRectangle rcLine, LineLayout *ll, int subLine=0);
 	void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret);
@@ -443,7 +445,10 @@
 	void CheckForChangeOutsidePaint(Range r);
 	void SetBraceHighlight(Position pos0, Position pos1, int matchStyle);
 
+	void SetAnnotationHeights(int start, int end);
 	void SetDocPointer(Document *document);
+	
+	void SetAnnotationVisible(int visible);
 
 	void Expand(int &line, bool doExpand);
 	void ToggleContraction(int line);

Modified: trunk/scintilla/Indicator.cxx
===================================================================
--- trunk/scintilla/Indicator.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/Indicator.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -72,7 +72,7 @@
 		rcBox.top = rcLine.top + 1;
 		rcBox.left = rc.left;
 		rcBox.right = rc.right;
-		surface->AlphaRectangle(rcBox, 1, fore.allocated, 30, fore.allocated, 50, 0);
+		surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, 50, 0);
 	} else {	// Either INDIC_PLAIN or unknown
 		surface->MoveTo(rc.left, ymid);
 		surface->LineTo(rc.right, ymid);

Modified: trunk/scintilla/Indicator.h
===================================================================
--- trunk/scintilla/Indicator.h	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/Indicator.h	2009-05-03 17:49:33 UTC (rev 3769)
@@ -19,7 +19,8 @@
 	int style;
 	bool under;
 	ColourPair fore;
-	Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)) {
+	int fillAlpha;
+	Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) {
 	}
 	void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
 };

Modified: trunk/scintilla/KeyWords.cxx
===================================================================
--- trunk/scintilla/KeyWords.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/KeyWords.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -144,7 +144,6 @@
 	LINK_LEXER(lmAda);
 	LINK_LEXER(lmAsm);
 	LINK_LEXER(lmBash);
-	LINK_LEXER(lmFreeBasic);
 	LINK_LEXER(lmCaml);
 	LINK_LEXER(lmCmake);
 	LINK_LEXER(lmCPP);
@@ -153,6 +152,7 @@
 	LINK_LEXER(lmDiff);
 	LINK_LEXER(lmF77);
 	LINK_LEXER(lmFortran);
+	LINK_LEXER(lmFreeBasic);
 	LINK_LEXER(lmHaskell);
 	LINK_LEXER(lmHTML);
 	LINK_LEXER(lmLatex);

Modified: trunk/scintilla/LexBash.cxx
===================================================================
--- trunk/scintilla/LexBash.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/LexBash.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -334,6 +334,10 @@
 					}
 					char s[HERE_DELIM_MAX];
 					sc.GetCurrent(s, sizeof(s));
+					if (sc.LengthCurrent() == 0)
+						break;
+					if (s[strlen(s) - 1] == '\r')
+						s[strlen(s) - 1] = '\0';
 					if (strcmp(HereDoc.Delimiter, s) == 0) {
 						if ((prefixws > 0 && HereDoc.Indent) ||	// indentation rule
 							(prefixws == 0 && !HereDoc.Indent)) {

Modified: trunk/scintilla/LexCPP.cxx
===================================================================
--- trunk/scintilla/LexCPP.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/LexCPP.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -58,6 +58,9 @@
 	WordList &keywords3 = *keywordlists[2];
 	WordList &keywords4 = *keywordlists[3];
 
+	// property styling.within.preprocessor
+	//	For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) 
+	//	or only from the initial # to the end of the command word(1). 
 	bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
 
 	CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
@@ -67,6 +70,9 @@
 
 	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
 	CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+	// property lexer.cpp.allow.dollars
+	//	Set to 0 to disallow the '$' character in identifiers with the cpp lexer. 
 	if (styler.GetPropertyInt("lexer.cpp.allow.dollars", 1) != 0) {
 		setWordStart.Add('$');
 		setWord.Add('$');
@@ -77,6 +83,7 @@
 	bool lastWordWasUUID = false;
 	int styleBeforeDCKeyword = SCE_C_DEFAULT;
 	bool continuationLine = false;
+	bool isIncludePreprocessor = false;
 
 	if (initStyle == SCE_C_PREPROCESSOR) {
 		// Set continuationLine if last character of previous line is '\'
@@ -118,6 +125,7 @@
 			// if different sets of lines lexed.
 			visibleChars = 0;
 			lastWordWasUUID = false;
+			isIncludePreprocessor = false;
 		}
 
 		// Handle line continuation generically.
@@ -230,6 +238,11 @@
 			case SCE_C_STRING:
 				if (sc.atLineEnd) {
 					sc.ChangeState(SCE_C_STRINGEOL);
+				} else if (isIncludePreprocessor) {
+					if (sc.ch == '>') {
+						sc.ForwardSetState(SCE_C_DEFAULT);
+						isIncludePreprocessor = false;
+					}
 				} else if (sc.ch == '\\') {
 					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 						sc.Forward();
@@ -321,6 +334,9 @@
 				sc.SetState(SCE_C_REGEX);	// JavaScript's RegEx
 			} else if (sc.ch == '\"') {
 				sc.SetState(SCE_C_STRING);
+				isIncludePreprocessor = false;	// ensure that '>' won't end the string
+			} else if (isIncludePreprocessor && sc.ch == '<') {
+				sc.SetState(SCE_C_STRING);
 			} else if (sc.ch == '\'') {
 				sc.SetState(SCE_C_CHARACTER);
 			} else if (sc.ch == '#' && visibleChars == 0) {
@@ -332,6 +348,8 @@
 				} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
 				if (sc.atLineEnd) {
 					sc.SetState(SCE_C_DEFAULT);
+				} else if (sc.Match("include")) {
+					isIncludePreprocessor = true;
 				}
 			} else if (isoperator(static_cast<char>(sc.ch))) {
 				sc.SetState(SCE_C_OPERATOR);
@@ -359,10 +377,24 @@
 // and to make it possible to fiddle the current level for "} else {".
 static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
 					   WordList *[], Accessor &styler) {
+
+	// property fold.comment
+	//	This option enables folding multi-line comments and explicit fold points when using the C++ lexer. 
+	//	Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} 
+	//	at the end of a section that should fold. 
 	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+
+	// property fold.preprocessor
+	//	This option enables folding preprocessor directives when using the C++ lexer. 
+	//	Includes C#'s explicit #region and #endregion folding directives. 
 	bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+
 	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+	// property fold.at.else 
+	//	This option enables C++ folding on a "} else {" line of an if statement. 
 	bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+
 	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
 	int lineCurrent = styler.GetLine(startPos);

Modified: trunk/scintilla/LexD.cxx
===================================================================
--- trunk/scintilla/LexD.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/LexD.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -268,6 +268,9 @@
 static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) {
     bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
     bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+    // property lexer.d.fold.at.else 
+    //	This option enables D folding on a "} else {" line of an if statement. 
     bool foldAtElse = styler.GetPropertyInt("lexer.d.fold.at.else",
 		styler.GetPropertyInt("fold.at.else", 0)) != 0;
     unsigned int endPos = startPos + length;

Modified: trunk/scintilla/LexFortran.cxx
===================================================================
--- trunk/scintilla/LexFortran.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/LexFortran.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -83,7 +83,7 @@
 		// Handle the fix format generically
 		int toLineStart = sc.currentPos - posLineStart;
 		if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
-			if (toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*') || sc.ch == '!') {
+			if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') {
                 if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") ||
                     sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") ||
                     sc.MatchIgnoreCase("cms$")  || sc.MatchIgnoreCase("*ms$")  || sc.MatchIgnoreCase("!ms$")  ||
@@ -252,7 +252,7 @@
 				lev = 0;
 			else
 				lev = 1;
-	} else if (strcmp(s, "end") == 0 && chNextNonBlank != '='
+	} else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=')
 		|| strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
 		|| strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
 		|| strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0

Modified: trunk/scintilla/LexHTML.cxx
===================================================================
--- trunk/scintilla/LexHTML.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/LexHTML.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -274,17 +274,30 @@
 	s[i] = '\0';
 
 	// No keywords -> all are known
-	// Name of a closing tag starts at s + 1
 	char chAttr = SCE_H_TAGUNKNOWN;
 	if (s[0] == '!') {
 		chAttr = SCE_H_SGML_DEFAULT;
-	} else if (!keywords || keywords.InList(s[0] == '/' ? s + 1 : s)) {
+	} else if (!keywords || keywords.InList(s)) {
 		chAttr = SCE_H_TAG;
 	}
 	styler.ColourTo(end, chAttr);
 	if (chAttr == SCE_H_TAG) {
 		if (allowScripts && 0 == strcmp(s, "script")) {
-			chAttr = SCE_H_SCRIPT;
+			// check to see if this is a self-closing tag by sniffing ahead
+			bool isSelfClose = false;
+			for (unsigned int cPos = end; cPos <= end + 100; cPos++) {
+				char ch = styler.SafeGetCharAt(cPos, '\0');
+				if (ch == '\0' || ch == '>')
+					break;
+				else if (ch == '/' && styler.SafeGetCharAt(cPos + 1, '\0') == '>') {
+					isSelfClose = true;
+					break;
+				}
+			}
+
+			// do not enter a script state if the tag self-closed
+			if (!isSelfClose)
+				chAttr = SCE_H_SCRIPT;
 		} else if (!isXml && 0 == strcmp(s, "comment")) {
 			chAttr = SCE_H_COMMENT;
 		}
@@ -561,6 +574,10 @@
 	} else {
 		// Default client and ASP scripting language is JavaScript
 		lineState = eScriptJS << 8;
+
+		// property asp.default.language 
+		//	Script in ASP code is initially assumed to be in JavaScript. 
+		//	To change this to VBScript set asp.default.language to 2. Python is 3.
 		lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4;
 	}
 	script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode
@@ -577,13 +594,37 @@
 		scriptLanguage = eScriptComment;
 	}
 
+	// property fold.html 
+	//	Folding is turned on or off for HTML and XML files with this option. 
+	//	The fold option must also be on for folding to occur.
 	const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
+
 	const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
+
+	// property fold.html.preprocessor 
+	//	Folding is turned on or off for scripts embedded in HTML files with this option. 
+	//	The default is on.
 	const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
+
 	const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+	// property fold.hypertext.comment 
+	//	Allow folding for comments in scripts embedded in HTML. 
+	//	The default is off. 
 	const bool foldComment = fold && styler.GetPropertyInt("fold.hypertext.comment", 0) != 0;
+
+	// property fold.hypertext.heredoc 
+	//	Allow folding for heredocs in scripts embedded in HTML. 
+	//	The default is off.  
 	const bool foldHeredoc = fold && styler.GetPropertyInt("fold.hypertext.heredoc", 0) != 0;
+
+	// property html.tags.case.sensitive 
+	//	For XML and HTML, setting this property to 1 will make tags match in a case 
+	//	sensitive way which is the expected behaviour for XML and XHTML. 
 	const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
+
+	// property lexer.xml.allow.scripts 
+	//	Set to 0 to disable scripts in XML.  
 	const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
 
 	const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);

Modified: trunk/scintilla/LexOthers.cxx
===================================================================
--- trunk/scintilla/LexOthers.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/LexOthers.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -694,6 +694,11 @@
 	styler.StartSegment(startPos);
 	unsigned int linePos = 0;
 	unsigned int startLine = startPos;
+
+	// property lexer.props.allow.initial.spaces 
+	//	For properties files, set to 0 to style all lines that start with whitespace in the default style. 
+	//	This is not suitable for SciTE .properties files which use indentation for flow control but 
+	//	can be used for RFC2822 text where indentation is used for continuation lines. 
 	bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0;
 
 	for (unsigned int i = startPos; i < startPos + length; i++) {
@@ -782,7 +787,7 @@
 		lev = SC_FOLDLEVELBASE;
 	}
 	int flagsNext = styler.LevelAt(lineCurrent);
-	styler.SetLevel(lineCurrent, lev | flagsNext & ~SC_FOLDLEVELNUMBERMASK);
+	styler.SetLevel(lineCurrent, lev | (flagsNext & ~SC_FOLDLEVELNUMBERMASK));
 }
 
 static void ColouriseMakeLine(
@@ -1097,6 +1102,12 @@
 	styler.StartAt(startPos);
 	styler.StartSegment(startPos);
 	unsigned int linePos = 0;
+
+	// property lexer.errorlist.value.separate 
+	//	For lines in the output pane that are matches from Find in Files or GCC-style 
+	//	diagnostics, style the path and line number separately from the rest of the 
+	//	line with style 21 used for the rest of the line. 
+	//	This allows matched text to be more easily distinguished from its location. 
 	bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0;
 	for (unsigned int i = startPos; i < startPos + length; i++) {
 		lineBuffer[linePos++] = styler[i];

Modified: trunk/scintilla/LexPascal.cxx
===================================================================
--- trunk/scintilla/LexPascal.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/LexPascal.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -4,8 +4,109 @@
  ** Written by Laurent le Tynevez
  ** Updated by Simon Steele <s.steele at pnotepad.org> September 2002
  ** Updated by Mathias Rauen <scite at madshi.net> May 2003 (Delphi adjustments)
+ ** Completely rewritten by Marko Njezic <sf at maxempire.com> October 2008
  **/
 
+/*
+
+A few words about features of the new completely rewritten LexPascal...
+
+Generally speaking LexPascal tries to support all available Delphi features (up 
+to Delphi 2009 at this time), including .NET specific features.
+
+~ HIGHLIGHTING:
+
+If you enable "lexer.pascal.smart.highlighting" property, some keywords will 
+only be highlighted in appropriate context. As implemented those are keywords 
+related to property and DLL exports declarations (similar to how Delphi IDE 
+works). 
+
+For example, keywords "read" and "write" will only be highlighted if they are in 
+property declaration:
+
+property MyProperty: boolean read FMyProperty write FMyProperty; 
+
+~ FOLDING:
+
+Folding is supported in the following cases:
+
+- Folding of stream-like comments
+- Folding of groups of consecutive line comments
+- Folding of preprocessor blocks (the following preprocessor blocks are 
+supported: IF / IFEND; IFDEF, IFNDEF, IFOPT / ENDIF and REGION / ENDREGION 
+blocks), including nesting of preprocessor blocks up to 255 levels
+- Folding of code blocks on appropriate keywords (the following code blocks are 
+supported: "begin, asm, record, try, case / end" blocks, class & object 
+declarations and interface declarations)
+
+Remarks:
+
+- Folding of code blocks tries to handle all special cases in which folding 
+should not occur. As implemented those are:
+
+1. Structure "record case / end" (there's only one "end" statement and "case" is 
+ignored as fold point)
+2. Forward class declarations ("type TMyClass = class;") and object method 
+declarations ("TNotifyEvent = procedure(Sender: TObject) of object;") are 
+ignored as fold points
+3. Simplified complete class declarations ("type TMyClass = class(TObject);") 
+are ignored as fold points
+4. Every other situation when class keyword doesn't actually start class 
+declaration ("class procedure", "class function", "class of", "class var", 
+"class property" and "class operator")
+
+- Folding of code blocks inside preprocessor blocks is disabled (any comments 
+inside them will be folded fine) because there is no guarantee that complete 
+code block will be contained inside folded preprocessor block in which case 
+folded code block could end prematurely at the end of preprocessor block if 
+there is no closing statement inside. This was done in order to properly process 
+document that may contain something like this:
+
+type
+{$IFDEF UNICODE}
+  TMyClass = class(UnicodeAncestor)
+{$ELSE}
+  TMyClass = class(AnsiAncestor)
+{$ENDIF}
+  private
+  ...
+  public
+  ...
+  published
+  ...
+end;
+
+If class declarations were folded, then the second class declaration would end 
+at "$ENDIF" statement, first class statement would end at "end;" statement and 
+preprocessor "$IFDEF" block would go all the way to the end of document. 
+However, having in mind all this, if you want to enable folding of code blocks 
+inside preprocessor blocks, you can disable folding of preprocessor blocks by 
+changing "fold.preprocessor" property, in which case everything inside them 
+would be folded.
+
+~ KEYWORDS:
+
+The list of keywords that can be used in pascal.properties file (up to Delphi 
+2009):
+
+- Keywords: absolute abstract and array as asm assembler automated begin case 
+cdecl class const constructor deprecated destructor dispid dispinterface div do 
+downto dynamic else end except export exports external far file final 
+finalization finally for forward function goto if implementation in inherited 
+initialization inline interface is label library message mod near nil not object 
+of on or out overload override packed pascal platform private procedure program 
+property protected public published raise record register reintroduce repeat 
+resourcestring safecall sealed set shl shr static stdcall strict string then 
+threadvar to try type unit unsafe until uses var varargs virtual while with xor
+
+- Keywords related to the "smart highlithing" feature: add default implements 
+index name nodefault read readonly remove stored write writeonly
+
+- Keywords related to Delphi packages (in addition to all above): package 
+contains requires
+
+*/
+
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -20,12 +121,13 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-static void getRange(unsigned int start,
+static void GetRangeLowered(unsigned int start,
 		unsigned int end,
 		Accessor &styler,
 		char *s,
@@ -38,241 +140,361 @@
 	s[i] = '\0';
 }
 
-static bool IsStreamCommentStyle(int style) {
-	return style == SCE_C_COMMENT ||
-		style == SCE_C_COMMENTDOC ||
-		style == SCE_C_COMMENTDOCKEYWORD ||
-		style == SCE_C_COMMENTDOCKEYWORDERROR;
-}
+static void GetForwardRangeLowered(unsigned int start,
+		CharacterSet &charSet,
+		Accessor &styler,
+		char *s,
+		unsigned int len) {
+	unsigned int i = 0;
+	while ((i < len-1) && charSet.Contains(styler.SafeGetCharAt(start + i))) {
+		s[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i)));
+		i++;
+	}
+	s[i] = '\0';
 
-static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
-	if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
-		styler.ColourTo(end, SCE_C_REGEX);
-	} else
-		styler.ColourTo(end, attr);
 }
 
-// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
-static int classifyWordPascal(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInClass, bool bInAsm) {
-	int ret = 0;
+enum {
+	stateInAsm = 0x1000, 
+	stateInProperty = 0x2000, 
+	stateInExport = 0x4000, 
+	stateFoldInPreprocessor = 0x0100, 
+	stateFoldInRecord = 0x0200, 
+	stateFoldInPreprocessorLevelMask = 0x00FF, 
+	stateFoldMaskAll = 0x0FFF
+};
 
+static void ClassifyPascalWord(WordList *keywordlists[], StyleContext &sc, int &curLineState, bool bSmartHighlighting) {
 	WordList& keywords = *keywordlists[0];
-	WordList& classwords = *keywordlists[1];
 
 	char s[100];
-	getRange(start, end, styler, s, sizeof(s));
+	sc.GetCurrentLowered(s, sizeof(s));
+	if (keywords.InList(s)) {
+		if (curLineState & stateInAsm) {
+			if (strcmp(s, "end") == 0 && sc.GetRelative(-4) != '@') {
+				curLineState &= ~stateInAsm;
+				sc.ChangeState(SCE_PAS_WORD);
+			} else {
+				sc.ChangeState(SCE_PAS_ASM);
+			}
+		} else {
+			bool ignoreKeyword = false;
+			if (strcmp(s, "asm") == 0) {
+				curLineState |= stateInAsm;
+			} else if (bSmartHighlighting) {
+				if (strcmp(s, "property") == 0) {
+					curLineState |= stateInProperty;
+				} else if (strcmp(s, "exports") == 0) {
+					curLineState |= stateInExport;
+				} else if (!(curLineState & (stateInProperty | stateInExport)) && strcmp(s, "index") == 0) {
+					ignoreKeyword = true;
+				} else if (!(curLineState & stateInExport) && strcmp(s, "name") == 0) {
+					ignoreKeyword = true;
+				} else if (!(curLineState & stateInProperty) && 
+					(strcmp(s, "read") == 0 || strcmp(s, "write") == 0 || 
+					 strcmp(s, "default") == 0 || strcmp(s, "nodefault") == 0 || 
+					 strcmp(s, "stored") == 0 || strcmp(s, "implements") == 0 || 
+					 strcmp(s, "readonly") == 0 || strcmp(s, "writeonly") == 0 || 
+					 strcmp(s, "add") == 0 || strcmp(s, "remove") == 0)) {
+					ignoreKeyword = true;
+				}
+			}
+			if (!ignoreKeyword) {
+				sc.ChangeState(SCE_PAS_WORD);
+			}
+		}
+	} else if (curLineState & stateInAsm) {
+		sc.ChangeState(SCE_PAS_ASM);
+	}
+	sc.SetState(SCE_PAS_DEFAULT);
+}
 
-	char chAttr = SCE_C_IDENTIFIER;
-	if (isdigit(s[0]) || (s[0] == '.') ||(s[0] == '$')) {
-		chAttr = SCE_C_NUMBER;
-	}
-	else {
-		if (s[0] == '#') {
-			chAttr = SCE_C_CHARACTER;
+static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+		Accessor &styler) {
+	bool bSmartHighlighting = styler.GetPropertyInt("lexer.pascal.smart.highlighting", 1) != 0;
+
+	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+	CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
+	CharacterSet setNumber(CharacterSet::setDigits, ".-+eE");
+	CharacterSet setHexNumber(CharacterSet::setDigits, "abcdefABCDEF");
+	CharacterSet setOperator(CharacterSet::setNone, "#$&'()*+,-./:;<=>@[]^{}");
+
+	int curLine = styler.GetLine(startPos);
+	int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
+
+	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
+			curLine = styler.GetLine(sc.currentPos);
+			styler.SetLineState(curLine, curLineState);
 		}
-		else {
-			if (keywords.InList(s)) {
-				chAttr = SCE_C_WORD;
 
-				if(strcmp(s, "class") == 0) {
-					ret = 1;
+		// Determine if the current state should terminate.
+		switch (sc.state) {
+			case SCE_PAS_NUMBER:
+				if (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) {
+					sc.SetState(SCE_PAS_DEFAULT);
+				} else if (sc.ch == '-' || sc.ch == '+') {
+					if (sc.chPrev != 'E' && sc.chPrev != 'e') {
+						sc.SetState(SCE_PAS_DEFAULT);
+					}
 				}
-				else if (strcmp(s, "asm") == 0) {
-					ret = 2;
+				break;
+			case SCE_PAS_IDENTIFIER:
+				if (!setWord.Contains(sc.ch)) {
+					ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting);
 				}
-				else if (strcmp(s, "end") == 0) {
-					ret = -1;
+				break;
+			case SCE_PAS_HEXNUMBER:
+				if (!setHexNumber.Contains(sc.ch)) {
+					sc.SetState(SCE_PAS_DEFAULT);
 				}
-			} else if (bInClass) {
-				if (classwords.InList(s)) {
-					chAttr = SCE_C_WORD;
+				break;
+			case SCE_PAS_COMMENT:
+			case SCE_PAS_PREPROCESSOR:
+				if (sc.ch == '}') {
+					sc.ForwardSetState(SCE_PAS_DEFAULT);
 				}
+				break;
+			case SCE_PAS_COMMENT2:
+			case SCE_PAS_PREPROCESSOR2:
+				if (sc.Match('*', ')')) {
+					sc.Forward();
+					sc.ForwardSetState(SCE_PAS_DEFAULT);
+				}
+				break;
+			case SCE_PAS_COMMENTLINE:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_PAS_DEFAULT);
+				}
+				break;
+			case SCE_PAS_STRING:
+				if (sc.atLineEnd) {
+					sc.ChangeState(SCE_PAS_STRINGEOL);
+				} else if (sc.ch == '\'' && sc.chNext == '\'') {
+					sc.Forward();
+				} else if (sc.ch == '\'') {
+					sc.ForwardSetState(SCE_PAS_DEFAULT);
+				}
+				break;
+			case SCE_PAS_STRINGEOL:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_PAS_DEFAULT);
+				}
+				break;
+			case SCE_PAS_CHARACTER:
+				if (!setHexNumber.Contains(sc.ch) && sc.ch != '$') {
+					sc.SetState(SCE_PAS_DEFAULT);
+				}
+				break;
+			case SCE_PAS_OPERATOR:
+				if (bSmartHighlighting && sc.chPrev == ';') {
+					curLineState &= ~(stateInProperty | stateInExport);
+				}
+				sc.SetState(SCE_PAS_DEFAULT);
+				break;
+			case SCE_PAS_ASM:
+				sc.SetState(SCE_PAS_DEFAULT);
+				break;
+		}
+
+		// Determine if a new state should be entered.
+		if (sc.state == SCE_PAS_DEFAULT) {
+			if (IsADigit(sc.ch) && !(curLineState & stateInAsm)) {
+				sc.SetState(SCE_PAS_NUMBER);
+			} else if (setWordStart.Contains(sc.ch)) {
+				sc.SetState(SCE_PAS_IDENTIFIER);
+			} else if (sc.ch == '$' && !(curLineState & stateInAsm)) {
+				sc.SetState(SCE_PAS_HEXNUMBER);
+			} else if (sc.Match('{', '$')) {
+				sc.SetState(SCE_PAS_PREPROCESSOR);
+			} else if (sc.ch == '{') {
+				sc.SetState(SCE_PAS_COMMENT);
+			} else if (sc.Match("(*$")) {
+				sc.SetState(SCE_PAS_PREPROCESSOR2);
+			} else if (sc.Match('(', '*')) {
+				sc.SetState(SCE_PAS_COMMENT2);
+				sc.Forward();	// Eat the * so it isn't used for the end of the comment
+			} else if (sc.Match('/', '/')) {
+				sc.SetState(SCE_PAS_COMMENTLINE);
+			} else if (sc.ch == '\'') {
+				sc.SetState(SCE_PAS_STRING);
+			} else if (sc.ch == '#') {
+				sc.SetState(SCE_PAS_CHARACTER);
+			} else if (setOperator.Contains(sc.ch) && !(curLineState & stateInAsm)) {
+				sc.SetState(SCE_PAS_OPERATOR);
+			} else if (curLineState & stateInAsm) {
+				sc.SetState(SCE_PAS_ASM);
 			}
 		}
 	}
-	ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
-	return ret;
+
+	if (sc.state == SCE_PAS_IDENTIFIER && setWord.Contains(sc.chPrev)) {
+		ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting);
+	}
+
+	sc.Complete();
 }
 
-static int classifyFoldPointPascal(const char* s) {
-	int lev = 0;
-	if (!(isdigit(s[0]) || (s[0] == '.'))) {
-		if (strcmp(s, "begin") == 0 ||
-			strcmp(s, "object") == 0 ||
-			strcmp(s, "case") == 0 ||
-			strcmp(s, "class") == 0 ||
-			strcmp(s, "record") == 0 ||
-			strcmp(s, "try") == 0) {
-			lev=1;
-		} else if (strcmp(s, "end") == 0) {
-			lev=-1;
+static bool IsStreamCommentStyle(int style) {
+	return style == SCE_PAS_COMMENT || style == SCE_PAS_COMMENT2;
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+	int pos = styler.LineStart(line);
+	int eolPos = styler.LineStart(line + 1) - 1;
+	for (int i = pos; i < eolPos; i++) {
+		char ch = styler[i];
+		char chNext = styler.SafeGetCharAt(i + 1);
+		int style = styler.StyleAt(i);
+		if (ch == '/' && chNext == '/' && style == SCE_PAS_COMMENTLINE) {
+			return true;
+		} else if (!IsASpaceOrTab(ch)) {
+			return false;
 		}
 	}
-	return lev;
+	return false;
 }
 
-static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-	Accessor &styler) {
+static unsigned int GetFoldInPreprocessorLevelFlag(int lineFoldStateCurrent) {
+	return lineFoldStateCurrent & stateFoldInPreprocessorLevelMask;
+}
 
-	styler.StartAt(startPos);
+static void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned int nestLevel) {
+	lineFoldStateCurrent &= ~stateFoldInPreprocessorLevelMask;
+	lineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;
+}
 
-	int state = initStyle;
-	if (state == SCE_C_CHARACTER)	// Does not leak onto next line
-		state = SCE_C_DEFAULT;
-	char chPrev = ' ';
-	char chNext = styler[startPos];
-	unsigned int lengthDoc = startPos + length;
+static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent, 
+		unsigned int startPos, Accessor &styler) {
+	CharacterSet setWord(CharacterSet::setAlpha);
 
-	bool bInClassDefinition;
+	char s[11];	// Size of the longest possible keyword + one additional character + null
+	GetForwardRangeLowered(startPos, setWord, styler, s, sizeof(s));
 
-	int currentLine = styler.GetLine(startPos);
-	if (currentLine > 0) {
-		styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
-		bInClassDefinition = (styler.GetLineState(currentLine) == 1);
-	} else {
-		styler.SetLineState(currentLine, 0);
-		bInClassDefinition = false;
-	}
+	unsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);
 
-	bool bInAsm = (state == SCE_C_REGEX);
-	if (bInAsm)
-		state = SCE_C_DEFAULT;
-
-	styler.StartSegment(startPos);
-	for (unsigned int i = startPos; i < lengthDoc; i++) {
-		char ch = chNext;
-
-		chNext = styler.SafeGetCharAt(i + 1);
-
-		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
-			// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
-			// Avoid triggering two times on Dos/Win
-			// End of line
-			if (state == SCE_C_CHARACTER) {
-				ColourTo(styler, i, state, bInAsm);
-				state = SCE_C_DEFAULT;
-			}
-			currentLine++;
-			styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
+	if (strcmp(s, "if") == 0 || 
+		strcmp(s, "ifdef") == 0 || 
+		strcmp(s, "ifndef") == 0 || 
+		strcmp(s, "ifopt") == 0 || 
+		strcmp(s, "region") == 0) {
+		nestLevel++;
+		SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
+		lineFoldStateCurrent |= stateFoldInPreprocessor;
+		levelCurrent++;
+	} else if (strcmp(s, "endif") == 0 || 
+		strcmp(s, "ifend") == 0 || 
+		strcmp(s, "endregion") == 0) {
+		nestLevel--;
+		SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
+		if (nestLevel == 0) {
+			lineFoldStateCurrent &= ~stateFoldInPreprocessor;
 		}
-
-		if (styler.IsLeadByte(ch)) {
-			chNext = styler.SafeGetCharAt(i + 2);
-			chPrev = ' ';
-			i += 1;
-			continue;
+		levelCurrent--;
+		if (levelCurrent < SC_FOLDLEVELBASE) {
+			levelCurrent = SC_FOLDLEVELBASE;
 		}
+	}
+}
 
-		if (state == SCE_C_DEFAULT) {
-			if (iswordstart(ch) || ch == '#' || ch == '$' || (ch == '@' && bInAsm)) {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_IDENTIFIER;
-			} else if (ch == '{' && chNext != '$' && chNext != '&') {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_COMMENT;
-			} else if (ch == '(' && chNext == '*'
-						&& styler.SafeGetCharAt(i + 2) != '$'
-						&& styler.SafeGetCharAt(i + 2) != '&') {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_COMMENTDOC;
-			} else if (ch == '/' && chNext == '/') {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_COMMENTLINE;
-			} else if (ch == '\'') {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_CHARACTER;
-			} else if (ch == '{' && (chNext == '$' || chNext=='&')) {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_PREPROCESSOR;
-			} else if (isoperator(ch)) {
-				ColourTo(styler, i-1, state, bInAsm);
-				ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos, 
+		Accessor &styler, bool includeChars = false) {
+	CharacterSet setWord(CharacterSet::setAlphaNum, "_");
+	unsigned int j = currentPos + 1;
+	char ch = styler.SafeGetCharAt(j);
+	while ((j < endPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' || 
+		IsStreamCommentStyle(styler.StyleAt(j)) || (includeChars && setWord.Contains(ch)))) {
+		j++;
+		ch = styler.SafeGetCharAt(j);
+	}
+	return j;
+}
 
-			}
-		} else if (state == SCE_C_IDENTIFIER) {
-			bool bDoublePoint = ((ch == '.') && (chPrev == '.'));
-			bool bSinglePoint = (ch == '.');
+static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent, 
+		unsigned int startPos, unsigned int endPos, 
+		unsigned int lastStart, unsigned int currentPos, Accessor &styler) {
+	char s[100];
+	GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
 
-			if ((!iswordchar(ch) && ch != '$' && ch != '#' && (ch != '@' || !bInAsm)) || bDoublePoint || bSinglePoint) {
-				if (bDoublePoint) i--;
-				int lStateChange = classifyWordPascal(styler.GetStartSegment(), i - 1, keywordlists, styler, bInClassDefinition, bInAsm);
+	if (strcmp(s, "record") == 0) {
+		lineFoldStateCurrent |= stateFoldInRecord;
+		levelCurrent++;
+	} else if (strcmp(s, "begin") == 0 || 
+		strcmp(s, "asm") == 0 || 
+		strcmp(s, "try") == 0 || 
+		(strcmp(s, "case") == 0 && !(lineFoldStateCurrent & stateFoldInRecord))) {
+		levelCurrent++;
+	} else if (strcmp(s, "class") == 0 || strcmp(s, "object") == 0) {
+		// "class" & "object" keywords require special handling...
+		bool ignoreKeyword = false;
+		unsigned int j = SkipWhiteSpace(currentPos, endPos, styler);
+		if (j < endPos) {
+			CharacterSet setWordStart(CharacterSet::setAlpha, "_");
+			CharacterSet setWord(CharacterSet::setAlphaNum, "_");
 
-				if(lStateChange == 1) {
-					styler.SetLineState(currentLine, 1);
-					bInClassDefinition = true;
-				} else if(lStateChange == 2) {
-					bInAsm = true;
-				} else if(lStateChange == -1) {
-					styler.SetLineState(currentLine, 0);
-					bInClassDefinition = false;
-					bInAsm = false;
-				}
-				if (bDoublePoint) {
-					i++;
-					ColourTo(styler, i-1, SCE_C_DEFAULT, bInAsm);
-				}
+			if (styler.SafeGetCharAt(j) == ';') {
+				// Handle forward class declarations ("type TMyClass = class;") 
+				// and object method declarations ("TNotifyEvent = procedure(Sender: TObject) of object;")
+				ignoreKeyword = true;
+			} else if (strcmp(s, "class") == 0) {
+				// "class" keyword has a few more special cases...
+				if (styler.SafeGetCharAt(j) == '(') {
+					// Handle simplified complete class declarations ("type TMyClass = class(TObject);") 
+					j = SkipWhiteSpace(j, endPos, styler, true);
+					if (j < endPos && styler.SafeGetCharAt(j) == ')') {
+						j = SkipWhiteSpace(j, endPos, styler);
+						if (j < endPos && styler.SafeGetCharAt(j) == ';') {
+							ignoreKeyword = true;
+						}
+					}
+				} else if (setWordStart.Contains(styler.SafeGetCharAt(j))) {
+					char s2[11];	// Size of the longest possible keyword + one additional character + null
+					GetForwardRangeLowered(j, setWord, styler, s2, sizeof(s2));
 
-				state = SCE_C_DEFAULT;
-				chNext = styler.SafeGetCharAt(i + 1);
-				if (ch == '{' && chNext != '$' && chNext != '&') {
-					state = SCE_C_COMMENT;
-				} else if (ch == '(' && chNext == '*'
-						&& styler.SafeGetCharAt(i + 2) != '$'
-						&& styler.SafeGetCharAt(i + 2) != '&') {
-					ColourTo(styler, i-1, state, bInAsm);
-					state = SCE_C_COMMENTDOC;
-				} else if (ch == '/' && chNext == '/') {
-					state = SCE_C_COMMENTLINE;
-				} else if (ch == '\'') {
-					state = SCE_C_CHARACTER;
-				} else if (isoperator(ch)) {
-					ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
-				}
-			}
-		} else {
-			if (state == SCE_C_PREPROCESSOR) {
-				if (ch=='}'){
-					ColourTo(styler, i, state, bInAsm);
-					state = SCE_C_DEFAULT;
-				} else {
-					if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
-						ColourTo(styler, i-1, state, bInAsm);
-						state = SCE_C_DEFAULT;
+					if (strcmp(s2, "procedure") == 0 || 
+						strcmp(s2, "function") == 0 || 
+						strcmp(s2, "of") == 0 || 
+						strcmp(s2, "var") == 0 || 
+						strcmp(s2, "property") == 0 || 
+						strcmp(s2, "operator") == 0) {
+						ignoreKeyword = true;
 					}
 				}
-			} else if (state == SCE_C_COMMENT) {
-				if (ch == '}' ) {
-					ColourTo(styler, i, state, bInAsm);
-					state = SCE_C_DEFAULT;
-				}
-			} else if (state == SCE_C_COMMENTDOC) {
-				if (ch == ')' && chPrev == '*') {
-					if (((i > styler.GetStartSegment() + 2) || (
-						(initStyle == SCE_C_COMMENTDOC) &&
-						(styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
-							ColourTo(styler, i, state, bInAsm);
-							state = SCE_C_DEFAULT;
-					}
-				}
-			} else if (state == SCE_C_COMMENTLINE) {
-				if (ch == '\r' || ch == '\n') {
-					ColourTo(styler, i-1, state, bInAsm);
-					state = SCE_C_DEFAULT;
-				}
-			} else if (state == SCE_C_CHARACTER) {
-				if (ch == '\'') {
-					ColourTo(styler, i, state, bInAsm);
-					state = SCE_C_DEFAULT;
-				}
 			}
 		}
-		chPrev = ch;
+		if (!ignoreKeyword) {
+			levelCurrent++;
+		}
+	} else if (strcmp(s, "interface") == 0) {
+		// "interface" keyword requires special handling...
+		bool ignoreKeyword = true;
+		unsigned int j = lastStart - 1;
+		char ch = styler.SafeGetCharAt(j);
+		while ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' || 
+			IsStreamCommentStyle(styler.StyleAt(j)))) {
+			j--;
+			ch = styler.SafeGetCharAt(j);
+		}
+		if (j >= startPos && styler.SafeGetCharAt(j) == '=') {
+			ignoreKeyword = false;
+		}
+		if (!ignoreKeyword) {
+			levelCurrent++;
+		}
+	} else if (strcmp(s, "end") == 0) {
+		lineFoldStateCurrent &= ~stateFoldInRecord;
+		levelCurrent--;
+		if (levelCurrent < SC_FOLDLEVELBASE) {
+			levelCurrent = SC_FOLDLEVELBASE;
+		}
 	}
-	ColourTo(styler, lengthDoc - 1, state, bInAsm);
 }
 
 static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, WordList *[],
-                            Accessor &styler) {
+		Accessor &styler) {
 	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 	bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
 	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
@@ -281,11 +503,13 @@
 	int lineCurrent = styler.GetLine(startPos);
 	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 	int levelCurrent = levelPrev;
+	int lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0;
 	char chNext = styler[startPos];
 	int styleNext = styler.StyleAt(startPos);
 	int style = initStyle;
 
 	int lastStart = 0;
+	CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
 
 	for (unsigned int i = startPos; i < endPos; i++) {
 		char ch = chNext;
@@ -295,53 +519,45 @@
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
-		if (stylePrev != SCE_C_WORD && style == SCE_C_WORD)
+		if (foldComment && IsStreamCommentStyle(style)) {
+			if (!IsStreamCommentStyle(stylePrev)) {
+				levelCurrent++;
+			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+				// Comments don't end at end of line and the next character may be unstyled.
+				levelCurrent--;
+			}
+		}
+		if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
 		{
-			// Store last word start point.
-			lastStart = i;
+			if (!IsCommentLine(lineCurrent - 1, styler)
+			    && IsCommentLine(lineCurrent + 1, styler))
+				levelCurrent++;
+			else if (IsCommentLine(lineCurrent - 1, styler)
+			         && !IsCommentLine(lineCurrent+1, styler))
+				levelCurrent--;
 		}
-
-		if (stylePrev == SCE_C_WORD) {
-			if(iswordchar(ch) && !iswordchar(chNext)) {
-				char s[100];
-				getRange(lastStart, i, styler, s, sizeof(s));
-				levelCurrent += classifyFoldPointPascal(s);
+		if (foldPreprocessor) {
+			if (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') {
+				ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler);
+			} else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*' 
+			           && styler.SafeGetCharAt(i + 2) == '$') {
+				ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);
 			}
 		}
 
-		if (foldComment && (style == SCE_C_COMMENTLINE)) {
-			if ((ch == '/') && (chNext == '/')) {
-				char chNext2 = styler.SafeGetCharAt(i + 2);
-				if (chNext2 == '{') {
-					levelCurrent++;
-				} else if (chNext2 == '}') {
-					levelCurrent--;
-				}
-			}
+		if (stylePrev != SCE_PAS_WORD && style == SCE_PAS_WORD)
+		{
+			// Store last word start point.
+			lastStart = i;
 		}
-
-		if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
-			if (ch == '{' && chNext == '$') {
-				unsigned int j=i+2; // skip {$
-				while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
-					j++;
-				}
-				if (styler.Match(j, "region") || styler.Match(j, "if")) {
-					levelCurrent++;
-				} else if (styler.Match(j, "end")) {
-					levelCurrent--;
-				}
+		if (stylePrev == SCE_PAS_WORD && !(lineFoldStateCurrent & stateFoldInPreprocessor)) {
+			if(setWord.Contains(ch) && !setWord.Contains(chNext)) {
+				ClassifyPascalWordFoldPoint(levelCurrent, lineFoldStateCurrent, startPos, endPos, lastStart, i, styler);
 			}
 		}
 
-		if (foldComment && IsStreamCommentStyle(style)) {
-			if (!IsStreamCommentStyle(stylePrev)) {
-				levelCurrent++;
-			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
-				// Comments don't end at end of line and the next character may be unstyled.
-				levelCurrent--;
-			}
-		}
+		if (!IsASpace(ch))
+			visibleChars++;
 
 		if (atEOL) {
 			int lev = levelPrev;
@@ -352,23 +568,24 @@
 			if (lev != styler.LevelAt(lineCurrent)) {
 				styler.SetLevel(lineCurrent, lev);
 			}
+			int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent;
+			styler.SetLineState(lineCurrent, newLineState);
 			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);
+	// If we didn't reach the EOL in previous loop, store line level and whitespace information.
+	// The rest will be filled in later...
+	int lev = levelPrev;
+	if (visibleChars == 0 && foldCompact)
+		lev |= SC_FOLDLEVELWHITEFLAG;
+	styler.SetLevel(lineCurrent, lev);
 }
 
 static const char * const pascalWordListDesc[] = {
 	"Keywords",
-	"Classwords",
 	0
 };
 

Modified: trunk/scintilla/LexPerl.cxx
===================================================================
--- trunk/scintilla/LexPerl.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/LexPerl.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -247,8 +247,9 @@
 static bool isMatch(const char *sref, char *s)
 {
 	// match per-line delimiter - must kill trailing CR if CRLF
-	if (s[strlen(s) - 1] == '\r')
-		s[strlen(s) - 1] = '\0';
+	int i = strlen(s);
+	if (i != 0 && s[i - 1] == '\r')
+		s[i - 1] = '\0';
 	return (strcmp(sref, s) == 0);
 }
 
@@ -569,7 +570,7 @@
 						sc.Forward(ws_skip + 1);
 						HereDoc.Quote = delim_ch;
 						HereDoc.Quoted = true;
-					} else if (ws_skip == 0 && setNonHereDoc.Contains(sc.chNext)
+					} else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext))
 							   || ws_skip > 0) {
 						// left shift << or <<= operator cases
 						// restore position if operator
@@ -1183,8 +1184,15 @@
 	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 	// Custom folding of POD and packages
+
+	// property fold.perl.pod 
+	//	Enable folding Pod blocks when using the Perl lexer. 
 	bool foldPOD = styler.GetPropertyInt("fold.perl.pod", 1) != 0;
+
+	// property fold.perl.package 
+	//	Enable folding packages when using the Perl lexer. 
 	bool foldPackage = styler.GetPropertyInt("fold.perl.package", 1) != 0;
+
 	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
 	int lineCurrent = styler.GetLine(startPos);

Modified: trunk/scintilla/LexPython.cxx
===================================================================
--- trunk/scintilla/LexPython.cxx	2009-05-02 19:12:15 UTC (rev 3768)
+++ trunk/scintilla/LexPython.cxx	2009-05-03 17:49:33 UTC (rev 3769)
@@ -24,17 +24,27 @@
 using namespace Scintilla;
 #endif
 
-enum kwType { kwOther, kwClass, kwDef, kwImport };
+/* kwCDef, kwCTypeName only used for Cython */
+enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName };
+
 static const int indicatorWhitespace = 1;
 
 static bool IsPyComment(Accessor &styler, int pos, int len) {
 	return len > 0 && styler[pos] == '#';
 }
 
-static bool IsPyStringStart(int ch, int chNext, int chNext2) {
+enum literalsAllowed { litNone=0, litU=1, litB=2};
+
+static bool IsPyStringTypeChar(int ch, literalsAllowed allowed) {
+	return 
+		((allowed & litB) && (ch == 'b' || ch == 'B')) ||
+		((allowed & litU) && (ch == 'u' || ch == 'U'));
+}
+
+static bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) {
 	if (ch == '\'' || ch == '"')
 		return true;
-	if (ch == 'u' || ch == 'U') {
+	if (IsPyStringTypeChar(ch, allowed)) {
 		if (chNext == '"' || chNext == '\'')
 			return true;
 		if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\''))
@@ -47,16 +57,16 @@
 }
 
 /* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
-static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex) {
+static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex, literalsAllowed allowed) {
 	char ch = styler.SafeGetCharAt(i);
 	char chNext = styler.SafeGetCharAt(i + 1);
 
-	// Advance beyond r, u, or ur prefix, but bail if there are any unexpected chars
+	// Advance beyond r, u, or ur prefix (or r, b, or br in Python 3.0), but bail if there are any unexpected chars
 	if (ch == 'r' || ch == 'R') {
 		i++;
 		ch = styler.SafeGetCharAt(i);
 		chNext = styler.SafeGetCharAt(i + 1);
-	} else if (ch == 'u' || ch == 'U') {
+	} else if (IsPyStringTypeChar(ch, allowed)) {
 		if (chNext == 'r' || chNext == 'R')
 			i += 2;
 		else
@@ -96,7 +106,7 @@
 }
 
 static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
-                           WordList *keywordlists[], Accessor &styler) {
+        WordList *keywordlists[], Accessor &styler) {
 
 	int endPos = startPos + length;
 
@@ -105,19 +115,49 @@
 	if (startPos > 0) {
 		if (lineCurrent > 0) {
 			lineCurrent--;
+			// Look for backslash-continued lines
+			while (lineCurrent > 0) {
+				int eolPos = styler.LineStart(lineCurrent) - 1;
+				int eolStyle = styler.StyleAt(eolPos);
+				if (eolStyle == SCE_P_STRING
+				    || eolStyle == SCE_P_CHARACTER
+				    || eolStyle == SCE_P_STRINGEOL) {
+					lineCurrent -= 1;
+				} else {
+					break;
+				}
+			}
 			startPos = styler.LineStart(lineCurrent);
-			if (startPos == 0)
-				initStyle = SCE_P_DEFAULT;
-			else
-				initStyle = styler.StyleAt(startPos - 1);
 		}
+		initStyle = startPos == 0 ? SCE_P_DEFAULT : styler.StyleAt(startPos - 1);
 	}
 
 	WordList &keywords = *keywordlists[0];
 	WordList &keywords2 = *keywordlists[1];
 
+	// property tab.timmy.whinge.level
+	//	For Python code, checks whether indenting is consistent. 
+	//	The default, 0 turns off indentation checking, 
+	//	1 checks whether each line is potentially inconsistent with the previous line, 
+	//	2 checks whether any space characters occur before a tab character in the indentation, 
+	//	3 checks whether any spaces are in the indentation, and 
+	//	4 checks for any tab characters in the indentation.
+	//	1 is a good level to use. 
 	const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
 
+	// property lexer.python.literals.binary
+	//	Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.
+	bool base2or8Literals = styler.GetPropertyInt("lexer.python.literals.binary", 1) != 0;
+
+	// property lexer.python.strings.u
+	//	Set to 0 to not recognise Python Unicode literals u"x" as used before Python 3.
+	literalsAllowed allowedLiterals = (styler.GetPropertyInt("lexer.python.strings.u", 1)) ? litU : litNone;
+
+	// property lexer.python.strings.b
+	//	Set to 0 to not recognise Python 3 bytes literals b"x".
+	if (styler.GetPropertyInt("lexer.python.strings.b", 1))
+		allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB);
+
 	initStyle = initStyle & 31;
 	if (initStyle == SCE_P_STRINGEOL) {
 		initStyle = SCE_P_DEFAULT;
@@ -126,12 +166,13 @@
 	kwType kwLast = kwOther;
 	int spaceFlags = 0;
 	styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
-	bool hexadecimal = false;
+	bool base_n_number = false;
 
 	StyleContext sc(startPos, endPos - startPos, initStyle, styler);
 
 	bool indentGood = true;
 	int startIndicator = sc.currentPos;
+	bool inContinuedString = false;
 
 	for (; sc.More(); sc.Forward()) {
 
@@ -163,8 +204,12 @@
 			}
 			lineCurrent++;
 			if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
-				sc.ChangeState(SCE_P_STRINGEOL);
-				sc.ForwardSetState(SCE_P_DEFAULT);
+				if (inContinuedString) {
+					inContinuedString = false;
+				} else {
+					sc.ChangeState(SCE_P_STRINGEOL);
+					sc.ForwardSetState(SCE_P_DEFAULT);
+				}
 			}
 			if (!sc.More())
 				break;
@@ -178,7 +223,7 @@
 			sc.SetState(SCE_P_DEFAULT);
 		} else if (sc.state == SCE_P_NUMBER) {
 			if (!IsAWordChar(sc.ch) &&
-			        !(!hexadecimal && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+			        !(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
 				sc.SetState(SCE_P_DEFAULT);
 			}
 		} else if (sc.state == SCE_P_IDENTIFIER) {
@@ -194,6 +239,23 @@
 					style = SCE_P_CLASSNAME;
 				} else if (kwLast == kwDef) {
 					style = SCE_P_DEFNAME;
+				} else if (kwLast == kwCDef) {
+					int pos = sc.currentPos;
+					unsigned char ch = styler.SafeGetCharAt(pos, '\0');
+					while (ch != '\0') {
+						if (ch == '(') {
+							style = SCE_P_DEFNAME;
+							break;
+						} else if (ch == ':') {
+							style = SCE_P_CLASSNAME;
+							break;
+						} else if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
+							pos++;
+							ch = styler.SafeGetCharAt(pos, '\0');
+						} else {
+							break;
+						}
+					}
 				} else if (keywords2.InList(s)) {
 					style = SCE_P_WORD2;
 				}
@@ -206,9 +268,13 @@
 						kwLast = kwDef;
 					else if (0 == strcmp(s, "import"))
 						kwLast = kwImport;
-					else
+					else if (0 == strcmp(s, "cdef"))
+						kwLast = kwCDef;
+					else if (0 == strcmp(s, "cimport"))
+						kwLast = kwImport;
+					else if (kwLast != kwCDef)
 						kwLast = kwOther;
-				} else {
+				} else if (kwLast != kwCDef) {
 					kwLast = kwOther;
 				}
 			}
@@ -225,7 +291,12 @@
 				if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
 					sc.Forward();
 				}
-				sc.Forward();
+				if (sc.chNext == '\n' || sc.chNext == '\r') {

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list