Update Scintilla to version 2.25.
git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@5682 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
4ffcfbba6c
commit
c0b726a298
@ -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:
|
||||
|
@ -61,6 +61,7 @@ lexlib/LexerSimple.h \
|
||||
lexlib/OptionSet.h \
|
||||
lexlib/PropSetSimple.cxx \
|
||||
lexlib/PropSetSimple.h \
|
||||
lexlib/SparseState.h \
|
||||
lexlib/StyleContext.cxx \
|
||||
lexlib/StyleContext.h \
|
||||
lexlib/WordList.cxx \
|
||||
|
@ -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 @@ namespace Scintilla {
|
||||
#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 @@ void SurfaceImpl::SetConverter(int characterSet_) {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ SurfaceImpl::~SurfaceImpl() {
|
||||
|
||||
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 @@ bool SurfaceImpl::Initialised() {
|
||||
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 @@ void SurfaceImpl::Init(SurfaceID sid, WindowID wid) {
|
||||
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 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID
|
||||
PLATFORM_ASSERT(surface_);
|
||||
Release();
|
||||
SurfaceImpl *surfImpl = static_cast<SurfaceImpl *>(surface_);
|
||||
PLATFORM_ASSERT(surfImpl->drawable);
|
||||
PLATFORM_ASSERT(wid);
|
||||
#ifdef USE_CAIRO
|
||||
context = cairo_reference(surfImpl->context);
|
||||
#else
|
||||
PLATFORM_ASSERT(surfImpl->drawable);
|
||||
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 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID
|
||||
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 @@ void SurfaceImpl::MoveTo(int x_, int y_) {
|
||||
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 @@ void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore,
|
||||
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 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
|
||||
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 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl
|
||||
}
|
||||
}
|
||||
|
||||
#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,18 +1220,6 @@ static void AllFour(guint32 *pixels, int stride, int width, int height, int x, i
|
||||
pixels[(height-1-y)*stride+width-1-x] = val;
|
||||
}
|
||||
|
||||
static unsigned int GetRValue(unsigned int co) {
|
||||
return (co >> 16) & 0xff;
|
||||
}
|
||||
|
||||
static unsigned int GetGValue(unsigned int co) {
|
||||
return (co >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static unsigned int GetBValue(unsigned int co) {
|
||||
return co & 0xff;
|
||||
}
|
||||
|
||||
static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
|
||||
union {
|
||||
guint8 pixVal[4];
|
||||
@ -1037,8 +1232,41 @@ static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
|
||||
return converter.val;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static unsigned int GetRValue(unsigned int co) {
|
||||
return (co >> 16) & 0xff;
|
||||
}
|
||||
|
||||
static unsigned int GetGValue(unsigned int co) {
|
||||
return (co >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static unsigned int GetBValue(unsigned int co) {
|
||||
return co & 0xff;
|
||||
}
|
||||
|
||||
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 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
|
||||
|
||||
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 @@ void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated b
|
||||
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 @@ const int maxLengthTextRun = 10000;
|
||||
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 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
|
||||
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 @@ int SurfaceImpl::SetPalette(Palette *, bool) {
|
||||
}
|
||||
|
||||
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 @@ void Window::SetTitle(const char *s) {
|
||||
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 @@ PRectangle Window::GetMonitorRect(Point pt) {
|
||||
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 @@ public:
|
||||
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) {
|
||||
}
|
||||
|
@ -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 @@ void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internal
|
||||
|
||||
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::FocusIn(GtkWidget *widget, GdkEventFocus * /*event*/) {
|
||||
|
||||
gint ScintillaGTK::FocusOutThis(GtkWidget *widget) {
|
||||
try {
|
||||
GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
|
||||
SetFocusState(false);
|
||||
|
||||
if (PWidget(wPreedit) != NULL)
|
||||
@ -1422,7 +1424,7 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
|
||||
|
||||
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 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose)
|
||||
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 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose)
|
||||
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);
|
||||
|
@ -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,
|
||||
|
@ -255,8 +255,8 @@ class Palette {
|
||||
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 @@ protected:
|
||||
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();
|
||||
|
@ -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
|
||||
|
@ -159,6 +159,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
||||
#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 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
||||
#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 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
||||
#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 @@ struct SCNotification {
|
||||
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
|
||||
|
@ -352,6 +352,12 @@ set void SetMarginSensitiveN=2246(int margin, bool sensitive)
|
||||
# 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 @@ get bool GetMouseDownCaptures=2385(,)
|
||||
|
||||
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_CONTAINER=0x40000
|
||||
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_NIMROD=96
|
||||
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_WORD2=16
|
||||
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_COMMENTBLOCK=11
|
||||
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_COMMENT=22
|
||||
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
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -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,15 +62,184 @@ static inline bool IsAsmOperator(const int ch) {
|
||||
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)
|
||||
@ -104,6 +281,7 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
|
||||
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 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
|
||||
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 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
|
||||
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);
|
||||
|
||||
|
@ -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 @@ static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
|
||||
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)
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -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 @@ struct OptionsCPP {
|
||||
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 @@ struct OptionsCPP {
|
||||
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 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
|
||||
|
||||
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 @@ class LexerCPP : public ILexer {
|
||||
CharacterSet setLogicalOp;
|
||||
PPStates vlls;
|
||||
std::vector<PPDefinition> ppDefineHistory;
|
||||
PropSetSimple props;
|
||||
WordList keywords;
|
||||
WordList keywords2;
|
||||
WordList keywords3;
|
||||
@ -297,6 +318,7 @@ class LexerCPP : public ILexer {
|
||||
std::map<std::string, std::string> preprocessorDefinitionsStart;
|
||||
OptionsCPP options;
|
||||
OptionSetCPP osCPP;
|
||||
SparseState<std::string> rawStringTerminators;
|
||||
public:
|
||||
LexerCPP(bool caseSensitive_) :
|
||||
caseSensitive(caseSensitive_),
|
||||
@ -419,7 +441,6 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
||||
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 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
||||
}
|
||||
|
||||
const int maskActivity = 0x3F;
|
||||
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
|
||||
SparseState<std::string> rawSTNew(lineCurrent);
|
||||
|
||||
int activitySet = preproc.IsInactive() ? 0x40 : 0;
|
||||
|
||||
for (; sc.More(); sc.Forward()) {
|
||||
|
||||
if (sc.atLineStart) {
|
||||
if (sc.state == SCE_C_STRING) {
|
||||
if ((sc.state == SCE_C_STRING) || (sc.state == SCE_C_CHARACTER)) {
|
||||
// Prevent SCE_C_STRINGEOL from leaking back to previous line which
|
||||
// ends with a line continuation by locking in the state upto this position.
|
||||
sc.SetState(SCE_C_STRING);
|
||||
sc.SetState(sc.state);
|
||||
}
|
||||
// Reset states to begining of colourise so no surprises
|
||||
// if different sets of lines lexed.
|
||||
@ -515,6 +538,9 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
||||
if (sc.atLineEnd) {
|
||||
lineCurrent++;
|
||||
vlls.Add(lineCurrent, preproc);
|
||||
if (rawStringTerminator != "") {
|
||||
rawSTNew.Set(lineCurrent-1, rawStringTerminator);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle line continuation generically.
|
||||
@ -558,6 +584,23 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
||||
} 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 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
||||
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 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
||||
}
|
||||
}
|
||||
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 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
||||
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 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
||||
|| !FollowsPostfixOperator(sc, styler))) {
|
||||
sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx
|
||||
} else if (sc.ch == '\"') {
|
||||
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 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
||||
}
|
||||
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 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
|
||||
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 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
|
||||
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,7 +946,14 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
|
||||
levelNext--;
|
||||
}
|
||||
}
|
||||
if (options.foldComment && options.foldCommentExplicit && (style == SCE_C_COMMENTLINE)) {
|
||||
if (options.foldComment && options.foldCommentExplicit && ((style == SCE_C_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 == '{') {
|
||||
@ -881,6 +963,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
|
||||
if (ch == '#') {
|
||||
unsigned int j = i + 1;
|
||||
@ -894,7 +977,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
|
||||
}
|
||||
}
|
||||
}
|
||||
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 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
|
||||
visibleChars++;
|
||||
if (atEOL || (i == endPos-1)) {
|
||||
int levelUse = levelCurrent;
|
||||
if (options.foldAtElse) {
|
||||
if (options.foldSyntaxBased && options.foldAtElse) {
|
||||
levelUse = levelMinCurrent;
|
||||
}
|
||||
int lev = levelUse | levelNext << 16;
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -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,17 +66,187 @@ static bool IsStringSuffix(int ch) {
|
||||
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;
|
||||
|
||||
@ -294,24 +471,17 @@ static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
|
||||
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 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
|
||||
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 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
|
||||
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 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
|
||||
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 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
|
||||
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 FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -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 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
|
||||
|| 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;
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
@ -745,7 +744,17 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
|
||||
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 == '*'))) {
|
||||
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 == '/')) {
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -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 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
|
||||
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 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
|
||||
// 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] == '+') {
|
||||
|
@ -118,7 +118,6 @@ contains requires
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -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) {
|
||||
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) {
|
||||
@ -51,27 +63,285 @@ static inline bool IsANumberChar(int ch) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short int IgnoreWhen (unsigned short int sqlStatesLine, bool enable) {
|
||||
if (enable)
|
||||
sqlStatesLine |= MASK_IGNORE_WHEN;
|
||||
else
|
||||
sqlStatesLine &= ~MASK_IGNORE_WHEN;
|
||||
|
||||
return sqlStatesLine;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// property sql.backslash.escapes
|
||||
// Enables backslash as an escape character in SQL.
|
||||
bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
|
||||
|
||||
bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
|
||||
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 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
|
||||
}
|
||||
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 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
|
||||
}
|
||||
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 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
|
||||
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
|
||||
@ -206,7 +476,7 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
|
||||
// Perhaps we should enforce that with proper property:
|
||||
//~ } 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 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
|
||||
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 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
||||
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 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
||||
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 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
||||
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 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
||||
}
|
||||
if (style == SCE_SQL_OPERATOR) {
|
||||
if (ch == '(') {
|
||||
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 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
||||
} else {
|
||||
s[j] = '\0';
|
||||
}
|
||||
if ((!foldOnlyBegin) && (strcmp(s, "if") == 0 || strcmp(s, "loop") == 0)) {
|
||||
|
||||
if (strcmp(s, "if") == 0) {
|
||||
if (endFound) {
|
||||
// ignore
|
||||
endFound = false;
|
||||
} else {
|
||||
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 {
|
||||
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.
|
||||
// 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 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
||||
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 void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "PropSetSimple.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
|
@ -50,8 +50,8 @@ public:
|
||||
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);
|
||||
|
@ -20,7 +20,7 @@ protected:
|
||||
WordList *keyWordLists[numWordLists+1];
|
||||
public:
|
||||
LexerBase();
|
||||
~LexerBase();
|
||||
virtual ~LexerBase();
|
||||
void SCI_METHOD Release();
|
||||
int SCI_METHOD Version() const;
|
||||
const char * SCI_METHOD PropertyNames();
|
||||
|
@ -80,6 +80,8 @@ class OptionSet {
|
||||
names += name;
|
||||
}
|
||||
public:
|
||||
virtual ~OptionSet() {
|
||||
}
|
||||
void DefineProperty(const char *name, plcob pb, std::string description="") {
|
||||
nameToDef[name] = Option(pb, description);
|
||||
AppendName(name);
|
||||
|
110
scintilla/lexlib/SparseState.h
Normal file
110
scintilla/lexlib/SparseState.h
Normal file
@ -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
|
@ -110,6 +110,11 @@ void WordList::Set(const char *s) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Check whether a string is in the list.
|
||||
* List elements are either exact matches or prefixes.
|
||||
* Prefix elements start with '^' and match all strings that start with the rest of the element
|
||||
* so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'.
|
||||
*/
|
||||
bool WordList::InList(const char *s) const {
|
||||
if (0 == words)
|
||||
return false;
|
||||
|
@ -1,8 +1,8 @@
|
||||
A patch to Scintilla 2.22 containing our changes to Scintilla
|
||||
A patch to Scintilla 2.25 containing our changes to Scintilla
|
||||
(removing unused lexers and an updated marshallers file).
|
||||
diff -Naur scintilla_orig/gtk/scintilla-marshal.c scintilla/gtk/scintilla-marshal.c
|
||||
--- scintilla_orig/gtk/scintilla-marshal.c 2010-09-04 12:03:35.000000000 +0200
|
||||
+++ scintilla/gtk/scintilla-marshal.c 2008-12-06 12:11:33.000000000 +0100
|
||||
--- scintilla_orig/gtk/scintilla-marshal.c 2010-10-27 23:15:45.000000000 +0200
|
||||
+++ scintilla/gtk/scintilla-marshal.c 2011-04-03 17:42:59.000000000 +0200
|
||||
@@ -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
|
||||
@ -28,12 +28,13 @@ diff -Naur scintilla_orig/gtk/scintilla-marshal.c scintilla/gtk/scintilla-marsha
|
||||
{
|
||||
typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1,
|
||||
diff -Naur scintilla_orig/src/Catalogue.cxx scintilla/src/Catalogue.cxx
|
||||
--- scintilla_orig/src/Catalogue.cxx 2010-09-04 12:03:35.000000000 +0200
|
||||
+++ scintilla/src/Catalogue.cxx 2010-11-21 18:00:07.000000000 +0100
|
||||
@@ -81,98 +81,41 @@
|
||||
--- scintilla_orig/src/Catalogue.cxx 2011-03-17 23:41:24.000000000 +0100
|
||||
+++ scintilla/src/Catalogue.cxx 2011-04-03 17:43:45.000000000 +0200
|
||||
@@ -81,100 +81,42 @@
|
||||
|
||||
//++Autogenerated -- run src/LexGen.py to regenerate
|
||||
//**\(\tLINK_LEXER(\*);\n\)
|
||||
- LINK_LEXER(lmA68k);
|
||||
- LINK_LEXER(lmAbaqus);
|
||||
LINK_LEXER(lmAda);
|
||||
- LINK_LEXER(lmAns1);
|
||||
@ -51,7 +52,7 @@ diff -Naur scintilla_orig/src/Catalogue.cxx scintilla/src/Catalogue.cxx
|
||||
- LINK_LEXER(lmClw);
|
||||
- LINK_LEXER(lmClwNoCase);
|
||||
LINK_LEXER(lmCmake);
|
||||
- LINK_LEXER(lmCOBOL);
|
||||
LINK_LEXER(lmCOBOL);
|
||||
- LINK_LEXER(lmConf);
|
||||
LINK_LEXER(lmCPP);
|
||||
- LINK_LEXER(lmCPPNoCase);
|
||||
@ -86,6 +87,7 @@ diff -Naur scintilla_orig/src/Catalogue.cxx scintilla/src/Catalogue.cxx
|
||||
- LINK_LEXER(lmMatlab);
|
||||
- LINK_LEXER(lmMETAPOST);
|
||||
- LINK_LEXER(lmMMIXAL);
|
||||
- LINK_LEXER(lmModula);
|
||||
- LINK_LEXER(lmMSSQL);
|
||||
- LINK_LEXER(lmMySQL);
|
||||
- LINK_LEXER(lmNimrod);
|
||||
|
@ -129,11 +129,11 @@ void AutoComplete::Select(const char *word) {
|
||||
size_t lenWord = strlen(word);
|
||||
int location = -1;
|
||||
const int maxItemLen=1000;
|
||||
char item[maxItemLen];
|
||||
int start = 0; // lower bound of the api array block to search
|
||||
int end = lb->Length() - 1; // upper bound of the api array block to search
|
||||
while ((start <= end) && (location == -1)) { // Binary searching loop
|
||||
int pivot = (start + end) / 2;
|
||||
char item[maxItemLen];
|
||||
lb->GetValue(pivot, item, maxItemLen);
|
||||
int cond;
|
||||
if (ignoreCase)
|
||||
|
@ -29,6 +29,7 @@ CallTip::CallTip() {
|
||||
rectUp = PRectangle(0,0,0,0);
|
||||
rectDown = PRectangle(0,0,0,0);
|
||||
lineHeight = 1;
|
||||
offsetMain = 0;
|
||||
startHighlight = 0;
|
||||
endHighlight = 0;
|
||||
tabSize = 0;
|
||||
@ -45,6 +46,8 @@ CallTip::CallTip() {
|
||||
colourSel.desired = ColourDesired(0, 0, 0x80);
|
||||
colourShade.desired = ColourDesired(0, 0, 0);
|
||||
colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
|
||||
codePage = 0;
|
||||
clickPlace = 0;
|
||||
}
|
||||
|
||||
CallTip::~CallTip() {
|
||||
|
@ -14,14 +14,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// With Borland C++ 5.5, including <string> includes Windows.h leading to defining
|
||||
// FindText to FindTextA which makes calls here to Document::FindText fail.
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef FindText
|
||||
#undef FindText
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "ILexer.h"
|
||||
@ -95,7 +87,7 @@ void LexInterface::Colourise(int start, int end) {
|
||||
|
||||
Document::Document() {
|
||||
refCount = 0;
|
||||
#ifdef unix
|
||||
#ifdef __unix__
|
||||
eolMode = SC_EOL_LF;
|
||||
#else
|
||||
eolMode = SC_EOL_CRLF;
|
||||
@ -552,7 +544,7 @@ int Document::NextPosition(int pos, int moveDir) const {
|
||||
// See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx
|
||||
// http://msdn.microsoft.com/en-us/library/cc194790.aspx
|
||||
if ((pos - 1) <= posStartLine) {
|
||||
return posStartLine - 1;
|
||||
return pos - 1;
|
||||
} else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) {
|
||||
// Must actually be trail byte
|
||||
return pos - 2;
|
||||
@ -1317,7 +1309,11 @@ long Document::FindText(int minPos, int maxPos, const char *search,
|
||||
|
||||
//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
|
||||
const int limitPos = Platform::Maximum(startPos, endPos);
|
||||
int pos = forward ? startPos : (startPos - 1);
|
||||
int pos = startPos;
|
||||
if (!forward) {
|
||||
// Back all of a character
|
||||
pos = NextPosition(pos, increment);
|
||||
}
|
||||
if (caseSensitive) {
|
||||
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
|
||||
bool found = (pos + lengthFind) <= limitPos;
|
||||
@ -1526,8 +1522,8 @@ void Document::EnsureStyledTo(int pos) {
|
||||
IncrementStyleClock();
|
||||
if (pli && !pli->UseContainerLexing()) {
|
||||
int lineEndStyled = LineFromPosition(GetEndStyled());
|
||||
int endStyled = LineStart(lineEndStyled);
|
||||
pli->Colourise(endStyled, pos);
|
||||
int endStyledTo = LineStart(lineEndStyled);
|
||||
pli->Colourise(endStyledTo, pos);
|
||||
} else {
|
||||
// Ask the watchers to style, and stop as soon as one responds.
|
||||
for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
|
||||
|
@ -357,6 +357,7 @@ public:
|
||||
const WatcherWithUserData *GetWatchers() const { return watchers; }
|
||||
int GetLenWatchers() const { return lenWatchers; }
|
||||
|
||||
CharClassify::cc WordCharClass(unsigned char ch);
|
||||
bool IsWordPartSeparator(char ch);
|
||||
int WordPartLeft(int pos);
|
||||
int WordPartRight(int pos);
|
||||
@ -368,7 +369,6 @@ public:
|
||||
int BraceMatch(int position, int maxReStyle);
|
||||
|
||||
private:
|
||||
CharClassify::cc WordCharClass(unsigned char ch);
|
||||
bool IsWordStartAt(int pos);
|
||||
bool IsWordEndAt(int pos);
|
||||
bool IsWordAt(int start, int end);
|
||||
|
@ -16,14 +16,6 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
// With Borland C++ 5.5, including <string> includes Windows.h leading to defining
|
||||
// FindText to FindTextA which makes calls here to Document::FindText fail.
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef FindText
|
||||
#undef FindText
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "ILexer.h"
|
||||
@ -141,6 +133,9 @@ Editor::Editor() {
|
||||
lastXChosen = 0;
|
||||
lineAnchor = 0;
|
||||
originalAnchorPos = 0;
|
||||
wordSelectAnchorStartPos = 0;
|
||||
wordSelectAnchorEndPos = 0;
|
||||
wordSelectInitialCaretPos = -1;
|
||||
|
||||
primarySelection = true;
|
||||
|
||||
@ -183,7 +178,8 @@ Editor::Editor() {
|
||||
|
||||
lengthForEncode = -1;
|
||||
|
||||
needUpdateUI = true;
|
||||
needUpdateUI = 0;
|
||||
ContainerNeedsUpdate(SC_UPDATE_CONTENT);
|
||||
braces[0] = invalidPosition;
|
||||
braces[1] = invalidPosition;
|
||||
bracesMatchStyle = STYLE_BRACEBAD;
|
||||
@ -442,7 +438,10 @@ int Editor::LineFromLocation(Point pt) {
|
||||
}
|
||||
|
||||
void Editor::SetTopLine(int topLineNew) {
|
||||
if (topLine != topLineNew) {
|
||||
topLine = topLineNew;
|
||||
ContainerNeedsUpdate(SC_UPDATE_V_SCROLL);
|
||||
}
|
||||
posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine));
|
||||
}
|
||||
|
||||
@ -706,17 +705,17 @@ void Editor::SetRectangularRange() {
|
||||
if (sel.selType == Selection::selThin) {
|
||||
xCaret = xAnchor;
|
||||
}
|
||||
int lineAnchor = pdoc->LineFromPosition(sel.Rectangular().anchor.Position());
|
||||
int lineAnchorRect = pdoc->LineFromPosition(sel.Rectangular().anchor.Position());
|
||||
int lineCaret = pdoc->LineFromPosition(sel.Rectangular().caret.Position());
|
||||
int increment = (lineCaret > lineAnchor) ? 1 : -1;
|
||||
for (int line=lineAnchor; line != lineCaret+increment; line += increment) {
|
||||
int increment = (lineCaret > lineAnchorRect) ? 1 : -1;
|
||||
for (int line=lineAnchorRect; line != lineCaret+increment; line += increment) {
|
||||
SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor));
|
||||
if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0)
|
||||
range.ClearVirtualSpace();
|
||||
if (line == lineAnchor)
|
||||
if (line == lineAnchorRect)
|
||||
sel.SetSelection(range);
|
||||
else
|
||||
sel.AddSelection(range);
|
||||
sel.AddSelectionWithoutTrim(range);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -749,7 +748,7 @@ void Editor::InvalidateSelection(SelectionRange newMain, bool invalidateWholeSel
|
||||
lastAffected = Platform::Maximum(lastAffected, sel.Range(r).anchor.Position());
|
||||
}
|
||||
}
|
||||
needUpdateUI = true;
|
||||
ContainerNeedsUpdate(SC_UPDATE_SELECTION);
|
||||
InvalidateRange(firstAffected, lastAffected);
|
||||
}
|
||||
|
||||
@ -990,6 +989,7 @@ void Editor::HorizontalScrollTo(int xPos) {
|
||||
xPos = 0;
|
||||
if ((wrapState == eWrapNone) && (xOffset != xPos)) {
|
||||
xOffset = xPos;
|
||||
ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
|
||||
SetHorizontalScrollPos();
|
||||
RedrawRect(GetClientRectangle());
|
||||
}
|
||||
@ -1299,6 +1299,7 @@ void Editor::SetXYScroll(XYScrollPosition newXY) {
|
||||
}
|
||||
if (newXY.xOffset != xOffset) {
|
||||
xOffset = newXY.xOffset;
|
||||
ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
|
||||
if (newXY.xOffset > 0) {
|
||||
PRectangle rcText = GetTextRectangle();
|
||||
if (horizontalScrollBarVisible &&
|
||||
@ -2042,7 +2043,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
|
||||
ll->edgeColumn = -1;
|
||||
}
|
||||
|
||||
char styleByte = 0;
|
||||
char styleByte;
|
||||
const int styleMask = pdoc->stylingBitsMask;
|
||||
ll->styleBitsSet = 0;
|
||||
// Fill base line layout
|
||||
@ -3043,7 +3044,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
|
||||
}
|
||||
|
||||
// Draw any translucent whole line states
|
||||
rcSegment.left = xStart;
|
||||
rcSegment.left = 0;
|
||||
rcSegment.right = rcLine.right - 1;
|
||||
if (caret.active && vsDraw.showCaretLineBackground && ll->containsCaret) {
|
||||
SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground.allocated, vsDraw.caretLineAlpha);
|
||||
@ -3165,11 +3166,11 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
|
||||
}
|
||||
|
||||
pixmapSelPattern->FillRectangle(rcPattern, colourFMFill);
|
||||
pixmapSelPattern->PenColour(colourFMStripes);
|
||||
for (int stripe = 0; stripe < patternSize; stripe++) {
|
||||
// Alternating 1 pixel stripes is same as checkerboard.
|
||||
pixmapSelPattern->MoveTo(0, stripe * 2);
|
||||
pixmapSelPattern->LineTo(patternSize, stripe * 2 - patternSize);
|
||||
for (int y = 0; y < patternSize; y++) {
|
||||
for (int x = y % 2; x < patternSize; x+=2) {
|
||||
PRectangle rcPixel(x, y, x+1, y+1);
|
||||
pixmapSelPattern->FillRectangle(rcPixel, colourFMStripes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3183,10 +3184,9 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
|
||||
pixmapIndentGuideHighlight->FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated);
|
||||
pixmapIndentGuideHighlight->PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated);
|
||||
for (int stripe = 1; stripe < vs.lineHeight + 1; stripe += 2) {
|
||||
pixmapIndentGuide->MoveTo(0, stripe);
|
||||
pixmapIndentGuide->LineTo(2, stripe);
|
||||
pixmapIndentGuideHighlight->MoveTo(0, stripe);
|
||||
pixmapIndentGuideHighlight->LineTo(2, stripe);
|
||||
PRectangle rcPixel(0, stripe, 1, stripe+1);
|
||||
pixmapIndentGuide->FillRectangle(rcPixel, vs.styles[STYLE_INDENTGUIDE].fore.allocated);
|
||||
pixmapIndentGuideHighlight->FillRectangle(rcPixel, vs.styles[STYLE_BRACELIGHT].fore.allocated);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3316,7 +3316,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
|
||||
surfaceWindow->SetPalette(&palTemp, true);
|
||||
|
||||
NotifyUpdateUI();
|
||||
needUpdateUI = false;
|
||||
needUpdateUI = 0;
|
||||
|
||||
RefreshStyleData();
|
||||
RefreshPixMaps(surfaceWindow);
|
||||
@ -3921,8 +3921,8 @@ void Editor::InsertPaste(SelectionPosition selStart, const char *text, int len)
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::ClearSelection() {
|
||||
if (!sel.IsRectangular())
|
||||
void Editor::ClearSelection(bool retainMultipleSelections) {
|
||||
if (!sel.IsRectangular() && !retainMultipleSelections)
|
||||
FilterSelections();
|
||||
UndoGroup ug(pdoc);
|
||||
for (size_t r=0; r<sel.Count(); r++) {
|
||||
@ -4222,6 +4222,7 @@ void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool
|
||||
void Editor::NotifyUpdateUI() {
|
||||
SCNotification scn = {0};
|
||||
scn.nmhdr.code = SCN_UPDATEUI;
|
||||
scn.updated = needUpdateUI;
|
||||
NotifyParent(scn);
|
||||
}
|
||||
|
||||
@ -4338,7 +4339,7 @@ static inline int MovePositionForDeletion(int position, int startDeletion, int l
|
||||
}
|
||||
|
||||
void Editor::NotifyModified(Document *, DocModification mh, void *) {
|
||||
needUpdateUI = true;
|
||||
ContainerNeedsUpdate(SC_UPDATE_CONTENT);
|
||||
if (paintState == painting) {
|
||||
CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length));
|
||||
}
|
||||
@ -4620,6 +4621,11 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
|
||||
NotifyParent(scn);
|
||||
}
|
||||
|
||||
// Something has changed that the container should know about
|
||||
void Editor::ContainerNeedsUpdate(int flags) {
|
||||
needUpdateUI |= flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force scroll and keep position relative to top of window.
|
||||
*
|
||||
@ -4727,7 +4733,6 @@ void Editor::Duplicate(bool forLine) {
|
||||
forLine = true;
|
||||
}
|
||||
UndoGroup ug(pdoc, sel.Count() > 1);
|
||||
SelectionPosition last;
|
||||
const char *eol = "";
|
||||
int eolLen = 0;
|
||||
if (forLine) {
|
||||
@ -5131,6 +5136,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
|
||||
inOverstrike = !inOverstrike;
|
||||
DropCaret();
|
||||
ShowCaretAtCurrentPosition();
|
||||
ContainerNeedsUpdate(SC_UPDATE_CONTENT);
|
||||
NotifyUpdateUI();
|
||||
break;
|
||||
case SCI_CANCEL: // Cancel any modes - handled in subclass
|
||||
@ -5230,6 +5236,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
|
||||
UndoGroup ug(pdoc);
|
||||
sel.RangeMain().caret = SelectionPosition(
|
||||
InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
|
||||
sel.RangeMain().anchor = sel.RangeMain().caret;
|
||||
int endWord = pdoc->NextWordStart(sel.MainCaret(), 1);
|
||||
pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret());
|
||||
}
|
||||
@ -5836,6 +5843,16 @@ bool Editor::PointInSelMargin(Point pt) {
|
||||
}
|
||||
}
|
||||
|
||||
Window::Cursor Editor::GetMarginCursor(Point pt) {
|
||||
int x = 0;
|
||||
for (int margin = 0; margin < ViewStyle::margins; margin++) {
|
||||
if ((pt.x >= x) && (pt.x < x + vs.ms[margin].width))
|
||||
return static_cast<Window::Cursor>(vs.ms[margin].cursor);
|
||||
x += vs.ms[margin].width;
|
||||
}
|
||||
return Window::cursorReverseArrow;
|
||||
}
|
||||
|
||||
void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {
|
||||
if (lineAnchor_ < lineCurrent_) {
|
||||
SetSelection(pdoc->LineStart(lineCurrent_ + 1),
|
||||
@ -5849,6 +5866,30 @@ void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::WordSelection(int pos) {
|
||||
if (pos < wordSelectAnchorStartPos) {
|
||||
// Extend backward to the word containing pos.
|
||||
// Skip ExtendWordSelect if the line is empty or if pos is after the last character.
|
||||
// This ensures that a series of empty lines isn't counted as a single "word".
|
||||
if (!pdoc->IsLineEndPosition(pos))
|
||||
pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos + 1, 1), -1);
|
||||
SetSelection(pos, wordSelectAnchorEndPos);
|
||||
} else if (pos > wordSelectAnchorEndPos) {
|
||||
// Extend forward to the word containing the character to the left of pos.
|
||||
// Skip ExtendWordSelect if the line is empty or if pos is the first position on the line.
|
||||
// This ensures that a series of empty lines isn't counted as a single "word".
|
||||
if (pos > pdoc->LineStart(pdoc->LineFromPosition(pos)))
|
||||
pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos - 1, -1), 1);
|
||||
SetSelection(pos, wordSelectAnchorStartPos);
|
||||
} else {
|
||||
// Select only the anchored word
|
||||
if (pos >= originalAnchorPos)
|
||||
SetSelection(wordSelectAnchorEndPos, wordSelectAnchorStartPos);
|
||||
else
|
||||
SetSelection(wordSelectAnchorStartPos, wordSelectAnchorEndPos);
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DwellEnd(bool mouseMoved) {
|
||||
if (mouseMoved)
|
||||
ticksToDwell = dwellDelay;
|
||||
@ -5910,13 +5951,33 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
|
||||
}
|
||||
|
||||
if (selectionType == selWord) {
|
||||
if (sel.MainCaret() >= originalAnchorPos) { // Moved forward
|
||||
SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), 1),
|
||||
pdoc->ExtendWordSelect(originalAnchorPos, -1));
|
||||
} else { // Moved backward
|
||||
SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), -1),
|
||||
pdoc->ExtendWordSelect(originalAnchorPos, 1));
|
||||
int charPos = originalAnchorPos;
|
||||
if (sel.MainCaret() == originalAnchorPos) {
|
||||
charPos = PositionFromLocation(pt, false, true);
|
||||
charPos = MovePositionOutsideChar(charPos, -1);
|
||||
}
|
||||
|
||||
int startWord, endWord;
|
||||
if ((sel.MainCaret() >= originalAnchorPos) && !pdoc->IsLineEndPosition(charPos)) {
|
||||
startWord = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(charPos + 1, 1), -1);
|
||||
endWord = pdoc->ExtendWordSelect(charPos, 1);
|
||||
} else {
|
||||
// Selecting backwards, or anchor beyond last character on line. In these cases,
|
||||
// we select the word containing the character to the *left* of the anchor.
|
||||
if (charPos > pdoc->LineStart(pdoc->LineFromPosition(charPos))) {
|
||||
startWord = pdoc->ExtendWordSelect(charPos, -1);
|
||||
endWord = pdoc->ExtendWordSelect(startWord, 1);
|
||||
} else {
|
||||
// Anchor at start of line; select nothing to begin with.
|
||||
startWord = charPos;
|
||||
endWord = charPos;
|
||||
}
|
||||
}
|
||||
|
||||
wordSelectAnchorStartPos = startWord;
|
||||
wordSelectAnchorEndPos = endWord;
|
||||
wordSelectInitialCaretPos = sel.MainCaret();
|
||||
WordSelection(wordSelectInitialCaretPos);
|
||||
} else if (selectionType == selLine) {
|
||||
lineAnchor = LineFromLocation(pt);
|
||||
SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
|
||||
@ -5981,6 +6042,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
|
||||
InvalidateSelection(SelectionRange(newPos), true);
|
||||
if (sel.Count() > 1)
|
||||
Redraw();
|
||||
if ((sel.Count() > 1) || (sel.selType != Selection::selStream))
|
||||
sel.Clear();
|
||||
sel.selType = alt ? Selection::selRectangle : Selection::selStream;
|
||||
SetSelection(newPos, newPos);
|
||||
@ -6098,7 +6160,7 @@ void Editor::ButtonMove(Point pt) {
|
||||
}
|
||||
} else if (selectionType == selWord) {
|
||||
// Continue selecting by word
|
||||
if (movePos.Position() == originalAnchorPos) { // Didn't move
|
||||
if (movePos.Position() == wordSelectInitialCaretPos) { // Didn't move
|
||||
// No need to do anything. Previously this case was lumped
|
||||
// in with "Moved forward", but that can be harmful in this
|
||||
// case: a handler for the NotifyDoubleClick re-adjusts
|
||||
@ -6108,12 +6170,9 @@ void Editor::ButtonMove(Point pt) {
|
||||
// the ButtonMove() called via Tick() for auto-scrolling
|
||||
// could result in the fancier word selection adjustment
|
||||
// being unmade.
|
||||
} else if (movePos.Position() > originalAnchorPos) { // Moved forward
|
||||
SetSelection(pdoc->ExtendWordSelect(movePos.Position(), 1),
|
||||
pdoc->ExtendWordSelect(originalAnchorPos, -1));
|
||||
} else { // Moved backward
|
||||
SetSelection(pdoc->ExtendWordSelect(movePos.Position(), -1),
|
||||
pdoc->ExtendWordSelect(originalAnchorPos, 1));
|
||||
} else {
|
||||
wordSelectInitialCaretPos = -1;
|
||||
WordSelection(movePos.Position());
|
||||
}
|
||||
} else {
|
||||
// Continue selecting by line
|
||||
@ -6151,7 +6210,7 @@ void Editor::ButtonMove(Point pt) {
|
||||
} else {
|
||||
if (vs.fixedColumnWidth > 0) { // There is a margin
|
||||
if (PointInSelMargin(pt)) {
|
||||
DisplayCursor(Window::cursorReverseArrow);
|
||||
DisplayCursor(GetMarginCursor(pt));
|
||||
SetHotSpotRange(NULL);
|
||||
return; // No need to test for selection
|
||||
}
|
||||
@ -6177,6 +6236,8 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
|
||||
if (inDragDrop == ddInitial) {
|
||||
inDragDrop = ddNone;
|
||||
SetEmptySelection(newPos.Position());
|
||||
selectionType = selChar;
|
||||
originalAnchorPos = sel.MainCaret();
|
||||
}
|
||||
if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) {
|
||||
hotSpotClickPos = INVALID_POSITION;
|
||||
@ -6184,7 +6245,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
|
||||
}
|
||||
if (HaveMouseCapture()) {
|
||||
if (PointInSelMargin(pt)) {
|
||||
DisplayCursor(Window::cursorReverseArrow);
|
||||
DisplayCursor(GetMarginCursor(pt));
|
||||
} else {
|
||||
DisplayCursor(Window::cursorText);
|
||||
SetHotSpotRange(NULL);
|
||||
@ -6344,7 +6405,7 @@ void Editor::IdleStyling() {
|
||||
|
||||
if (needUpdateUI) {
|
||||
NotifyUpdateUI();
|
||||
needUpdateUI = false;
|
||||
needUpdateUI = 0;
|
||||
}
|
||||
styleNeeded.Reset();
|
||||
}
|
||||
@ -7001,6 +7062,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
|
||||
|
||||
case SCI_SETXOFFSET:
|
||||
xOffset = wParam;
|
||||
ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
|
||||
SetHorizontalScrollPos();
|
||||
Redraw();
|
||||
break;
|
||||
@ -7315,7 +7377,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
|
||||
case SCI_GOTOPOS:
|
||||
SetEmptySelection(wParam);
|
||||
EnsureCaretVisible();
|
||||
Redraw();
|
||||
break;
|
||||
|
||||
case SCI_GETCURLINE: {
|
||||
@ -7466,6 +7527,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
|
||||
break;
|
||||
}
|
||||
xOffset = 0;
|
||||
ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
|
||||
InvalidateStyleRedraw();
|
||||
ReconfigureScrollBars();
|
||||
break;
|
||||
@ -7786,6 +7848,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
|
||||
else
|
||||
return 0;
|
||||
|
||||
case SCI_SETMARGINCURSORN:
|
||||
if (ValidMargin(wParam))
|
||||
vs.ms[wParam].cursor = lParam;
|
||||
break;
|
||||
|
||||
case SCI_GETMARGINCURSORN:
|
||||
if (ValidMargin(wParam))
|
||||
return vs.ms[wParam].cursor;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case SCI_STYLECLEARALL:
|
||||
vs.ClearStyles();
|
||||
InvalidateStyleRedraw();
|
||||
|
@ -201,6 +201,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
int lastXChosen;
|
||||
int lineAnchor;
|
||||
int originalAnchorPos;
|
||||
int wordSelectAnchorStartPos;
|
||||
int wordSelectAnchorEndPos;
|
||||
int wordSelectInitialCaretPos;
|
||||
int targetStart;
|
||||
int targetEnd;
|
||||
int searchFlags;
|
||||
@ -208,7 +211,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
int posTopLine;
|
||||
int lengthForEncode;
|
||||
|
||||
bool needUpdateUI;
|
||||
int needUpdateUI;
|
||||
Position braces[2];
|
||||
int bracesMatchStyle;
|
||||
int highlightGuideColumn;
|
||||
@ -391,7 +394,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
void AddChar(char ch);
|
||||
virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
|
||||
void InsertPaste(SelectionPosition selStart, const char *text, int len);
|
||||
void ClearSelection();
|
||||
void ClearSelection(bool retainMultipleSelections=false);
|
||||
void ClearAll();
|
||||
void ClearDocumentStyle();
|
||||
void Cut();
|
||||
@ -438,6 +441,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
void NotifyErrorOccurred(Document *doc, void *userData, int status);
|
||||
void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
|
||||
|
||||
void ContainerNeedsUpdate(int flags);
|
||||
void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false);
|
||||
enum { cmSame, cmUpper, cmLower } caseMap;
|
||||
virtual std::string CaseMapString(const std::string &s, int caseMapping);
|
||||
@ -479,7 +483,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
bool PositionInSelection(int pos);
|
||||
bool PointInSelection(Point pt);
|
||||
bool PointInSelMargin(Point pt);
|
||||
Window::Cursor GetMarginCursor(Point pt);
|
||||
void LineSelection(int lineCurrent_, int lineAnchor_);
|
||||
void WordSelection(int pos);
|
||||
void DwellEnd(bool mouseMoved);
|
||||
void MouseLeave();
|
||||
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
|
||||
|
@ -38,7 +38,6 @@ LexerManager *LexerManager::theInstance = NULL;
|
||||
void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
|
||||
fneFactory = fFactory;
|
||||
fnFactory = fFactory(index);
|
||||
externalLanguage = index;
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -27,11 +27,12 @@ typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned i
|
||||
class ExternalLexerModule : public LexerModule {
|
||||
protected:
|
||||
GetLexerFactoryFunction fneFactory;
|
||||
int externalLanguage;
|
||||
char name[100];
|
||||
public:
|
||||
ExternalLexerModule(int language_, LexerFunction fnLexer_,
|
||||
const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_) {
|
||||
const char *languageName_=0, LexerFunction fnFolder_=0) :
|
||||
LexerModule(language_, fnLexer_, 0, fnFolder_),
|
||||
fneFactory(0) {
|
||||
strncpy(name, languageName_, sizeof(name));
|
||||
name[sizeof(name)-1] = '\0';
|
||||
languageName = name;
|
||||
|
@ -42,6 +42,10 @@ public:
|
||||
|
||||
/// Divide an interval into multiple partitions.
|
||||
/// Useful for breaking a document down into sections such as lines.
|
||||
/// A 0 length interval has a single 0 length partition, numbered 0
|
||||
/// If interval not 0 length then each partition non-zero length
|
||||
/// When needed, positions after the interval are considered part of the last partition
|
||||
/// but the end of the last partition can be found with PositionFromPartition(last+1).
|
||||
|
||||
class Partitioning {
|
||||
private:
|
||||
@ -153,6 +157,7 @@ public:
|
||||
return pos;
|
||||
}
|
||||
|
||||
/// Return value in range [0 .. Partitions() - 1] even for arguments outside interval
|
||||
int PartitionFromPosition(int pos) const {
|
||||
if (body->Length() <= 1)
|
||||
return 0;
|
||||
|
@ -68,6 +68,8 @@ LineLayout::LineLayout(int maxLineLength_) :
|
||||
widthLine(wrapWidthInfinite),
|
||||
lines(1),
|
||||
wrapIndent(0) {
|
||||
bracePreviousStyles[0] = 0;
|
||||
bracePreviousStyles[1] = 0;
|
||||
Resize(maxLineLength_);
|
||||
}
|
||||
|
||||
|
@ -147,8 +147,10 @@ bool RunStyles::FillRange(int &position, int value, int &fillLength) {
|
||||
runEnd = RunFromPosition(end);
|
||||
RemoveRunIfSameAsPrevious(runEnd);
|
||||
RemoveRunIfSameAsPrevious(runStart);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void RunStyles::SetValueAt(int position, int value) {
|
||||
|
@ -20,6 +20,9 @@ using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
|
||||
if (position == startChange) {
|
||||
virtualSpace = 0;
|
||||
}
|
||||
if (insertion) {
|
||||
if (position > startChange) {
|
||||
position += length;
|
||||
@ -31,6 +34,7 @@ void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int
|
||||
position -= length;
|
||||
} else {
|
||||
position = startChange;
|
||||
virtualSpace = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -291,6 +295,11 @@ void Selection::AddSelection(SelectionRange range) {
|
||||
mainRange = ranges.size() - 1;
|
||||
}
|
||||
|
||||
void Selection::AddSelectionWithoutTrim(SelectionRange range) {
|
||||
ranges.push_back(range);
|
||||
mainRange = ranges.size() - 1;
|
||||
}
|
||||
|
||||
void Selection::TentativeSelection(SelectionRange range) {
|
||||
if (!tentativeMain) {
|
||||
rangesSaved = ranges;
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
struct SelectionSegment {
|
||||
SelectionPosition start;
|
||||
SelectionPosition end;
|
||||
SelectionSegment() {
|
||||
SelectionSegment() : start(), end() {
|
||||
}
|
||||
SelectionSegment(SelectionPosition a, SelectionPosition b) {
|
||||
if (a < b) {
|
||||
@ -86,7 +86,7 @@ struct SelectionRange {
|
||||
SelectionPosition caret;
|
||||
SelectionPosition anchor;
|
||||
|
||||
SelectionRange() {
|
||||
SelectionRange() : caret(), anchor() {
|
||||
}
|
||||
SelectionRange(SelectionPosition single) : caret(single), anchor(single) {
|
||||
}
|
||||
@ -166,6 +166,7 @@ public:
|
||||
void TrimSelection(SelectionRange range);
|
||||
void SetSelection(SelectionRange range);
|
||||
void AddSelection(SelectionRange range);
|
||||
void AddSelectionWithoutTrim(SelectionRange range);
|
||||
void TentativeSelection(SelectionRange range);
|
||||
void CommitTentative();
|
||||
int CharacterInSelection(int posCharacter) const;
|
||||
|
@ -238,7 +238,7 @@ public:
|
||||
DeleteRange(0, lengthBody);
|
||||
}
|
||||
|
||||
// Retrieve a range of elemetns into an array
|
||||
// Retrieve a range of elements into an array
|
||||
void GetRange(T *buffer, int position, int retrieveLength) const {
|
||||
// Split into up to 2 ranges, before and after the split then use memcpy on each.
|
||||
int range1Length = 0;
|
||||
|
@ -24,7 +24,7 @@ using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
MarginStyle::MarginStyle() :
|
||||
style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false) {
|
||||
style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false), cursor(SC_CURSORREVERSEARROW) {
|
||||
}
|
||||
|
||||
// A list of the fontnames - avoids wasting space in each style
|
||||
|
@ -20,6 +20,7 @@ public:
|
||||
int width;
|
||||
int mask;
|
||||
bool sensitive;
|
||||
int cursor;
|
||||
MarginStyle();
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user