SF.net SVN: geany:[5682] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Sun Apr 3 16:16:53 UTC 2011


Revision: 5682
          http://geany.svn.sourceforge.net/geany/?rev=5682&view=rev
Author:   eht16
Date:     2011-04-03 16:16:52 +0000 (Sun, 03 Apr 2011)

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

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/scintilla/Makefile.am
    trunk/scintilla/gtk/PlatGTK.cxx
    trunk/scintilla/gtk/ScintillaGTK.cxx
    trunk/scintilla/gtk/scintilla-marshal.c
    trunk/scintilla/include/Platform.h
    trunk/scintilla/include/SciLexer.h
    trunk/scintilla/include/Scintilla.h
    trunk/scintilla/include/Scintilla.iface
    trunk/scintilla/lexers/LexAda.cxx
    trunk/scintilla/lexers/LexAsm.cxx
    trunk/scintilla/lexers/LexBash.cxx
    trunk/scintilla/lexers/LexCOBOL.cxx
    trunk/scintilla/lexers/LexCPP.cxx
    trunk/scintilla/lexers/LexCSS.cxx
    trunk/scintilla/lexers/LexCmake.cxx
    trunk/scintilla/lexers/LexD.cxx
    trunk/scintilla/lexers/LexErlang.cxx
    trunk/scintilla/lexers/LexForth.cxx
    trunk/scintilla/lexers/LexFortran.cxx
    trunk/scintilla/lexers/LexHTML.cxx
    trunk/scintilla/lexers/LexLisp.cxx
    trunk/scintilla/lexers/LexLua.cxx
    trunk/scintilla/lexers/LexMarkdown.cxx
    trunk/scintilla/lexers/LexMatlab.cxx
    trunk/scintilla/lexers/LexNsis.cxx
    trunk/scintilla/lexers/LexOthers.cxx
    trunk/scintilla/lexers/LexPascal.cxx
    trunk/scintilla/lexers/LexPerl.cxx
    trunk/scintilla/lexers/LexPython.cxx
    trunk/scintilla/lexers/LexR.cxx
    trunk/scintilla/lexers/LexSQL.cxx
    trunk/scintilla/lexers/LexTCL.cxx
    trunk/scintilla/lexers/LexTxt2tags.cxx
    trunk/scintilla/lexers/LexVHDL.cxx
    trunk/scintilla/lexers/LexVerilog.cxx
    trunk/scintilla/lexers/LexYAML.cxx
    trunk/scintilla/lexlib/CharacterSet.h
    trunk/scintilla/lexlib/LexerBase.h
    trunk/scintilla/lexlib/OptionSet.h
    trunk/scintilla/lexlib/WordList.cxx
    trunk/scintilla/scintilla_changes.patch
    trunk/scintilla/src/AutoComplete.cxx
    trunk/scintilla/src/CallTip.cxx
    trunk/scintilla/src/Document.cxx
    trunk/scintilla/src/Document.h
    trunk/scintilla/src/Editor.cxx
    trunk/scintilla/src/Editor.h
    trunk/scintilla/src/ExternalLexer.cxx
    trunk/scintilla/src/ExternalLexer.h
    trunk/scintilla/src/Partitioning.h
    trunk/scintilla/src/PositionCache.cxx
    trunk/scintilla/src/RunStyles.cxx
    trunk/scintilla/src/Selection.cxx
    trunk/scintilla/src/Selection.h
    trunk/scintilla/src/SplitVector.h
    trunk/scintilla/src/ViewStyle.cxx
    trunk/scintilla/src/ViewStyle.h

Added Paths:
-----------
    trunk/scintilla/lexlib/SparseState.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/ChangeLog	2011-04-03 16:16:52 UTC (rev 5682)
