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>
|
2011-04-03 Colomban Wendling <colomban(at)geany(dot)org>
|
||||||
|
|
||||||
* src/main.c, src/prefs.c, src/tools.c:
|
* src/main.c, src/prefs.c, src/tools.c:
|
||||||
|
@ -61,6 +61,7 @@ lexlib/LexerSimple.h \
|
|||||||
lexlib/OptionSet.h \
|
lexlib/OptionSet.h \
|
||||||
lexlib/PropSetSimple.cxx \
|
lexlib/PropSetSimple.cxx \
|
||||||
lexlib/PropSetSimple.h \
|
lexlib/PropSetSimple.h \
|
||||||
|
lexlib/SparseState.h \
|
||||||
lexlib/StyleContext.cxx \
|
lexlib/StyleContext.cxx \
|
||||||
lexlib/StyleContext.h \
|
lexlib/StyleContext.h \
|
||||||
lexlib/WordList.cxx \
|
lexlib/WordList.cxx \
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
@ -39,6 +40,14 @@
|
|||||||
#define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w))
|
#define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w))
|
||||||
#endif
|
#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
|
#ifdef _MSC_VER
|
||||||
// Ignore unreferenced local functions in GTK+ headers
|
// Ignore unreferenced local functions in GTK+ headers
|
||||||
#pragma warning(disable: 4505)
|
#pragma warning(disable: 4505)
|
||||||
@ -688,9 +697,14 @@ namespace Scintilla {
|
|||||||
#endif
|
#endif
|
||||||
class SurfaceImpl : public Surface {
|
class SurfaceImpl : public Surface {
|
||||||
encodingType et;
|
encodingType et;
|
||||||
|
#ifdef USE_CAIRO
|
||||||
|
cairo_t *context;
|
||||||
|
cairo_surface_t *psurf;
|
||||||
|
#else
|
||||||
GdkDrawable *drawable;
|
GdkDrawable *drawable;
|
||||||
GdkGC *gc;
|
GdkGC *gc;
|
||||||
GdkPixmap *ppixmap;
|
GdkPixmap *ppixmap;
|
||||||
|
#endif
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
bool inited;
|
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)
|
x(0), y(0), inited(false), createdGC(false)
|
||||||
, pcontext(0), layout(0), characterSet(-1) {
|
, pcontext(0), layout(0), characterSet(-1) {
|
||||||
}
|
}
|
||||||
@ -817,15 +839,28 @@ SurfaceImpl::~SurfaceImpl() {
|
|||||||
|
|
||||||
void SurfaceImpl::Release() {
|
void SurfaceImpl::Release() {
|
||||||
et = singleByte;
|
et = singleByte;
|
||||||
|
#ifndef USE_CAIRO
|
||||||
drawable = 0;
|
drawable = 0;
|
||||||
|
#endif
|
||||||
if (createdGC) {
|
if (createdGC) {
|
||||||
createdGC = false;
|
createdGC = false;
|
||||||
|
#ifdef USE_CAIRO
|
||||||
|
cairo_destroy(context);
|
||||||
|
#else
|
||||||
g_object_unref(gc);
|
g_object_unref(gc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifdef USE_CAIRO
|
||||||
|
context = 0;
|
||||||
|
if (psurf)
|
||||||
|
cairo_surface_destroy(psurf);
|
||||||
|
psurf = 0;
|
||||||
|
#else
|
||||||
gc = 0;
|
gc = 0;
|
||||||
if (ppixmap)
|
if (ppixmap)
|
||||||
g_object_unref(ppixmap);
|
g_object_unref(ppixmap);
|
||||||
ppixmap = 0;
|
ppixmap = 0;
|
||||||
|
#endif
|
||||||
if (layout)
|
if (layout)
|
||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
layout = 0;
|
layout = 0;
|
||||||
@ -847,10 +882,28 @@ bool SurfaceImpl::Initialised() {
|
|||||||
void SurfaceImpl::Init(WindowID wid) {
|
void SurfaceImpl::Init(WindowID wid) {
|
||||||
Release();
|
Release();
|
||||||
PLATFORM_ASSERT(wid);
|
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));
|
pcontext = gtk_widget_create_pango_context(PWidget(wid));
|
||||||
PLATFORM_ASSERT(pcontext);
|
PLATFORM_ASSERT(pcontext);
|
||||||
layout = pango_layout_new(pcontext);
|
layout = pango_layout_new(pcontext);
|
||||||
PLATFORM_ASSERT(layout);
|
PLATFORM_ASSERT(layout);
|
||||||
|
#endif
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -859,12 +912,27 @@ void SurfaceImpl::Init(SurfaceID sid, WindowID wid) {
|
|||||||
GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid);
|
GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid);
|
||||||
Release();
|
Release();
|
||||||
PLATFORM_ASSERT(wid);
|
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));
|
pcontext = gtk_widget_create_pango_context(PWidget(wid));
|
||||||
layout = pango_layout_new(pcontext);
|
layout = pango_layout_new(pcontext);
|
||||||
drawable = drawable_;
|
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
|
// 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);
|
gdk_gc_set_line_attributes(gc, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
|
||||||
|
#endif
|
||||||
createdGC = true;
|
createdGC = true;
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
@ -873,8 +941,23 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID
|
|||||||
PLATFORM_ASSERT(surface_);
|
PLATFORM_ASSERT(surface_);
|
||||||
Release();
|
Release();
|
||||||
SurfaceImpl *surfImpl = static_cast<SurfaceImpl *>(surface_);
|
SurfaceImpl *surfImpl = static_cast<SurfaceImpl *>(surface_);
|
||||||
PLATFORM_ASSERT(surfImpl->drawable);
|
|
||||||
PLATFORM_ASSERT(wid);
|
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));
|
pcontext = gtk_widget_create_pango_context(PWidget(wid));
|
||||||
PLATFORM_ASSERT(pcontext);
|
PLATFORM_ASSERT(pcontext);
|
||||||
layout = pango_layout_new(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)
|
if (height > 0 && width > 0)
|
||||||
ppixmap = gdk_pixmap_new(surfImpl->drawable, width, height, -1);
|
ppixmap = gdk_pixmap_new(surfImpl->drawable, width, height, -1);
|
||||||
drawable = ppixmap;
|
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
|
// 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);
|
gdk_gc_set_line_attributes(gc, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
|
||||||
|
#endif
|
||||||
createdGC = true;
|
createdGC = true;
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceImpl::PenColour(ColourAllocated fore) {
|
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) {
|
if (gc) {
|
||||||
GdkColor co;
|
GdkColor co;
|
||||||
co.pixel = fore.AsLong();
|
co.pixel = fore.AsLong();
|
||||||
gdk_gc_set_foreground(gc, &co);
|
gdk_gc_set_foreground(gc, &co);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int SurfaceImpl::LogPixelsY() {
|
int SurfaceImpl::LogPixelsY() {
|
||||||
@ -911,18 +1017,71 @@ void SurfaceImpl::MoveTo(int x_, int y_) {
|
|||||||
y = 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_) {
|
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) {
|
if (drawable && gc) {
|
||||||
gdk_draw_line(drawable, gc,
|
gdk_draw_line(drawable, gc,
|
||||||
x, y,
|
x, y,
|
||||||
x_, y_);
|
x_, y_);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
x = x_;
|
x = x_;
|
||||||
y = y_;
|
y = y_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore,
|
void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore,
|
||||||
ColourAllocated back) {
|
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];
|
GdkPoint gpts[20];
|
||||||
if (npts < static_cast<int>((sizeof(gpts) / sizeof(gpts[0])))) {
|
if (npts < static_cast<int>((sizeof(gpts) / sizeof(gpts[0])))) {
|
||||||
for (int i = 0;i < npts;i++) {
|
for (int i = 0;i < npts;i++) {
|
||||||
@ -934,35 +1093,62 @@ void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore,
|
|||||||
PenColour(fore);
|
PenColour(fore);
|
||||||
gdk_draw_polygon(drawable, gc, 0, gpts, npts);
|
gdk_draw_polygon(drawable, gc, 0, gpts, npts);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
|
void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
|
||||||
|
#ifdef USE_CAIRO
|
||||||
|
if (context) {
|
||||||
|
#else
|
||||||
if (gc && drawable) {
|
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);
|
PenColour(back);
|
||||||
gdk_draw_rectangle(drawable, gc, 1,
|
gdk_draw_rectangle(drawable, gc, 1,
|
||||||
rc.left + 1, rc.top + 1,
|
rc.left + 1, rc.top + 1,
|
||||||
rc.right - rc.left - 2, rc.bottom - rc.top - 2);
|
rc.right - rc.left - 2, rc.bottom - rc.top - 2);
|
||||||
|
|
||||||
PenColour(fore);
|
PenColour(fore);
|
||||||
// The subtraction of 1 off the width and height here shouldn't be needed but
|
// 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
|
// otherwise a different rectangle is drawn than would be done if the fill parameter == 1
|
||||||
gdk_draw_rectangle(drawable, gc, 0,
|
gdk_draw_rectangle(drawable, gc, 0,
|
||||||
rc.left, rc.top,
|
rc.left, rc.top,
|
||||||
rc.right - rc.left - 1, rc.bottom - rc.top - 1);
|
rc.right - rc.left - 1, rc.bottom - rc.top - 1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
|
void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
|
||||||
PenColour(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
|
if (drawable && (rc.left < maxCoordinate)) { // Protect against out of range
|
||||||
gdk_draw_rectangle(drawable, gc, 1,
|
gdk_draw_rectangle(drawable, gc, 1,
|
||||||
rc.left, rc.top,
|
rc.left, rc.top,
|
||||||
rc.right - rc.left, rc.bottom - rc.top);
|
rc.right - rc.left, rc.bottom - rc.top);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
|
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
|
// Tile pattern over rectangle
|
||||||
// Currently assumes 8x8 pattern
|
// Currently assumes 8x8 pattern
|
||||||
int widthPat = 8;
|
int widthPat = 8;
|
||||||
@ -971,12 +1157,18 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
|
|||||||
int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat;
|
int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat;
|
||||||
for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) {
|
for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) {
|
||||||
int heighty = (yTile + heightPat > rc.bottom) ? 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,
|
gdk_draw_drawable(drawable,
|
||||||
gc,
|
gc,
|
||||||
static_cast<SurfaceImpl &>(surfacePattern).drawable,
|
static_cast<SurfaceImpl &>(surfacePattern).drawable,
|
||||||
0, 0,
|
0, 0,
|
||||||
xTile, yTile,
|
xTile, yTile,
|
||||||
widthx, heighty);
|
widthx, heighty);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// 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) {
|
static void AllFour(guint32 *pixels, int stride, int width, int height, int x, int y, guint32 val) {
|
||||||
pixels[y*stride+x] = 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;
|
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) {
|
static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
|
||||||
union {
|
union {
|
||||||
guint8 pixVal[4];
|
guint8 pixVal[4];
|
||||||
@ -1037,8 +1232,41 @@ static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
|
|||||||
return converter.val;
|
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,
|
void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
|
||||||
ColourAllocated outline, int alphaOutline, int flags) {
|
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) {
|
if (gc && drawable && rc.Width() > 0) {
|
||||||
int width = rc.Width();
|
int width = rc.Width();
|
||||||
int height = rc.Height();
|
int height = rc.Height();
|
||||||
@ -1078,10 +1306,18 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
|
|||||||
|
|
||||||
g_object_unref(pixalpha);
|
g_object_unref(pixalpha);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
|
void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
|
||||||
PenColour(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,
|
gdk_draw_arc(drawable, gc, 1,
|
||||||
rc.left + 1, rc.top + 1,
|
rc.left + 1, rc.top + 1,
|
||||||
rc.right - rc.left - 2, rc.bottom - rc.top - 2,
|
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.left, rc.top,
|
||||||
rc.right - rc.left - 1, rc.bottom - rc.top - 1,
|
rc.right - rc.left - 1, rc.bottom - rc.top - 1,
|
||||||
0, 32767);
|
0, 32767);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
|
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,
|
gdk_draw_drawable(drawable,
|
||||||
gc,
|
gc,
|
||||||
static_cast<SurfaceImpl &>(surfaceSource).drawable,
|
static_cast<SurfaceImpl &>(surfaceSource).drawable,
|
||||||
from.x, from.y,
|
from.x, from.y,
|
||||||
rc.left, rc.top,
|
rc.left, rc.top,
|
||||||
rc.right - rc.left, rc.bottom - 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,
|
void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char *s, int len,
|
||||||
ColourAllocated fore) {
|
ColourAllocated fore) {
|
||||||
PenColour(fore);
|
PenColour(fore);
|
||||||
|
#ifdef USE_CAIRO
|
||||||
|
if (context) {
|
||||||
|
#else
|
||||||
if (gc && drawable) {
|
if (gc && drawable) {
|
||||||
|
#endif
|
||||||
int xText = rc.left;
|
int xText = rc.left;
|
||||||
if (PFont(font_)->pfd) {
|
if (PFont(font_)->pfd) {
|
||||||
char *utfForm = 0;
|
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_text(layout, utfForm, len);
|
||||||
}
|
}
|
||||||
pango_layout_set_font_description(layout, PFont(font_)->pfd);
|
pango_layout_set_font_description(layout, PFont(font_)->pfd);
|
||||||
|
#ifdef USE_CAIRO
|
||||||
|
pango_cairo_update_layout(context, layout);
|
||||||
|
#endif
|
||||||
#ifdef PANGO_VERSION
|
#ifdef PANGO_VERSION
|
||||||
PangoLayoutLine *pll = pango_layout_get_line_readonly(layout,0);
|
PangoLayoutLine *pll = pango_layout_get_line_readonly(layout,0);
|
||||||
#else
|
#else
|
||||||
PangoLayoutLine *pll = pango_layout_get_line(layout,0);
|
PangoLayoutLine *pll = pango_layout_get_line(layout,0);
|
||||||
#endif
|
#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);
|
gdk_draw_layout_line(drawable, gc, xText, ybase, pll);
|
||||||
|
#endif
|
||||||
if (useGFree) {
|
if (useGFree) {
|
||||||
g_free(utfForm);
|
g_free(utfForm);
|
||||||
} else {
|
} else {
|
||||||
@ -1717,9 +1979,14 @@ int SurfaceImpl::SetPalette(Palette *, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceImpl::SetClip(PRectangle rc) {
|
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,
|
GdkRectangle area = {rc.left, rc.top,
|
||||||
rc.right - rc.left, rc.bottom - rc.top};
|
rc.right - rc.left, rc.bottom - rc.top};
|
||||||
gdk_gc_set_clip_rectangle(gc, &area);
|
gdk_gc_set_clip_rectangle(gc, &area);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceImpl::FlushCachedState() {}
|
void SurfaceImpl::FlushCachedState() {}
|
||||||
@ -1875,7 +2142,6 @@ void Window::SetTitle(const char *s) {
|
|||||||
gdk window coordinates */
|
gdk window coordinates */
|
||||||
PRectangle Window::GetMonitorRect(Point pt) {
|
PRectangle Window::GetMonitorRect(Point pt) {
|
||||||
gint x_offset, y_offset;
|
gint x_offset, y_offset;
|
||||||
pt = pt;
|
|
||||||
|
|
||||||
gdk_window_get_origin(PWidget(wid)->window, &x_offset, &y_offset);
|
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);
|
return PRectangle(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
pt = pt;
|
||||||
return PRectangle(-x_offset, -y_offset, (-x_offset) + gdk_screen_width(),
|
return PRectangle(-x_offset, -y_offset, (-x_offset) + gdk_screen_width(),
|
||||||
(-y_offset) + gdk_screen_height());
|
(-y_offset) + gdk_screen_height());
|
||||||
#endif
|
#endif
|
||||||
@ -1936,7 +2203,7 @@ public:
|
|||||||
CallBackAction doubleClickAction;
|
CallBackAction doubleClickAction;
|
||||||
void *doubleClickActionData;
|
void *doubleClickActionData;
|
||||||
|
|
||||||
ListBoxX() : list(0), pixhash(NULL), pixbuf_renderer(0),
|
ListBoxX() : list(0), scroller(0), pixhash(NULL), pixbuf_renderer(0),
|
||||||
desiredVisibleRows(5), maxItemCharacters(0),
|
desiredVisibleRows(5), maxItemCharacters(0),
|
||||||
aveCharWidth(1), doubleClickAction(NULL), doubleClickActionData(NULL) {
|
aveCharWidth(1), doubleClickAction(NULL), doubleClickActionData(NULL) {
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,10 @@
|
|||||||
#define IS_WIDGET_VISIBLE(w) (GTK_WIDGET_VISIBLE(w))
|
#define IS_WIDGET_VISIBLE(w) (GTK_WIDGET_VISIBLE(w))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GTK_CHECK_VERSION(2,22,0)
|
||||||
|
#define USE_CAIRO 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// Constant conditional expressions are because of GTK+ headers
|
// Constant conditional expressions are because of GTK+ headers
|
||||||
#pragma warning(disable: 4127)
|
#pragma warning(disable: 4127)
|
||||||
@ -531,7 +535,6 @@ void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internal
|
|||||||
|
|
||||||
gint ScintillaGTK::FocusInThis(GtkWidget *widget) {
|
gint ScintillaGTK::FocusInThis(GtkWidget *widget) {
|
||||||
try {
|
try {
|
||||||
GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
|
|
||||||
SetFocusState(true);
|
SetFocusState(true);
|
||||||
if (im_context != NULL) {
|
if (im_context != NULL) {
|
||||||
gchar *str = NULL;
|
gchar *str = NULL;
|
||||||
@ -562,7 +565,6 @@ gint ScintillaGTK::FocusIn(GtkWidget *widget, GdkEventFocus * /*event*/) {
|
|||||||
|
|
||||||
gint ScintillaGTK::FocusOutThis(GtkWidget *widget) {
|
gint ScintillaGTK::FocusOutThis(GtkWidget *widget) {
|
||||||
try {
|
try {
|
||||||
GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
|
|
||||||
SetFocusState(false);
|
SetFocusState(false);
|
||||||
|
|
||||||
if (PWidget(wPreedit) != NULL)
|
if (PWidget(wPreedit) != NULL)
|
||||||
@ -1422,7 +1424,7 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
|
|||||||
|
|
||||||
UndoGroup ug(pdoc);
|
UndoGroup ug(pdoc);
|
||||||
if (selection_data->selection != GDK_SELECTION_PRIMARY) {
|
if (selection_data->selection != GDK_SELECTION_PRIMARY) {
|
||||||
ClearSelection();
|
ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH);
|
||||||
}
|
}
|
||||||
SelectionPosition selStart = sel.IsRectangular() ?
|
SelectionPosition selStart = sel.IsRectangular() ?
|
||||||
sel.Rectangular().Start() :
|
sel.Rectangular().Start() :
|
||||||
@ -1983,6 +1985,7 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose)
|
|||||||
PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
|
PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
|
||||||
pango_layout_set_attributes(layout, attrs);
|
pango_layout_set_attributes(layout, attrs);
|
||||||
|
|
||||||
|
#ifndef USE_CAIRO
|
||||||
GdkGC *gc = gdk_gc_new(widget->window);
|
GdkGC *gc = gdk_gc_new(widget->window);
|
||||||
GdkColor color[2] = { {0, 0x0000, 0x0000, 0x0000},
|
GdkColor color[2] = { {0, 0x0000, 0x0000, 0x0000},
|
||||||
{0, 0xffff, 0xffff, 0xffff}
|
{0, 0xffff, 0xffff, 0xffff}
|
||||||
@ -1997,8 +2000,8 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose)
|
|||||||
gdk_gc_set_foreground(gc, color);
|
gdk_gc_set_foreground(gc, color);
|
||||||
gdk_gc_set_background(gc, color + 1);
|
gdk_gc_set_background(gc, color + 1);
|
||||||
gdk_draw_layout(widget->window, gc, 0, 0, layout);
|
gdk_draw_layout(widget->window, gc, 0, 0, layout);
|
||||||
|
|
||||||
g_object_unref(gc);
|
g_object_unref(gc);
|
||||||
|
#endif
|
||||||
g_free(str);
|
g_free(str);
|
||||||
pango_attr_list_unref(attrs);
|
pango_attr_list_unref(attrs);
|
||||||
g_object_unref(layout);
|
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_ulong(v) (v)->data[0].v_ulong
|
||||||
#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
|
#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_uint64(v) (v)->data[0].v_uint64
|
||||||
#define g_marshal_value_peek_enum(v) (v)->data[0].v_int
|
#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
|
||||||
#define g_marshal_value_peek_flags(v) (v)->data[0].v_uint
|
#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_float(v) (v)->data[0].v_float
|
||||||
#define g_marshal_value_peek_double(v) (v)->data[0].v_double
|
#define g_marshal_value_peek_double(v) (v)->data[0].v_double
|
||||||
#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
|
#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
|
||||||
@ -50,10 +50,10 @@
|
|||||||
/* NONE:INT,POINTER (scintilla-marshal.list:1) */
|
/* NONE:INT,POINTER (scintilla-marshal.list:1) */
|
||||||
void
|
void
|
||||||
scintilla_marshal_VOID__INT_POINTER (GClosure *closure,
|
scintilla_marshal_VOID__INT_POINTER (GClosure *closure,
|
||||||
GValue *return_value,
|
GValue *return_value G_GNUC_UNUSED,
|
||||||
guint n_param_values,
|
guint n_param_values,
|
||||||
const GValue *param_values,
|
const GValue *param_values,
|
||||||
gpointer invocation_hint,
|
gpointer invocation_hint G_GNUC_UNUSED,
|
||||||
gpointer marshal_data)
|
gpointer marshal_data)
|
||||||
{
|
{
|
||||||
typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1,
|
typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1,
|
||||||
|
@ -255,8 +255,8 @@ class Palette {
|
|||||||
int allocatedLen;
|
int allocatedLen;
|
||||||
#endif
|
#endif
|
||||||
// Private so Palette objects can not be copied
|
// Private so Palette objects can not be copied
|
||||||
Palette(const Palette &) {}
|
Palette(const Palette &);
|
||||||
Palette &operator=(const Palette &) { return *this; }
|
Palette &operator=(const Palette &);
|
||||||
public:
|
public:
|
||||||
#if PLAT_WIN
|
#if PLAT_WIN
|
||||||
void *hpal;
|
void *hpal;
|
||||||
@ -288,8 +288,8 @@ protected:
|
|||||||
int ascent;
|
int ascent;
|
||||||
#endif
|
#endif
|
||||||
// Private so Font objects can not be copied
|
// Private so Font objects can not be copied
|
||||||
Font(const Font &) {}
|
Font(const Font &);
|
||||||
Font &operator=(const Font &) { fid=0; return *this; }
|
Font &operator=(const Font &);
|
||||||
public:
|
public:
|
||||||
Font();
|
Font();
|
||||||
virtual ~Font();
|
virtual ~Font();
|
||||||
|
@ -112,6 +112,8 @@
|
|||||||
#define SCLEX_SML 97
|
#define SCLEX_SML 97
|
||||||
#define SCLEX_MARKDOWN 98
|
#define SCLEX_MARKDOWN 98
|
||||||
#define SCLEX_TXT2TAGS 99
|
#define SCLEX_TXT2TAGS 99
|
||||||
|
#define SCLEX_A68K 100
|
||||||
|
#define SCLEX_MODULA 101
|
||||||
#define SCLEX_AUTOMATIC 1000
|
#define SCLEX_AUTOMATIC 1000
|
||||||
#define SCE_P_DEFAULT 0
|
#define SCE_P_DEFAULT 0
|
||||||
#define SCE_P_COMMENTLINE 1
|
#define SCE_P_COMMENTLINE 1
|
||||||
@ -149,6 +151,8 @@
|
|||||||
#define SCE_C_COMMENTDOCKEYWORD 17
|
#define SCE_C_COMMENTDOCKEYWORD 17
|
||||||
#define SCE_C_COMMENTDOCKEYWORDERROR 18
|
#define SCE_C_COMMENTDOCKEYWORDERROR 18
|
||||||
#define SCE_C_GLOBALCLASS 19
|
#define SCE_C_GLOBALCLASS 19
|
||||||
|
#define SCE_C_STRINGRAW 20
|
||||||
|
#define SCE_C_TRIPLEVERBATIM 21
|
||||||
#define SCE_D_DEFAULT 0
|
#define SCE_D_DEFAULT 0
|
||||||
#define SCE_D_COMMENT 1
|
#define SCE_D_COMMENT 1
|
||||||
#define SCE_D_COMMENTLINE 2
|
#define SCE_D_COMMENTLINE 2
|
||||||
@ -601,6 +605,7 @@
|
|||||||
#define SCE_ASM_CHARACTER 12
|
#define SCE_ASM_CHARACTER 12
|
||||||
#define SCE_ASM_STRINGEOL 13
|
#define SCE_ASM_STRINGEOL 13
|
||||||
#define SCE_ASM_EXTINSTRUCTION 14
|
#define SCE_ASM_EXTINSTRUCTION 14
|
||||||
|
#define SCE_ASM_COMMENTDIRECTIVE 15
|
||||||
#define SCE_F_DEFAULT 0
|
#define SCE_F_DEFAULT 0
|
||||||
#define SCE_F_COMMENT 1
|
#define SCE_F_COMMENT 1
|
||||||
#define SCE_F_NUMBER 2
|
#define SCE_F_NUMBER 2
|
||||||
@ -1415,6 +1420,43 @@
|
|||||||
#define SCE_TXT2TAGS_OPTION 23
|
#define SCE_TXT2TAGS_OPTION 23
|
||||||
#define SCE_TXT2TAGS_PREPROC 24
|
#define SCE_TXT2TAGS_PREPROC 24
|
||||||
#define SCE_TXT2TAGS_POSTPROC 25
|
#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 */
|
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -159,6 +159,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
|
|||||||
#define SCI_GETMARGINMASKN 2245
|
#define SCI_GETMARGINMASKN 2245
|
||||||
#define SCI_SETMARGINSENSITIVEN 2246
|
#define SCI_SETMARGINSENSITIVEN 2246
|
||||||
#define SCI_GETMARGINSENSITIVEN 2247
|
#define SCI_GETMARGINSENSITIVEN 2247
|
||||||
|
#define SCI_SETMARGINCURSORN 2248
|
||||||
|
#define SCI_GETMARGINCURSORN 2249
|
||||||
#define STYLE_DEFAULT 32
|
#define STYLE_DEFAULT 32
|
||||||
#define STYLE_LINENUMBER 33
|
#define STYLE_LINENUMBER 33
|
||||||
#define STYLE_BRACELIGHT 34
|
#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_SETMOUSEDOWNCAPTURES 2384
|
||||||
#define SCI_GETMOUSEDOWNCAPTURES 2385
|
#define SCI_GETMOUSEDOWNCAPTURES 2385
|
||||||
#define SC_CURSORNORMAL -1
|
#define SC_CURSORNORMAL -1
|
||||||
|
#define SC_CURSORARROW 2
|
||||||
#define SC_CURSORWAIT 4
|
#define SC_CURSORWAIT 4
|
||||||
|
#define SC_CURSORREVERSEARROW 7
|
||||||
#define SCI_SETCURSOR 2386
|
#define SCI_SETCURSOR 2386
|
||||||
#define SCI_GETCURSOR 2387
|
#define SCI_GETCURSOR 2387
|
||||||
#define SCI_SETCONTROLCHARSYMBOL 2388
|
#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_CONTAINER 0x40000
|
||||||
#define SC_MOD_LEXERSTATE 0x80000
|
#define SC_MOD_LEXERSTATE 0x80000
|
||||||
#define SC_MODEVENTMASKALL 0xFFFFF
|
#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_CHANGE 768
|
||||||
#define SCEN_SETFOCUS 512
|
#define SCEN_SETFOCUS 512
|
||||||
#define SCEN_KILLFOCUS 256
|
#define SCEN_KILLFOCUS 256
|
||||||
@ -971,6 +979,7 @@ struct SCNotification {
|
|||||||
int y; /* SCN_DWELLSTART, SCN_DWELLEND */
|
int y; /* SCN_DWELLSTART, SCN_DWELLEND */
|
||||||
int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */
|
int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */
|
||||||
int annotationLinesAdded; /* SC_MOD_CHANGEANNOTATION */
|
int annotationLinesAdded; /* SC_MOD_CHANGEANNOTATION */
|
||||||
|
int updated; /* SCN_UPDATEUI */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef SCI_NAMESPACE
|
#ifdef SCI_NAMESPACE
|
||||||
|
@ -352,6 +352,12 @@ set void SetMarginSensitiveN=2246(int margin, bool sensitive)
|
|||||||
# Retrieve the mouse click sensitivity of a margin.
|
# Retrieve the mouse click sensitivity of a margin.
|
||||||
get bool GetMarginSensitiveN=2247(int 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.
|
# 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.
|
# Style 39 is for future use.
|
||||||
enu StylesCommon=STYLE_
|
enu StylesCommon=STYLE_
|
||||||
@ -1540,7 +1546,9 @@ get bool GetMouseDownCaptures=2385(,)
|
|||||||
|
|
||||||
enu CursorShape=SC_CURSOR
|
enu CursorShape=SC_CURSOR
|
||||||
val SC_CURSORNORMAL=-1
|
val SC_CURSORNORMAL=-1
|
||||||
|
val SC_CURSORARROW=2
|
||||||
val SC_CURSORWAIT=4
|
val SC_CURSORWAIT=4
|
||||||
|
val SC_CURSORREVERSEARROW=7
|
||||||
# Sets the cursor to one of the SC_CURSOR* values.
|
# Sets the cursor to one of the SC_CURSOR* values.
|
||||||
set void SetCursor=2386(int cursorType,)
|
set void SetCursor=2386(int cursorType,)
|
||||||
# Get cursor type.
|
# Get cursor type.
|
||||||
@ -2193,6 +2201,12 @@ val SC_MOD_CONTAINER=0x40000
|
|||||||
val SC_MOD_LEXERSTATE=0x80000
|
val SC_MOD_LEXERSTATE=0x80000
|
||||||
val SC_MODEVENTMASKALL=0xFFFFF
|
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
|
# For compatibility, these go through the COMMAND notification rather than NOTIFY
|
||||||
# and should have had exactly the same values as the EN_* constants.
|
# and should have had exactly the same values as the EN_* constants.
|
||||||
# Unfortunately the SETFOCUS and KILLFOCUS are flipped over from EN_*
|
# Unfortunately the SETFOCUS and KILLFOCUS are flipped over from EN_*
|
||||||
@ -2335,6 +2349,8 @@ val SCLEX_NIMROD=96
|
|||||||
val SCLEX_SML=97
|
val SCLEX_SML=97
|
||||||
val SCLEX_MARKDOWN=98
|
val SCLEX_MARKDOWN=98
|
||||||
val SCLEX_TXT2TAGS=99
|
val SCLEX_TXT2TAGS=99
|
||||||
|
val SCLEX_A68K=100
|
||||||
|
val SCLEX_MODULA=101
|
||||||
|
|
||||||
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
|
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
|
||||||
# value assigned in sequence from SCLEX_AUTOMATIC+1.
|
# 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_COMMENTDOCKEYWORD=17
|
||||||
val SCE_C_COMMENTDOCKEYWORDERROR=18
|
val SCE_C_COMMENTDOCKEYWORDERROR=18
|
||||||
val SCE_C_GLOBALCLASS=19
|
val SCE_C_GLOBALCLASS=19
|
||||||
|
val SCE_C_STRINGRAW=20
|
||||||
|
val SCE_C_TRIPLEVERBATIM=21
|
||||||
# Lexical states for SCLEX_D
|
# Lexical states for SCLEX_D
|
||||||
lex D=SCLEX_D SCE_D_
|
lex D=SCLEX_D SCE_D_
|
||||||
val SCE_D_DEFAULT=0
|
val SCE_D_DEFAULT=0
|
||||||
@ -2900,6 +2918,7 @@ val SCE_ASM_COMMENTBLOCK=11
|
|||||||
val SCE_ASM_CHARACTER=12
|
val SCE_ASM_CHARACTER=12
|
||||||
val SCE_ASM_STRINGEOL=13
|
val SCE_ASM_STRINGEOL=13
|
||||||
val SCE_ASM_EXTINSTRUCTION=14
|
val SCE_ASM_EXTINSTRUCTION=14
|
||||||
|
val SCE_ASM_COMMENTDIRECTIVE=15
|
||||||
# Lexical states for SCLEX_FORTRAN
|
# Lexical states for SCLEX_FORTRAN
|
||||||
lex Fortran=SCLEX_FORTRAN SCE_F_
|
lex Fortran=SCLEX_FORTRAN SCE_F_
|
||||||
lex F77=SCLEX_F77 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_OPTION=23
|
||||||
val SCE_TXT2TAGS_PREPROC=24
|
val SCE_TXT2TAGS_PREPROC=24
|
||||||
val SCE_TXT2TAGS_POSTPROC=25
|
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
|
# Events
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
** Written by The Black Horus
|
** Written by The Black Horus
|
||||||
** Enhancements and NASM stuff by Kein-Hong Man, 2003-10
|
** Enhancements and NASM stuff by Kein-Hong Man, 2003-10
|
||||||
** SCE_ASM_COMMENTBLOCK and SCE_ASM_CHARACTER are for future GNU as colouring
|
** 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>
|
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
|
||||||
// The License.txt file describes the conditions under which this software may be distributed.
|
// The License.txt file describes the conditions under which this software may be distributed.
|
||||||
@ -15,17 +16,24 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable: 4786)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "ILexer.h"
|
#include "ILexer.h"
|
||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
|
||||||
#include "StyleContext.h"
|
#include "StyleContext.h"
|
||||||
#include "CharacterSet.h"
|
#include "CharacterSet.h"
|
||||||
#include "LexerModule.h"
|
#include "LexerModule.h"
|
||||||
|
#include "OptionSet.h"
|
||||||
|
|
||||||
#ifdef SCI_NAMESPACE
|
#ifdef SCI_NAMESPACE
|
||||||
using namespace Scintilla;
|
using namespace Scintilla;
|
||||||
@ -54,15 +62,184 @@ static inline bool IsAsmOperator(const int ch) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
|
static bool IsStreamCommentStyle(int style) {
|
||||||
Accessor &styler) {
|
return style == SCE_ASM_COMMENTDIRECTIVE || style == SCE_ASM_COMMENTBLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
WordList &cpuInstruction = *keywordlists[0];
|
static inline int LowerCase(int c) {
|
||||||
WordList &mathInstruction = *keywordlists[1];
|
if (c >= 'A' && c <= 'Z')
|
||||||
WordList ®isters = *keywordlists[2];
|
return 'a' + c - 'A';
|
||||||
WordList &directive = *keywordlists[3];
|
return c;
|
||||||
WordList &directiveOperand = *keywordlists[4];
|
}
|
||||||
WordList &extInstruction = *keywordlists[5];
|
|
||||||
|
// 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
|
// Do not leak onto next line
|
||||||
if (initStyle == SCE_ASM_STRINGEOL)
|
if (initStyle == SCE_ASM_STRINGEOL)
|
||||||
@ -96,7 +273,7 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
|
|||||||
if (!IsAsmOperator(sc.ch)) {
|
if (!IsAsmOperator(sc.ch)) {
|
||||||
sc.SetState(SCE_ASM_DEFAULT);
|
sc.SetState(SCE_ASM_DEFAULT);
|
||||||
}
|
}
|
||||||
}else if (sc.state == SCE_ASM_NUMBER) {
|
} else if (sc.state == SCE_ASM_NUMBER) {
|
||||||
if (!IsAWordChar(sc.ch)) {
|
if (!IsAWordChar(sc.ch)) {
|
||||||
sc.SetState(SCE_ASM_DEFAULT);
|
sc.SetState(SCE_ASM_DEFAULT);
|
||||||
}
|
}
|
||||||
@ -104,6 +281,7 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
|
|||||||
if (!IsAWordChar(sc.ch) ) {
|
if (!IsAWordChar(sc.ch) ) {
|
||||||
char s[100];
|
char s[100];
|
||||||
sc.GetCurrentLowered(s, sizeof(s));
|
sc.GetCurrentLowered(s, sizeof(s));
|
||||||
|
bool IsDirective = false;
|
||||||
|
|
||||||
if (cpuInstruction.InList(s)) {
|
if (cpuInstruction.InList(s)) {
|
||||||
sc.ChangeState(SCE_ASM_CPUINSTRUCTION);
|
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);
|
sc.ChangeState(SCE_ASM_REGISTER);
|
||||||
} else if (directive.InList(s)) {
|
} else if (directive.InList(s)) {
|
||||||
sc.ChangeState(SCE_ASM_DIRECTIVE);
|
sc.ChangeState(SCE_ASM_DIRECTIVE);
|
||||||
|
IsDirective = true;
|
||||||
} else if (directiveOperand.InList(s)) {
|
} else if (directiveOperand.InList(s)) {
|
||||||
sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
|
sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
|
||||||
} else if (extInstruction.InList(s)) {
|
} else if (extInstruction.InList(s)) {
|
||||||
sc.ChangeState(SCE_ASM_EXTINSTRUCTION);
|
sc.ChangeState(SCE_ASM_EXTINSTRUCTION);
|
||||||
}
|
}
|
||||||
sc.SetState(SCE_ASM_DEFAULT);
|
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_COMMENTDIRECTIVE) {
|
||||||
else if (sc.state == SCE_ASM_COMMENT ) {
|
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) {
|
if (sc.atLineEnd) {
|
||||||
sc.SetState(SCE_ASM_DEFAULT);
|
sc.SetState(SCE_ASM_DEFAULT);
|
||||||
}
|
}
|
||||||
@ -170,15 +365,100 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
|
|||||||
sc.Complete();
|
sc.Complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * const asmWordListDesc[] = {
|
// Store both the current line's fold level and the next lines in the
|
||||||
"CPU instructions",
|
// level store to make it easy to pick up with each increment
|
||||||
"FPU instructions",
|
// and to make it possible to fiddle the current level for "else".
|
||||||
"Registers",
|
|
||||||
"Directives",
|
|
||||||
"Directive operands",
|
|
||||||
"Extended instructions",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
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 "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
@ -640,6 +639,14 @@ static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
|
|||||||
levelCurrent--;
|
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) {
|
if (atEOL) {
|
||||||
int lev = levelPrev;
|
int lev = levelPrev;
|
||||||
if (visibleChars == 0 && foldCompact)
|
if (visibleChars == 0 && foldCompact)
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Scintilla source code edit control
|
// Scintilla source code edit control
|
||||||
/** @file LexCPP.cxx
|
/** @file LexCPP.cxx
|
||||||
** Lexer for C++, C, Java, and JavaScript.
|
** 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>
|
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
|
||||||
// The License.txt file describes the conditions under which this software may be distributed.
|
// The License.txt file describes the conditions under which this software may be distributed.
|
||||||
@ -15,10 +16,6 @@
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable: 4786)
|
#pragma warning(disable: 4786)
|
||||||
#endif
|
#endif
|
||||||
#ifdef __BORLANDC__
|
|
||||||
// Borland C++ displays warnings in vector header without this
|
|
||||||
#pragma option -w-ccc -w-rch
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -29,7 +26,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
@ -37,6 +33,7 @@
|
|||||||
#include "CharacterSet.h"
|
#include "CharacterSet.h"
|
||||||
#include "LexerModule.h"
|
#include "LexerModule.h"
|
||||||
#include "OptionSet.h"
|
#include "OptionSet.h"
|
||||||
|
#include "SparseState.h"
|
||||||
|
|
||||||
#ifdef SCI_NAMESPACE
|
#ifdef SCI_NAMESPACE
|
||||||
using namespace Scintilla;
|
using namespace Scintilla;
|
||||||
@ -212,8 +209,13 @@ struct OptionsCPP {
|
|||||||
bool trackPreprocessor;
|
bool trackPreprocessor;
|
||||||
bool updatePreprocessor;
|
bool updatePreprocessor;
|
||||||
bool fold;
|
bool fold;
|
||||||
|
bool foldSyntaxBased;
|
||||||
bool foldComment;
|
bool foldComment;
|
||||||
|
bool foldCommentMultiline;
|
||||||
bool foldCommentExplicit;
|
bool foldCommentExplicit;
|
||||||
|
std::string foldExplicitStart;
|
||||||
|
std::string foldExplicitEnd;
|
||||||
|
bool foldExplicitAnywhere;
|
||||||
bool foldPreprocessor;
|
bool foldPreprocessor;
|
||||||
bool foldCompact;
|
bool foldCompact;
|
||||||
bool foldAtElse;
|
bool foldAtElse;
|
||||||
@ -223,8 +225,13 @@ struct OptionsCPP {
|
|||||||
trackPreprocessor = true;
|
trackPreprocessor = true;
|
||||||
updatePreprocessor = true;
|
updatePreprocessor = true;
|
||||||
fold = false;
|
fold = false;
|
||||||
|
foldSyntaxBased = true;
|
||||||
foldComment = false;
|
foldComment = false;
|
||||||
|
foldCommentMultiline = true;
|
||||||
foldCommentExplicit = true;
|
foldCommentExplicit = true;
|
||||||
|
foldExplicitStart = "";
|
||||||
|
foldExplicitEnd = "";
|
||||||
|
foldExplicitAnywhere = false;
|
||||||
foldPreprocessor = false;
|
foldPreprocessor = false;
|
||||||
foldCompact = false;
|
foldCompact = false;
|
||||||
foldAtElse = false;
|
foldAtElse = false;
|
||||||
@ -258,14 +265,29 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
|
|||||||
|
|
||||||
DefineProperty("fold", &OptionsCPP::fold);
|
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,
|
DefineProperty("fold.comment", &OptionsCPP::foldComment,
|
||||||
"This option enables folding multi-line comments and explicit fold points when using the C++ lexer. "
|
"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 //} "
|
"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.");
|
"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,
|
DefineProperty("fold.cpp.comment.explicit", &OptionsCPP::foldCommentExplicit,
|
||||||
"Set this property to 0 to disable folding explicit fold points when fold.comment=1.");
|
"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,
|
DefineProperty("fold.preprocessor", &OptionsCPP::foldPreprocessor,
|
||||||
"This option enables folding preprocessor directives when using the C++ lexer. "
|
"This option enables folding preprocessor directives when using the C++ lexer. "
|
||||||
"Includes C#'s explicit #region and #endregion folding directives.");
|
"Includes C#'s explicit #region and #endregion folding directives.");
|
||||||
@ -288,7 +310,6 @@ class LexerCPP : public ILexer {
|
|||||||
CharacterSet setLogicalOp;
|
CharacterSet setLogicalOp;
|
||||||
PPStates vlls;
|
PPStates vlls;
|
||||||
std::vector<PPDefinition> ppDefineHistory;
|
std::vector<PPDefinition> ppDefineHistory;
|
||||||
PropSetSimple props;
|
|
||||||
WordList keywords;
|
WordList keywords;
|
||||||
WordList keywords2;
|
WordList keywords2;
|
||||||
WordList keywords3;
|
WordList keywords3;
|
||||||
@ -297,6 +318,7 @@ class LexerCPP : public ILexer {
|
|||||||
std::map<std::string, std::string> preprocessorDefinitionsStart;
|
std::map<std::string, std::string> preprocessorDefinitionsStart;
|
||||||
OptionsCPP options;
|
OptionsCPP options;
|
||||||
OptionSetCPP osCPP;
|
OptionSetCPP osCPP;
|
||||||
|
SparseState<std::string> rawStringTerminators;
|
||||||
public:
|
public:
|
||||||
LexerCPP(bool caseSensitive_) :
|
LexerCPP(bool caseSensitive_) :
|
||||||
caseSensitive(caseSensitive_),
|
caseSensitive(caseSensitive_),
|
||||||
@ -419,7 +441,6 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
|||||||
CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
|
CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
|
||||||
|
|
||||||
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
|
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
|
||||||
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
|
|
||||||
|
|
||||||
if (options.identifiersAllowDollars) {
|
if (options.identifiersAllowDollars) {
|
||||||
setWordStart.Add('$');
|
setWordStart.Add('$');
|
||||||
@ -483,16 +504,18 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int maskActivity = 0x3F;
|
const int maskActivity = 0x3F;
|
||||||
|
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
|
||||||
|
SparseState<std::string> rawSTNew(lineCurrent);
|
||||||
|
|
||||||
int activitySet = preproc.IsInactive() ? 0x40 : 0;
|
int activitySet = preproc.IsInactive() ? 0x40 : 0;
|
||||||
|
|
||||||
for (; sc.More(); sc.Forward()) {
|
for (; sc.More(); sc.Forward()) {
|
||||||
|
|
||||||
if (sc.atLineStart) {
|
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
|
// Prevent SCE_C_STRINGEOL from leaking back to previous line which
|
||||||
// ends with a line continuation by locking in the state upto this position.
|
// 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
|
// Reset states to begining of colourise so no surprises
|
||||||
// if different sets of lines lexed.
|
// 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) {
|
if (sc.atLineEnd) {
|
||||||
lineCurrent++;
|
lineCurrent++;
|
||||||
vlls.Add(lineCurrent, preproc);
|
vlls.Add(lineCurrent, preproc);
|
||||||
|
if (rawStringTerminator != "") {
|
||||||
|
rawSTNew.Set(lineCurrent-1, rawStringTerminator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle line continuation generically.
|
// 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)) {
|
} else if (keywords4.InList(s)) {
|
||||||
sc.ChangeState(SCE_C_GLOBALCLASS|activitySet);
|
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);
|
sc.SetState(SCE_C_DEFAULT|activitySet);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -642,6 +685,14 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
|||||||
sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
|
sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case SCE_C_CHARACTER:
|
||||||
if (sc.atLineEnd) {
|
if (sc.atLineEnd) {
|
||||||
sc.ChangeState(SCE_C_STRINGEOL|activitySet);
|
sc.ChangeState(SCE_C_STRINGEOL|activitySet);
|
||||||
@ -682,6 +733,14 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SCE_C_TRIPLEVERBATIM:
|
||||||
|
if (sc.Match ("\"\"\"")) {
|
||||||
|
while (sc.Match('"')) {
|
||||||
|
sc.Forward();
|
||||||
|
}
|
||||||
|
sc.SetState(SCE_C_DEFAULT|activitySet);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SCE_C_UUID:
|
case SCE_C_UUID:
|
||||||
if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
|
if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
|
||||||
sc.SetState(SCE_C_DEFAULT|activitySet);
|
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('@', '\"')) {
|
if (sc.Match('@', '\"')) {
|
||||||
sc.SetState(SCE_C_VERBATIM|activitySet);
|
sc.SetState(SCE_C_VERBATIM|activitySet);
|
||||||
sc.Forward();
|
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))) {
|
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
|
||||||
if (lastWordWasUUID) {
|
if (lastWordWasUUID) {
|
||||||
sc.SetState(SCE_C_UUID|activitySet);
|
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))) {
|
|| !FollowsPostfixOperator(sc, styler))) {
|
||||||
sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx
|
sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx
|
||||||
} else if (sc.ch == '\"') {
|
} else if (sc.ch == '\"') {
|
||||||
sc.SetState(SCE_C_STRING|activitySet);
|
if (sc.chPrev == 'R') {
|
||||||
|
sc.SetState(SCE_C_STRINGRAW|activitySet);
|
||||||
|
rawStringTerminator = ")";
|
||||||
|
for (int termPos = sc.currentPos + 1;;termPos++) {
|
||||||
|
char chTerminator = styler.SafeGetCharAt(termPos, '(');
|
||||||
|
if (chTerminator == '(')
|
||||||
|
break;
|
||||||
|
rawStringTerminator += chTerminator;
|
||||||
|
}
|
||||||
|
rawStringTerminator += '\"';
|
||||||
|
} else {
|
||||||
|
sc.SetState(SCE_C_STRING|activitySet);
|
||||||
|
}
|
||||||
isIncludePreprocessor = false; // ensure that '>' won't end the string
|
isIncludePreprocessor = false; // ensure that '>' won't end the string
|
||||||
} else if (isIncludePreprocessor && sc.ch == '<') {
|
} else if (isIncludePreprocessor && sc.ch == '<') {
|
||||||
sc.SetState(SCE_C_STRING|activitySet);
|
sc.SetState(SCE_C_STRING|activitySet);
|
||||||
@ -828,10 +902,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
|
|||||||
}
|
}
|
||||||
continuationLine = false;
|
continuationLine = false;
|
||||||
}
|
}
|
||||||
if (definitionsChanged)
|
const bool rawStringsChanged = rawStringTerminators.Merge(rawSTNew, lineCurrent);
|
||||||
|
if (definitionsChanged || rawStringsChanged)
|
||||||
styler.ChangeLexerState(startPos, startPos + length);
|
styler.ChangeLexerState(startPos, startPos + length);
|
||||||
sc.Complete();
|
sc.Complete();
|
||||||
styler.Flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store both the current line's fold level and the next lines in the
|
// 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];
|
char chNext = styler[startPos];
|
||||||
int styleNext = styler.StyleAt(startPos);
|
int styleNext = styler.StyleAt(startPos);
|
||||||
int style = initStyle;
|
int style = initStyle;
|
||||||
|
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
|
||||||
for (unsigned int i = startPos; i < endPos; i++) {
|
for (unsigned int i = startPos; i < endPos; i++) {
|
||||||
char ch = chNext;
|
char ch = chNext;
|
||||||
chNext = styler.SafeGetCharAt(i + 1);
|
chNext = styler.SafeGetCharAt(i + 1);
|
||||||
@ -863,7 +938,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
|
|||||||
style = styleNext;
|
style = styleNext;
|
||||||
styleNext = styler.StyleAt(i + 1);
|
styleNext = styler.StyleAt(i + 1);
|
||||||
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
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)) {
|
if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {
|
||||||
levelNext++;
|
levelNext++;
|
||||||
} else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) && !atEOL) {
|
} else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) && !atEOL) {
|
||||||
@ -871,14 +946,22 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
|
|||||||
levelNext--;
|
levelNext--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options.foldComment && options.foldCommentExplicit && (style == SCE_C_COMMENTLINE)) {
|
if (options.foldComment && options.foldCommentExplicit && ((style == SCE_C_COMMENTLINE) || options.foldExplicitAnywhere)) {
|
||||||
if ((ch == '/') && (chNext == '/')) {
|
if (userDefinedFoldMarkers) {
|
||||||
char chNext2 = styler.SafeGetCharAt(i + 2);
|
if (styler.Match(i, options.foldExplicitStart.c_str())) {
|
||||||
if (chNext2 == '{') {
|
|
||||||
levelNext++;
|
levelNext++;
|
||||||
} else if (chNext2 == '}') {
|
} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
|
||||||
levelNext--;
|
levelNext--;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if ((ch == '/') && (chNext == '/')) {
|
||||||
|
char chNext2 = styler.SafeGetCharAt(i + 2);
|
||||||
|
if (chNext2 == '{') {
|
||||||
|
levelNext++;
|
||||||
|
} else if (chNext2 == '}') {
|
||||||
|
levelNext--;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
|
if (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
|
||||||
@ -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 == '{') {
|
if (ch == '{') {
|
||||||
// Measure the minimum before a '{' to allow
|
// Measure the minimum before a '{' to allow
|
||||||
// folding on "} else {"
|
// folding on "} else {"
|
||||||
@ -910,7 +993,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
|
|||||||
visibleChars++;
|
visibleChars++;
|
||||||
if (atEOL || (i == endPos-1)) {
|
if (atEOL || (i == endPos-1)) {
|
||||||
int levelUse = levelCurrent;
|
int levelUse = levelCurrent;
|
||||||
if (options.foldAtElse) {
|
if (options.foldSyntaxBased && options.foldAtElse) {
|
||||||
levelUse = levelMinCurrent;
|
levelUse = levelMinCurrent;
|
||||||
}
|
}
|
||||||
int lev = levelUse | levelNext << 16;
|
int lev = levelUse | levelNext << 16;
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
** Lexer for D.
|
** Lexer for D.
|
||||||
**
|
**
|
||||||
** Copyright (c) 2006 by Waldemar Augustyn <waldemar@wdmsys.com>
|
** 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>
|
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
|
||||||
// The License.txt file describes the conditions under which this software may be distributed.
|
// The License.txt file describes the conditions under which this software may be distributed.
|
||||||
@ -13,17 +14,23 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable: 4786)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "ILexer.h"
|
#include "ILexer.h"
|
||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
|
||||||
#include "StyleContext.h"
|
#include "StyleContext.h"
|
||||||
#include "CharacterSet.h"
|
#include "CharacterSet.h"
|
||||||
#include "LexerModule.h"
|
#include "LexerModule.h"
|
||||||
|
#include "OptionSet.h"
|
||||||
|
|
||||||
#ifdef SCI_NAMESPACE
|
#ifdef SCI_NAMESPACE
|
||||||
using namespace Scintilla;
|
using namespace Scintilla;
|
||||||
@ -59,17 +66,187 @@ static bool IsStringSuffix(int ch) {
|
|||||||
return ch == 'c' || ch == 'w' || ch == 'd';
|
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,
|
// An individual named option for use in an OptionSet
|
||||||
WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
|
|
||||||
|
|
||||||
WordList &keywords = *keywordlists[0];
|
// Options used for LexerD
|
||||||
WordList &keywords2 = *keywordlists[1];
|
struct OptionsD {
|
||||||
WordList &keywords3 = *keywordlists[2]; //doxygen
|
bool fold;
|
||||||
WordList &keywords4 = *keywordlists[3];
|
bool foldSyntaxBased;
|
||||||
WordList &keywords5 = *keywordlists[4];
|
bool foldComment;
|
||||||
WordList &keywords6 = *keywordlists[5];
|
bool foldCommentMultiline;
|
||||||
WordList &keywords7 = *keywordlists[6];
|
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;
|
int styleBeforeDCKeyword = SCE_D_DEFAULT;
|
||||||
|
|
||||||
@ -294,24 +471,17 @@ static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
|
|||||||
sc.Complete();
|
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
|
// 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
|
// level store to make it easy to pick up with each increment
|
||||||
// and to make it possible to fiddle the current level for "} else {".
|
// 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
|
void SCI_METHOD LexerD::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
|
||||||
// This option enables D folding on a "} else {" line of an if statement.
|
|
||||||
bool foldAtElse = styler.GetPropertyInt("lexer.d.fold.at.else",
|
if (!options.fold)
|
||||||
styler.GetPropertyInt("fold.at.else", 0)) != 0;
|
return;
|
||||||
|
|
||||||
|
LexAccessor styler(pAccess);
|
||||||
|
|
||||||
unsigned int endPos = startPos + length;
|
unsigned int endPos = startPos + length;
|
||||||
int visibleChars = 0;
|
int visibleChars = 0;
|
||||||
int lineCurrent = styler.GetLine(startPos);
|
int lineCurrent = styler.GetLine(startPos);
|
||||||
@ -323,6 +493,8 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
|
|||||||
char chNext = styler[startPos];
|
char chNext = styler[startPos];
|
||||||
int styleNext = styler.StyleAt(startPos);
|
int styleNext = styler.StyleAt(startPos);
|
||||||
int style = initStyle;
|
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++) {
|
for (unsigned int i = startPos; i < endPos; i++) {
|
||||||
char ch = chNext;
|
char ch = chNext;
|
||||||
chNext = styler.SafeGetCharAt(i + 1);
|
chNext = styler.SafeGetCharAt(i + 1);
|
||||||
@ -330,7 +502,7 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
|
|||||||
style = styleNext;
|
style = styleNext;
|
||||||
styleNext = styler.StyleAt(i + 1);
|
styleNext = styler.StyleAt(i + 1);
|
||||||
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||||
if (foldComment && IsStreamCommentStyle(style)) {
|
if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
|
||||||
if (!IsStreamCommentStyle(stylePrev)) {
|
if (!IsStreamCommentStyle(stylePrev)) {
|
||||||
levelNext++;
|
levelNext++;
|
||||||
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
|
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
|
||||||
@ -338,7 +510,25 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
|
|||||||
levelNext--;
|
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 == '{') {
|
if (ch == '{') {
|
||||||
// Measure the minimum before a '{' to allow
|
// Measure the minimum before a '{' to allow
|
||||||
// folding on "} else {"
|
// folding on "} else {"
|
||||||
@ -350,19 +540,19 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
|
|||||||
levelNext--;
|
levelNext--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (atEOL) {
|
if (atEOL || (i == endPos-1)) {
|
||||||
if (foldComment) { // Handle nested comments
|
if (options.foldComment && options.foldCommentMultiline) { // Handle nested comments
|
||||||
int nc;
|
int nc;
|
||||||
nc = styler.GetLineState(lineCurrent);
|
nc = styler.GetLineState(lineCurrent);
|
||||||
nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
|
nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
|
||||||
levelNext += nc;
|
levelNext += nc;
|
||||||
}
|
}
|
||||||
int levelUse = levelCurrent;
|
int levelUse = levelCurrent;
|
||||||
if (foldAtElse) {
|
if (options.foldSyntaxBased && foldAtElse) {
|
||||||
levelUse = levelMinCurrent;
|
levelUse = levelMinCurrent;
|
||||||
}
|
}
|
||||||
int lev = levelUse | levelNext << 16;
|
int lev = levelUse | levelNext << 16;
|
||||||
if (visibleChars == 0 && foldCompact)
|
if (visibleChars == 0 && options.foldCompact)
|
||||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||||
if (levelUse < levelNext)
|
if (levelUse < levelNext)
|
||||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
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,
|
LexerModule lmD(SCLEX_D, LexerD::LexerFactoryD, "d", dWordLists);
|
||||||
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);
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.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, "endmodule") == 0 || strcmp(s, "endprogram") == 0
|
||||||
|| strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
|
|| strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
|
||||||
|| strcmp(s, "endwhere") == 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;
|
lev = -1;
|
||||||
} else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
|
} else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
|
||||||
lev = 0;
|
lev = 0;
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
@ -745,8 +744,18 @@ 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))) {
|
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);
|
//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 ((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 == '#') {
|
||||||
levelCurrent += ((ch == '{') || (ch == '/')) ? 1 : -1;
|
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 == '/')) {
|
} else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
|
||||||
levelCurrent--;
|
levelCurrent--;
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -44,7 +44,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
@ -510,7 +509,7 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
|
|||||||
styler.ColourTo(endLine, SCE_DIFF_COMMAND);
|
styler.ColourTo(endLine, SCE_DIFF_COMMAND);
|
||||||
} else if (0 == strncmp(lineBuffer, "Index: ", 7)) { // For subversion's diff
|
} else if (0 == strncmp(lineBuffer, "Index: ", 7)) { // For subversion's diff
|
||||||
styler.ColourTo(endLine, SCE_DIFF_COMMAND);
|
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
|
// In a context diff, --- appears in both the header and the position markers
|
||||||
if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
|
if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
|
||||||
styler.ColourTo(endLine, SCE_DIFF_POSITION);
|
styler.ColourTo(endLine, SCE_DIFF_POSITION);
|
||||||
@ -930,8 +929,8 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
|
|||||||
// Command or return status
|
// Command or return status
|
||||||
return SCE_ERR_CMD;
|
return SCE_ERR_CMD;
|
||||||
} else if (lineBuffer[0] == '<') {
|
} else if (lineBuffer[0] == '<') {
|
||||||
// Diff removal, but not interested. Trapped to avoid hitting CTAG cases.
|
// Diff removal.
|
||||||
return SCE_ERR_DEFAULT;
|
return SCE_ERR_DIFF_DELETION;
|
||||||
} else if (lineBuffer[0] == '!') {
|
} else if (lineBuffer[0] == '!') {
|
||||||
return SCE_ERR_DIFF_CHANGED;
|
return SCE_ERR_DIFF_CHANGED;
|
||||||
} else if (lineBuffer[0] == '+') {
|
} else if (lineBuffer[0] == '+') {
|
||||||
|
@ -118,7 +118,6 @@ contains requires
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
/** @file LexSQL.cxx
|
/** @file LexSQL.cxx
|
||||||
** Lexer for SQL, including PL/SQL and SQL*Plus.
|
** 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.
|
// The License.txt file describes the conditions under which this software may be distributed.
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -12,24 +12,36 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable: 4786)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "ILexer.h"
|
#include "ILexer.h"
|
||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
#include "StyleContext.h"
|
#include "StyleContext.h"
|
||||||
#include "CharacterSet.h"
|
#include "CharacterSet.h"
|
||||||
#include "LexerModule.h"
|
#include "LexerModule.h"
|
||||||
|
#include "OptionSet.h"
|
||||||
|
|
||||||
#ifdef SCI_NAMESPACE
|
#ifdef SCI_NAMESPACE
|
||||||
using namespace Scintilla;
|
using namespace Scintilla;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline bool IsAWordChar(int ch) {
|
static inline bool IsAWordChar(int ch, bool sqlAllowDottedWord) {
|
||||||
return (ch < 0x80) && (isalnum(ch) || ch == '_');
|
if (!sqlAllowDottedWord)
|
||||||
|
return (ch < 0x80) && (isalnum(ch) || ch == '_');
|
||||||
|
else
|
||||||
|
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool IsAWordStart(int ch) {
|
static inline bool IsAWordStart(int ch) {
|
||||||
@ -47,31 +59,289 @@ static inline bool IsANumberChar(int ch) {
|
|||||||
// Not exactly following number definition (several dots are seen as OK, etc.)
|
// Not exactly following number definition (several dots are seen as OK, etc.)
|
||||||
// but probably enough in most cases.
|
// but probably enough in most cases.
|
||||||
return (ch < 0x80) &&
|
return (ch < 0x80) &&
|
||||||
(isdigit(ch) || toupper(ch) == 'E' ||
|
(isdigit(ch) || toupper(ch) == 'E' ||
|
||||||
ch == '.' || ch == '-' || ch == '+');
|
ch == '.' || ch == '-' || ch == '+');
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
|
|
||||||
Accessor &styler) {
|
|
||||||
|
|
||||||
WordList &keywords1 = *keywordlists[0];
|
class SQLStates {
|
||||||
WordList &keywords2 = *keywordlists[1];
|
public :
|
||||||
WordList &kw_pldoc = *keywordlists[2];
|
void Set(int lineNumber, unsigned short int sqlStatesLine) {
|
||||||
WordList &kw_sqlplus = *keywordlists[3];
|
if (!sqlStatement.size() == 0 || !sqlStatesLine == 0) {
|
||||||
WordList &kw_user1 = *keywordlists[4];
|
sqlStatement.resize(lineNumber + 1, 0);
|
||||||
WordList &kw_user2 = *keywordlists[5];
|
sqlStatement[lineNumber] = sqlStatesLine;
|
||||||
WordList &kw_user3 = *keywordlists[6];
|
}
|
||||||
WordList &kw_user4 = *keywordlists[7];
|
}
|
||||||
|
|
||||||
|
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);
|
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;
|
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.
|
// Determine if the current state should terminate.
|
||||||
switch (sc.state) {
|
switch (sc.state) {
|
||||||
case SCE_SQL_OPERATOR:
|
case SCE_SQL_OPERATOR:
|
||||||
@ -84,7 +354,7 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCE_SQL_IDENTIFIER:
|
case SCE_SQL_IDENTIFIER:
|
||||||
if (!IsAWordChar(sc.ch)) {
|
if (!IsAWordChar(sc.ch, options.sqlAllowDottedWord)) {
|
||||||
int nextState = SCE_SQL_DEFAULT;
|
int nextState = SCE_SQL_DEFAULT;
|
||||||
char s[1000];
|
char s[1000];
|
||||||
sc.GetCurrentLowered(s, sizeof(s));
|
sc.GetCurrentLowered(s, sizeof(s));
|
||||||
@ -161,7 +431,7 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCE_SQL_CHARACTER:
|
case SCE_SQL_CHARACTER:
|
||||||
if (sqlBackslashEscapes && sc.ch == '\\') {
|
if (options.sqlBackslashEscapes && sc.ch == '\\') {
|
||||||
sc.Forward();
|
sc.Forward();
|
||||||
} else if (sc.ch == '\'') {
|
} else if (sc.ch == '\'') {
|
||||||
if (sc.chNext == '\"') {
|
if (sc.chNext == '\"') {
|
||||||
@ -191,7 +461,7 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
|
|||||||
sc.SetState(SCE_SQL_NUMBER);
|
sc.SetState(SCE_SQL_NUMBER);
|
||||||
} else if (IsAWordStart(sc.ch)) {
|
} else if (IsAWordStart(sc.ch)) {
|
||||||
sc.SetState(SCE_SQL_IDENTIFIER);
|
sc.SetState(SCE_SQL_IDENTIFIER);
|
||||||
} else if (sc.ch == 0x60 && sqlBackticksIdentifier) {
|
} else if (sc.ch == 0x60 && options.sqlBackticksIdentifier) {
|
||||||
sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
|
sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
|
||||||
} else if (sc.Match('/', '*')) {
|
} else if (sc.Match('/', '*')) {
|
||||||
if (sc.Match("/**") || sc.Match("/*!")) { // Support of Doxygen doc. style
|
if (sc.Match("/**") || sc.Match("/*!")) { // Support of Doxygen doc. style
|
||||||
@ -204,9 +474,9 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
|
|||||||
// MySQL requires a space or control char after --
|
// MySQL requires a space or control char after --
|
||||||
// http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
|
// http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
|
||||||
// Perhaps we should enforce that with proper property:
|
// Perhaps we should enforce that with proper property:
|
||||||
//~ } else if (sc.Match("-- ")) {
|
//~ } else if (sc.Match("-- ")) {
|
||||||
sc.SetState(SCE_SQL_COMMENTLINE);
|
sc.SetState(SCE_SQL_COMMENTLINE);
|
||||||
} else if (sc.ch == '#') {
|
} else if (sc.ch == '#' && options.sqlNumbersignComment) {
|
||||||
sc.SetState(SCE_SQL_COMMENTLINEDOC);
|
sc.SetState(SCE_SQL_COMMENTLINEDOC);
|
||||||
} else if (sc.ch == '\'') {
|
} else if (sc.ch == '\'') {
|
||||||
sc.SetState(SCE_SQL_CHARACTER);
|
sc.SetState(SCE_SQL_CHARACTER);
|
||||||
@ -220,25 +490,10 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
|
|||||||
sc.Complete();
|
sc.Complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsStreamCommentStyle(int style) {
|
void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
|
||||||
return style == SCE_SQL_COMMENT ||
|
if (!options.fold)
|
||||||
style == SCE_SQL_COMMENTDOC ||
|
return;
|
||||||
style == SCE_SQL_COMMENTDOCKEYWORD ||
|
LexAccessor styler(pAccess);
|
||||||
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;
|
|
||||||
|
|
||||||
unsigned int endPos = startPos + length;
|
unsigned int endPos = startPos + length;
|
||||||
int visibleChars = 0;
|
int visibleChars = 0;
|
||||||
int lineCurrent = styler.GetLine(startPos);
|
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 styleNext = styler.StyleAt(startPos);
|
||||||
int style = initStyle;
|
int style = initStyle;
|
||||||
bool endFound = false;
|
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++) {
|
for (unsigned int i = startPos; i < endPos; i++) {
|
||||||
char ch = chNext;
|
char ch = chNext;
|
||||||
chNext = styler.SafeGetCharAt(i + 1);
|
chNext = styler.SafeGetCharAt(i + 1);
|
||||||
@ -258,7 +521,16 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
|||||||
style = styleNext;
|
style = styleNext;
|
||||||
styleNext = styler.StyleAt(i + 1);
|
styleNext = styler.StyleAt(i + 1);
|
||||||
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
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)) {
|
if (!IsStreamCommentStyle(stylePrev)) {
|
||||||
levelNext++;
|
levelNext++;
|
||||||
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
|
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
|
||||||
@ -266,7 +538,7 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
|||||||
levelNext--;
|
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
|
// MySQL needs -- comments to be followed by space or control char
|
||||||
if ((ch == '-') && (chNext == '-')) {
|
if ((ch == '-') && (chNext == '-')) {
|
||||||
char chNext2 = styler.SafeGetCharAt(i + 2);
|
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 (style == SCE_SQL_OPERATOR) {
|
||||||
if (ch == '(') {
|
if (ch == '(') {
|
||||||
levelNext++;
|
if (levelCurrent > levelNext)
|
||||||
|
levelCurrent--;
|
||||||
|
levelNext++;
|
||||||
} else if (ch == ')') {
|
} else if (ch == ')') {
|
||||||
levelNext--;
|
levelNext--;
|
||||||
|
} else if ((!options.foldOnlyBegin) && ch == ';') {
|
||||||
|
sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If new keyword (cannot trigger on elseif or nullif, does less tests)
|
// If new keyword (cannot trigger on elseif or nullif, does less tests)
|
||||||
if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {
|
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];
|
char s[MAX_KW_LEN + 2];
|
||||||
unsigned int j = 0;
|
unsigned int j = 0;
|
||||||
for (; j < MAX_KW_LEN + 1; j++) {
|
for (; j < MAX_KW_LEN + 1; j++) {
|
||||||
@ -302,33 +578,133 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
|||||||
} else {
|
} else {
|
||||||
s[j] = '\0';
|
s[j] = '\0';
|
||||||
}
|
}
|
||||||
if ((!foldOnlyBegin) && (strcmp(s, "if") == 0 || strcmp(s, "loop") == 0)) {
|
|
||||||
|
if (strcmp(s, "if") == 0) {
|
||||||
if (endFound) {
|
if (endFound) {
|
||||||
// ignore
|
|
||||||
endFound = false;
|
endFound = false;
|
||||||
|
if (options.foldOnlyBegin && !isUnfoldingIgnored) {
|
||||||
|
// this end isn't for begin block, but for if block ("end if;")
|
||||||
|
// so ignore previous "end" by increment levelNext.
|
||||||
|
levelNext++;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
levelNext++;
|
if (!options.foldOnlyBegin)
|
||||||
|
sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
|
||||||
|
if (levelCurrent > levelNext) {
|
||||||
|
// doesn't include this line into the folding block
|
||||||
|
// because doesn't hide IF (eg "END; IF")
|
||||||
|
levelCurrent = levelNext;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (!options.foldOnlyBegin &&
|
||||||
|
strcmp(s, "then") == 0 &&
|
||||||
|
sqlStates.IsIntoCondition(sqlStatesCurrentLine)) {
|
||||||
|
sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, false);
|
||||||
|
if (!options.foldOnlyBegin) {
|
||||||
|
if (levelCurrent > levelNext) {
|
||||||
|
levelCurrent = levelNext;
|
||||||
|
}
|
||||||
|
if (!statementFound)
|
||||||
|
levelNext++;
|
||||||
|
|
||||||
|
statementFound = true;
|
||||||
|
} else if (levelCurrent > levelNext) {
|
||||||
|
// doesn't include this line into the folding block
|
||||||
|
// because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
|
||||||
|
levelCurrent = levelNext;
|
||||||
|
}
|
||||||
|
} else if (strcmp(s, "loop") == 0 ||
|
||||||
|
strcmp(s, "case") == 0) {
|
||||||
|
if (endFound) {
|
||||||
|
endFound = false;
|
||||||
|
if (options.foldOnlyBegin && !isUnfoldingIgnored) {
|
||||||
|
// this end isn't for begin block, but for loop block ("end loop;") or case block ("end case;")
|
||||||
|
// so ignore previous "end" by increment levelNext.
|
||||||
|
levelNext++;
|
||||||
|
}
|
||||||
|
if ((!options.foldOnlyBegin) && strcmp(s, "case") == 0) {
|
||||||
|
sqlStatesCurrentLine = sqlStates.EndCaseBlock(sqlStatesCurrentLine);
|
||||||
|
levelNext--; //again for the "end case;" and block when
|
||||||
|
}
|
||||||
|
} else if (!options.foldOnlyBegin) {
|
||||||
|
if (strcmp(s, "case") == 0) {
|
||||||
|
sqlStatesCurrentLine = sqlStates.BeginCaseBlock(sqlStatesCurrentLine);
|
||||||
|
|
||||||
|
//for case block increment 2 times
|
||||||
|
if (!statementFound)
|
||||||
|
levelNext++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (levelCurrent > levelNext) {
|
||||||
|
levelCurrent = levelNext;
|
||||||
|
}
|
||||||
|
if (!statementFound)
|
||||||
|
levelNext++;
|
||||||
|
|
||||||
|
statementFound = true;
|
||||||
|
} else if (levelCurrent > levelNext) {
|
||||||
|
// doesn't include this line into the folding block
|
||||||
|
// because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
|
||||||
|
levelCurrent = levelNext;
|
||||||
|
}
|
||||||
|
} else if ((!options.foldOnlyBegin) && (
|
||||||
|
// folding for ELSE and ELSIF block only if foldAtElse is set
|
||||||
|
// and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
|
||||||
|
options.foldAtElse && !statementFound) && strcmp(s, "elsif") == 0) {
|
||||||
|
sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
|
||||||
|
levelCurrent--;
|
||||||
|
levelNext--;
|
||||||
|
} else if ((!options.foldOnlyBegin) && (
|
||||||
|
// folding for ELSE and ELSIF block only if foldAtElse is set
|
||||||
|
// and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
|
||||||
|
options.foldAtElse && !statementFound) && strcmp(s, "else") == 0) {
|
||||||
|
// prevent also ELSE is on the same line (eg. "ELSE ... END IF;")
|
||||||
|
statementFound = true;
|
||||||
|
// we are in same case "} ELSE {" in C language
|
||||||
|
levelCurrent--;
|
||||||
|
|
||||||
} else if (strcmp(s, "begin") == 0) {
|
} else if (strcmp(s, "begin") == 0) {
|
||||||
levelNext++;
|
levelNext++;
|
||||||
|
sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, false);
|
||||||
} else if ((strcmp(s, "end") == 0) ||
|
} else if ((strcmp(s, "end") == 0) ||
|
||||||
// // DROP TABLE IF EXISTS or CREATE TABLE IF NOT EXISTS
|
// SQL Anywhere permits IF ... ELSE ... ENDIF
|
||||||
(foldSqlExists && (strcmp(s, "exists") == 0)) ||
|
// will only be active if "endif" appears in the
|
||||||
// // SQL Anywhere permits IF ... ELSE ... ENDIF
|
// keyword list.
|
||||||
// // will only be active if "endif" appears in the
|
(strcmp(s, "endif") == 0)) {
|
||||||
// // keyword list.
|
|
||||||
(strcmp(s, "endif") == 0)) {
|
|
||||||
endFound = true;
|
endFound = true;
|
||||||
levelNext--;
|
levelNext--;
|
||||||
if (levelNext < SC_FOLDLEVELBASE) {
|
if (levelNext < SC_FOLDLEVELBASE) {
|
||||||
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) {
|
if (atEOL) {
|
||||||
int levelUse = levelCurrent;
|
int levelUse = levelCurrent;
|
||||||
int lev = levelUse | levelNext << 16;
|
int lev = levelUse | levelNext << 16;
|
||||||
if (visibleChars == 0 && foldCompact)
|
if (visibleChars == 0 && options.foldCompact)
|
||||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||||
if (levelUse < levelNext)
|
if (levelUse < levelNext)
|
||||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||||
@ -338,7 +714,9 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
|||||||
lineCurrent++;
|
lineCurrent++;
|
||||||
levelCurrent = levelNext;
|
levelCurrent = levelNext;
|
||||||
visibleChars = 0;
|
visibleChars = 0;
|
||||||
endFound = false;
|
statementFound = false;
|
||||||
|
if (!options.foldOnlyBegin)
|
||||||
|
sqlStates.Set(lineCurrent, sqlStatesCurrentLine);
|
||||||
}
|
}
|
||||||
if (!isspacechar(ch)) {
|
if (!isspacechar(ch)) {
|
||||||
visibleChars++;
|
visibleChars++;
|
||||||
@ -346,16 +724,4 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * const sqlWordListDesc[] = {
|
LexerModule lmSQL(SCLEX_SQL, LexerSQL::LexerFactorySQL, "sql", 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);
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "Scintilla.h"
|
#include "Scintilla.h"
|
||||||
#include "SciLexer.h"
|
#include "SciLexer.h"
|
||||||
|
|
||||||
#include "PropSetSimple.h"
|
|
||||||
#include "WordList.h"
|
#include "WordList.h"
|
||||||
#include "LexAccessor.h"
|
#include "LexAccessor.h"
|
||||||
#include "Accessor.h"
|
#include "Accessor.h"
|
||||||
|
@ -50,8 +50,8 @@ public:
|
|||||||
assert(val < size);
|
assert(val < size);
|
||||||
bset[val] = true;
|
bset[val] = true;
|
||||||
}
|
}
|
||||||
void AddString(const char *CharacterSet) {
|
void AddString(const char *setToAdd) {
|
||||||
for (const char *cp=CharacterSet; *cp; cp++) {
|
for (const char *cp=setToAdd; *cp; cp++) {
|
||||||
int val = static_cast<unsigned char>(*cp);
|
int val = static_cast<unsigned char>(*cp);
|
||||||
assert(val >= 0);
|
assert(val >= 0);
|
||||||
assert(val < size);
|
assert(val < size);
|
||||||
|
@ -20,7 +20,7 @@ protected:
|
|||||||
WordList *keyWordLists[numWordLists+1];
|
WordList *keyWordLists[numWordLists+1];
|
||||||
public:
|
public:
|
||||||
LexerBase();
|
LexerBase();
|
||||||
~LexerBase();
|
virtual ~LexerBase();
|
||||||
void SCI_METHOD Release();
|
void SCI_METHOD Release();
|
||||||
int SCI_METHOD Version() const;
|
int SCI_METHOD Version() const;
|
||||||
const char * SCI_METHOD PropertyNames();
|
const char * SCI_METHOD PropertyNames();
|
||||||
|
@ -80,6 +80,8 @@ class OptionSet {
|
|||||||
names += name;
|
names += name;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
virtual ~OptionSet() {
|
||||||
|
}
|
||||||
void DefineProperty(const char *name, plcob pb, std::string description="") {
|
void DefineProperty(const char *name, plcob pb, std::string description="") {
|
||||||
nameToDef[name] = Option(pb, description);
|
nameToDef[name] = Option(pb, description);
|
||||||
AppendName(name);
|
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 {
|
bool WordList::InList(const char *s) const {
|
||||||
if (0 == words)
|
if (0 == words)
|
||||||
return false;
|
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).
|
(removing unused lexers and an updated marshallers file).
|
||||||
diff -Naur scintilla_orig/gtk/scintilla-marshal.c scintilla/gtk/scintilla-marshal.c
|
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_orig/gtk/scintilla-marshal.c 2010-10-27 23:15:45.000000000 +0200
|
||||||
+++ scintilla/gtk/scintilla-marshal.c 2008-12-06 12:11:33.000000000 +0100
|
+++ scintilla/gtk/scintilla-marshal.c 2011-04-03 17:42:59.000000000 +0200
|
||||||
@@ -35,8 +35,8 @@
|
@@ -35,8 +35,8 @@
|
||||||
#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
|
#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_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,
|
typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1,
|
||||||
diff -Naur scintilla_orig/src/Catalogue.cxx scintilla/src/Catalogue.cxx
|
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_orig/src/Catalogue.cxx 2011-03-17 23:41:24.000000000 +0100
|
||||||
+++ scintilla/src/Catalogue.cxx 2010-11-21 18:00:07.000000000 +0100
|
+++ scintilla/src/Catalogue.cxx 2011-04-03 17:43:45.000000000 +0200
|
||||||
@@ -81,98 +81,41 @@
|
@@ -81,100 +81,42 @@
|
||||||
|
|
||||||
//++Autogenerated -- run src/LexGen.py to regenerate
|
//++Autogenerated -- run src/LexGen.py to regenerate
|
||||||
//**\(\tLINK_LEXER(\*);\n\)
|
//**\(\tLINK_LEXER(\*);\n\)
|
||||||
|
- LINK_LEXER(lmA68k);
|
||||||
- LINK_LEXER(lmAbaqus);
|
- LINK_LEXER(lmAbaqus);
|
||||||
LINK_LEXER(lmAda);
|
LINK_LEXER(lmAda);
|
||||||
- LINK_LEXER(lmAns1);
|
- LINK_LEXER(lmAns1);
|
||||||
@ -51,7 +52,7 @@ diff -Naur scintilla_orig/src/Catalogue.cxx scintilla/src/Catalogue.cxx
|
|||||||
- LINK_LEXER(lmClw);
|
- LINK_LEXER(lmClw);
|
||||||
- LINK_LEXER(lmClwNoCase);
|
- LINK_LEXER(lmClwNoCase);
|
||||||
LINK_LEXER(lmCmake);
|
LINK_LEXER(lmCmake);
|
||||||
- LINK_LEXER(lmCOBOL);
|
LINK_LEXER(lmCOBOL);
|
||||||
- LINK_LEXER(lmConf);
|
- LINK_LEXER(lmConf);
|
||||||
LINK_LEXER(lmCPP);
|
LINK_LEXER(lmCPP);
|
||||||
- LINK_LEXER(lmCPPNoCase);
|
- LINK_LEXER(lmCPPNoCase);
|
||||||
@ -86,6 +87,7 @@ diff -Naur scintilla_orig/src/Catalogue.cxx scintilla/src/Catalogue.cxx
|
|||||||
- LINK_LEXER(lmMatlab);
|
- LINK_LEXER(lmMatlab);
|
||||||
- LINK_LEXER(lmMETAPOST);
|
- LINK_LEXER(lmMETAPOST);
|
||||||
- LINK_LEXER(lmMMIXAL);
|
- LINK_LEXER(lmMMIXAL);
|
||||||
|
- LINK_LEXER(lmModula);
|
||||||
- LINK_LEXER(lmMSSQL);
|
- LINK_LEXER(lmMSSQL);
|
||||||
- LINK_LEXER(lmMySQL);
|
- LINK_LEXER(lmMySQL);
|
||||||
- LINK_LEXER(lmNimrod);
|
- LINK_LEXER(lmNimrod);
|
||||||
|
@ -129,11 +129,11 @@ void AutoComplete::Select(const char *word) {
|
|||||||
size_t lenWord = strlen(word);
|
size_t lenWord = strlen(word);
|
||||||
int location = -1;
|
int location = -1;
|
||||||
const int maxItemLen=1000;
|
const int maxItemLen=1000;
|
||||||
char item[maxItemLen];
|
|
||||||
int start = 0; // lower bound of the api array block to search
|
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
|
int end = lb->Length() - 1; // upper bound of the api array block to search
|
||||||
while ((start <= end) && (location == -1)) { // Binary searching loop
|
while ((start <= end) && (location == -1)) { // Binary searching loop
|
||||||
int pivot = (start + end) / 2;
|
int pivot = (start + end) / 2;
|
||||||
|
char item[maxItemLen];
|
||||||
lb->GetValue(pivot, item, maxItemLen);
|
lb->GetValue(pivot, item, maxItemLen);
|
||||||
int cond;
|
int cond;
|
||||||
if (ignoreCase)
|
if (ignoreCase)
|
||||||
|
@ -29,6 +29,7 @@ CallTip::CallTip() {
|
|||||||
rectUp = PRectangle(0,0,0,0);
|
rectUp = PRectangle(0,0,0,0);
|
||||||
rectDown = PRectangle(0,0,0,0);
|
rectDown = PRectangle(0,0,0,0);
|
||||||
lineHeight = 1;
|
lineHeight = 1;
|
||||||
|
offsetMain = 0;
|
||||||
startHighlight = 0;
|
startHighlight = 0;
|
||||||
endHighlight = 0;
|
endHighlight = 0;
|
||||||
tabSize = 0;
|
tabSize = 0;
|
||||||
@ -45,6 +46,8 @@ CallTip::CallTip() {
|
|||||||
colourSel.desired = ColourDesired(0, 0, 0x80);
|
colourSel.desired = ColourDesired(0, 0, 0x80);
|
||||||
colourShade.desired = ColourDesired(0, 0, 0);
|
colourShade.desired = ColourDesired(0, 0, 0);
|
||||||
colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
|
colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
|
||||||
|
codePage = 0;
|
||||||
|
clickPlace = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CallTip::~CallTip() {
|
CallTip::~CallTip() {
|
||||||
|
@ -14,14 +14,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#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 "Platform.h"
|
||||||
|
|
||||||
#include "ILexer.h"
|
#include "ILexer.h"
|
||||||
@ -95,7 +87,7 @@ void LexInterface::Colourise(int start, int end) {
|
|||||||
|
|
||||||
Document::Document() {
|
Document::Document() {
|
||||||
refCount = 0;
|
refCount = 0;
|
||||||
#ifdef unix
|
#ifdef __unix__
|
||||||
eolMode = SC_EOL_LF;
|
eolMode = SC_EOL_LF;
|
||||||
#else
|
#else
|
||||||
eolMode = SC_EOL_CRLF;
|
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
|
// See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx
|
||||||
// http://msdn.microsoft.com/en-us/library/cc194790.aspx
|
// http://msdn.microsoft.com/en-us/library/cc194790.aspx
|
||||||
if ((pos - 1) <= posStartLine) {
|
if ((pos - 1) <= posStartLine) {
|
||||||
return posStartLine - 1;
|
return pos - 1;
|
||||||
} else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) {
|
} else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) {
|
||||||
// Must actually be trail byte
|
// Must actually be trail byte
|
||||||
return pos - 2;
|
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);
|
//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
|
||||||
const int limitPos = Platform::Maximum(startPos, endPos);
|
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) {
|
if (caseSensitive) {
|
||||||
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
|
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
|
||||||
bool found = (pos + lengthFind) <= limitPos;
|
bool found = (pos + lengthFind) <= limitPos;
|
||||||
@ -1526,8 +1522,8 @@ void Document::EnsureStyledTo(int pos) {
|
|||||||
IncrementStyleClock();
|
IncrementStyleClock();
|
||||||
if (pli && !pli->UseContainerLexing()) {
|
if (pli && !pli->UseContainerLexing()) {
|
||||||
int lineEndStyled = LineFromPosition(GetEndStyled());
|
int lineEndStyled = LineFromPosition(GetEndStyled());
|
||||||
int endStyled = LineStart(lineEndStyled);
|
int endStyledTo = LineStart(lineEndStyled);
|
||||||
pli->Colourise(endStyled, pos);
|
pli->Colourise(endStyledTo, pos);
|
||||||
} else {
|
} else {
|
||||||
// Ask the watchers to style, and stop as soon as one responds.
|
// Ask the watchers to style, and stop as soon as one responds.
|
||||||
for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
|
for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
|
||||||
|
@ -357,6 +357,7 @@ public:
|
|||||||
const WatcherWithUserData *GetWatchers() const { return watchers; }
|
const WatcherWithUserData *GetWatchers() const { return watchers; }
|
||||||
int GetLenWatchers() const { return lenWatchers; }
|
int GetLenWatchers() const { return lenWatchers; }
|
||||||
|
|
||||||
|
CharClassify::cc WordCharClass(unsigned char ch);
|
||||||
bool IsWordPartSeparator(char ch);
|
bool IsWordPartSeparator(char ch);
|
||||||
int WordPartLeft(int pos);
|
int WordPartLeft(int pos);
|
||||||
int WordPartRight(int pos);
|
int WordPartRight(int pos);
|
||||||
@ -368,7 +369,6 @@ public:
|
|||||||
int BraceMatch(int position, int maxReStyle);
|
int BraceMatch(int position, int maxReStyle);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CharClassify::cc WordCharClass(unsigned char ch);
|
|
||||||
bool IsWordStartAt(int pos);
|
bool IsWordStartAt(int pos);
|
||||||
bool IsWordEndAt(int pos);
|
bool IsWordEndAt(int pos);
|
||||||
bool IsWordAt(int start, int end);
|
bool IsWordAt(int start, int end);
|
||||||
|
@ -16,14 +16,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#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 "Platform.h"
|
||||||
|
|
||||||
#include "ILexer.h"
|
#include "ILexer.h"
|
||||||
@ -141,6 +133,9 @@ Editor::Editor() {
|
|||||||
lastXChosen = 0;
|
lastXChosen = 0;
|
||||||
lineAnchor = 0;
|
lineAnchor = 0;
|
||||||
originalAnchorPos = 0;
|
originalAnchorPos = 0;
|
||||||
|
wordSelectAnchorStartPos = 0;
|
||||||
|
wordSelectAnchorEndPos = 0;
|
||||||
|
wordSelectInitialCaretPos = -1;
|
||||||
|
|
||||||
primarySelection = true;
|
primarySelection = true;
|
||||||
|
|
||||||
@ -183,7 +178,8 @@ Editor::Editor() {
|
|||||||
|
|
||||||
lengthForEncode = -1;
|
lengthForEncode = -1;
|
||||||
|
|
||||||
needUpdateUI = true;
|
needUpdateUI = 0;
|
||||||
|
ContainerNeedsUpdate(SC_UPDATE_CONTENT);
|
||||||
braces[0] = invalidPosition;
|
braces[0] = invalidPosition;
|
||||||
braces[1] = invalidPosition;
|
braces[1] = invalidPosition;
|
||||||
bracesMatchStyle = STYLE_BRACEBAD;
|
bracesMatchStyle = STYLE_BRACEBAD;
|
||||||
@ -442,7 +438,10 @@ int Editor::LineFromLocation(Point pt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Editor::SetTopLine(int topLineNew) {
|
void Editor::SetTopLine(int topLineNew) {
|
||||||
topLine = topLineNew;
|
if (topLine != topLineNew) {
|
||||||
|
topLine = topLineNew;
|
||||||
|
ContainerNeedsUpdate(SC_UPDATE_V_SCROLL);
|
||||||
|
}
|
||||||
posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine));
|
posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,17 +705,17 @@ void Editor::SetRectangularRange() {
|
|||||||
if (sel.selType == Selection::selThin) {
|
if (sel.selType == Selection::selThin) {
|
||||||
xCaret = xAnchor;
|
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 lineCaret = pdoc->LineFromPosition(sel.Rectangular().caret.Position());
|
||||||
int increment = (lineCaret > lineAnchor) ? 1 : -1;
|
int increment = (lineCaret > lineAnchorRect) ? 1 : -1;
|
||||||
for (int line=lineAnchor; line != lineCaret+increment; line += increment) {
|
for (int line=lineAnchorRect; line != lineCaret+increment; line += increment) {
|
||||||
SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor));
|
SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor));
|
||||||
if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0)
|
if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0)
|
||||||
range.ClearVirtualSpace();
|
range.ClearVirtualSpace();
|
||||||
if (line == lineAnchor)
|
if (line == lineAnchorRect)
|
||||||
sel.SetSelection(range);
|
sel.SetSelection(range);
|
||||||
else
|
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());
|
lastAffected = Platform::Maximum(lastAffected, sel.Range(r).anchor.Position());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
needUpdateUI = true;
|
ContainerNeedsUpdate(SC_UPDATE_SELECTION);
|
||||||
InvalidateRange(firstAffected, lastAffected);
|
InvalidateRange(firstAffected, lastAffected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -990,6 +989,7 @@ void Editor::HorizontalScrollTo(int xPos) {
|
|||||||
xPos = 0;
|
xPos = 0;
|
||||||
if ((wrapState == eWrapNone) && (xOffset != xPos)) {
|
if ((wrapState == eWrapNone) && (xOffset != xPos)) {
|
||||||
xOffset = xPos;
|
xOffset = xPos;
|
||||||
|
ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
|
||||||
SetHorizontalScrollPos();
|
SetHorizontalScrollPos();
|
||||||
RedrawRect(GetClientRectangle());
|
RedrawRect(GetClientRectangle());
|
||||||
}
|
}
|
||||||
@ -1299,6 +1299,7 @@ void Editor::SetXYScroll(XYScrollPosition newXY) {
|
|||||||
}
|
}
|
||||||
if (newXY.xOffset != xOffset) {
|
if (newXY.xOffset != xOffset) {
|
||||||
xOffset = newXY.xOffset;
|
xOffset = newXY.xOffset;
|
||||||
|
ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
|
||||||
if (newXY.xOffset > 0) {
|
if (newXY.xOffset > 0) {
|
||||||
PRectangle rcText = GetTextRectangle();
|
PRectangle rcText = GetTextRectangle();
|
||||||
if (horizontalScrollBarVisible &&
|
if (horizontalScrollBarVisible &&
|
||||||
@ -2042,7 +2043,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
|
|||||||
ll->edgeColumn = -1;
|
ll->edgeColumn = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char styleByte = 0;
|
char styleByte;
|
||||||
const int styleMask = pdoc->stylingBitsMask;
|
const int styleMask = pdoc->stylingBitsMask;
|
||||||
ll->styleBitsSet = 0;
|
ll->styleBitsSet = 0;
|
||||||
// Fill base line layout
|
// 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
|
// Draw any translucent whole line states
|
||||||
rcSegment.left = xStart;
|
rcSegment.left = 0;
|
||||||
rcSegment.right = rcLine.right - 1;
|
rcSegment.right = rcLine.right - 1;
|
||||||
if (caret.active && vsDraw.showCaretLineBackground && ll->containsCaret) {
|
if (caret.active && vsDraw.showCaretLineBackground && ll->containsCaret) {
|
||||||
SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground.allocated, vsDraw.caretLineAlpha);
|
SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground.allocated, vsDraw.caretLineAlpha);
|
||||||
@ -3165,11 +3166,11 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pixmapSelPattern->FillRectangle(rcPattern, colourFMFill);
|
pixmapSelPattern->FillRectangle(rcPattern, colourFMFill);
|
||||||
pixmapSelPattern->PenColour(colourFMStripes);
|
for (int y = 0; y < patternSize; y++) {
|
||||||
for (int stripe = 0; stripe < patternSize; stripe++) {
|
for (int x = y % 2; x < patternSize; x+=2) {
|
||||||
// Alternating 1 pixel stripes is same as checkerboard.
|
PRectangle rcPixel(x, y, x+1, y+1);
|
||||||
pixmapSelPattern->MoveTo(0, stripe * 2);
|
pixmapSelPattern->FillRectangle(rcPixel, colourFMStripes);
|
||||||
pixmapSelPattern->LineTo(patternSize, stripe * 2 - patternSize);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3183,10 +3184,9 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
|
|||||||
pixmapIndentGuideHighlight->FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated);
|
pixmapIndentGuideHighlight->FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated);
|
||||||
pixmapIndentGuideHighlight->PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated);
|
pixmapIndentGuideHighlight->PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated);
|
||||||
for (int stripe = 1; stripe < vs.lineHeight + 1; stripe += 2) {
|
for (int stripe = 1; stripe < vs.lineHeight + 1; stripe += 2) {
|
||||||
pixmapIndentGuide->MoveTo(0, stripe);
|
PRectangle rcPixel(0, stripe, 1, stripe+1);
|
||||||
pixmapIndentGuide->LineTo(2, stripe);
|
pixmapIndentGuide->FillRectangle(rcPixel, vs.styles[STYLE_INDENTGUIDE].fore.allocated);
|
||||||
pixmapIndentGuideHighlight->MoveTo(0, stripe);
|
pixmapIndentGuideHighlight->FillRectangle(rcPixel, vs.styles[STYLE_BRACELIGHT].fore.allocated);
|
||||||
pixmapIndentGuideHighlight->LineTo(2, stripe);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3316,7 +3316,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
|
|||||||
surfaceWindow->SetPalette(&palTemp, true);
|
surfaceWindow->SetPalette(&palTemp, true);
|
||||||
|
|
||||||
NotifyUpdateUI();
|
NotifyUpdateUI();
|
||||||
needUpdateUI = false;
|
needUpdateUI = 0;
|
||||||
|
|
||||||
RefreshStyleData();
|
RefreshStyleData();
|
||||||
RefreshPixMaps(surfaceWindow);
|
RefreshPixMaps(surfaceWindow);
|
||||||
@ -3921,8 +3921,8 @@ void Editor::InsertPaste(SelectionPosition selStart, const char *text, int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::ClearSelection() {
|
void Editor::ClearSelection(bool retainMultipleSelections) {
|
||||||
if (!sel.IsRectangular())
|
if (!sel.IsRectangular() && !retainMultipleSelections)
|
||||||
FilterSelections();
|
FilterSelections();
|
||||||
UndoGroup ug(pdoc);
|
UndoGroup ug(pdoc);
|
||||||
for (size_t r=0; r<sel.Count(); r++) {
|
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() {
|
void Editor::NotifyUpdateUI() {
|
||||||
SCNotification scn = {0};
|
SCNotification scn = {0};
|
||||||
scn.nmhdr.code = SCN_UPDATEUI;
|
scn.nmhdr.code = SCN_UPDATEUI;
|
||||||
|
scn.updated = needUpdateUI;
|
||||||
NotifyParent(scn);
|
NotifyParent(scn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4338,7 +4339,7 @@ static inline int MovePositionForDeletion(int position, int startDeletion, int l
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Editor::NotifyModified(Document *, DocModification mh, void *) {
|
void Editor::NotifyModified(Document *, DocModification mh, void *) {
|
||||||
needUpdateUI = true;
|
ContainerNeedsUpdate(SC_UPDATE_CONTENT);
|
||||||
if (paintState == painting) {
|
if (paintState == painting) {
|
||||||
CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length));
|
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);
|
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.
|
* Force scroll and keep position relative to top of window.
|
||||||
*
|
*
|
||||||
@ -4727,7 +4733,6 @@ void Editor::Duplicate(bool forLine) {
|
|||||||
forLine = true;
|
forLine = true;
|
||||||
}
|
}
|
||||||
UndoGroup ug(pdoc, sel.Count() > 1);
|
UndoGroup ug(pdoc, sel.Count() > 1);
|
||||||
SelectionPosition last;
|
|
||||||
const char *eol = "";
|
const char *eol = "";
|
||||||
int eolLen = 0;
|
int eolLen = 0;
|
||||||
if (forLine) {
|
if (forLine) {
|
||||||
@ -5131,6 +5136,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
|
|||||||
inOverstrike = !inOverstrike;
|
inOverstrike = !inOverstrike;
|
||||||
DropCaret();
|
DropCaret();
|
||||||
ShowCaretAtCurrentPosition();
|
ShowCaretAtCurrentPosition();
|
||||||
|
ContainerNeedsUpdate(SC_UPDATE_CONTENT);
|
||||||
NotifyUpdateUI();
|
NotifyUpdateUI();
|
||||||
break;
|
break;
|
||||||
case SCI_CANCEL: // Cancel any modes - handled in subclass
|
case SCI_CANCEL: // Cancel any modes - handled in subclass
|
||||||
@ -5230,6 +5236,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
|
|||||||
UndoGroup ug(pdoc);
|
UndoGroup ug(pdoc);
|
||||||
sel.RangeMain().caret = SelectionPosition(
|
sel.RangeMain().caret = SelectionPosition(
|
||||||
InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
|
InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
|
||||||
|
sel.RangeMain().anchor = sel.RangeMain().caret;
|
||||||
int endWord = pdoc->NextWordStart(sel.MainCaret(), 1);
|
int endWord = pdoc->NextWordStart(sel.MainCaret(), 1);
|
||||||
pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret());
|
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_) {
|
void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {
|
||||||
if (lineAnchor_ < lineCurrent_) {
|
if (lineAnchor_ < lineCurrent_) {
|
||||||
SetSelection(pdoc->LineStart(lineCurrent_ + 1),
|
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) {
|
void Editor::DwellEnd(bool mouseMoved) {
|
||||||
if (mouseMoved)
|
if (mouseMoved)
|
||||||
ticksToDwell = dwellDelay;
|
ticksToDwell = dwellDelay;
|
||||||
@ -5910,13 +5951,33 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (selectionType == selWord) {
|
if (selectionType == selWord) {
|
||||||
if (sel.MainCaret() >= originalAnchorPos) { // Moved forward
|
int charPos = originalAnchorPos;
|
||||||
SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), 1),
|
if (sel.MainCaret() == originalAnchorPos) {
|
||||||
pdoc->ExtendWordSelect(originalAnchorPos, -1));
|
charPos = PositionFromLocation(pt, false, true);
|
||||||
} else { // Moved backward
|
charPos = MovePositionOutsideChar(charPos, -1);
|
||||||
SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), -1),
|
|
||||||
pdoc->ExtendWordSelect(originalAnchorPos, 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) {
|
} else if (selectionType == selLine) {
|
||||||
lineAnchor = LineFromLocation(pt);
|
lineAnchor = LineFromLocation(pt);
|
||||||
SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
|
SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
|
||||||
@ -5981,7 +6042,8 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
|
|||||||
InvalidateSelection(SelectionRange(newPos), true);
|
InvalidateSelection(SelectionRange(newPos), true);
|
||||||
if (sel.Count() > 1)
|
if (sel.Count() > 1)
|
||||||
Redraw();
|
Redraw();
|
||||||
sel.Clear();
|
if ((sel.Count() > 1) || (sel.selType != Selection::selStream))
|
||||||
|
sel.Clear();
|
||||||
sel.selType = alt ? Selection::selRectangle : Selection::selStream;
|
sel.selType = alt ? Selection::selRectangle : Selection::selStream;
|
||||||
SetSelection(newPos, newPos);
|
SetSelection(newPos, newPos);
|
||||||
}
|
}
|
||||||
@ -6098,7 +6160,7 @@ void Editor::ButtonMove(Point pt) {
|
|||||||
}
|
}
|
||||||
} else if (selectionType == selWord) {
|
} else if (selectionType == selWord) {
|
||||||
// Continue selecting by word
|
// 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
|
// No need to do anything. Previously this case was lumped
|
||||||
// in with "Moved forward", but that can be harmful in this
|
// in with "Moved forward", but that can be harmful in this
|
||||||
// case: a handler for the NotifyDoubleClick re-adjusts
|
// 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
|
// the ButtonMove() called via Tick() for auto-scrolling
|
||||||
// could result in the fancier word selection adjustment
|
// could result in the fancier word selection adjustment
|
||||||
// being unmade.
|
// being unmade.
|
||||||
} else if (movePos.Position() > originalAnchorPos) { // Moved forward
|
} else {
|
||||||
SetSelection(pdoc->ExtendWordSelect(movePos.Position(), 1),
|
wordSelectInitialCaretPos = -1;
|
||||||
pdoc->ExtendWordSelect(originalAnchorPos, -1));
|
WordSelection(movePos.Position());
|
||||||
} else { // Moved backward
|
|
||||||
SetSelection(pdoc->ExtendWordSelect(movePos.Position(), -1),
|
|
||||||
pdoc->ExtendWordSelect(originalAnchorPos, 1));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Continue selecting by line
|
// Continue selecting by line
|
||||||
@ -6151,7 +6210,7 @@ void Editor::ButtonMove(Point pt) {
|
|||||||
} else {
|
} else {
|
||||||
if (vs.fixedColumnWidth > 0) { // There is a margin
|
if (vs.fixedColumnWidth > 0) { // There is a margin
|
||||||
if (PointInSelMargin(pt)) {
|
if (PointInSelMargin(pt)) {
|
||||||
DisplayCursor(Window::cursorReverseArrow);
|
DisplayCursor(GetMarginCursor(pt));
|
||||||
SetHotSpotRange(NULL);
|
SetHotSpotRange(NULL);
|
||||||
return; // No need to test for selection
|
return; // No need to test for selection
|
||||||
}
|
}
|
||||||
@ -6177,6 +6236,8 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
|
|||||||
if (inDragDrop == ddInitial) {
|
if (inDragDrop == ddInitial) {
|
||||||
inDragDrop = ddNone;
|
inDragDrop = ddNone;
|
||||||
SetEmptySelection(newPos.Position());
|
SetEmptySelection(newPos.Position());
|
||||||
|
selectionType = selChar;
|
||||||
|
originalAnchorPos = sel.MainCaret();
|
||||||
}
|
}
|
||||||
if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) {
|
if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) {
|
||||||
hotSpotClickPos = INVALID_POSITION;
|
hotSpotClickPos = INVALID_POSITION;
|
||||||
@ -6184,7 +6245,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
|
|||||||
}
|
}
|
||||||
if (HaveMouseCapture()) {
|
if (HaveMouseCapture()) {
|
||||||
if (PointInSelMargin(pt)) {
|
if (PointInSelMargin(pt)) {
|
||||||
DisplayCursor(Window::cursorReverseArrow);
|
DisplayCursor(GetMarginCursor(pt));
|
||||||
} else {
|
} else {
|
||||||
DisplayCursor(Window::cursorText);
|
DisplayCursor(Window::cursorText);
|
||||||
SetHotSpotRange(NULL);
|
SetHotSpotRange(NULL);
|
||||||
@ -6344,7 +6405,7 @@ void Editor::IdleStyling() {
|
|||||||
|
|
||||||
if (needUpdateUI) {
|
if (needUpdateUI) {
|
||||||
NotifyUpdateUI();
|
NotifyUpdateUI();
|
||||||
needUpdateUI = false;
|
needUpdateUI = 0;
|
||||||
}
|
}
|
||||||
styleNeeded.Reset();
|
styleNeeded.Reset();
|
||||||
}
|
}
|
||||||
@ -7001,6 +7062,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
|
|||||||
|
|
||||||
case SCI_SETXOFFSET:
|
case SCI_SETXOFFSET:
|
||||||
xOffset = wParam;
|
xOffset = wParam;
|
||||||
|
ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
|
||||||
SetHorizontalScrollPos();
|
SetHorizontalScrollPos();
|
||||||
Redraw();
|
Redraw();
|
||||||
break;
|
break;
|
||||||
@ -7315,7 +7377,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
|
|||||||
case SCI_GOTOPOS:
|
case SCI_GOTOPOS:
|
||||||
SetEmptySelection(wParam);
|
SetEmptySelection(wParam);
|
||||||
EnsureCaretVisible();
|
EnsureCaretVisible();
|
||||||
Redraw();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCI_GETCURLINE: {
|
case SCI_GETCURLINE: {
|
||||||
@ -7466,6 +7527,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
xOffset = 0;
|
xOffset = 0;
|
||||||
|
ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
|
||||||
InvalidateStyleRedraw();
|
InvalidateStyleRedraw();
|
||||||
ReconfigureScrollBars();
|
ReconfigureScrollBars();
|
||||||
break;
|
break;
|
||||||
@ -7786,6 +7848,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
|
|||||||
else
|
else
|
||||||
return 0;
|
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:
|
case SCI_STYLECLEARALL:
|
||||||
vs.ClearStyles();
|
vs.ClearStyles();
|
||||||
InvalidateStyleRedraw();
|
InvalidateStyleRedraw();
|
||||||
|
@ -201,6 +201,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
|||||||
int lastXChosen;
|
int lastXChosen;
|
||||||
int lineAnchor;
|
int lineAnchor;
|
||||||
int originalAnchorPos;
|
int originalAnchorPos;
|
||||||
|
int wordSelectAnchorStartPos;
|
||||||
|
int wordSelectAnchorEndPos;
|
||||||
|
int wordSelectInitialCaretPos;
|
||||||
int targetStart;
|
int targetStart;
|
||||||
int targetEnd;
|
int targetEnd;
|
||||||
int searchFlags;
|
int searchFlags;
|
||||||
@ -208,7 +211,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
|||||||
int posTopLine;
|
int posTopLine;
|
||||||
int lengthForEncode;
|
int lengthForEncode;
|
||||||
|
|
||||||
bool needUpdateUI;
|
int needUpdateUI;
|
||||||
Position braces[2];
|
Position braces[2];
|
||||||
int bracesMatchStyle;
|
int bracesMatchStyle;
|
||||||
int highlightGuideColumn;
|
int highlightGuideColumn;
|
||||||
@ -391,7 +394,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
|||||||
void AddChar(char ch);
|
void AddChar(char ch);
|
||||||
virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
|
virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
|
||||||
void InsertPaste(SelectionPosition selStart, const char *text, int len);
|
void InsertPaste(SelectionPosition selStart, const char *text, int len);
|
||||||
void ClearSelection();
|
void ClearSelection(bool retainMultipleSelections=false);
|
||||||
void ClearAll();
|
void ClearAll();
|
||||||
void ClearDocumentStyle();
|
void ClearDocumentStyle();
|
||||||
void Cut();
|
void Cut();
|
||||||
@ -438,6 +441,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
|||||||
void NotifyErrorOccurred(Document *doc, void *userData, int status);
|
void NotifyErrorOccurred(Document *doc, void *userData, int status);
|
||||||
void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
|
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);
|
void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false);
|
||||||
enum { cmSame, cmUpper, cmLower } caseMap;
|
enum { cmSame, cmUpper, cmLower } caseMap;
|
||||||
virtual std::string CaseMapString(const std::string &s, int caseMapping);
|
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 PositionInSelection(int pos);
|
||||||
bool PointInSelection(Point pt);
|
bool PointInSelection(Point pt);
|
||||||
bool PointInSelMargin(Point pt);
|
bool PointInSelMargin(Point pt);
|
||||||
|
Window::Cursor GetMarginCursor(Point pt);
|
||||||
void LineSelection(int lineCurrent_, int lineAnchor_);
|
void LineSelection(int lineCurrent_, int lineAnchor_);
|
||||||
|
void WordSelection(int pos);
|
||||||
void DwellEnd(bool mouseMoved);
|
void DwellEnd(bool mouseMoved);
|
||||||
void MouseLeave();
|
void MouseLeave();
|
||||||
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
|
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) {
|
void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
|
||||||
fneFactory = fFactory;
|
fneFactory = fFactory;
|
||||||
fnFactory = fFactory(index);
|
fnFactory = fFactory(index);
|
||||||
externalLanguage = index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
|
@ -27,11 +27,12 @@ typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned i
|
|||||||
class ExternalLexerModule : public LexerModule {
|
class ExternalLexerModule : public LexerModule {
|
||||||
protected:
|
protected:
|
||||||
GetLexerFactoryFunction fneFactory;
|
GetLexerFactoryFunction fneFactory;
|
||||||
int externalLanguage;
|
|
||||||
char name[100];
|
char name[100];
|
||||||
public:
|
public:
|
||||||
ExternalLexerModule(int language_, LexerFunction fnLexer_,
|
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));
|
strncpy(name, languageName_, sizeof(name));
|
||||||
name[sizeof(name)-1] = '\0';
|
name[sizeof(name)-1] = '\0';
|
||||||
languageName = name;
|
languageName = name;
|
||||||
|
@ -42,6 +42,10 @@ public:
|
|||||||
|
|
||||||
/// Divide an interval into multiple partitions.
|
/// Divide an interval into multiple partitions.
|
||||||
/// Useful for breaking a document down into sections such as lines.
|
/// 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 {
|
class Partitioning {
|
||||||
private:
|
private:
|
||||||
@ -153,6 +157,7 @@ public:
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return value in range [0 .. Partitions() - 1] even for arguments outside interval
|
||||||
int PartitionFromPosition(int pos) const {
|
int PartitionFromPosition(int pos) const {
|
||||||
if (body->Length() <= 1)
|
if (body->Length() <= 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -68,6 +68,8 @@ LineLayout::LineLayout(int maxLineLength_) :
|
|||||||
widthLine(wrapWidthInfinite),
|
widthLine(wrapWidthInfinite),
|
||||||
lines(1),
|
lines(1),
|
||||||
wrapIndent(0) {
|
wrapIndent(0) {
|
||||||
|
bracePreviousStyles[0] = 0;
|
||||||
|
bracePreviousStyles[1] = 0;
|
||||||
Resize(maxLineLength_);
|
Resize(maxLineLength_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,8 +147,10 @@ bool RunStyles::FillRange(int &position, int value, int &fillLength) {
|
|||||||
runEnd = RunFromPosition(end);
|
runEnd = RunFromPosition(end);
|
||||||
RemoveRunIfSameAsPrevious(runEnd);
|
RemoveRunIfSameAsPrevious(runEnd);
|
||||||
RemoveRunIfSameAsPrevious(runStart);
|
RemoveRunIfSameAsPrevious(runStart);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunStyles::SetValueAt(int position, int value) {
|
void RunStyles::SetValueAt(int position, int value) {
|
||||||
|
@ -20,6 +20,9 @@ using namespace Scintilla;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
|
void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
|
||||||
|
if (position == startChange) {
|
||||||
|
virtualSpace = 0;
|
||||||
|
}
|
||||||
if (insertion) {
|
if (insertion) {
|
||||||
if (position > startChange) {
|
if (position > startChange) {
|
||||||
position += length;
|
position += length;
|
||||||
@ -31,6 +34,7 @@ void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int
|
|||||||
position -= length;
|
position -= length;
|
||||||
} else {
|
} else {
|
||||||
position = startChange;
|
position = startChange;
|
||||||
|
virtualSpace = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -291,6 +295,11 @@ void Selection::AddSelection(SelectionRange range) {
|
|||||||
mainRange = ranges.size() - 1;
|
mainRange = ranges.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Selection::AddSelectionWithoutTrim(SelectionRange range) {
|
||||||
|
ranges.push_back(range);
|
||||||
|
mainRange = ranges.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
void Selection::TentativeSelection(SelectionRange range) {
|
void Selection::TentativeSelection(SelectionRange range) {
|
||||||
if (!tentativeMain) {
|
if (!tentativeMain) {
|
||||||
rangesSaved = ranges;
|
rangesSaved = ranges;
|
||||||
|
@ -60,7 +60,7 @@ public:
|
|||||||
struct SelectionSegment {
|
struct SelectionSegment {
|
||||||
SelectionPosition start;
|
SelectionPosition start;
|
||||||
SelectionPosition end;
|
SelectionPosition end;
|
||||||
SelectionSegment() {
|
SelectionSegment() : start(), end() {
|
||||||
}
|
}
|
||||||
SelectionSegment(SelectionPosition a, SelectionPosition b) {
|
SelectionSegment(SelectionPosition a, SelectionPosition b) {
|
||||||
if (a < b) {
|
if (a < b) {
|
||||||
@ -86,7 +86,7 @@ struct SelectionRange {
|
|||||||
SelectionPosition caret;
|
SelectionPosition caret;
|
||||||
SelectionPosition anchor;
|
SelectionPosition anchor;
|
||||||
|
|
||||||
SelectionRange() {
|
SelectionRange() : caret(), anchor() {
|
||||||
}
|
}
|
||||||
SelectionRange(SelectionPosition single) : caret(single), anchor(single) {
|
SelectionRange(SelectionPosition single) : caret(single), anchor(single) {
|
||||||
}
|
}
|
||||||
@ -166,6 +166,7 @@ public:
|
|||||||
void TrimSelection(SelectionRange range);
|
void TrimSelection(SelectionRange range);
|
||||||
void SetSelection(SelectionRange range);
|
void SetSelection(SelectionRange range);
|
||||||
void AddSelection(SelectionRange range);
|
void AddSelection(SelectionRange range);
|
||||||
|
void AddSelectionWithoutTrim(SelectionRange range);
|
||||||
void TentativeSelection(SelectionRange range);
|
void TentativeSelection(SelectionRange range);
|
||||||
void CommitTentative();
|
void CommitTentative();
|
||||||
int CharacterInSelection(int posCharacter) const;
|
int CharacterInSelection(int posCharacter) const;
|
||||||
|
@ -238,7 +238,7 @@ public:
|
|||||||
DeleteRange(0, lengthBody);
|
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 {
|
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.
|
// Split into up to 2 ranges, before and after the split then use memcpy on each.
|
||||||
int range1Length = 0;
|
int range1Length = 0;
|
||||||
|
@ -24,7 +24,7 @@ using namespace Scintilla;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
MarginStyle::MarginStyle() :
|
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
|
// A list of the fontnames - avoids wasting space in each style
|
||||||
|
@ -20,6 +20,7 @@ public:
|
|||||||
int width;
|
int width;
|
||||||
int mask;
|
int mask;
|
||||||
bool sensitive;
|
bool sensitive;
|
||||||
|
int cursor;
|
||||||
MarginStyle();
|
MarginStyle();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user