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@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 ®isters = *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@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; + SparseStatestd::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); + SparseStatestd::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@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@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@scintilla.org +// Copyright 1998-2011 by Neil Hodgson neilh@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@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.