@@ -1,3 +1,9 @@
+2011-04-03  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
+
+ * scintilla/*:
+   Update Scintilla to version 2.25.
+
+
 2011-04-03  Colomban Wendling  <colomban(at)geany(dot)org>
 
  * src/main.c, src/prefs.c, src/tools.c:

Modified: trunk/scintilla/Makefile.am
===================================================================
--- trunk/scintilla/Makefile.am	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/Makefile.am	2011-04-03 16:16:52 UTC (rev 5682)
@@ -61,6 +61,7 @@
 lexlib/OptionSet.h \
 lexlib/PropSetSimple.cxx \
 lexlib/PropSetSimple.h \
+lexlib/SparseState.h \
 lexlib/StyleContext.cxx \
 lexlib/StyleContext.h \
 lexlib/WordList.cxx \

Modified: trunk/scintilla/gtk/PlatGTK.cxx
===================================================================
--- trunk/scintilla/gtk/PlatGTK.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/gtk/PlatGTK.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
+#include <math.h>
 
 #include <glib.h>
 #include <gmodule.h>
@@ -39,6 +40,14 @@
 #define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w))
 #endif
 
+#if GTK_CHECK_VERSION(2,22,0)
+#define USE_CAIRO 1
+#endif
+
+#ifdef USE_CAIRO
+#define DISABLE_GDK_FONT 1
+#endif
+
 #ifdef _MSC_VER
 // Ignore unreferenced local functions in GTK+ headers
 #pragma warning(disable: 4505)
@@ -688,9 +697,14 @@
 #endif
 class SurfaceImpl : public Surface {
 	encodingType et;
+#ifdef USE_CAIRO
+	cairo_t *context;
+	cairo_surface_t *psurf;
+#else
 	GdkDrawable *drawable;
 	GdkGC *gc;
 	GdkPixmap *ppixmap;
+#endif
 	int x;
 	int y;
 	bool inited;
@@ -806,7 +820,15 @@
 	}
 }
 
-SurfaceImpl::SurfaceImpl() : et(singleByte), drawable(0), gc(0), ppixmap(0),
+SurfaceImpl::SurfaceImpl() : et(singleByte),
+#ifdef USE_CAIRO
+context(0),
+psurf(0),
+#else
+drawable(0),
+gc(0),
+ppixmap(0),
+#endif
 x(0), y(0), inited(false), createdGC(false)
 , pcontext(0), layout(0), characterSet(-1) {
 }
@@ -817,15 +839,28 @@
 
 void SurfaceImpl::Release() {
 	et = singleByte;
+#ifndef USE_CAIRO
 	drawable = 0;
+#endif
 	if (createdGC) {
 		createdGC = false;
+#ifdef USE_CAIRO
+		cairo_destroy(context);
+#else
 		g_object_unref(gc);
+#endif
 	}
+#ifdef USE_CAIRO
+	context = 0;
+	if (psurf)
+		cairo_surface_destroy(psurf);
+	psurf = 0;
+#else
 	gc = 0;
 	if (ppixmap)
 		g_object_unref(ppixmap);
 	ppixmap = 0;
+#endif
 	if (layout)
 		g_object_unref(layout);
 	layout = 0;
@@ -847,10 +882,28 @@
 void SurfaceImpl::Init(WindowID wid) {
 	Release();
 	PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+	GdkDrawable *drawable_ = GDK_DRAWABLE(PWidget(wid)->window);
+	if (drawable_) {
+		context = gdk_cairo_create(drawable_);
+		PLATFORM_ASSERT(context);
+	} else {
+		// Shouldn't happen with valid window but may when calls made before
+		// window completely allocated and mapped.
+		psurf = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 1, 1);
+		context = cairo_create(psurf);
+	}
+	createdGC = true;
+	pcontext = pango_cairo_create_context(context);
+	PLATFORM_ASSERT(pcontext);
+	layout = pango_cairo_create_layout(context);
+	PLATFORM_ASSERT(layout);
+#else
 	pcontext = gtk_widget_create_pango_context(PWidget(wid));
 	PLATFORM_ASSERT(pcontext);
 	layout = pango_layout_new(pcontext);
 	PLATFORM_ASSERT(layout);
+#endif
 	inited = true;
 }
 
@@ -859,12 +912,27 @@
 	GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid);
 	Release();
 	PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+	context = gdk_cairo_create(drawable_);
+#else
+	gc = gdk_gc_new(drawable_);
+#endif
+#ifdef USE_CAIRO
+	pcontext = pango_cairo_create_context(context);
+	PLATFORM_ASSERT(pcontext);
+	layout = pango_cairo_create_layout(context);
+	PLATFORM_ASSERT(layout);
+#else
 	pcontext = gtk_widget_create_pango_context(PWidget(wid));
 	layout = pango_layout_new(pcontext);
 	drawable = drawable_;
-	gc = gdk_gc_new(drawable_);
+#endif
+#ifdef USE_CAIRO
+	cairo_set_line_width(context, 1);
+#else
 	// Ask for lines that do not paint the last pixel so is like Win32
 	gdk_gc_set_line_attributes(gc, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+#endif
 	createdGC = true;
 	inited = true;
 }
@@ -873,8 +941,23 @@
 	PLATFORM_ASSERT(surface_);
 	Release();
 	SurfaceImpl *surfImpl = static_cast<SurfaceImpl *>(surface_);
+	PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+	context = cairo_reference(surfImpl->context);
+#else
 	PLATFORM_ASSERT(surfImpl->drawable);
-	PLATFORM_ASSERT(wid);
+	gc = gdk_gc_new(surfImpl->drawable);
+#endif
+#ifdef USE_CAIRO
+	pcontext = pango_cairo_create_context(context);
+	PLATFORM_ASSERT(pcontext);
+	layout = pango_cairo_create_layout(context);
+	PLATFORM_ASSERT(layout);
+	if (height > 0 && width > 0)
+		psurf = gdk_window_create_similar_surface(
+			gtk_widget_get_window(PWidget(wid)),
+			CAIRO_CONTENT_COLOR_ALPHA, width, height);
+#else
 	pcontext = gtk_widget_create_pango_context(PWidget(wid));
 	PLATFORM_ASSERT(pcontext);
 	layout = pango_layout_new(pcontext);
@@ -882,19 +965,42 @@
 	if (height > 0 && width > 0)
 		ppixmap = gdk_pixmap_new(surfImpl->drawable, width, height, -1);
 	drawable = ppixmap;
-	gc = gdk_gc_new(surfImpl->drawable);
+#endif
+#ifdef USE_CAIRO
+	cairo_destroy(context);
+	context = cairo_create(psurf);
+	cairo_rectangle(context, 0, 0, width, height);
+	cairo_set_source_rgb(context, 1.0, 0, 0);
+	cairo_fill(context);
+	// This produces sharp drawing more similar to GDK:
+	//cairo_set_antialias(context, CAIRO_ANTIALIAS_NONE);
+#endif
+#ifdef USE_CAIRO
+	cairo_set_line_width(context, 1);
+#else
 	// Ask for lines that do not paint the last pixel so is like Win32
 	gdk_gc_set_line_attributes(gc, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+#endif
 	createdGC = true;
 	inited = true;
 }
 
 void SurfaceImpl::PenColour(ColourAllocated fore) {
+#ifdef USE_CAIRO
+	if (context) {
+		ColourDesired cdFore(fore.AsLong());
+		cairo_set_source_rgb(context,
+			cdFore.GetBlue() / 255.0,
+			cdFore.GetGreen() / 255.0,
+			cdFore.GetRed() / 255.0);
+	}
+#else
 	if (gc) {
 		GdkColor co;
 		co.pixel = fore.AsLong();
 		gdk_gc_set_foreground(gc, &co);
 	}
+#endif
 }
 
 int SurfaceImpl::LogPixelsY() {
@@ -911,18 +1017,71 @@
 	y = y_;
 }
 
+#ifdef USE_CAIRO
+static int Delta(int difference) {
+	if (difference < 0)
+		return -1;
+	else if (difference > 0)
+		return 1;
+	else
+		return 0;
+}
+#endif
+
 void SurfaceImpl::LineTo(int x_, int y_) {
+#ifdef USE_CAIRO
+	// cairo_line_to draws the end position, unlike Win32 or GDK with GDK_CAP_NOT_LAST.
+	// For simple cases, move back one pixel from end.
+	if (context) {
+		int xDiff = x_ - x;
+		int xDelta = Delta(xDiff);
+		int yDiff = y_ - y;
+		int yDelta = Delta(yDiff);
+		if ((xDiff == 0) || (yDiff == 0)) {
+			// Horizontal or vertical lines can be more precisely drawn as a filled rectangle
+			int xEnd = x_ - xDelta;
+			int left = Platform::Minimum(x, xEnd);
+			int width = abs(x - xEnd) + 1;
+			int yEnd = y_ - yDelta;
+			int top = Platform::Minimum(y, yEnd);
+			int height = abs(y - yEnd) + 1;
+			cairo_rectangle(context, left, top, width, height);
+			cairo_fill(context);
+		} else if ((abs(xDiff) == abs(yDiff))) {
+			// 45 degree slope
+			cairo_move_to(context, x + 0.5, y + 0.5);
+			cairo_line_to(context, x_ + 0.5 - xDelta, y_ + 0.5 - yDelta);
+		} else {
+			// Line has a different slope so difficult to avoid last pixel
+			cairo_move_to(context, x + 0.5, y + 0.5);
+			cairo_line_to(context, x_ + 0.5, y_ + 0.5);
+		}
+		cairo_stroke(context);
+	}
+#else
 	if (drawable && gc) {
 		gdk_draw_line(drawable, gc,
 		              x, y,
 		              x_, y_);
 	}
+#endif
 	x = x_;
 	y = y_;
 }
 
 void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore,
                           ColourAllocated back) {
+#ifdef USE_CAIRO
+	PenColour(back);
+	cairo_move_to(context, pts[0].x + 0.5, pts[0].y + 0.5);
+	for (int i = 1;i < npts;i++) {
+		cairo_line_to(context, pts[i].x + 0.5, pts[i].y + 0.5);
+	}
+	cairo_close_path(context);
+	cairo_fill_preserve(context);
+	PenColour(fore);
+	cairo_stroke(context);
+#else
 	GdkPoint gpts[20];
 	if (npts < static_cast<int>((sizeof(gpts) / sizeof(gpts[0])))) {
 		for (int i = 0;i < npts;i++) {
@@ -934,35 +1093,62 @@
 		PenColour(fore);
 		gdk_draw_polygon(drawable, gc, 0, gpts, npts);
 	}
+#endif
 }
 
 void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
+#ifdef USE_CAIRO
+	if (context) {
+#else
 	if (gc && drawable) {
+#endif
+#ifdef USE_CAIRO
+		cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5,
+	                     rc.right - rc.left - 1, rc.bottom - rc.top - 1);
 		PenColour(back);
+		cairo_fill_preserve(context);
+		PenColour(fore);
+		cairo_stroke(context);
+#else
+		PenColour(back);
 		gdk_draw_rectangle(drawable, gc, 1,
 		                   rc.left + 1, rc.top + 1,
 		                   rc.right - rc.left - 2, rc.bottom - rc.top - 2);
-
 		PenColour(fore);
 		// The subtraction of 1 off the width and height here shouldn't be needed but
 		// otherwise a different rectangle is drawn than would be done if the fill parameter == 1
 		gdk_draw_rectangle(drawable, gc, 0,
 		                   rc.left, rc.top,
 		                   rc.right - rc.left - 1, rc.bottom - rc.top - 1);
+#endif
 	}
 }
 
 void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
 	PenColour(back);
+#ifdef USE_CAIRO
+	if (context && (rc.left < maxCoordinate)) {	// Protect against out of range
+		cairo_rectangle(context, rc.left, rc.top,
+	                     rc.right - rc.left, rc.bottom - rc.top);
+		cairo_fill(context);
+	}
+#else
 	if (drawable && (rc.left < maxCoordinate)) {	// Protect against out of range
 		gdk_draw_rectangle(drawable, gc, 1,
 		                   rc.left, rc.top,
 		                   rc.right - rc.left, rc.bottom - rc.top);
 	}
+#endif
 }
 
 void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
-	if (static_cast<SurfaceImpl &>(surfacePattern).drawable) {
+	SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfacePattern);
+#ifdef USE_CAIRO
+	bool canDraw = surfi.psurf;
+#else
+	bool canDraw = surfi.drawable;
+#endif
+	if (canDraw) {
 		// Tile pattern over rectangle
 		// Currently assumes 8x8 pattern
 		int widthPat = 8;
@@ -971,12 +1157,18 @@
 			int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat;
 			for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) {
 				int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat;
+#ifdef USE_CAIRO
+				cairo_set_source_surface(context, surfi.psurf, xTile, yTile);
+				cairo_rectangle(context, xTile, yTile, widthx, heighty);
+				cairo_fill(context);
+#else
 				gdk_draw_drawable(drawable,
 				                gc,
 				                static_cast<SurfaceImpl &>(surfacePattern).drawable,
 				                0, 0,
 				                xTile, yTile,
 				                widthx, heighty);
+#endif
 			}
 		}
 	} else {
@@ -1005,6 +1197,21 @@
 	}
 }
 
+#ifdef USE_CAIRO
+
+static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) {
+	double degrees = M_PI / 180.0;
+
+	cairo_new_sub_path(context);
+	cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees);
+	cairo_arc(context, left + width - radius, top + height - radius, radius, 0 * degrees, 90 * degrees);
+	cairo_arc(context, left + radius, top + height - radius, radius, 90 * degrees, 180 * degrees);
+	cairo_arc(context, left + radius, top + radius, radius, 180 * degrees, 270 * degrees);
+	cairo_close_path(context);
+}
+
+#else
+
 // Plot a point into a guint32 buffer symetrically to all 4 qudrants
 static void AllFour(guint32 *pixels, int stride, int width, int height, int x, int y, guint32 val) {
 	pixels[y*stride+x] = val;
@@ -1013,6 +1220,20 @@
 	pixels[(height-1-y)*stride+width-1-x] = val;
 }
 
+static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
+	union {
+		guint8 pixVal[4];
+		guint32 val;
+	} converter;
+	converter.pixVal[0] = r;
+	converter.pixVal[1] = g;
+	converter.pixVal[2] = b;
+	converter.pixVal[3] = a;
+	return converter.val;
+}
+
+#endif
+
 static unsigned int GetRValue(unsigned int co) {
 	return (co >> 16) & 0xff;
 }
@@ -1025,20 +1246,27 @@
 	return co & 0xff;
 }
 
-static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
-	union {
-		guint8 pixVal[4];
-		guint32 val;
-	} converter;
-	converter.pixVal[0] = r;
-	converter.pixVal[1] = g;
-	converter.pixVal[2] = b;
-	converter.pixVal[3] = a;
-	return converter.val;
-}
-
 void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
 		ColourAllocated outline, int alphaOutline, int flags) {
+#ifdef USE_CAIRO
+	if (context && rc.Width() > 0) {
+		cairo_set_source_rgba(context,
+			GetRValue(fill.AsLong()) / 255.0,
+			GetGValue(fill.AsLong()) / 255.0,
+			GetBValue(fill.AsLong()) / 255.0,
+			alphaFill / 255.0);
+		PathRoundRectangle(context, rc.left + 1.0, rc.top+1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize);
+		cairo_fill(context);
+
+		cairo_set_source_rgba(context,
+			GetRValue(outline.AsLong()) / 255.0,
+			GetGValue(outline.AsLong()) / 255.0,
+			GetBValue(outline.AsLong()) / 255.0,
+			alphaOutline / 255.0);
+		PathRoundRectangle(context, rc.left +0.5, rc.top+0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize);
+		cairo_stroke(context);
+	}
+#else
 	if (gc && drawable && rc.Width() > 0) {
 		int width = rc.Width();
 		int height = rc.Height();
@@ -1078,10 +1306,18 @@
 
 		g_object_unref(pixalpha);
 	}
+#endif
 }
 
 void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
 	PenColour(back);
+#ifdef USE_CAIRO
+	cairo_arc(context, (rc.left + rc.right) / 2 + 0.5, (rc.top + rc.bottom) / 2 + 0.5,
+		Platform::Minimum(rc.Width(), rc.Height()) / 2, 0, 2*M_PI);
+	cairo_fill_preserve(context);
+	PenColour(fore);
+	cairo_stroke(context);
+#else
 	gdk_draw_arc(drawable, gc, 1,
 	             rc.left + 1, rc.top + 1,
 	             rc.right - rc.left - 2, rc.bottom - rc.top - 2,
@@ -1093,16 +1329,30 @@
 	             rc.left, rc.top,
 	             rc.right - rc.left - 1, rc.bottom - rc.top - 1,
 	             0, 32767);
+#endif
 }
 
 void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
-	if (static_cast<SurfaceImpl &>(surfaceSource).drawable) {
+	SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfaceSource);
+#ifdef USE_CAIRO
+	bool canDraw = surfi.psurf;
+#else
+	bool canDraw = surfi.drawable;
+#endif
+	if (canDraw) {
+#ifdef USE_CAIRO
+		cairo_set_source_surface(context, surfi.psurf,
+			rc.left - from.x, rc.top - from.y);
+		cairo_rectangle(context, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
+		cairo_fill(context);
+#else
 		gdk_draw_drawable(drawable,
 		                gc,
 		                static_cast<SurfaceImpl &>(surfaceSource).drawable,
 		                from.x, from.y,
 		                rc.left, rc.top,
 		                rc.right - rc.left, rc.bottom - rc.top);
+#endif
 	}
 }
 
@@ -1232,7 +1482,11 @@
 void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char *s, int len,
                                  ColourAllocated fore) {
 	PenColour(fore);
+#ifdef USE_CAIRO
+	if (context) {
+#else
 	if (gc && drawable) {
+#endif
 		int xText = rc.left;
 		if (PFont(font_)->pfd) {
 			char *utfForm = 0;
@@ -1256,12 +1510,20 @@
 				pango_layout_set_text(layout, utfForm, len);
 			}
 			pango_layout_set_font_description(layout, PFont(font_)->pfd);
+#ifdef USE_CAIRO
+			pango_cairo_update_layout(context, layout);
+#endif
 #ifdef PANGO_VERSION
 			PangoLayoutLine *pll = pango_layout_get_line_readonly(layout,0);
 #else
 			PangoLayoutLine *pll = pango_layout_get_line(layout,0);
 #endif
+#ifdef USE_CAIRO
+			cairo_move_to(context, xText, ybase);
+			pango_cairo_show_layout_line(context, pll);
+#else
 			gdk_draw_layout_line(drawable, gc, xText, ybase, pll);
+#endif
 			if (useGFree) {
 				g_free(utfForm);
 			} else {
@@ -1717,9 +1979,14 @@
 }
 
 void SurfaceImpl::SetClip(PRectangle rc) {
+#ifdef USE_CAIRO
+	cairo_rectangle(context, rc.left, rc.top, rc.right, rc.bottom);
+	cairo_clip(context);
+#else
 	GdkRectangle area = {rc.left, rc.top,
 	                     rc.right - rc.left, rc.bottom - rc.top};
 	gdk_gc_set_clip_rectangle(gc, &area);
+#endif
 }
 
 void SurfaceImpl::FlushCachedState() {}
@@ -1875,7 +2142,6 @@
    gdk window coordinates */
 PRectangle Window::GetMonitorRect(Point pt) {
 	gint x_offset, y_offset;
-	pt = pt;
 
 	gdk_window_get_origin(PWidget(wid)->window, &x_offset, &y_offset);
 
@@ -1894,6 +2160,7 @@
 		return PRectangle(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
 	}
 #else
+	pt = pt;
 	return PRectangle(-x_offset, -y_offset, (-x_offset) + gdk_screen_width(),
 	                  (-y_offset) + gdk_screen_height());
 #endif
@@ -1936,7 +2203,7 @@
 	CallBackAction doubleClickAction;
 	void *doubleClickActionData;
 
-	ListBoxX() : list(0), pixhash(NULL), pixbuf_renderer(0),
+	ListBoxX() : list(0), scroller(0), pixhash(NULL), pixbuf_renderer(0),
 		desiredVisibleRows(5), maxItemCharacters(0),
 		aveCharWidth(1), doubleClickAction(NULL), doubleClickActionData(NULL) {
 	}

Modified: trunk/scintilla/gtk/ScintillaGTK.cxx
===================================================================
--- trunk/scintilla/gtk/ScintillaGTK.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/gtk/ScintillaGTK.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -75,6 +75,10 @@
 #define IS_WIDGET_VISIBLE(w) (GTK_WIDGET_VISIBLE(w))
 #endif
 
+#if GTK_CHECK_VERSION(2,22,0)
+#define USE_CAIRO 1
+#endif
+
 #ifdef _MSC_VER
 // Constant conditional expressions are because of GTK+ headers
 #pragma warning(disable: 4127)
@@ -531,7 +535,6 @@
 
 gint ScintillaGTK::FocusInThis(GtkWidget *widget) {
 	try {
-		GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
 		SetFocusState(true);
 		if (im_context != NULL) {
 			gchar *str = NULL;
@@ -562,7 +565,6 @@
 
 gint ScintillaGTK::FocusOutThis(GtkWidget *widget) {
 	try {
-		GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
 		SetFocusState(false);
 
 		if (PWidget(wPreedit) != NULL)
@@ -1422,7 +1424,7 @@
 
 				UndoGroup ug(pdoc);
 				if (selection_data->selection != GDK_SELECTION_PRIMARY) {
-					ClearSelection();
+					ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH);
 				}
 				SelectionPosition selStart = sel.IsRectangular() ?
 					sel.Rectangular().Start() :
@@ -1983,6 +1985,7 @@
 		PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
 		pango_layout_set_attributes(layout, attrs);
 
+#ifndef USE_CAIRO
 		GdkGC *gc = gdk_gc_new(widget->window);
 		GdkColor color[2] = {   {0, 0x0000, 0x0000, 0x0000},
 			{0, 0xffff, 0xffff, 0xffff}
@@ -1997,8 +2000,8 @@
 		gdk_gc_set_foreground(gc, color);
 		gdk_gc_set_background(gc, color + 1);
 		gdk_draw_layout(widget->window, gc, 0, 0, layout);
-
 		g_object_unref(gc);
+#endif
 		g_free(str);
 		pango_attr_list_unref(attrs);
 		g_object_unref(layout);

Modified: trunk/scintilla/gtk/scintilla-marshal.c
===================================================================
--- trunk/scintilla/gtk/scintilla-marshal.c	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/gtk/scintilla-marshal.c	2011-04-03 16:16:52 UTC (rev 5682)
@@ -35,8 +35,8 @@
 #define g_marshal_value_peek_ulong(v)    (v)->data[0].v_ulong
 #define g_marshal_value_peek_int64(v)    (v)->data[0].v_int64
 #define g_marshal_value_peek_uint64(v)   (v)->data[0].v_uint64
-#define g_marshal_value_peek_enum(v)     (v)->data[0].v_int
-#define g_marshal_value_peek_flags(v)    (v)->data[0].v_uint
+#define g_marshal_value_peek_enum(v)     (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v)    (v)->data[0].v_ulong
 #define g_marshal_value_peek_float(v)    (v)->data[0].v_float
 #define g_marshal_value_peek_double(v)   (v)->data[0].v_double
 #define g_marshal_value_peek_string(v)   (v)->data[0].v_pointer
@@ -50,10 +50,10 @@
 /* NONE:INT,POINTER (scintilla-marshal.list:1) */
 void
 scintilla_marshal_VOID__INT_POINTER (GClosure     *closure,
-                                     GValue       *return_value,
+                                     GValue       *return_value G_GNUC_UNUSED,
                                      guint         n_param_values,
                                      const GValue *param_values,
-                                     gpointer      invocation_hint,
+                                     gpointer      invocation_hint G_GNUC_UNUSED,
                                      gpointer      marshal_data)
 {
   typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer     data1,

Modified: trunk/scintilla/include/Platform.h
===================================================================
--- trunk/scintilla/include/Platform.h	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/include/Platform.h	2011-04-03 16:16:52 UTC (rev 5682)
@@ -255,8 +255,8 @@
 	int allocatedLen;
 #endif
 	// Private so Palette objects can not be copied
-	Palette(const Palette &) {}
-	Palette &operator=(const Palette &) { return *this; }
+	Palette(const Palette &);
+	Palette &operator=(const Palette &);
 public:
 #if PLAT_WIN
 	void *hpal;
@@ -288,8 +288,8 @@
 	int ascent;
 #endif
 	// Private so Font objects can not be copied
-	Font(const Font &) {}
-	Font &operator=(const Font &) { fid=0; return *this; }
+	Font(const Font &);
+	Font &operator=(const Font &);
 public:
 	Font();
 	virtual ~Font();

Modified: trunk/scintilla/include/SciLexer.h
===================================================================
--- trunk/scintilla/include/SciLexer.h	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/include/SciLexer.h	2011-04-03 16:16:52 UTC (rev 5682)
@@ -112,6 +112,8 @@
 #define SCLEX_SML 97
 #define SCLEX_MARKDOWN 98
 #define SCLEX_TXT2TAGS 99
+#define SCLEX_A68K 100
+#define SCLEX_MODULA 101
 #define SCLEX_AUTOMATIC 1000
 #define SCE_P_DEFAULT 0
 #define SCE_P_COMMENTLINE 1
@@ -149,6 +151,8 @@
 #define SCE_C_COMMENTDOCKEYWORD 17
 #define SCE_C_COMMENTDOCKEYWORDERROR 18
 #define SCE_C_GLOBALCLASS 19
+#define SCE_C_STRINGRAW 20
+#define SCE_C_TRIPLEVERBATIM 21
 #define SCE_D_DEFAULT 0
 #define SCE_D_COMMENT 1
 #define SCE_D_COMMENTLINE 2
@@ -601,6 +605,7 @@
 #define SCE_ASM_CHARACTER 12
 #define SCE_ASM_STRINGEOL 13
 #define SCE_ASM_EXTINSTRUCTION 14
+#define SCE_ASM_COMMENTDIRECTIVE 15
 #define SCE_F_DEFAULT 0
 #define SCE_F_COMMENT 1
 #define SCE_F_NUMBER 2
@@ -1415,6 +1420,43 @@
 #define SCE_TXT2TAGS_OPTION 23
 #define SCE_TXT2TAGS_PREPROC 24
 #define SCE_TXT2TAGS_POSTPROC 25
+#define SCE_A68K_DEFAULT 0
+#define SCE_A68K_COMMENT 1
+#define SCE_A68K_NUMBER_DEC 2
+#define SCE_A68K_NUMBER_BIN 3
+#define SCE_A68K_NUMBER_HEX 4
+#define SCE_A68K_STRING1 5
+#define SCE_A68K_OPERATOR 6
+#define SCE_A68K_CPUINSTRUCTION 7
+#define SCE_A68K_EXTINSTRUCTION 8
+#define SCE_A68K_REGISTER 9
+#define SCE_A68K_DIRECTIVE 10
+#define SCE_A68K_MACRO_ARG 11
+#define SCE_A68K_LABEL 12
+#define SCE_A68K_STRING2 13
+#define SCE_A68K_IDENTIFIER 14
+#define SCE_A68K_MACRO_DECLARATION 15
+#define SCE_A68K_COMMENT_WORD 16
+#define SCE_A68K_COMMENT_SPECIAL 17
+#define SCE_A68K_COMMENT_DOXYGEN 18
+#define SCE_MODULA_DEFAULT 0
+#define SCE_MODULA_COMMENT 1
+#define SCE_MODULA_DOXYCOMM 2
+#define SCE_MODULA_DOXYKEY 3
+#define SCE_MODULA_KEYWORD 4
+#define SCE_MODULA_RESERVED 5
+#define SCE_MODULA_NUMBER 6
+#define SCE_MODULA_BASENUM 7
+#define SCE_MODULA_FLOAT 8
+#define SCE_MODULA_STRING 9
+#define SCE_MODULA_STRSPEC 10
+#define SCE_MODULA_CHAR 11
+#define SCE_MODULA_CHARSPEC 12
+#define SCE_MODULA_PROC 13
+#define SCE_MODULA_PRAGMA 14
+#define SCE_MODULA_PRGKEY 15
+#define SCE_MODULA_OPERATOR 16
+#define SCE_MODULA_BADSTR 17
 /* --Autogenerated -- end of section automatically generated from Scintilla.iface */
 
 #endif

Modified: trunk/scintilla/include/Scintilla.h
===================================================================
--- trunk/scintilla/include/Scintilla.h	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/include/Scintilla.h	2011-04-03 16:16:52 UTC (rev 5682)
@@ -159,6 +159,8 @@
 #define SCI_GETMARGINMASKN 2245
 #define SCI_SETMARGINSENSITIVEN 2246
 #define SCI_GETMARGINSENSITIVEN 2247
+#define SCI_SETMARGINCURSORN 2248
+#define SCI_GETMARGINCURSORN 2249
 #define STYLE_DEFAULT 32
 #define STYLE_LINENUMBER 33
 #define STYLE_BRACELIGHT 34
@@ -590,7 +592,9 @@
 #define SCI_SETMOUSEDOWNCAPTURES 2384
 #define SCI_GETMOUSEDOWNCAPTURES 2385
 #define SC_CURSORNORMAL -1
+#define SC_CURSORARROW 2
 #define SC_CURSORWAIT 4
+#define SC_CURSORREVERSEARROW 7
 #define SCI_SETCURSOR 2386
 #define SCI_GETCURSOR 2387
 #define SCI_SETCONTROLCHARSYMBOL 2388
@@ -832,6 +836,10 @@
 #define SC_MOD_CONTAINER 0x40000
 #define SC_MOD_LEXERSTATE 0x80000
 #define SC_MODEVENTMASKALL 0xFFFFF
+#define SC_UPDATE_CONTENT 0x1
+#define SC_UPDATE_SELECTION 0x2
+#define SC_UPDATE_V_SCROLL 0x4
+#define SC_UPDATE_H_SCROLL 0x8
 #define SCEN_CHANGE 768
 #define SCEN_SETFOCUS 512
 #define SCEN_KILLFOCUS 256
@@ -971,6 +979,7 @@
 	int y;		/* SCN_DWELLSTART, SCN_DWELLEND */
 	int token;		/* SCN_MODIFIED with SC_MOD_CONTAINER */
 	int annotationLinesAdded;	/* SC_MOD_CHANGEANNOTATION */
+	int updated;	/* SCN_UPDATEUI */
 };
 
 #ifdef SCI_NAMESPACE

Modified: trunk/scintilla/include/Scintilla.iface
===================================================================
--- trunk/scintilla/include/Scintilla.iface	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/include/Scintilla.iface	2011-04-03 16:16:52 UTC (rev 5682)
@@ -352,6 +352,12 @@
 # Retrieve the mouse click sensitivity of a margin.
 get bool GetMarginSensitiveN=2247(int margin,)
 
+# Set the cursor shown when the mouse is inside a margin.
+set void SetMarginCursorN=2248(int margin, int cursor)
+
+# Retrieve the cursor shown in a margin.
+get int GetMarginCursorN=2249(int margin,)
+
 # Styles in range 32..38 are predefined for parts of the UI and are not used as normal styles.
 # Style 39 is for future use.
 enu StylesCommon=STYLE_
@@ -1540,7 +1546,9 @@
 
 enu CursorShape=SC_CURSOR
 val SC_CURSORNORMAL=-1
+val SC_CURSORARROW=2
 val SC_CURSORWAIT=4
+val SC_CURSORREVERSEARROW=7
 # Sets the cursor to one of the SC_CURSOR* values.
 set void SetCursor=2386(int cursorType,)
 # Get cursor type.
@@ -2193,6 +2201,12 @@
 val SC_MOD_LEXERSTATE=0x80000
 val SC_MODEVENTMASKALL=0xFFFFF
 
+enu Update=SC_UPDATE_
+val SC_UPDATE_CONTENT=0x1
+val SC_UPDATE_SELECTION=0x2
+val SC_UPDATE_V_SCROLL=0x4
+val SC_UPDATE_H_SCROLL=0x8
+
 # For compatibility, these go through the COMMAND notification rather than NOTIFY
 # and should have had exactly the same values as the EN_* constants.
 # Unfortunately the SETFOCUS and KILLFOCUS are flipped over from EN_*
@@ -2335,6 +2349,8 @@
 val SCLEX_SML=97
 val SCLEX_MARKDOWN=98
 val SCLEX_TXT2TAGS=99
+val SCLEX_A68K=100
+val SCLEX_MODULA=101
 
 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
 # value assigned in sequence from SCLEX_AUTOMATIC+1.
@@ -2381,6 +2397,8 @@
 val SCE_C_COMMENTDOCKEYWORD=17
 val SCE_C_COMMENTDOCKEYWORDERROR=18
 val SCE_C_GLOBALCLASS=19
+val SCE_C_STRINGRAW=20
+val SCE_C_TRIPLEVERBATIM=21
 # Lexical states for SCLEX_D
 lex D=SCLEX_D SCE_D_
 val SCE_D_DEFAULT=0
@@ -2900,6 +2918,7 @@
 val SCE_ASM_CHARACTER=12
 val SCE_ASM_STRINGEOL=13
 val SCE_ASM_EXTINSTRUCTION=14
+val SCE_ASM_COMMENTDIRECTIVE=15
 # Lexical states for SCLEX_FORTRAN
 lex Fortran=SCLEX_FORTRAN SCE_F_
 lex F77=SCLEX_F77 SCE_F_
@@ -3819,6 +3838,47 @@
 val SCE_TXT2TAGS_OPTION=23
 val SCE_TXT2TAGS_PREPROC=24
 val SCE_TXT2TAGS_POSTPROC=25
+# Lexical states for SCLEX_A68K
+lex A68k=SCLEX_A68K SCE_A68K_
+val SCE_A68K_DEFAULT=0
+val SCE_A68K_COMMENT=1
+val SCE_A68K_NUMBER_DEC=2
+val SCE_A68K_NUMBER_BIN=3
+val SCE_A68K_NUMBER_HEX=4
+val SCE_A68K_STRING1=5
+val SCE_A68K_OPERATOR=6
+val SCE_A68K_CPUINSTRUCTION=7
+val SCE_A68K_EXTINSTRUCTION=8
+val SCE_A68K_REGISTER=9
+val SCE_A68K_DIRECTIVE=10
+val SCE_A68K_MACRO_ARG=11
+val SCE_A68K_LABEL=12
+val SCE_A68K_STRING2=13
+val SCE_A68K_IDENTIFIER=14
+val SCE_A68K_MACRO_DECLARATION=15
+val SCE_A68K_COMMENT_WORD=16
+val SCE_A68K_COMMENT_SPECIAL=17
+val SCE_A68K_COMMENT_DOXYGEN=18
+# Lexical states for SCLEX_MODULA
+lex Modula=SCLEX_MODULA SCE_MODULA_
+val SCE_MODULA_DEFAULT=0
+val SCE_MODULA_COMMENT=1
+val SCE_MODULA_DOXYCOMM=2
+val SCE_MODULA_DOXYKEY=3
+val SCE_MODULA_KEYWORD=4
+val SCE_MODULA_RESERVED=5
+val SCE_MODULA_NUMBER=6
+val SCE_MODULA_BASENUM=7
+val SCE_MODULA_FLOAT=8
+val SCE_MODULA_STRING=9
+val SCE_MODULA_STRSPEC=10
+val SCE_MODULA_CHAR=11
+val SCE_MODULA_CHARSPEC=12
+val SCE_MODULA_PROC=13
+val SCE_MODULA_PRAGMA=14
+val SCE_MODULA_PRGKEY=15
+val SCE_MODULA_OPERATOR=16
+val SCE_MODULA_BADSTR=17
 
 # Events
 

Modified: trunk/scintilla/lexers/LexAda.cxx
===================================================================
--- trunk/scintilla/lexers/LexAda.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexAda.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexAsm.cxx
===================================================================
--- trunk/scintilla/lexers/LexAsm.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexAsm.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -4,6 +4,7 @@
  ** Written by The Black Horus
  ** Enhancements and NASM stuff by Kein-Hong Man, 2003-10
  ** SCE_ASM_COMMENTBLOCK and SCE_ASM_CHARACTER are for future GNU as colouring
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
  **/
 // Copyright 1998-2003 by Neil Hodgson <neilh at scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
@@ -15,17 +16,24 @@
 #include <assert.h>
 #include <ctype.h>
 
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+
+#include <string>
+#include <map>
+#include <set>
+
 #include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
-#include "Accessor.h"
 #include "StyleContext.h"
 #include "CharacterSet.h"
 #include "LexerModule.h"
+#include "OptionSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -54,16 +62,185 @@
 	return false;
 }
 
-static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                            Accessor &styler) {
+static bool IsStreamCommentStyle(int style) {
+	return style == SCE_ASM_COMMENTDIRECTIVE || style == SCE_ASM_COMMENTBLOCK;
+}
 
-	WordList &cpuInstruction = *keywordlists[0];
-	WordList &mathInstruction = *keywordlists[1];
-	WordList &registers = *keywordlists[2];
-	WordList &directive = *keywordlists[3];
-	WordList &directiveOperand = *keywordlists[4];
-	WordList &extInstruction = *keywordlists[5];
+static inline int LowerCase(int c) {
+	if (c >= 'A' && c <= 'Z')
+		return 'a' + c - 'A';
+	return c;
+}
 
+// An individual named option for use in an OptionSet
+
+// Options used for LexerAsm
+struct OptionsAsm {
+	std::string delimiter;
+	bool fold;
+	bool foldSyntaxBased;
+	bool foldCommentMultiline;
+	bool foldCommentExplicit;
+	std::string foldExplicitStart;
+	std::string foldExplicitEnd;
+	bool foldExplicitAnywhere;
+	bool foldCompact;
+	OptionsAsm() {
+		delimiter = "";
+		fold = false;
+		foldSyntaxBased = true;
+		foldCommentMultiline = false;
+		foldCommentExplicit = false;
+		foldExplicitStart = "";
+		foldExplicitEnd   = "";
+		foldExplicitAnywhere = false;
+		foldCompact = true;
+	}
+};
+
+static const char * const asmWordListDesc[] = {
+	"CPU instructions",
+	"FPU instructions",
+	"Registers",
+	"Directives",
+	"Directive operands",
+	"Extended instructions",
+	"Directives4Foldstart",
+	"Directives4Foldend",
+	0
+};
+
+struct OptionSetAsm : public OptionSet<OptionsAsm> {
+	OptionSetAsm() {
+		DefineProperty("lexer.asm.comment.delimiter", &OptionsAsm::delimiter,
+			"Character used for COMMENT directive's delimiter, replacing the standard \"~\".");
+
+		DefineProperty("fold", &OptionsAsm::fold);
+
+		DefineProperty("fold.asm.syntax.based", &OptionsAsm::foldSyntaxBased,
+			"Set this property to 0 to disable syntax based folding.");
+
+		DefineProperty("fold.asm.comment.multiline", &OptionsAsm::foldCommentMultiline,
+			"Set this property to 1 to enable folding multi-line comments.");
+
+		DefineProperty("fold.asm.comment.explicit", &OptionsAsm::foldCommentExplicit,
+			"This option enables folding explicit fold points when using the Asm 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.");
+
+		DefineProperty("fold.asm.explicit.start", &OptionsAsm::foldExplicitStart,
+			"The string to use for explicit fold start points, replacing the standard ;{.");
+
+		DefineProperty("fold.asm.explicit.end", &OptionsAsm::foldExplicitEnd,
+			"The string to use for explicit fold end points, replacing the standard ;}.");
+
+		DefineProperty("fold.asm.explicit.anywhere", &OptionsAsm::foldExplicitAnywhere,
+			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+		DefineProperty("fold.compact", &OptionsAsm::foldCompact);
+
+		DefineWordListSets(asmWordListDesc);
+	}
+};
+
+class LexerAsm : public ILexer {
+	WordList cpuInstruction;
+	WordList mathInstruction;
+	WordList registers;
+	WordList directive;
+	WordList directiveOperand;
+	WordList extInstruction;
+	WordList directives4foldstart;
+	WordList directives4foldend;
+	OptionsAsm options;
+	OptionSetAsm osAsm;
+public:
+	LexerAsm() {
+	}
+	~LexerAsm() {
+	}
+	void SCI_METHOD Release() {
+		delete this;
+	}
+	int SCI_METHOD Version() const {
+		return lvOriginal;
+	}
+	const char * SCI_METHOD PropertyNames() {
+		return osAsm.PropertyNames();
+	}
+	int SCI_METHOD PropertyType(const char *name) {
+		return osAsm.PropertyType(name);
+	}
+	const char * SCI_METHOD DescribeProperty(const char *name) {
+		return osAsm.DescribeProperty(name);
+	}
+	int SCI_METHOD PropertySet(const char *key, const char *val);
+	const char * SCI_METHOD DescribeWordListSets() {
+		return osAsm.DescribeWordListSets();
+	}
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+	void * SCI_METHOD PrivateCall(int, void *) {
+		return 0;
+	}
+
+	static ILexer *LexerFactoryAsm() {
+		return new LexerAsm();
+	}
+};
+
+int SCI_METHOD LexerAsm::PropertySet(const char *key, const char *val) {
+	if (osAsm.PropertySet(&options, key, val)) {
+		return 0;
+	}
+	return -1;
+}
+
+int SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) {
+	WordList *wordListN = 0;
+	switch (n) {
+	case 0:
+		wordListN = &cpuInstruction;
+		break;
+	case 1:
+		wordListN = &mathInstruction;
+		break;
+	case 2:
+		wordListN = ®isters;
+		break;
+	case 3:
+		wordListN = &directive;
+		break;
+	case 4:
+		wordListN = &directiveOperand;
+		break;
+	case 5:
+		wordListN = &extInstruction;
+		break;
+	case 6:
+		wordListN = &directives4foldstart;
+		break;
+	case 7:
+		wordListN = &directives4foldend;
+		break;
+	}
+	int firstModification = -1;
+	if (wordListN) {
+		WordList wlNew;
+		wlNew.Set(wl);
+		if (*wordListN != wlNew) {
+			wordListN->Set(wl);
+			firstModification = 0;
+		}
+	}
+	return firstModification;
+}
+
+void SCI_METHOD LexerAsm::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	LexAccessor styler(pAccess);
+
 	// Do not leak onto next line
 	if (initStyle == SCE_ASM_STRINGEOL)
 		initStyle = SCE_ASM_DEFAULT;
@@ -96,7 +273,7 @@
 			if (!IsAsmOperator(sc.ch)) {
 			    sc.SetState(SCE_ASM_DEFAULT);
 			}
-		}else if (sc.state == SCE_ASM_NUMBER) {
+		} else if (sc.state == SCE_ASM_NUMBER) {
 			if (!IsAWordChar(sc.ch)) {
 				sc.SetState(SCE_ASM_DEFAULT);
 			}
@@ -104,6 +281,7 @@
 			if (!IsAWordChar(sc.ch) ) {
 				char s[100];
 				sc.GetCurrentLowered(s, sizeof(s));
+				bool IsDirective = false;
 
 				if (cpuInstruction.InList(s)) {
 					sc.ChangeState(SCE_ASM_CPUINSTRUCTION);
@@ -113,15 +291,32 @@
 					sc.ChangeState(SCE_ASM_REGISTER);
 				}  else if (directive.InList(s)) {
 					sc.ChangeState(SCE_ASM_DIRECTIVE);
+					IsDirective = true;
 				} else if (directiveOperand.InList(s)) {
 					sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
 				} else if (extInstruction.InList(s)) {
 					sc.ChangeState(SCE_ASM_EXTINSTRUCTION);
 				}
 				sc.SetState(SCE_ASM_DEFAULT);
+				if (IsDirective && !strcmp(s, "comment")) {
+					char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
+					while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) {
+						sc.ForwardSetState(SCE_ASM_DEFAULT);
+					}
+					if (sc.ch == delimiter) {
+						sc.SetState(SCE_ASM_COMMENTDIRECTIVE);
+					}
+				}
 			}
-		}
-		else if (sc.state == SCE_ASM_COMMENT ) {
+		} else if (sc.state == SCE_ASM_COMMENTDIRECTIVE) {
+			char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
+			if (sc.ch == delimiter) {
+				while (!sc.atLineEnd) {
+					sc.Forward();
+				}
+				sc.SetState(SCE_ASM_DEFAULT);
+			}
+		} else if (sc.state == SCE_ASM_COMMENT ) {
 			if (sc.atLineEnd) {
 				sc.SetState(SCE_ASM_DEFAULT);
 			}
@@ -170,15 +365,100 @@
 	sc.Complete();
 }
 
-static const char * const asmWordListDesc[] = {
-	"CPU instructions",
-	"FPU instructions",
-	"Registers",
-	"Directives",
-	"Directive operands",
-	"Extended instructions",
-	0
-};
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "else".
 
-LexerModule lmAsm(SCLEX_ASM, ColouriseAsmDoc, "asm", 0, asmWordListDesc);
+void SCI_METHOD LexerAsm::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
 
+	if (!options.fold)
+		return;
+
+	LexAccessor styler(pAccess);
+
+	unsigned int endPos = startPos + length;
+	int visibleChars = 0;
+	int lineCurrent = styler.GetLine(startPos);
+	int levelCurrent = SC_FOLDLEVELBASE;
+	if (lineCurrent > 0)
+		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+	int levelNext = levelCurrent;
+	char chNext = styler[startPos];
+	int styleNext = styler.StyleAt(startPos);
+	int style = initStyle;
+	char word[100];
+	int wordlen = 0;
+	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
+	for (unsigned int i = startPos; i < endPos; i++) {
+		char ch = chNext;
+		chNext = styler.SafeGetCharAt(i + 1);
+		int stylePrev = style;
+		style = styleNext;
+		styleNext = styler.StyleAt(i + 1);
+		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+		if (options.foldCommentMultiline && IsStreamCommentStyle(style)) {
+			if (!IsStreamCommentStyle(stylePrev)) {
+				levelNext++;
+			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+				// Comments don't end at end of line and the next character may be unstyled.
+				levelNext--;
+			}
+		}
+		if (options.foldCommentExplicit && ((style == SCE_ASM_COMMENT) || options.foldExplicitAnywhere)) {
+			if (userDefinedFoldMarkers) {
+				if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ 					levelNext++;
+				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ 					levelNext--;
+ 				}
+			} else {
+				if (ch == ';') {
+					if (chNext == '{') {
+						levelNext++;
+					} else if (chNext == '}') {
+						levelNext--;
+					}
+				}
+ 			}
+ 		}
+		if (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) {
+			word[wordlen++] = static_cast<char>(LowerCase(ch));
+			if (wordlen == 100) {                   // prevent overflow
+				word[0] = '\0';
+				wordlen = 1;
+			}
+			if (styleNext != SCE_ASM_DIRECTIVE) {   // reading directive ready
+				word[wordlen] = '\0';
+				wordlen = 0;
+				if (directives4foldstart.InList(word)) {
+					levelNext++;
+				} else if (directives4foldend.InList(word)){
+					levelNext--;
+				}
+			}
+		}
+		if (!IsASpace(ch))
+			visibleChars++;
+		if (atEOL || (i == endPos-1)) {
+			int levelUse = levelCurrent;
+			int lev = levelUse | levelNext << 16;
+			if (visibleChars == 0 && options.foldCompact)
+				lev |= SC_FOLDLEVELWHITEFLAG;
+			if (levelUse < levelNext)
+				lev |= SC_FOLDLEVELHEADERFLAG;
+			if (lev != styler.LevelAt(lineCurrent)) {
+				styler.SetLevel(lineCurrent, lev);
+			}
+			lineCurrent++;
+			levelCurrent = levelNext;
+			if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
+				// There is an empty line at end of file so give it same level and empty
+				styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
+			}
+			visibleChars = 0;
+		}
+	}
+}
+
+LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, "asm", asmWordListDesc);
+

Modified: trunk/scintilla/lexers/LexBash.cxx
===================================================================
--- trunk/scintilla/lexers/LexBash.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexBash.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -640,6 +639,14 @@
 				levelCurrent--;
 			}
 		}
+		// Here Document folding
+		if (style == SCE_SH_HERE_DELIM) {
+			if (ch == '<' && chNext == '<') {
+				levelCurrent++;
+			}
+		} else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_PL_DEFAULT) {
+			levelCurrent--;
+		}
 		if (atEOL) {
 			int lev = levelPrev;
 			if (visibleChars == 0 && foldCompact)

Modified: trunk/scintilla/lexers/LexCOBOL.cxx
===================================================================
--- trunk/scintilla/lexers/LexCOBOL.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexCOBOL.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -19,7 +19,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexCPP.cxx
===================================================================
--- trunk/scintilla/lexers/LexCPP.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexCPP.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -1,6 +1,7 @@
 // Scintilla source code edit control
 /** @file LexCPP.cxx
  ** Lexer for C++, C, Java, and JavaScript.
+ ** Further folding features and configuration properties added by "Udo Lechner" <dlchnr(at)gmx(dot)net>
  **/
 // Copyright 1998-2005 by Neil Hodgson <neilh at scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
@@ -15,10 +16,6 @@
 #ifdef _MSC_VER
 #pragma warning(disable: 4786)
 #endif
-#ifdef __BORLANDC__
-// Borland C++ displays warnings in vector header without this
-#pragma option -w-ccc -w-rch
-#endif
 
 #include <string>
 #include <vector>
@@ -29,7 +26,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -37,6 +33,7 @@
 #include "CharacterSet.h"
 #include "LexerModule.h"
 #include "OptionSet.h"
+#include "SparseState.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -212,8 +209,13 @@
 	bool trackPreprocessor;
 	bool updatePreprocessor;
 	bool fold;
+	bool foldSyntaxBased;
 	bool foldComment;
+	bool foldCommentMultiline;
 	bool foldCommentExplicit;
+	std::string foldExplicitStart;
+	std::string foldExplicitEnd;
+	bool foldExplicitAnywhere;
 	bool foldPreprocessor;
 	bool foldCompact;
 	bool foldAtElse;
@@ -223,8 +225,13 @@
 		trackPreprocessor = true;
 		updatePreprocessor = true;
 		fold = false;
+		foldSyntaxBased = true;
 		foldComment = false;
+		foldCommentMultiline = true;
 		foldCommentExplicit = true;
+		foldExplicitStart = "";
+		foldExplicitEnd = "";
+		foldExplicitAnywhere = false;
 		foldPreprocessor = false;
 		foldCompact = false;
 		foldAtElse = false;
@@ -258,14 +265,29 @@
 
 		DefineProperty("fold", &OptionsCPP::fold);
 
+		DefineProperty("fold.cpp.syntax.based", &OptionsCPP::foldSyntaxBased,
+			"Set this property to 0 to disable syntax based folding.");
+
 		DefineProperty("fold.comment", &OptionsCPP::foldComment,
 			"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.");
 
+		DefineProperty("fold.cpp.comment.multiline", &OptionsCPP::foldCommentMultiline,
+			"Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
+
 		DefineProperty("fold.cpp.comment.explicit", &OptionsCPP::foldCommentExplicit,
 			"Set this property to 0 to disable folding explicit fold points when fold.comment=1.");
 
+		DefineProperty("fold.cpp.explicit.start", &OptionsCPP::foldExplicitStart,
+			"The string to use for explicit fold start points, replacing the standard //{.");
+
+		DefineProperty("fold.cpp.explicit.end", &OptionsCPP::foldExplicitEnd,
+			"The string to use for explicit fold end points, replacing the standard //}.");
+
+		DefineProperty("fold.cpp.explicit.anywhere", &OptionsCPP::foldExplicitAnywhere,
+			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
 		DefineProperty("fold.preprocessor", &OptionsCPP::foldPreprocessor,
 			"This option enables folding preprocessor directives when using the C++ lexer. "
 			"Includes C#'s explicit #region and #endregion folding directives.");
@@ -288,7 +310,6 @@
 	CharacterSet setLogicalOp;
 	PPStates vlls;
 	std::vector<PPDefinition> ppDefineHistory;
-	PropSetSimple props;
 	WordList keywords;
 	WordList keywords2;
 	WordList keywords3;
@@ -297,6 +318,7 @@
 	std::map<std::string, std::string> preprocessorDefinitionsStart;
 	OptionsCPP options;
 	OptionSetCPP osCPP;
+	SparseState<std::string> rawStringTerminators;
 public:
 	LexerCPP(bool caseSensitive_) :
 		caseSensitive(caseSensitive_),
@@ -419,7 +441,6 @@
 	CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
 
 	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
-	CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
 
 	if (options.identifiersAllowDollars) {
 		setWordStart.Add('$');
@@ -483,16 +504,18 @@
 	}
 
 	const int maskActivity = 0x3F;
+	std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
+	SparseState<std::string> rawSTNew(lineCurrent);
 
 	int activitySet = preproc.IsInactive() ? 0x40 : 0;
 
 	for (; sc.More(); sc.Forward()) {
 
 		if (sc.atLineStart) {
-			if (sc.state == SCE_C_STRING) {
+			if ((sc.state == SCE_C_STRING) || (sc.state == SCE_C_CHARACTER)) {
 				// Prevent SCE_C_STRINGEOL from leaking back to previous line which
 				// ends with a line continuation by locking in the state upto this position.
-				sc.SetState(SCE_C_STRING);
+				sc.SetState(sc.state);
 			}
 			// Reset states to begining of colourise so no surprises
 			// if different sets of lines lexed.
@@ -515,6 +538,9 @@
 		if (sc.atLineEnd) {
 			lineCurrent++;
 			vlls.Add(lineCurrent, preproc);
+			if (rawStringTerminator != "") {
+				rawSTNew.Set(lineCurrent-1, rawStringTerminator);
+			}
 		}
 
 		// Handle line continuation generically.
@@ -558,6 +584,23 @@
 					} else if (keywords4.InList(s)) {
 						sc.ChangeState(SCE_C_GLOBALCLASS|activitySet);
 					}
+					const bool literalString = sc.ch == '\"';
+					if (literalString || sc.ch == '\'') {
+						size_t lenS = strlen(s);
+						const bool raw = literalString && sc.chPrev == 'R';
+						if (raw)
+							s[lenS--] = '\0';
+						bool valid =
+							(lenS == 0) ||
+							((lenS == 1) && ((s[0] == 'L') || (s[0] == 'u') || (s[0] == 'U'))) ||
+							((lenS == 2) && literalString && (s[0] == 'u') && (s[1] == '8'));
+						if (valid) {
+							if (literalString)
+								sc.ChangeState((raw ? SCE_C_STRINGRAW : SCE_C_STRING)|activitySet);
+							else
+								sc.ChangeState(SCE_C_CHARACTER|activitySet);
+						}
+					}
 					sc.SetState(SCE_C_DEFAULT|activitySet);
 				}
 				break;
@@ -642,6 +685,14 @@
 					sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
 				}
 				break;
+			case SCE_C_STRINGRAW:
+				if (sc.Match(rawStringTerminator.c_str())) {
+					for (size_t termPos=rawStringTerminator.size(); termPos; termPos--)
+						sc.Forward();
+					sc.SetState(SCE_C_DEFAULT|activitySet);
+					rawStringTerminator = "";
+				}
+				break;
 			case SCE_C_CHARACTER:
 				if (sc.atLineEnd) {
 					sc.ChangeState(SCE_C_STRINGEOL|activitySet);
@@ -682,6 +733,14 @@
 					}
 				}
 				break;
+			case SCE_C_TRIPLEVERBATIM:
+				if (sc.Match ("\"\"\"")) {
+					while (sc.Match('"')) {
+						sc.Forward();
+					}
+					sc.SetState(SCE_C_DEFAULT|activitySet);
+				}
+				break;
 			case SCE_C_UUID:
 				if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
 					sc.SetState(SCE_C_DEFAULT|activitySet);
@@ -699,6 +758,9 @@
 			if (sc.Match('@', '\"')) {
 				sc.SetState(SCE_C_VERBATIM|activitySet);
 				sc.Forward();
+			} else if (sc.Match("\"\"\"")) {
+				sc.SetState(SCE_C_TRIPLEVERBATIM|activitySet);
+				sc.Forward(2);
 			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 				if (lastWordWasUUID) {
 					sc.SetState(SCE_C_UUID|activitySet);
@@ -733,7 +795,19 @@
 				       || !FollowsPostfixOperator(sc, styler))) {
 				sc.SetState(SCE_C_REGEX|activitySet);	// JavaScript's RegEx
 			} else if (sc.ch == '\"') {
-				sc.SetState(SCE_C_STRING|activitySet);
+				if (sc.chPrev == 'R') {
+					sc.SetState(SCE_C_STRINGRAW|activitySet);
+					rawStringTerminator = ")";
+					for (int termPos = sc.currentPos + 1;;termPos++) {
+						char chTerminator = styler.SafeGetCharAt(termPos, '(');
+						if (chTerminator == '(')
+							break;
+						rawStringTerminator += chTerminator;
+					}
+					rawStringTerminator += '\"';
+				} else {
+					sc.SetState(SCE_C_STRING|activitySet);
+				}
 				isIncludePreprocessor = false;	// ensure that '>' won't end the string
 			} else if (isIncludePreprocessor && sc.ch == '<') {
 				sc.SetState(SCE_C_STRING|activitySet);
@@ -828,10 +902,10 @@
 		}
 		continuationLine = false;
 	}
-	if (definitionsChanged)
+	const bool rawStringsChanged = rawStringTerminators.Merge(rawSTNew, lineCurrent);
+	if (definitionsChanged || rawStringsChanged)
 		styler.ChangeLexerState(startPos, startPos + length);
 	sc.Complete();
-	styler.Flush();
 }
 
 // Store both the current line's fold level and the next lines in the
@@ -856,6 +930,7 @@
 	char chNext = styler[startPos];
 	int styleNext = styler.StyleAt(startPos);
 	int style = initStyle;
+	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
 	for (unsigned int i = startPos; i < endPos; i++) {
 		char ch = chNext;
 		chNext = styler.SafeGetCharAt(i + 1);
@@ -863,7 +938,7 @@
 		style = styleNext;
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-		if (options.foldComment && IsStreamCommentStyle(style)) {
+		if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
 			if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {
 				levelNext++;
 			} else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) && !atEOL) {
@@ -871,14 +946,22 @@
 				levelNext--;
 			}
 		}
-		if (options.foldComment && options.foldCommentExplicit && (style == SCE_C_COMMENTLINE)) {
-			if ((ch == '/') && (chNext == '/')) {
-				char chNext2 = styler.SafeGetCharAt(i + 2);
-				if (chNext2 == '{') {
+		if (options.foldComment && options.foldCommentExplicit && ((style == SCE_C_COMMENTLINE) || options.foldExplicitAnywhere)) {
+			if (userDefinedFoldMarkers) {
+				if (styler.Match(i, options.foldExplicitStart.c_str())) {
 					levelNext++;
-				} else if (chNext2 == '}') {
+				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
 					levelNext--;
 				}
+			} else {
+				if ((ch == '/') && (chNext == '/')) {
+					char chNext2 = styler.SafeGetCharAt(i + 2);
+					if (chNext2 == '{') {
+						levelNext++;
+					} else if (chNext2 == '}') {
+						levelNext--;
+					}
+				}
 			}
 		}
 		if (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
@@ -894,7 +977,7 @@
 				}
 			}
 		}
-		if (style == SCE_C_OPERATOR) {
+		if (options.foldSyntaxBased && (style == SCE_C_OPERATOR)) {
 			if (ch == '{') {
 				// Measure the minimum before a '{' to allow
 				// folding on "} else {"
@@ -910,7 +993,7 @@
 			visibleChars++;
 		if (atEOL || (i == endPos-1)) {
 			int levelUse = levelCurrent;
-			if (options.foldAtElse) {
+			if (options.foldSyntaxBased && options.foldAtElse) {
 				levelUse = levelMinCurrent;
 			}
 			int lev = levelUse | levelNext << 16;

Modified: trunk/scintilla/lexers/LexCSS.cxx
===================================================================
--- trunk/scintilla/lexers/LexCSS.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexCSS.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -18,7 +18,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexCmake.cxx
===================================================================
--- trunk/scintilla/lexers/LexCmake.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexCmake.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexD.cxx
===================================================================
--- trunk/scintilla/lexers/LexD.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexD.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -2,6 +2,7 @@
  ** Lexer for D.
  **
  ** Copyright (c) 2006 by Waldemar Augustyn <waldemar at wdmsys.com>
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
  **/
 // Copyright 1998-2005 by Neil Hodgson <neilh at scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
@@ -13,17 +14,23 @@
 #include <assert.h>
 #include <ctype.h>
 
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+
+#include <string>
+#include <map>
+
 #include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
-#include "Accessor.h"
 #include "StyleContext.h"
 #include "CharacterSet.h"
 #include "LexerModule.h"
+#include "OptionSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -59,18 +66,188 @@
 	return ch == 'c' || ch == 'w' || ch == 'd';
 }
 
+static bool IsStreamCommentStyle(int style) {
+	return style == SCE_D_COMMENT ||
+		style == SCE_D_COMMENTDOC ||
+		style == SCE_D_COMMENTDOCKEYWORD ||
+		style == SCE_D_COMMENTDOCKEYWORDERROR;
+}
 
-static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
-	WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
+// An individual named option for use in an OptionSet
 
-	WordList &keywords  = *keywordlists[0];
-	WordList &keywords2 = *keywordlists[1];
-	WordList &keywords3 = *keywordlists[2]; //doxygen
-	WordList &keywords4 = *keywordlists[3];
-	WordList &keywords5 = *keywordlists[4];
-	WordList &keywords6 = *keywordlists[5];
-	WordList &keywords7 = *keywordlists[6];
+// Options used for LexerD
+struct OptionsD {
+	bool fold;
+	bool foldSyntaxBased;
+	bool foldComment;
+	bool foldCommentMultiline;
+	bool foldCommentExplicit;
+	std::string foldExplicitStart;
+	std::string foldExplicitEnd;
+	bool foldExplicitAnywhere;
+	bool foldCompact;
+	int  foldAtElseInt;
+	bool foldAtElse;
+	OptionsD() {
+		fold = false;
+		foldSyntaxBased = true;
+		foldComment = false;
+		foldCommentMultiline = true;
+		foldCommentExplicit = true;
+		foldExplicitStart = "";
+		foldExplicitEnd   = "";
+		foldExplicitAnywhere = false;
+		foldCompact = true;
+		foldAtElseInt = -1;
+		foldAtElse = false;
+	}
+};
 
+static const char * const dWordLists[] = {
+			"Primary keywords and identifiers",
+			"Secondary keywords and identifiers",
+			"Documentation comment keywords",
+			"Type definitions and aliases",
+			"Keywords 5",
+			"Keywords 6",
+			"Keywords 7",
+			0,
+		};
+
+struct OptionSetD : public OptionSet<OptionsD> {
+	OptionSetD() {
+		DefineProperty("fold", &OptionsD::fold);
+
+		DefineProperty("fold.d.syntax.based", &OptionsD::foldSyntaxBased,
+			"Set this property to 0 to disable syntax based folding.");
+
+		DefineProperty("fold.comment", &OptionsD::foldComment);
+
+		DefineProperty("fold.d.comment.multiline", &OptionsD::foldCommentMultiline,
+			"Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
+
+		DefineProperty("fold.d.comment.explicit", &OptionsD::foldCommentExplicit,
+			"Set this property to 0 to disable folding explicit fold points when fold.comment=1.");
+
+		DefineProperty("fold.d.explicit.start", &OptionsD::foldExplicitStart,
+			"The string to use for explicit fold start points, replacing the standard //{.");
+
+		DefineProperty("fold.d.explicit.end", &OptionsD::foldExplicitEnd,
+			"The string to use for explicit fold end points, replacing the standard //}.");
+
+		DefineProperty("fold.d.explicit.anywhere", &OptionsD::foldExplicitAnywhere,
+			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+		DefineProperty("fold.compact", &OptionsD::foldCompact);
+
+		DefineProperty("lexer.d.fold.at.else", &OptionsD::foldAtElseInt,
+			"This option enables D folding on a \"} else {\" line of an if statement.");
+
+		DefineProperty("fold.at.else", &OptionsD::foldAtElse);
+
+		DefineWordListSets(dWordLists);
+	}
+};
+
+class LexerD : public ILexer {
+	bool caseSensitive;
+	WordList keywords;
+	WordList keywords2;
+	WordList keywords3;
+	WordList keywords4;
+	WordList keywords5;
+	WordList keywords6;
+	WordList keywords7;
+	OptionsD options;
+	OptionSetD osD;
+public:
+	LexerD(bool caseSensitive_) :
+		caseSensitive(caseSensitive_) {
+	}
+	~LexerD() {
+	}
+	void SCI_METHOD Release() {
+		delete this;
+	}
+	int SCI_METHOD Version() const {
+		return lvOriginal;
+	}
+	const char * SCI_METHOD PropertyNames() {
+		return osD.PropertyNames();
+	}
+	int SCI_METHOD PropertyType(const char *name) {
+		return osD.PropertyType(name);
+	}
+	const char * SCI_METHOD DescribeProperty(const char *name) {
+		return osD.DescribeProperty(name);
+	}
+	int SCI_METHOD PropertySet(const char *key, const char *val);
+	const char * SCI_METHOD DescribeWordListSets() {
+		return osD.DescribeWordListSets();
+	}
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+	void * SCI_METHOD PrivateCall(int, void *) {
+		return 0;
+	}
+
+	static ILexer *LexerFactoryD() {
+		return new LexerD(true);
+	}
+	static ILexer *LexerFactoryDInsensitive() {
+		return new LexerD(false);
+	}
+};
+
+int SCI_METHOD LexerD::PropertySet(const char *key, const char *val) {
+	if (osD.PropertySet(&options, key, val)) {
+		return 0;
+	}
+	return -1;
+}
+
+int SCI_METHOD LexerD::WordListSet(int n, const char *wl) {
+	WordList *wordListN = 0;
+	switch (n) {
+	case 0:
+		wordListN = &keywords;
+		break;
+	case 1:
+		wordListN = &keywords2;
+		break;
+	case 2:
+		wordListN = &keywords3;
+		break;
+	case 3:
+		wordListN = &keywords4;
+		break;
+	case 4:
+		wordListN = &keywords5;
+		break;
+	case 5:
+		wordListN = &keywords6;
+		break;
+	case 6:
+		wordListN = &keywords7;
+		break;
+	}
+	int firstModification = -1;
+	if (wordListN) {
+		WordList wlNew;
+		wlNew.Set(wl);
+		if (*wordListN != wlNew) {
+			wordListN->Set(wl);
+			firstModification = 0;
+		}
+	}
+	return firstModification;
+}
+
+void SCI_METHOD LexerD::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	LexAccessor styler(pAccess);
+
 	int styleBeforeDCKeyword = SCE_D_DEFAULT;
 
 	StyleContext sc(startPos, length, initStyle, styler);
@@ -294,24 +471,17 @@
 	sc.Complete();
 }
 
-static bool IsStreamCommentStyle(int style) {
-	return style == SCE_D_COMMENT ||
-		style == SCE_D_COMMENTDOC ||
-		style == SCE_D_COMMENTDOCKEYWORD ||
-		style == SCE_D_COMMENTDOCKEYWORDERROR;
-}
-
 // Store both the current line's fold level and the next lines in the
 // level store to make it easy to pick up with each increment
 // and to make it possible to fiddle the current level for "} else {".
-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;
+void SCI_METHOD LexerD::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+
+	if (!options.fold)
+		return;
+
+	LexAccessor styler(pAccess);
+
 	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
 	int lineCurrent = styler.GetLine(startPos);
@@ -323,6 +493,8 @@
 	char chNext = styler[startPos];
 	int styleNext = styler.StyleAt(startPos);
 	int style = initStyle;
+	bool foldAtElse = options.foldAtElseInt >= 0 ? options.foldAtElseInt != 0 : options.foldAtElse;
+	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
 	for (unsigned int i = startPos; i < endPos; i++) {
 		char ch = chNext;
 		chNext = styler.SafeGetCharAt(i + 1);
@@ -330,7 +502,7 @@
 		style = styleNext;
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-		if (foldComment && IsStreamCommentStyle(style)) {
+		if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
 			if (!IsStreamCommentStyle(stylePrev)) {
 				levelNext++;
 			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
@@ -338,7 +510,25 @@
 				levelNext--;
 			}
 		}
-		if (style == SCE_D_OPERATOR) {
+		if (options.foldComment && options.foldCommentExplicit && ((style == SCE_D_COMMENTLINE) || options.foldExplicitAnywhere)) {
+			if (userDefinedFoldMarkers) {
+				if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ 					levelNext++;
+				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ 					levelNext--;
+ 				}
+			} else {
+				if ((ch == '/') && (chNext == '/')) {
+					char chNext2 = styler.SafeGetCharAt(i + 2);
+					if (chNext2 == '{') {
+						levelNext++;
+					} else if (chNext2 == '}') {
+						levelNext--;
+					}
+				}
+ 			}
+ 		}
+		if (options.foldSyntaxBased && (style == SCE_D_OPERATOR)) {
 			if (ch == '{') {
 				// Measure the minimum before a '{' to allow
 				// folding on "} else {"
@@ -350,19 +540,19 @@
 				levelNext--;
 			}
 		}
-		if (atEOL) {
-			if (foldComment) {  // Handle nested comments
+		if (atEOL || (i == endPos-1)) {
+			if (options.foldComment && options.foldCommentMultiline) {  // Handle nested comments
 				int nc;
 				nc =  styler.GetLineState(lineCurrent);
 				nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
 				levelNext += nc;
 			}
 			int levelUse = levelCurrent;
-			if (foldAtElse) {
+			if (options.foldSyntaxBased && foldAtElse) {
 				levelUse = levelMinCurrent;
 			}
 			int lev = levelUse | levelNext << 16;
-			if (visibleChars == 0 && foldCompact)
+			if (visibleChars == 0 && options.foldCompact)
 				lev |= SC_FOLDLEVELWHITEFLAG;
 			if (levelUse < levelNext)
 				lev |= SC_FOLDLEVELHEADERFLAG;
@@ -379,25 +569,4 @@
 	}
 }
 
-static void FoldDDoc(unsigned int startPos, int length, int initStyle,
-	WordList *[], Accessor &styler) {
-		FoldDoc(startPos, length, initStyle, styler);
-}
-
-static const char * const dWordLists[] = {
-			"Primary keywords and identifiers",
-			"Secondary keywords and identifiers",
-			"Documentation comment keywords",
-			"Type definitions and aliases",
-			"Keywords 5",
-			"Keywords 6",
-			"Keywords 7",
-			0,
-		};
-
-static void ColouriseDDoc(unsigned int startPos, int length,
-	int initStyle, WordList *keywordlists[], Accessor &styler) {
-		ColouriseDoc(startPos, length, initStyle, keywordlists, styler, true);
-}
-
-LexerModule lmD(SCLEX_D, ColouriseDDoc, "d", FoldDDoc, dWordLists);
+LexerModule lmD(SCLEX_D, LexerD::LexerFactoryD, "d", dWordLists);

Modified: trunk/scintilla/lexers/LexErlang.cxx
===================================================================
--- trunk/scintilla/lexers/LexErlang.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexErlang.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -19,7 +19,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexForth.cxx
===================================================================
--- trunk/scintilla/lexers/LexForth.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexForth.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexFortran.cxx
===================================================================
--- trunk/scintilla/lexers/LexFortran.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexFortran.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -267,7 +266,7 @@
 		|| strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0
 		|| strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
 		|| strcmp(s, "endwhere") == 0
-		|| strcmp(s, "procedure") == 0 ) { // Take care of the module procedure statement
+		|| (strcmp(s, "procedure") == 0 && strcmp(prevWord,"module")==0) ) { // Take care of the module procedure statement
 			lev = -1;
 	} else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
 			lev = 0;

Modified: trunk/scintilla/lexers/LexHTML.cxx
===================================================================
--- trunk/scintilla/lexers/LexHTML.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexHTML.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -745,8 +744,18 @@
 				if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) {
 				//Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
 				//if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
-					if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
-						levelCurrent += ((ch == '{') || (ch == '/')) ? 1 : -1;
+					if (ch == '#') {
+						int j = i + 1;
+						while ((j < lengthDoc) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+							j++;
+						}
+						if (styler.Match(j, "region") || styler.Match(j, "if")) {
+							levelCurrent++;
+						} else if (styler.Match(j, "end")) {
+							levelCurrent--;
+						}
+					} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*')) ) {
+						levelCurrent += ((ch == '{') || (ch == '/') ) ? 1 : -1;
 					}
 				} else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
 					levelCurrent--;

Modified: trunk/scintilla/lexers/LexLisp.cxx
===================================================================
--- trunk/scintilla/lexers/LexLisp.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexLisp.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexLua.cxx
===================================================================
--- trunk/scintilla/lexers/LexLua.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexLua.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -18,7 +18,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexMarkdown.cxx
===================================================================
--- trunk/scintilla/lexers/LexMarkdown.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexMarkdown.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -44,7 +44,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexMatlab.cxx
===================================================================
--- trunk/scintilla/lexers/LexMatlab.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexMatlab.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -21,7 +21,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexNsis.cxx
===================================================================
--- trunk/scintilla/lexers/LexNsis.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexNsis.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexOthers.cxx
===================================================================
--- trunk/scintilla/lexers/LexOthers.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexOthers.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -510,7 +509,7 @@
 		styler.ColourTo(endLine, SCE_DIFF_COMMAND);
 	} else if (0 == strncmp(lineBuffer, "Index: ", 7)) {  // For subversion's diff
 		styler.ColourTo(endLine, SCE_DIFF_COMMAND);
-	} else if (0 == strncmp(lineBuffer, "---", 3)) {
+	} else if (0 == strncmp(lineBuffer, "---", 3) && lineBuffer[3] != '-') {
 		// In a context diff, --- appears in both the header and the position markers
 		if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
 			styler.ColourTo(endLine, SCE_DIFF_POSITION);
@@ -930,8 +929,8 @@
 		// Command or return status
 		return SCE_ERR_CMD;
 	} else if (lineBuffer[0] == '<') {
-		// Diff removal, but not interested. Trapped to avoid hitting CTAG cases.
-		return SCE_ERR_DEFAULT;
+		// Diff removal.
+		return SCE_ERR_DIFF_DELETION;
 	} else if (lineBuffer[0] == '!') {
 		return SCE_ERR_DIFF_CHANGED;
 	} else if (lineBuffer[0] == '+') {

Modified: trunk/scintilla/lexers/LexPascal.cxx
===================================================================
--- trunk/scintilla/lexers/LexPascal.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexPascal.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -118,7 +118,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexPerl.cxx
===================================================================
--- trunk/scintilla/lexers/LexPerl.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexPerl.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexPython.cxx
===================================================================
--- trunk/scintilla/lexers/LexPython.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexPython.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexR.cxx
===================================================================
--- trunk/scintilla/lexers/LexR.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexR.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexSQL.cxx
===================================================================
--- trunk/scintilla/lexers/LexSQL.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexSQL.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -2,7 +2,7 @@
 /** @file LexSQL.cxx
  ** Lexer for SQL, including PL/SQL and SQL*Plus.
  **/
-// Copyright 1998-2005 by Neil Hodgson <neilh at scintilla.org>
+// Copyright 1998-2011 by Neil Hodgson <neilh at scintilla.org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
@@ -12,24 +12,36 @@
 #include <assert.h>
 #include <ctype.h>
 
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+
+#include <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+
 #include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
 #include "CharacterSet.h"
 #include "LexerModule.h"
+#include "OptionSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-static inline bool IsAWordChar(int ch) {
-	return (ch < 0x80) && (isalnum(ch) || ch == '_');
+static inline bool IsAWordChar(int ch, bool sqlAllowDottedWord) {
+	if (!sqlAllowDottedWord)
+		return (ch < 0x80) && (isalnum(ch) || ch == '_');
+	else
+		return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
 }
 
 static inline bool IsAWordStart(int ch) {
@@ -47,31 +59,289 @@
 	// Not exactly following number definition (several dots are seen as OK, etc.)
 	// but probably enough in most cases.
 	return (ch < 0x80) &&
-	        (isdigit(ch) || toupper(ch) == 'E' ||
-             ch == '.' || ch == '-' || ch == '+');
+	       (isdigit(ch) || toupper(ch) == 'E' ||
+	        ch == '.' || ch == '-' || ch == '+');
 }
 
-static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                            Accessor &styler) {
 
-	WordList &keywords1 = *keywordlists[0];
-	WordList &keywords2 = *keywordlists[1];
-	WordList &kw_pldoc = *keywordlists[2];
-	WordList &kw_sqlplus = *keywordlists[3];
-	WordList &kw_user1 = *keywordlists[4];
-	WordList &kw_user2 = *keywordlists[5];
-	WordList &kw_user3 = *keywordlists[6];
-	WordList &kw_user4 = *keywordlists[7];
+class SQLStates {
+public :
+	void Set(int lineNumber, unsigned short int sqlStatesLine) {
+		if (!sqlStatement.size() == 0 || !sqlStatesLine == 0) {
+			sqlStatement.resize(lineNumber + 1, 0);
+			sqlStatement[lineNumber] = sqlStatesLine;
+		}
+	}
 
-	StyleContext sc(startPos, length, initStyle, styler);
+	unsigned short int IgnoreWhen (unsigned short int sqlStatesLine, bool enable) {
+		if (enable)
+			sqlStatesLine |= MASK_IGNORE_WHEN;
+		else
+			sqlStatesLine &= ~MASK_IGNORE_WHEN;
 
-	// property sql.backslash.escapes
-	//	Enables backslash as an escape character in SQL.
-	bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
+		return sqlStatesLine;
+	}
 
-	bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
+	unsigned short int IntoCondition (unsigned short int sqlStatesLine, bool enable) {
+		if (enable)
+			sqlStatesLine |= MASK_INTO_CONDITION;
+		else
+			sqlStatesLine &= ~MASK_INTO_CONDITION;
+
+		return sqlStatesLine;
+	}
+
+	unsigned short int IntoExceptionBlock (unsigned short int sqlStatesLine, bool enable) {
+		if (enable)
+			sqlStatesLine |= MASK_INTO_EXCEPTION;
+		else
+			sqlStatesLine &= ~MASK_INTO_EXCEPTION;
+
+		return sqlStatesLine;
+	}
+
+	unsigned short int IntoDeclareBlock (unsigned short int sqlStatesLine, bool enable) {
+		if (enable)
+			sqlStatesLine |= MASK_INTO_DECLARE;
+		else
+			sqlStatesLine &= ~MASK_INTO_DECLARE;
+
+		return sqlStatesLine;
+	}
+
+	unsigned short int BeginCaseBlock (unsigned short int sqlStatesLine) {
+		if ((sqlStatesLine & MASK_NESTED_CASES) < MASK_NESTED_CASES) {
+			sqlStatesLine++;
+		}
+		return sqlStatesLine;
+	}
+
+	unsigned short int EndCaseBlock (unsigned short int sqlStatesLine) {
+		if ((sqlStatesLine & MASK_NESTED_CASES) > 0) {
+			sqlStatesLine--;
+		}
+		return sqlStatesLine;
+	}
+
+	bool IsIgnoreWhen (unsigned short int sqlStatesLine) {
+		return (sqlStatesLine & MASK_IGNORE_WHEN) != 0;
+	}
+
+	bool IsIntoCondition (unsigned short int sqlStatesLine) {
+		return (sqlStatesLine & MASK_INTO_CONDITION) != 0;
+	}
+
+	bool IsIntoCaseBlock (unsigned short int sqlStatesLine) {
+		return (sqlStatesLine & MASK_NESTED_CASES) != 0;
+	}
+
+	bool IsIntoExceptionBlock (unsigned short int sqlStatesLine) {
+		return (sqlStatesLine & MASK_INTO_EXCEPTION) != 0;
+	}
+
+	bool IsIntoDeclareBlock (unsigned short int sqlStatesLine) {
+		return (sqlStatesLine & MASK_INTO_DECLARE) != 0;
+	}
+
+	unsigned short int ForLine(int lineNumber) {
+		if ((lineNumber > 0) && (sqlStatement.size() > static_cast<size_t>(lineNumber))) {
+			return sqlStatement[lineNumber];
+		} else {
+			return 0;
+		}
+	}
+
+	SQLStates() {}
+
+private :
+	std::vector <unsigned short int> sqlStatement;
+	enum {
+		MASK_INTO_DECLARE = 0x1000,
+		MASK_INTO_EXCEPTION = 0x2000,
+		MASK_INTO_CONDITION = 0x4000,
+		MASK_IGNORE_WHEN = 0x8000,
+		MASK_NESTED_CASES = 0x0FFF
+	};
+};
+
+// Options used for LexerSQL
+struct OptionsSQL {
+	bool fold;
+	bool foldAtElse;
+	bool foldComment;
+	bool foldCompact;
+	bool foldOnlyBegin;
+	bool sqlBackticksIdentifier;
+	bool sqlNumbersignComment;
+	bool sqlBackslashEscapes;
+	bool sqlAllowDottedWord;
+	OptionsSQL() {
+		fold = false;
+		foldAtElse = false;
+		foldComment = false;
+		foldCompact = false;
+		foldOnlyBegin = false;
+		sqlBackticksIdentifier = false;
+		sqlNumbersignComment = false;
+		sqlBackslashEscapes = false;
+		sqlAllowDottedWord = false;
+	}
+};
+
+static const char * const sqlWordListDesc[] = {
+	"Keywords",
+	"Database Objects",
+	"PLDoc",
+	"SQL*Plus",
+	"User Keywords 1",
+	"User Keywords 2",
+	"User Keywords 3",
+	"User Keywords 4",
+	0
+};
+
+struct OptionSetSQL : public OptionSet<OptionsSQL> {
+	OptionSetSQL() {
+		DefineProperty("fold", &OptionsSQL::fold);
+
+		DefineProperty("lexer.sql.fold.at.else", &OptionsSQL::foldAtElse,
+		               "This option enables SQL folding on a \"ELSE\" and \"ELSIF\"line of an IF statement.");
+
+		DefineProperty("fold.comment", &OptionsSQL::foldComment);
+
+		DefineProperty("fold.compact", &OptionsSQL::foldCompact);
+
+		DefineProperty("fold.sql.only.begin", &OptionsSQL::foldOnlyBegin);
+
+		DefineProperty("lexer.sql.backticks.identifier", &OptionsSQL::sqlBackticksIdentifier);
+
+		DefineProperty("lexer.sql.numbersign.comment", &OptionsSQL::sqlNumbersignComment,
+		               "If \"lexer.sql.numbersign.comment\" property is set to 0 a line beginning with '#' will not be a comment.");
+
+		DefineProperty("sql.backslash.escapes", &OptionsSQL::sqlBackslashEscapes,
+		               "Enables backslash as an escape character in SQL.");
+
+		DefineProperty("lexer.sql.allow.dotted.word", &OptionsSQL::sqlAllowDottedWord,
+		               "Set to 1 to colourise recognized words with dots "
+		               "(recommended for Oracle PL/SQL objects).");
+
+		DefineWordListSets(sqlWordListDesc);
+	}
+};
+
+class LexerSQL : public ILexer {
+public :
+	LexerSQL() {}
+
+	int SCI_METHOD Version () const {
+		return lvOriginal;
+	}
+
+	void SCI_METHOD Release() {
+		delete this;
+	}
+
+	const char * SCI_METHOD PropertyNames() {
+		return osSQL.PropertyNames();
+	}
+
+	int SCI_METHOD PropertyType(const char *name) {
+		return osSQL.PropertyType(name);
+	}
+
+	const char * SCI_METHOD DescribeProperty(const char *name) {
+		return osSQL.DescribeProperty(name);
+	}
+
+	int SCI_METHOD PropertySet(const char *key, const char *val) {
+		if (osSQL.PropertySet(&options, key, val)) {
+			return 0;
+		}
+		return -1;
+	}
+
+	const char * SCI_METHOD DescribeWordListSets() {
+		return osSQL.DescribeWordListSets();
+	}
+
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex (unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+
+	void * SCI_METHOD PrivateCall(int, void *) {
+		return 0;
+	}
+
+	static ILexer *LexerFactorySQL() {
+		return new LexerSQL();
+	}
+private:
+	bool IsStreamCommentStyle(int style) {
+		return style == SCE_SQL_COMMENT ||
+		       style == SCE_SQL_COMMENTDOC ||
+		       style == SCE_SQL_COMMENTDOCKEYWORD ||
+		       style == SCE_SQL_COMMENTDOCKEYWORDERROR;
+	}
+
+	OptionsSQL options;
+	OptionSetSQL osSQL;
+	SQLStates sqlStates;
+
+	WordList keywords1;
+	WordList keywords2;
+	WordList kw_pldoc;
+	WordList kw_sqlplus;
+	WordList kw_user1;
+	WordList kw_user2;
+	WordList kw_user3;
+	WordList kw_user4;
+};
+
+int SCI_METHOD LexerSQL::WordListSet(int n, const char *wl) {
+	WordList *wordListN = 0;
+	switch (n) {
+	case 0:
+		wordListN = &keywords1;
+		break;
+	case 1:
+		wordListN = &keywords2;
+		break;
+	case 2:
+		wordListN = &kw_pldoc;
+		break;
+	case 3:
+		wordListN = &kw_sqlplus;
+		break;
+	case 4:
+		wordListN = &kw_user1;
+		break;
+	case 5:
+		wordListN = &kw_user2;
+		break;
+	case 6:
+		wordListN = &kw_user3;
+		break;
+	case 7:
+		wordListN = &kw_user4;
+	}
+	int firstModification = -1;
+	if (wordListN) {
+		WordList wlNew;
+		wlNew.Set(wl);
+		if (*wordListN != wlNew) {
+			wordListN->Set(wl);
+			firstModification = 0;
+		}
+	}
+	return firstModification;
+}
+
+void SCI_METHOD LexerSQL::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	LexAccessor styler(pAccess);
+	StyleContext sc(startPos, length, initStyle, styler);
 	int styleBeforeDCKeyword = SCE_SQL_DEFAULT;
-	for (; sc.More(); sc.Forward()) {
+	int offset = 0;
+	for (; sc.More(); sc.Forward(), offset++) {
 		// Determine if the current state should terminate.
 		switch (sc.state) {
 		case SCE_SQL_OPERATOR:
@@ -84,7 +354,7 @@
 			}
 			break;
 		case SCE_SQL_IDENTIFIER:
-			if (!IsAWordChar(sc.ch)) {
+			if (!IsAWordChar(sc.ch, options.sqlAllowDottedWord)) {
 				int nextState = SCE_SQL_DEFAULT;
 				char s[1000];
 				sc.GetCurrentLowered(s, sizeof(s));
@@ -161,7 +431,7 @@
 			}
 			break;
 		case SCE_SQL_CHARACTER:
-			if (sqlBackslashEscapes && sc.ch == '\\') {
+			if (options.sqlBackslashEscapes && sc.ch == '\\') {
 				sc.Forward();
 			} else if (sc.ch == '\'') {
 				if (sc.chNext == '\"') {
@@ -191,7 +461,7 @@
 				sc.SetState(SCE_SQL_NUMBER);
 			} else if (IsAWordStart(sc.ch)) {
 				sc.SetState(SCE_SQL_IDENTIFIER);
-			} else if (sc.ch == 0x60 && sqlBackticksIdentifier) {
+			} else if (sc.ch == 0x60 && options.sqlBackticksIdentifier) {
 				sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
 			} else if (sc.Match('/', '*')) {
 				if (sc.Match("/**") || sc.Match("/*!")) {	// Support of Doxygen doc. style
@@ -204,9 +474,9 @@
 				// MySQL requires a space or control char after --
 				// http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
 				// Perhaps we should enforce that with proper property:
-//~ 			} else if (sc.Match("-- ")) {
+				//~ 			} else if (sc.Match("-- ")) {
 				sc.SetState(SCE_SQL_COMMENTLINE);
-			} else if (sc.ch == '#') {
+			} else if (sc.ch == '#' && options.sqlNumbersignComment) {
 				sc.SetState(SCE_SQL_COMMENTLINEDOC);
 			} else if (sc.ch == '\'') {
 				sc.SetState(SCE_SQL_CHARACTER);
@@ -220,25 +490,10 @@
 	sc.Complete();
 }
 
-static bool IsStreamCommentStyle(int style) {
-	return style == SCE_SQL_COMMENT ||
-	       style == SCE_SQL_COMMENTDOC ||
-	       style == SCE_SQL_COMMENTDOCKEYWORD ||
-	       style == SCE_SQL_COMMENTDOCKEYWORDERROR;
-}
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment.
-static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
-                            WordList *[], Accessor &styler) {
-	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
-	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-	bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0;
-
-	// property fold.sql.exists
-	//	Enables "EXISTS" to end a fold as is started by "IF" in "DROP TABLE IF EXISTS".
-	bool foldSqlExists = styler.GetPropertyInt("fold.sql.exists", 1) != 0;
-
+void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	if (!options.fold)
+		return;
+	LexAccessor styler(pAccess);
 	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
 	int lineCurrent = styler.GetLine(startPos);
@@ -251,6 +506,14 @@
 	int styleNext = styler.StyleAt(startPos);
 	int style = initStyle;
 	bool endFound = false;
+	bool isUnfoldingIgnored = false;
+	// this statementFound flag avoids to fold when the statement is on only one line by ignoring ELSE or ELSIF
+	// eg. "IF condition1 THEN ... ELSIF condition2 THEN ... ELSE ... END IF;"
+	bool statementFound = false;
+	unsigned short int sqlStatesCurrentLine = 0;
+	if (!options.foldOnlyBegin) {
+		sqlStatesCurrentLine = sqlStates.ForLine(lineCurrent);
+	}
 	for (unsigned int i = startPos; i < endPos; i++) {
 		char ch = chNext;
 		chNext = styler.SafeGetCharAt(i + 1);
@@ -258,7 +521,16 @@
 		style = styleNext;
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-		if (foldComment && IsStreamCommentStyle(style)) {
+		if (atEOL || (ch == ';')) {
+			if (endFound) {
+				//Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;")
+				sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false);
+			}
+			// set endFound and isUnfoldingIgnored to false if EOL is reached or ';' is found
+			endFound = false;
+			isUnfoldingIgnored = false;
+		}
+		if (options.foldComment && IsStreamCommentStyle(style)) {
 			if (!IsStreamCommentStyle(stylePrev)) {
 				levelNext++;
 			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
@@ -266,7 +538,7 @@
 				levelNext--;
 			}
 		}
-		if (foldComment && (style == SCE_SQL_COMMENTLINE)) {
+		if (options.foldComment && (style == SCE_SQL_COMMENTLINE)) {
 			// MySQL needs -- comments to be followed by space or control char
 			if ((ch == '-') && (chNext == '-')) {
 				char chNext2 = styler.SafeGetCharAt(i + 2);
@@ -280,14 +552,18 @@
 		}
 		if (style == SCE_SQL_OPERATOR) {
 			if (ch == '(') {
-				levelNext++;
+				if (levelCurrent > levelNext)
+					levelCurrent--;
+ 				levelNext++;
 			} else if (ch == ')') {
 				levelNext--;
+			} else if ((!options.foldOnlyBegin) && ch == ';') {
+				sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, false);
 			}
 		}
 		// If new keyword (cannot trigger on elseif or nullif, does less tests)
 		if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {
-			const int MAX_KW_LEN = 6;	// Maximum length of folding keywords
+			const int MAX_KW_LEN = 9;	// Maximum length of folding keywords
 			char s[MAX_KW_LEN + 2];
 			unsigned int j = 0;
 			for (; j < MAX_KW_LEN + 1; j++) {
@@ -302,33 +578,133 @@
 			} else {
 				s[j] = '\0';
 			}
-			if ((!foldOnlyBegin) && (strcmp(s, "if") == 0 || strcmp(s, "loop") == 0)) {
+
+			if (strcmp(s, "if") == 0) {
 				if (endFound) {
-					// ignore
 					endFound = false;
+					if (options.foldOnlyBegin && !isUnfoldingIgnored) {
+						// this end isn't for begin block, but for if block ("end if;")
+						// so ignore previous "end" by increment levelNext.
+						levelNext++;
+					}
 				} else {
-					levelNext++;
+					if (!options.foldOnlyBegin)
+						sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+					if (levelCurrent > levelNext) {
+						// doesn't include this line into the folding block
+						// because doesn't hide IF (eg "END; IF")
+						levelCurrent = levelNext;
+					}
 				}
+			} else if (!options.foldOnlyBegin &&
+			           strcmp(s, "then") == 0 &&
+			           sqlStates.IsIntoCondition(sqlStatesCurrentLine)) {
+				sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, false);
+				if (!options.foldOnlyBegin) {
+					if (levelCurrent > levelNext) {
+						levelCurrent = levelNext;
+					}
+					if (!statementFound)
+						levelNext++;
+
+					statementFound = true;
+				} else if (levelCurrent > levelNext) {
+					// doesn't include this line into the folding block
+					// because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
+					levelCurrent = levelNext;
+				}
+			} else if (strcmp(s, "loop") == 0 ||
+			           strcmp(s, "case") == 0) {
+				if (endFound) {
+					endFound = false;
+					if (options.foldOnlyBegin && !isUnfoldingIgnored) {
+						// this end isn't for begin block, but for loop block ("end loop;") or case block ("end case;")
+						// so ignore previous "end" by increment levelNext.
+						levelNext++;
+					}
+					if ((!options.foldOnlyBegin) && strcmp(s, "case") == 0) {
+						sqlStatesCurrentLine = sqlStates.EndCaseBlock(sqlStatesCurrentLine);
+						levelNext--; //again for the "end case;" and block when
+					}
+				} else if (!options.foldOnlyBegin) {
+					if (strcmp(s, "case") == 0) {
+						sqlStatesCurrentLine = sqlStates.BeginCaseBlock(sqlStatesCurrentLine);
+
+						//for case block increment 2 times
+						if (!statementFound)
+							levelNext++;
+					}
+
+					if (levelCurrent > levelNext) {
+						levelCurrent = levelNext;
+					}
+					if (!statementFound)
+						levelNext++;
+
+					statementFound = true;
+				} else if (levelCurrent > levelNext) {
+					// doesn't include this line into the folding block
+					// because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
+					levelCurrent = levelNext;
+				}
+			} else if ((!options.foldOnlyBegin) && (
+			               // folding for ELSE and ELSIF block only if foldAtElse is set
+			               // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
+			               options.foldAtElse && !statementFound) && strcmp(s, "elsif") == 0) {
+				sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+				levelCurrent--;
+				levelNext--;
+			} else if ((!options.foldOnlyBegin) && (
+			               // folding for ELSE and ELSIF block only if foldAtElse is set
+			               // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
+			               options.foldAtElse && !statementFound) && strcmp(s, "else") == 0) {
+				// prevent also ELSE is on the same line (eg. "ELSE ... END IF;")
+				statementFound = true;
+				// we are in same case "} ELSE {" in C language
+				levelCurrent--;
+
 			} else if (strcmp(s, "begin") == 0) {
 				levelNext++;
+				sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, false);
 			} else if ((strcmp(s, "end") == 0) ||
-//						// DROP TABLE IF EXISTS or CREATE TABLE IF NOT EXISTS
-						(foldSqlExists && (strcmp(s, "exists") == 0)) ||
-//						//  SQL Anywhere permits IF ... ELSE ... ENDIF
-//						//      will only be active if "endif" appears in the
-//						//		keyword list.
-						(strcmp(s, "endif") == 0)) {
+			           // SQL Anywhere permits IF ... ELSE ... ENDIF
+			           // will only be active if "endif" appears in the
+			           // keyword list.
+			           (strcmp(s, "endif") == 0)) {
 				endFound = true;
 				levelNext--;
 				if (levelNext < SC_FOLDLEVELBASE) {
 					levelNext = SC_FOLDLEVELBASE;
+					isUnfoldingIgnored = true;
 				}
+			} else if ((!options.foldOnlyBegin) &&
+			           strcmp(s, "when") == 0 &&
+			           !sqlStates.IsIgnoreWhen(sqlStatesCurrentLine) &&
+			           !sqlStates.IsIntoExceptionBlock(sqlStatesCurrentLine) &&
+			           sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine)) {
+				sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+
+				// Don't foldind when CASE and WHEN are on the same line (with flag statementFound) (eg. "CASE selector WHEN expression1 THEN sequence_of_statements1;\n")
+				if (!statementFound) {
+					levelCurrent--;
+					levelNext--;
+				}
+			} else if ((!options.foldOnlyBegin) && strcmp(s, "exit") == 0) {
+				sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, true);
+			} else if ((!options.foldOnlyBegin) && !sqlStates.IsIntoDeclareBlock(sqlStatesCurrentLine) && strcmp(s, "exception") == 0) {
+				sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, true);
+			} else if ((!options.foldOnlyBegin) &&
+			           (strcmp(s, "declare") == 0 ||
+			            strcmp(s, "function") == 0 ||
+			            strcmp(s, "procedure") == 0 ||
+			            strcmp(s, "package") == 0)) {
+				sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, true);
 			}
 		}
 		if (atEOL) {
 			int levelUse = levelCurrent;
 			int lev = levelUse | levelNext << 16;
-			if (visibleChars == 0 && foldCompact)
+			if (visibleChars == 0 && options.foldCompact)
 				lev |= SC_FOLDLEVELWHITEFLAG;
 			if (levelUse < levelNext)
 				lev |= SC_FOLDLEVELHEADERFLAG;
@@ -338,7 +714,9 @@
 			lineCurrent++;
 			levelCurrent = levelNext;
 			visibleChars = 0;
-			endFound = false;
+			statementFound = false;
+			if (!options.foldOnlyBegin)
+				sqlStates.Set(lineCurrent, sqlStatesCurrentLine);
 		}
 		if (!isspacechar(ch)) {
 			visibleChars++;
@@ -346,16 +724,4 @@
 	}
 }
 
-static const char * const sqlWordListDesc[] = {
-	"Keywords",
-	"Database Objects",
-	"PLDoc",
-	"SQL*Plus",
-	"User Keywords 1",
-	"User Keywords 2",
-	"User Keywords 3",
-	"User Keywords 4",
-	0
-};
-
-LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", FoldSQLDoc, sqlWordListDesc);
+LexerModule lmSQL(SCLEX_SQL, LexerSQL::LexerFactorySQL, "sql", sqlWordListDesc);

Modified: trunk/scintilla/lexers/LexTCL.cxx
===================================================================
--- trunk/scintilla/lexers/LexTCL.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexTCL.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexTxt2tags.cxx
===================================================================
--- trunk/scintilla/lexers/LexTxt2tags.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexTxt2tags.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -27,7 +27,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexVHDL.cxx
===================================================================
--- trunk/scintilla/lexers/LexVHDL.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexVHDL.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -21,7 +21,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexVerilog.cxx
===================================================================
--- trunk/scintilla/lexers/LexVerilog.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexVerilog.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexers/LexYAML.cxx
===================================================================
--- trunk/scintilla/lexers/LexYAML.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexers/LexYAML.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"

Modified: trunk/scintilla/lexlib/CharacterSet.h
===================================================================
--- trunk/scintilla/lexlib/CharacterSet.h	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexlib/CharacterSet.h	2011-04-03 16:16:52 UTC (rev 5682)
@@ -50,8 +50,8 @@
 		assert(val < size);
 		bset[val] = true;
 	}
-	void AddString(const char *CharacterSet) {
-		for (const char *cp=CharacterSet; *cp; cp++) {
+	void AddString(const char *setToAdd) {
+		for (const char *cp=setToAdd; *cp; cp++) {
 			int val = static_cast<unsigned char>(*cp);
 			assert(val >= 0);
 			assert(val < size);

Modified: trunk/scintilla/lexlib/LexerBase.h
===================================================================
--- trunk/scintilla/lexlib/LexerBase.h	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexlib/LexerBase.h	2011-04-03 16:16:52 UTC (rev 5682)
@@ -20,7 +20,7 @@
 	WordList *keyWordLists[numWordLists+1];
 public:
 	LexerBase();
-	~LexerBase();
+	virtual ~LexerBase();
 	void SCI_METHOD Release();
 	int SCI_METHOD Version() const;
 	const char * SCI_METHOD PropertyNames();

Modified: trunk/scintilla/lexlib/OptionSet.h
===================================================================
--- trunk/scintilla/lexlib/OptionSet.h	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexlib/OptionSet.h	2011-04-03 16:16:52 UTC (rev 5682)
@@ -80,6 +80,8 @@
 		names += name;
 	}
 public:
+	virtual ~OptionSet() {
+	}
 	void DefineProperty(const char *name, plcob pb, std::string description="") {
 		nameToDef[name] = Option(pb, description);
 		AppendName(name);

Added: trunk/scintilla/lexlib/SparseState.h
===================================================================
--- trunk/scintilla/lexlib/SparseState.h	                        (rev 0)
+++ trunk/scintilla/lexlib/SparseState.h	2011-04-03 16:16:52 UTC (rev 5682)
@@ -0,0 +1,110 @@
+// Scintilla source code edit control
+/** @file SparseState.h
+ ** Hold lexer state that may change rarely.
+ ** This is often per-line state such as whether a particular type of section has been entered.
+ ** A state continues until it is changed.
+ **/
+// Copyright 2011 by Neil Hodgson <neilh at scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SPARSESTATE_H
+#define SPARSESTATE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+template <typename T>
+class SparseState {
+	struct State {
+		int position;
+		T value;
+		State(int position_, T value_) : position(position_), value(value_) {
+		}
+		inline bool operator<(const State &other) const {
+			return position < other.position;
+		}
+		inline bool operator==(const State &other) const {
+			return (position == other.position) && (value == other.value);
+		}
+	};
+	int positionFirst;
+	typedef std::vector<State> stateVector;
+	stateVector states;
+
+	typename stateVector::iterator Find(int position) {
+		State searchValue(position, T());
+		return std::lower_bound(states.begin(), states.end(), searchValue);
+	}
+
+public:
+	SparseState(int positionFirst_=-1) {
+		positionFirst = positionFirst_;
+	}
+	void Set(int position, T value) {
+		Delete(position);
+		if ((states.size() == 0) || (value != states[states.size()-1].value)) {
+			states.push_back(State(position, value));
+		}
+	}
+	T ValueAt(int position) {
+		if (!states.size())
+			return T();
+		if (position < states[0].position)
+			return T();
+		typename stateVector::iterator low = Find(position);
+		if (low == states.end()) {
+			return states[states.size()-1].value;
+		} else {
+			if (low->position > position) {
+				--low;
+			}
+			return low->value;
+		}
+	}
+	bool Delete(int position) {
+		typename stateVector::iterator low = Find(position);
+		if (low != states.end()) {
+			states.erase(low, states.end());
+			return true;
+		}
+		return false;
+	}
+	size_t size() const {
+		return states.size();
+	}
+
+	// Returns true if Merge caused a significant change
+	bool Merge(const SparseState<T> &other, int ignoreAfter) {
+		// Changes caused beyond ignoreAfter are not significant
+		Delete(ignoreAfter+1);
+
+		bool different = true;
+		bool changed = false;
+		typename stateVector::iterator low = Find(other.positionFirst);
+		if (static_cast<size_t>(states.end() - low) == other.states.size()) {
+			// Same number in other as after positionFirst in this
+			different = !std::equal(low, states.end(), other.states.begin());
+		}
+		if (different) {
+			if (low != states.end()) {
+				states.erase(low, states.end());
+				changed = true;
+			}
+			typename stateVector::const_iterator startOther = other.states.begin();
+			if (!states.empty() && states.back().value == startOther->value)
+				++startOther;
+			if (startOther != other.states.end()) {
+				states.insert(states.end(), startOther, other.states.end());
+				changed = true;
+			}
+		}
+		return changed;
+	}
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif


Property changes on: trunk/scintilla/lexlib/SparseState.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:keywords
   + Author Date Id Revision
Added: svn:eol-style
   + native

Modified: trunk/scintilla/lexlib/WordList.cxx
===================================================================
--- trunk/scintilla/lexlib/WordList.cxx	2011-04-03 15:54:28 UTC (rev 5681)
+++ trunk/scintilla/lexlib/WordList.cxx	2011-04-03 16:16:52 UTC (rev 5682)
@@ -110,6 +110,11 @@
 	}
 }
 

@@ 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