Merge branch 'scintilla-update'

This commit is contained in:
Colomban Wendling 2011-10-22 23:28:46 +02:00
commit a0367acd2d
60 changed files with 4236 additions and 1422 deletions

6
NEWS
View File

@ -1,3 +1,9 @@
Geany 1.22 (unreleased)
Editor
* Update Scintilla to version 2.29.
Geany 0.21 (October 2, 2011) Geany 0.21 (October 2, 2011)
General General

View File

@ -6,6 +6,15 @@ command=keyword_1
tag=tag tag=tag
math=number_1 math=number_1
comment=comment comment=comment
# mappings below may need checking
tag2=tag
math2=number_1
comment2=comment
verbatim=default
shortcmd=keyword_1
special=keyword_2
cmdopt=keyword_1
error=error
[keywords] [keywords]
# all items must be in one line # all items must be in one line

View File

@ -21,6 +21,7 @@ word5=keyword_1
word6=keyword_2 word6=keyword_2
word7=keyword_3 word7=keyword_3
word8=keyword_4 word8=keyword_4
label=label
[keywords] [keywords]
# all items must be in one line # all items must be in one line

View File

@ -31,6 +31,18 @@ string_qx=string_2
string_qr=string_2 string_qr=string_2
string_qw=string_2 string_qw=string_2
variable_indexer=default variable_indexer=default
# *_var mappings may need checking
string_var=identifier_1
regex_var=identifier_2
regsubst_var=identifier_2
backticks_var=identifier_2
here_qq_var=identifier_2
here_qx_var=identifier_2
string_qq_var=identifier_2
string_qx_var=identifier_2
string_qr_var=identifier_2
# translation: tr{}{} y{}{}
xlat=string_2
# not used # not used
punctuation=default punctuation=default
# obsolete: replaced by qq, qx, qr, qw # obsolete: replaced by qq, qx, qr, qw

View File

@ -9,6 +9,9 @@
#include <stddef.h> #include <stddef.h>
#include <math.h> #include <math.h>
#include <vector>
#include <map>
#include <glib.h> #include <glib.h>
#include <gmodule.h> #include <gmodule.h>
#include <gdk/gdk.h> #include <gdk/gdk.h>
@ -40,9 +43,37 @@
#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 #define USE_CAIRO 1
#ifdef USE_CAIRO
static cairo_surface_t *CreateSimilarSurface(GdkWindow *window, cairo_content_t content, int width, int height) {
#if GTK_CHECK_VERSION(2,22,0)
return gdk_window_create_similar_surface(window, content, width, height);
#else
cairo_surface_t *window_surface, *surface;
g_return_val_if_fail(GDK_IS_WINDOW(window), NULL);
window_surface = GDK_DRAWABLE_GET_CLASS(window)->ref_cairo_surface(window);
surface = cairo_surface_create_similar(window_surface, content, width, height);
cairo_surface_destroy(window_surface);
return surface;
#endif #endif
}
#endif
static GdkWindow *WindowFromWidget(GtkWidget *w) {
#if GTK_CHECK_VERSION(3,0,0)
return gtk_widget_get_window(w);
#else
return w->window;
#endif
}
#ifdef USE_CAIRO #ifdef USE_CAIRO
#define DISABLE_GDK_FONT 1 #define DISABLE_GDK_FONT 1
@ -116,10 +147,17 @@ class FontHandle {
encodingType et; encodingType et;
public: public:
int ascent; int ascent;
#ifndef DISABLE_GDK_FONT
GdkFont *pfont; GdkFont *pfont;
#endif
PangoFontDescription *pfd; PangoFontDescription *pfd;
int characterSet; int characterSet;
FontHandle(GdkFont *pfont_) { #ifdef DISABLE_GDK_FONT
FontHandle() : et(singleByte), ascent(0), pfd(0), characterSet(-1) {
ResetWidths(et);
}
#else
FontHandle(GdkFont *pfont_=0) {
et = singleByte; et = singleByte;
ascent = 0; ascent = 0;
pfont = pfont_; pfont = pfont_;
@ -127,10 +165,13 @@ public:
characterSet = -1; characterSet = -1;
ResetWidths(et); ResetWidths(et);
} }
#endif
FontHandle(PangoFontDescription *pfd_, int characterSet_) { FontHandle(PangoFontDescription *pfd_, int characterSet_) {
et = singleByte; et = singleByte;
ascent = 0; ascent = 0;
#ifndef DISABLE_GDK_FONT
pfont = 0; pfont = 0;
#endif
pfd = pfd_; pfd = pfd_;
characterSet = characterSet_; characterSet = characterSet_;
ResetWidths(et); ResetWidths(et);
@ -139,8 +180,8 @@ public:
#ifndef DISABLE_GDK_FONT #ifndef DISABLE_GDK_FONT
if (pfont) if (pfont)
gdk_font_unref(pfont); gdk_font_unref(pfont);
#endif
pfont = 0; pfont = 0;
#endif
if (pfd) if (pfd)
pango_font_description_free(pfd); pango_font_description_free(pfd);
pfd = 0; pfd = 0;
@ -183,9 +224,11 @@ static GtkWidget *PWidget(WindowID wid) {
return reinterpret_cast<GtkWidget *>(wid); return reinterpret_cast<GtkWidget *>(wid);
} }
#if !GTK_CHECK_VERSION(3,0,0)
static GtkWidget *PWidget(Window &w) { static GtkWidget *PWidget(Window &w) {
return PWidget(w.GetID()); return PWidget(w.GetID());
} }
#endif
Point Point::FromLong(long lpoint) { Point Point::FromLong(long lpoint) {
return Point( return Point(
@ -254,6 +297,8 @@ void Palette::WantFind(ColourPair &cp, bool want) {
} }
void Palette::Allocate(Window &w) { void Palette::Allocate(Window &w) {
#if !GTK_CHECK_VERSION(3,0,0)
// Disable palette on GTK+ 3.
if (allocatedPalette) { if (allocatedPalette) {
gdk_colormap_free_colors(gtk_widget_get_colormap(PWidget(w)), gdk_colormap_free_colors(gtk_widget_get_colormap(PWidget(w)),
reinterpret_cast<GdkColor *>(allocatedPalette), reinterpret_cast<GdkColor *>(allocatedPalette),
@ -274,14 +319,17 @@ void Palette::Allocate(Window &w) {
paletteNew[iPal].blue = entries[iPal].desired.GetBlue() * (65535 / 255); paletteNew[iPal].blue = entries[iPal].desired.GetBlue() * (65535 / 255);
paletteNew[iPal].pixel = entries[iPal].desired.AsLong(); paletteNew[iPal].pixel = entries[iPal].desired.AsLong();
} }
#ifndef USE_CAIRO
gdk_colormap_alloc_colors(gtk_widget_get_colormap(PWidget(w)), gdk_colormap_alloc_colors(gtk_widget_get_colormap(PWidget(w)),
paletteNew, allocatedLen, FALSE, TRUE, paletteNew, allocatedLen, FALSE, TRUE,
successPalette); successPalette);
#endif
for (iPal = 0; iPal < used; iPal++) { for (iPal = 0; iPal < used; iPal++) {
entries[iPal].allocated.Set(paletteNew[iPal].pixel); entries[iPal].allocated.Set(paletteNew[iPal].pixel);
} }
} }
delete []successPalette; delete []successPalette;
#endif
} }
#ifndef DISABLE_GDK_FONT #ifndef DISABLE_GDK_FONT
@ -671,7 +719,7 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
} }
return new FontHandle(newid); return new FontHandle(newid);
#else #else
return new FontHandle(0); return new FontHandle();
#endif #endif
} }
@ -695,6 +743,8 @@ void Font::Release() {
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE
namespace Scintilla { namespace Scintilla {
#endif #endif
// On GTK+ 2.x, SurfaceID is a GdkDrawable* and on GTK+ 3.x, it is a cairo_t*
class SurfaceImpl : public Surface { class SurfaceImpl : public Surface {
encodingType et; encodingType et;
#ifdef USE_CAIRO #ifdef USE_CAIRO
@ -736,6 +786,7 @@ public:
void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back); void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags); ColourAllocated outline, int alphaOutline, int flags);
void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage);
void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back); void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
void Copy(PRectangle rc, Point from, Surface &surfaceSource); void Copy(PRectangle rc, Point from, Surface &surfaceSource);
@ -883,7 +934,11 @@ void SurfaceImpl::Init(WindowID wid) {
Release(); Release();
PLATFORM_ASSERT(wid); PLATFORM_ASSERT(wid);
#ifdef USE_CAIRO #ifdef USE_CAIRO
#if GTK_CHECK_VERSION(3,0,0)
GdkWindow *drawable_ = gtk_widget_get_window(PWidget(wid));
#else
GdkDrawable *drawable_ = GDK_DRAWABLE(PWidget(wid)->window); GdkDrawable *drawable_ = GDK_DRAWABLE(PWidget(wid)->window);
#endif
if (drawable_) { if (drawable_) {
context = gdk_cairo_create(drawable_); context = gdk_cairo_create(drawable_);
PLATFORM_ASSERT(context); PLATFORM_ASSERT(context);
@ -904,14 +959,17 @@ void SurfaceImpl::Init(WindowID wid) {
void SurfaceImpl::Init(SurfaceID sid, WindowID wid) { void SurfaceImpl::Init(SurfaceID sid, WindowID wid) {
PLATFORM_ASSERT(sid); PLATFORM_ASSERT(sid);
GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid);
Release(); Release();
PLATFORM_ASSERT(wid); PLATFORM_ASSERT(wid);
#ifdef USE_CAIRO #ifdef USE_CAIRO
context = gdk_cairo_create(drawable_); #if GTK_CHECK_VERSION(3,0,0)
context = cairo_reference(reinterpret_cast<cairo_t *>(sid));
#else #else
gc = gdk_gc_new(drawable_); context = gdk_cairo_create(reinterpret_cast<GdkDrawable *>(sid));
drawable = drawable_; #endif
#else
drawable = reinterpret_cast<GdkDrawable *>(sid);
gc = gdk_gc_new(drawable);
#endif #endif
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);
@ -942,8 +1000,8 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID
PLATFORM_ASSERT(layout); PLATFORM_ASSERT(layout);
#ifdef USE_CAIRO #ifdef USE_CAIRO
if (height > 0 && width > 0) if (height > 0 && width > 0)
psurf = gdk_window_create_similar_surface( psurf = CreateSimilarSurface(
gtk_widget_get_window(PWidget(wid)), WindowFromWidget(PWidget(wid)),
CAIRO_CONTENT_COLOR_ALPHA, width, height); CAIRO_CONTENT_COLOR_ALPHA, width, height);
#else #else
if (height > 0 && width > 0) if (height > 0 && width > 0)
@ -974,9 +1032,9 @@ void SurfaceImpl::PenColour(ColourAllocated fore) {
if (context) { if (context) {
ColourDesired cdFore(fore.AsLong()); ColourDesired cdFore(fore.AsLong());
cairo_set_source_rgb(context, cairo_set_source_rgb(context,
cdFore.GetBlue() / 255.0, cdFore.GetRed() / 255.0,
cdFore.GetGreen() / 255.0, cdFore.GetGreen() / 255.0,
cdFore.GetRed() / 255.0); cdFore.GetBlue() / 255.0);
} }
#else #else
if (gc) { if (gc) {
@ -1186,7 +1244,12 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl
static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) { static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) {
double degrees = M_PI / 180.0; double degrees = M_PI / 180.0;
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 2, 0)
cairo_new_sub_path(context); cairo_new_sub_path(context);
#else
// First arc is in the top-right corner and starts from a point on the top line
cairo_move_to(context, left + width - radius, top);
#endif
cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees); 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 + 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 + height - radius, radius, 90 * degrees, 180 * degrees);
@ -1216,8 +1279,6 @@ 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) { static unsigned int GetRValue(unsigned int co) {
return (co >> 16) & 0xff; return (co >> 16) & 0xff;
} }
@ -1230,24 +1291,34 @@ static unsigned int GetBValue(unsigned int co) {
return co & 0xff; return co & 0xff;
} }
#endif
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 #ifdef USE_CAIRO
if (context && rc.Width() > 0) { if (context && rc.Width() > 0) {
ColourDesired cdFill(fill.AsLong());
cairo_set_source_rgba(context, cairo_set_source_rgba(context,
GetRValue(fill.AsLong()) / 255.0, cdFill.GetRed() / 255.0,
GetGValue(fill.AsLong()) / 255.0, cdFill.GetGreen() / 255.0,
GetBValue(fill.AsLong()) / 255.0, cdFill.GetBlue() / 255.0,
alphaFill / 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); if (cornerSize > 0)
PathRoundRectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize);
else
cairo_rectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0);
cairo_fill(context); cairo_fill(context);
ColourDesired cdOutline(outline.AsLong());
cairo_set_source_rgba(context, cairo_set_source_rgba(context,
GetRValue(outline.AsLong()) / 255.0, cdOutline.GetRed() / 255.0,
GetGValue(outline.AsLong()) / 255.0, cdOutline.GetGreen() / 255.0,
GetBValue(outline.AsLong()) / 255.0, cdOutline.GetBlue() / 255.0,
alphaOutline / 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); if (cornerSize > 0)
PathRoundRectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize);
else
cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1);
cairo_stroke(context); cairo_stroke(context);
} }
#else #else
@ -1293,6 +1364,51 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
#endif #endif
} }
void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) {
if (rc.Width() > width)
rc.left += (rc.Width() - width) / 2;
rc.right = rc.left + width;
if (rc.Height() > height)
rc.top += (rc.Height() - height) / 2;
rc.bottom = rc.top + height;
#ifdef USE_CAIRO
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
int ucs = stride * height;
std::vector<unsigned char> image(ucs);
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
unsigned char *pixel = &image[0] + y*stride + x * 4;
unsigned char alpha = pixelsImage[3];
pixel[2] = (*pixelsImage++) * alpha / 255;
pixel[1] = (*pixelsImage++) * alpha / 255;
pixel[0] = (*pixelsImage++) * alpha / 255;
pixel[3] = *pixelsImage++;
}
}
cairo_surface_t *psurf = cairo_image_surface_create_for_data(&image[0], CAIRO_FORMAT_ARGB32, width, height, stride);
cairo_set_source_surface(context, psurf, rc.left, rc.top);
cairo_rectangle(context, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
cairo_fill(context);
cairo_surface_destroy(psurf);
#else
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(pixelsImage,
GDK_COLORSPACE_RGB,
TRUE,
8,
width,
height,
width * 4,
NULL,
NULL);
gdk_draw_pixbuf(drawable, gc, pixbuf,
0,0, rc.left,rc.top, width,height, GDK_RGB_DITHER_NORMAL, 0, 0);
g_object_unref(pixbuf);
#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 #ifdef USE_CAIRO
@ -1474,7 +1590,6 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
int xText = rc.left; int xText = rc.left;
if (PFont(font_)->pfd) { if (PFont(font_)->pfd) {
char *utfForm = 0; char *utfForm = 0;
bool useGFree = false;
if (et == UTF8) { if (et == UTF8) {
pango_layout_set_text(layout, s, len); pango_layout_set_text(layout, s, len);
} else { } else {
@ -1508,11 +1623,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
#else #else
gdk_draw_layout_line(drawable, gc, xText, ybase, pll); gdk_draw_layout_line(drawable, gc, xText, ybase, pll);
#endif #endif
if (useGFree) { delete []utfForm;
g_free(utfForm);
} else {
delete []utfForm;
}
return; return;
} }
#ifndef DISABLE_GDK_FONT #ifndef DISABLE_GDK_FONT
@ -1690,7 +1801,6 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
} }
if (positionsCalculated < 1 ) { if (positionsCalculated < 1 ) {
// Either Latin1 or DBCS conversion failed so treat as Latin1. // Either Latin1 or DBCS conversion failed so treat as Latin1.
bool useGFree = false;
SetConverter(PFont(font_)->characterSet); SetConverter(PFont(font_)->characterSet);
char *utfForm = UTF8FromIconv(conv, s, len); char *utfForm = UTF8FromIconv(conv, s, len);
if (!utfForm) { if (!utfForm) {
@ -1712,11 +1822,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
} }
clusterStart = clusterEnd; clusterStart = clusterEnd;
} }
if (useGFree) { delete []utfForm;
g_free(utfForm);
} else {
delete []utfForm;
}
PLATFORM_ASSERT(i == lenPositions); PLATFORM_ASSERT(i == lenPositions);
} }
} }
@ -1792,7 +1898,6 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
char *utfForm = 0; char *utfForm = 0;
pango_layout_set_font_description(layout, PFont(font_)->pfd); pango_layout_set_font_description(layout, PFont(font_)->pfd);
PangoRectangle pos; PangoRectangle pos;
bool useGFree = false;
if (et == UTF8) { if (et == UTF8) {
pango_layout_set_text(layout, s, len); pango_layout_set_text(layout, s, len);
} else { } else {
@ -1815,11 +1920,7 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
PangoLayoutLine *pangoLine = pango_layout_get_line(layout,0); PangoLayoutLine *pangoLine = pango_layout_get_line(layout,0);
#endif #endif
pango_layout_line_get_extents(pangoLine, NULL, &pos); pango_layout_line_get_extents(pangoLine, NULL, &pos);
if (useGFree) { delete []utfForm;
g_free(utfForm);
} else {
delete []utfForm;
}
return PANGO_PIXELS(pos.width); return PANGO_PIXELS(pos.width);
} }
#ifndef DISABLE_GDK_FONT #ifndef DISABLE_GDK_FONT
@ -2005,11 +2106,17 @@ PRectangle Window::GetPosition() {
// Before any size allocated pretend its 1000 wide so not scrolled // Before any size allocated pretend its 1000 wide so not scrolled
PRectangle rc(0, 0, 1000, 1000); PRectangle rc(0, 0, 1000, 1000);
if (wid) { if (wid) {
rc.left = PWidget(wid)->allocation.x; GtkAllocation allocation;
rc.top = PWidget(wid)->allocation.y; #if GTK_CHECK_VERSION(3,0,0)
if (PWidget(wid)->allocation.width > 20) { gtk_widget_get_allocation(PWidget(wid), &allocation);
rc.right = rc.left + PWidget(wid)->allocation.width; #else
rc.bottom = rc.top + PWidget(wid)->allocation.height; allocation = PWidget(wid)->allocation;
#endif
rc.left = allocation.x;
rc.top = allocation.y;
if (allocation.width > 20) {
rc.right = rc.left + allocation.width;
rc.bottom = rc.top + allocation.height;
} }
} }
return rc; return rc;
@ -2027,7 +2134,7 @@ void Window::SetPosition(PRectangle rc) {
void Window::SetPositionRelative(PRectangle rc, Window relativeTo) { void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
int ox = 0; int ox = 0;
int oy = 0; int oy = 0;
gdk_window_get_origin(PWidget(relativeTo.wid)->window, &ox, &oy); gdk_window_get_origin(WindowFromWidget(PWidget(relativeTo.wid)), &ox, &oy);
ox += rc.left; ox += rc.left;
if (ox < 0) if (ox < 0)
ox = 0; ox = 0;
@ -2113,9 +2220,13 @@ void Window::SetCursor(Cursor curs) {
break; break;
} }
if (PWidget(wid)->window) if (WindowFromWidget(PWidget(wid)))
gdk_window_set_cursor(PWidget(wid)->window, gdkCurs); gdk_window_set_cursor(WindowFromWidget(PWidget(wid)), gdkCurs);
#if GTK_CHECK_VERSION(3,0,0)
g_object_unref(gdkCurs);
#else
gdk_cursor_unref(gdkCurs); gdk_cursor_unref(gdkCurs);
#endif
} }
void Window::SetTitle(const char *s) { void Window::SetTitle(const char *s) {
@ -2127,7 +2238,7 @@ void Window::SetTitle(const char *s) {
PRectangle Window::GetMonitorRect(Point pt) { PRectangle Window::GetMonitorRect(Point pt) {
gint x_offset, y_offset; gint x_offset, y_offset;
gdk_window_get_origin(PWidget(wid)->window, &x_offset, &y_offset); gdk_window_get_origin(WindowFromWidget(PWidget(wid)), &x_offset, &y_offset);
#if GTK_CHECK_VERSION(2,2,0) #if GTK_CHECK_VERSION(2,2,0)
// GTK+ 2.2+ // GTK+ 2.2+
@ -2150,15 +2261,17 @@ PRectangle Window::GetMonitorRect(Point pt) {
#endif #endif
} }
typedef std::map<int, RGBAImage*> ImageMap;
struct ListImage { struct ListImage {
const char *xpm_data; const RGBAImage *rgba_data;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
}; };
static void list_image_free(gpointer, gpointer value, gpointer) { static void list_image_free(gpointer, gpointer value, gpointer) {
ListImage *list_image = (ListImage *) value; ListImage *list_image = (ListImage *) value;
if (list_image->pixbuf) if (list_image->pixbuf)
g_object_unref (list_image->pixbuf); g_object_unref(list_image->pixbuf);
g_free(list_image); g_free(list_image);
} }
@ -2179,7 +2292,7 @@ class ListBoxX : public ListBox {
WindowID scroller; WindowID scroller;
void *pixhash; void *pixhash;
GtkCellRenderer* pixbuf_renderer; GtkCellRenderer* pixbuf_renderer;
XPMSet xset; RGBAImageSet images;
int desiredVisibleRows; int desiredVisibleRows;
unsigned int maxItemCharacters; unsigned int maxItemCharacters;
unsigned int aveCharWidth; unsigned int aveCharWidth;
@ -2211,7 +2324,9 @@ public:
virtual int GetSelection(); virtual int GetSelection();
virtual int Find(const char *prefix); virtual int Find(const char *prefix);
virtual void GetValue(int n, char *value, int len); virtual void GetValue(int n, char *value, int len);
void RegisterRGBA(int type, RGBAImage *image);
virtual void RegisterImage(int type, const char *xpm_data); virtual void RegisterImage(int type, const char *xpm_data);
virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage);
virtual void ClearRegisteredImages(); virtual void ClearRegisteredImages();
virtual void SetDoubleClickAction(CallBackAction action, void *data) { virtual void SetDoubleClickAction(CallBackAction action, void *data) {
doubleClickAction = action; doubleClickAction = action;
@ -2242,24 +2357,47 @@ static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
/* Change the active color to the selected color so the listbox uses the color /* Change the active color to the selected color so the listbox uses the color
scheme that it would use if it had the focus. */ scheme that it would use if it had the focus. */
static void StyleSet(GtkWidget *w, GtkStyle*, void*) { static void StyleSet(GtkWidget *w, GtkStyle*, void*) {
GtkStyle* style;
g_return_if_fail(w != NULL); g_return_if_fail(w != NULL);
/* Copy the selected color to active. Note that the modify calls will cause /* Copy the selected color to active. Note that the modify calls will cause
recursive calls to this function after the value is updated and w->style to recursive calls to this function after the value is updated and w->style to
be set to a new object */ be set to a new object */
style = gtk_widget_get_style(w);
#if GTK_CHECK_VERSION(3,0,0)
GtkStyleContext *styleContext = gtk_widget_get_style_context(w);
if (styleContext == NULL)
return;
GdkRGBA colourForeSelected;
gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourForeSelected);
GdkRGBA colourForeActive;
gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourForeActive);
if (!gdk_rgba_equal(&colourForeSelected, &colourForeActive))
gtk_widget_override_color(w, GTK_STATE_FLAG_ACTIVE, &colourForeSelected);
styleContext = gtk_widget_get_style_context(w);
if (styleContext == NULL)
return;
GdkRGBA colourBaseSelected;
gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourBaseSelected);
GdkRGBA colourBaseActive;
gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourBaseActive);
if (!gdk_rgba_equal(&colourBaseSelected, &colourBaseActive))
gtk_widget_override_background_color(w, GTK_STATE_FLAG_ACTIVE, &colourBaseSelected);
#else
GtkStyle *style = gtk_widget_get_style(w);
if (style == NULL) if (style == NULL)
return; return;
if (!gdk_color_equal(&style->base[GTK_STATE_SELECTED], &style->base[GTK_STATE_ACTIVE])) if (!gdk_color_equal(&style->base[GTK_STATE_SELECTED], &style->base[GTK_STATE_ACTIVE]))
gtk_widget_modify_base(w, GTK_STATE_ACTIVE, &style->base[GTK_STATE_SELECTED]); gtk_widget_modify_base(w, GTK_STATE_ACTIVE, &style->base[GTK_STATE_SELECTED]);
style = gtk_widget_get_style(w); style = gtk_widget_get_style(w);
if (style == NULL) if (style == NULL)
return; return;
if (!gdk_color_equal(&style->text[GTK_STATE_SELECTED], &style->text[GTK_STATE_ACTIVE])) if (!gdk_color_equal(&style->text[GTK_STATE_SELECTED], &style->text[GTK_STATE_ACTIVE]))
gtk_widget_modify_text(w, GTK_STATE_ACTIVE, &style->text[GTK_STATE_SELECTED]); gtk_widget_modify_text(w, GTK_STATE_ACTIVE, &style->text[GTK_STATE_SELECTED]);
#endif
} }
void ListBoxX::Create(Window &, int, Point, int, bool) { void ListBoxX::Create(Window &, int, Point, int, bool) {
@ -2324,7 +2462,11 @@ void ListBoxX::SetFont(Font &scint_font) {
// Only do for Pango font as there have been crashes for GDK fonts // Only do for Pango font as there have been crashes for GDK fonts
if (Created() && PFont(scint_font)->pfd) { if (Created() && PFont(scint_font)->pfd) {
// Current font is Pango font // Current font is Pango font
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_override_font(PWidget(list), PFont(scint_font)->pfd);
#else
gtk_widget_modify_font(PWidget(list), PFont(scint_font)->pfd); gtk_widget_modify_font(PWidget(list), PFont(scint_font)->pfd);
#endif
} }
} }
@ -2360,14 +2502,27 @@ PRectangle ListBoxX::GetDesiredRect() {
gtk_tree_view_get_column(GTK_TREE_VIEW(list), 0); gtk_tree_view_get_column(GTK_TREE_VIEW(list), 0);
gtk_tree_view_column_cell_get_size(column, NULL, gtk_tree_view_column_cell_get_size(column, NULL,
NULL, NULL, &row_width, &row_height); NULL, NULL, &row_width, &row_height);
#if GTK_CHECK_VERSION(3,0,0)
GtkStyleContext *styleContextList = gtk_widget_get_style_context(PWidget(list));
GtkBorder padding;
gtk_style_context_get_padding(styleContextList, GTK_STATE_FLAG_NORMAL, &padding);
height = (rows * row_height
+ padding.top + padding.bottom
+ 2 * (gtk_container_get_border_width(GTK_CONTAINER(PWidget(list))) + 1));
#else
int ythickness = PWidget(list)->style->ythickness; int ythickness = PWidget(list)->style->ythickness;
height = (rows * row_height height = (rows * row_height
+ 2 * (ythickness + 2 * (ythickness
+ GTK_CONTAINER(PWidget(list))->border_width + 1)); + GTK_CONTAINER(PWidget(list))->border_width + 1));
#endif
gtk_widget_set_size_request(GTK_WIDGET(PWidget(list)), -1, height); gtk_widget_set_size_request(GTK_WIDGET(PWidget(list)), -1, height);
// Get the size of the scroller because we set usize on the window // Get the size of the scroller because we set usize on the window
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_preferred_size(GTK_WIDGET(scroller), NULL, &req);
#else
gtk_widget_size_request(GTK_WIDGET(scroller), &req); gtk_widget_size_request(GTK_WIDGET(scroller), &req);
#endif
rc.right = req.width; rc.right = req.width;
rc.bottom = req.height; rc.bottom = req.height;
@ -2396,25 +2551,21 @@ void ListBoxX::Clear() {
} }
static void init_pixmap(ListImage *list_image) { static void init_pixmap(ListImage *list_image) {
const char *textForm = list_image->xpm_data; if (list_image->rgba_data) {
const char * const * xpm_lineform = reinterpret_cast<const char * const *>(textForm); // Drop any existing pixmap/bitmap as data may have changed
const char **xpm_lineformfromtext = 0; if (list_image->pixbuf)
// The XPM data can be either in atext form as will be read from a file g_object_unref(list_image->pixbuf);
// or in a line form (array of char *) as will be used for images defined in code. list_image->pixbuf =
// Test for text form and convert to line form gdk_pixbuf_new_from_data(list_image->rgba_data->Pixels(),
if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) { GDK_COLORSPACE_RGB,
// Test done is two parts to avoid possibility of overstepping the memory TRUE,
// if memcmp implemented strangely. Must be 4 bytes at least at destination. 8,
xpm_lineformfromtext = XPM::LinesFormFromTextForm(textForm); list_image->rgba_data->GetWidth(),
xpm_lineform = xpm_lineformfromtext; list_image->rgba_data->GetHeight(),
list_image->rgba_data->GetWidth() * 4,
NULL,
NULL);
} }
// Drop any existing pixmap/bitmap as data may have changed
if (list_image->pixbuf)
g_object_unref(list_image->pixbuf);
list_image->pixbuf =
gdk_pixbuf_new_from_xpm_data((const gchar**)xpm_lineform);
delete []xpm_lineformfromtext;
} }
#define SPACING 5 #define SPACING 5
@ -2481,11 +2632,17 @@ void ListBoxX::Select(int n) {
// Move the scrollbar to show the selection. // Move the scrollbar to show the selection.
int total = Length(); int total = Length();
#if GTK_CHECK_VERSION(3,0,0)
GtkAdjustment *adj =
gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list));
gfloat value = ((gfloat)n / total) * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj))
+ gtk_adjustment_get_lower(adj) - gtk_adjustment_get_page_size(adj) / 2;
#else
GtkAdjustment *adj = GtkAdjustment *adj =
gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(list)); gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(list));
gfloat value = ((gfloat)n / total) * (adj->upper - adj->lower) gfloat value = ((gfloat)n / total) * (adj->upper - adj->lower)
+ adj->lower - adj->page_size / 2; + adj->lower - adj->page_size / 2;
#endif
// Get cell height // Get cell height
int row_width; int row_width;
int row_height; int row_height;
@ -2504,8 +2661,13 @@ void ListBoxX::Select(int n) {
} }
// Clamp it. // Clamp it.
value = (value < 0)? 0 : value; value = (value < 0)? 0 : value;
#if GTK_CHECK_VERSION(3,0,0)
value = (value > (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)))?
(gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)) : value;
#else
value = (value > (adj->upper - adj->page_size))? value = (value > (adj->upper - adj->page_size))?
(adj->upper - adj->page_size) : value; (adj->upper - adj->page_size) : value;
#endif
// Set it. // Set it.
gtk_adjustment_set_value(adj, value); gtk_adjustment_set_value(adj, value);
@ -2571,13 +2733,8 @@ void ListBoxX::GetValue(int n, char *value, int len) {
#pragma warning(disable: 4127) #pragma warning(disable: 4127)
#endif #endif
void ListBoxX::RegisterImage(int type, const char *xpm_data) { void ListBoxX::RegisterRGBA(int type, RGBAImage *image) {
g_return_if_fail(xpm_data); images.Add(type, image);
// Saved and use the saved copy so caller's copy can disappear.
xset.Add(type, xpm_data);
XPM *pxpm = xset.Get(type);
xpm_data = reinterpret_cast<const char *>(pxpm->InLinesForm());
if (!pixhash) { if (!pixhash) {
pixhash = g_hash_table_new(g_direct_hash, g_direct_equal); pixhash = g_hash_table_new(g_direct_hash, g_direct_equal);
@ -2589,17 +2746,27 @@ void ListBoxX::RegisterImage(int type, const char *xpm_data) {
if (list_image->pixbuf) if (list_image->pixbuf)
g_object_unref(list_image->pixbuf); g_object_unref(list_image->pixbuf);
list_image->pixbuf = NULL; list_image->pixbuf = NULL;
list_image->xpm_data = xpm_data; list_image->rgba_data = image;
} else { } else {
list_image = g_new0(ListImage, 1); list_image = g_new0(ListImage, 1);
list_image->xpm_data = xpm_data; list_image->rgba_data = image;
g_hash_table_insert((GHashTable *) pixhash, GINT_TO_POINTER(type), g_hash_table_insert((GHashTable *) pixhash, GINT_TO_POINTER(type),
(gpointer) list_image); (gpointer) list_image);
} }
} }
void ListBoxX::RegisterImage(int type, const char *xpm_data) {
g_return_if_fail(xpm_data);
XPM xpmImage(xpm_data);
RegisterRGBA(type, new RGBAImage(xpmImage));
}
void ListBoxX::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) {
RegisterRGBA(type, new RGBAImage(width, height, pixelsImage));
}
void ListBoxX::ClearRegisteredImages() { void ListBoxX::ClearRegisteredImages() {
xset.Clear(); images.Clear();
} }
void ListBoxX::SetList(const char *listText, char separator, char typesep) { void ListBoxX::SetList(const char *listText, char separator, char typesep) {
@ -2663,7 +2830,11 @@ void Menu::Show(Point pt, Window &) {
GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid); GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid);
gtk_widget_show_all(GTK_WIDGET(widget)); gtk_widget_show_all(GTK_WIDGET(widget));
GtkRequisition requisition; GtkRequisition requisition;
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_preferred_size(GTK_WIDGET(widget), NULL, &requisition);
#else
gtk_widget_size_request(GTK_WIDGET(widget), &requisition); gtk_widget_size_request(GTK_WIDGET(widget), &requisition);
#endif
if ((pt.x + requisition.width) > screenWidth) { if ((pt.x + requisition.width) > screenWidth) {
pt.x = screenWidth - requisition.width; pt.x = screenWidth - requisition.width;
} }
@ -2791,7 +2962,8 @@ bool Platform::IsDBCSLeadByte(int codePage, char ch) {
case 932: case 932:
// Shift_jis // Shift_jis
return ((uch >= 0x81) && (uch <= 0x9F)) || return ((uch >= 0x81) && (uch <= 0x9F)) ||
((uch >= 0xE0) && (uch <= 0xEF)); ((uch >= 0xE0) && (uch <= 0xFC));
// Lead bytes F0 to FC may be a Microsoft addition.
case 936: case 936:
// GBK // GBK
return (uch >= 0x81) && (uch <= 0xFE); return (uch >= 0x81) && (uch <= 0xFE);

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@
#define PLAT_GTK 0 #define PLAT_GTK 0
#define PLAT_GTK_WIN32 0 #define PLAT_GTK_WIN32 0
#define PLAT_GTK_MACOSX 0
#define PLAT_MACOSX 0 #define PLAT_MACOSX 0
#define PLAT_WIN 0 #define PLAT_WIN 0
#define PLAT_WX 0 #define PLAT_WX 0
@ -38,6 +39,11 @@
#define PLAT_GTK_WIN32 1 #define PLAT_GTK_WIN32 1
#endif #endif
#if defined(__APPLE__)
#undef PLAT_GTK_MACOSX
#define PLAT_GTK_MACOSX 1
#endif
#elif defined(__APPLE__) #elif defined(__APPLE__)
#undef PLAT_MACOSX #undef PLAT_MACOSX
@ -301,8 +307,11 @@ public:
FontID GetID() { return fid; } FontID GetID() { return fid; }
// Alias another font - caller guarantees not to Release // Alias another font - caller guarantees not to Release
void SetID(FontID fid_) { fid = fid_; } void SetID(FontID fid_) { fid = fid_; }
#if PLAT_WX
void SetAscent(int ascent_) { ascent = ascent_; }
#endif
friend class Surface; friend class Surface;
friend class SurfaceImpl; friend class SurfaceImpl;
}; };
/** /**
@ -336,6 +345,7 @@ public:
virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags)=0; ColourAllocated outline, int alphaOutline, int flags)=0;
virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0;
virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0;
@ -411,8 +421,8 @@ public:
void SetTitle(const char *s); void SetTitle(const char *s);
PRectangle GetMonitorRect(Point pt); PRectangle GetMonitorRect(Point pt);
#if PLAT_MACOSX #if PLAT_MACOSX
void SetWindow(void *ref) { windowRef = ref; }; void SetWindow(void *ref) { windowRef = ref; }
void SetControl(void *_control) { control = _control; }; void SetControl(void *_control) { control = _control; }
#endif #endif
private: private:
Cursor cursorLast; Cursor cursorLast;
@ -443,6 +453,7 @@ public:
virtual int Find(const char *prefix)=0; virtual int Find(const char *prefix)=0;
virtual void GetValue(int n, char *value, int len)=0; virtual void GetValue(int n, char *value, int len)=0;
virtual void RegisterImage(int type, const char *xpm_data)=0; virtual void RegisterImage(int type, const char *xpm_data)=0;
virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0;
virtual void ClearRegisteredImages()=0; virtual void ClearRegisteredImages()=0;
virtual void SetDoubleClickAction(CallBackAction, void *)=0; virtual void SetDoubleClickAction(CallBackAction, void *)=0;
virtual void SetList(const char* list, char separator, char typesep)=0; virtual void SetList(const char* list, char separator, char typesep)=0;

View File

@ -344,6 +344,16 @@
#define SCE_PL_SUB_PROTOTYPE 40 #define SCE_PL_SUB_PROTOTYPE 40
#define SCE_PL_FORMAT_IDENT 41 #define SCE_PL_FORMAT_IDENT 41
#define SCE_PL_FORMAT 42 #define SCE_PL_FORMAT 42
#define SCE_PL_STRING_VAR 43
#define SCE_PL_XLAT 44
#define SCE_PL_REGEX_VAR 54
#define SCE_PL_REGSUBST_VAR 55
#define SCE_PL_BACKTICKS_VAR 57
#define SCE_PL_HERE_QQ_VAR 61
#define SCE_PL_HERE_QX_VAR 62
#define SCE_PL_STRING_QQ_VAR 64
#define SCE_PL_STRING_QX_VAR 65
#define SCE_PL_STRING_QR_VAR 66
#define SCE_RB_DEFAULT 0 #define SCE_RB_DEFAULT 0
#define SCE_RB_ERROR 1 #define SCE_RB_ERROR 1
#define SCE_RB_COMMENTLINE 2 #define SCE_RB_COMMENTLINE 2
@ -408,6 +418,14 @@
#define SCE_L_TAG 2 #define SCE_L_TAG 2
#define SCE_L_MATH 3 #define SCE_L_MATH 3
#define SCE_L_COMMENT 4 #define SCE_L_COMMENT 4
#define SCE_L_TAG2 5
#define SCE_L_MATH2 6
#define SCE_L_COMMENT2 7
#define SCE_L_VERBATIM 8
#define SCE_L_SHORTCMD 9
#define SCE_L_SPECIAL 10
#define SCE_L_CMDOPT 11
#define SCE_L_ERROR 12
#define SCE_LUA_DEFAULT 0 #define SCE_LUA_DEFAULT 0
#define SCE_LUA_COMMENT 1 #define SCE_LUA_COMMENT 1
#define SCE_LUA_COMMENTLINE 2 #define SCE_LUA_COMMENTLINE 2
@ -428,6 +446,7 @@
#define SCE_LUA_WORD6 17 #define SCE_LUA_WORD6 17
#define SCE_LUA_WORD7 18 #define SCE_LUA_WORD7 18
#define SCE_LUA_WORD8 19 #define SCE_LUA_WORD8 19
#define SCE_LUA_LABEL 20
#define SCE_ERR_DEFAULT 0 #define SCE_ERR_DEFAULT 0
#define SCE_ERR_PYTHON 1 #define SCE_ERR_PYTHON 1
#define SCE_ERR_GCC 2 #define SCE_ERR_GCC 2

View File

@ -124,6 +124,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SC_MARK_LEFTRECT 27 #define SC_MARK_LEFTRECT 27
#define SC_MARK_AVAILABLE 28 #define SC_MARK_AVAILABLE 28
#define SC_MARK_UNDERLINE 29 #define SC_MARK_UNDERLINE 29
#define SC_MARK_RGBAIMAGE 30
#define SC_MARK_CHARACTER 10000 #define SC_MARK_CHARACTER 10000
#define SC_MARKNUM_FOLDEREND 25 #define SC_MARKNUM_FOLDEREND 25
#define SC_MARKNUM_FOLDEROPENMID 26 #define SC_MARKNUM_FOLDEROPENMID 26
@ -136,6 +137,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARKERDEFINE 2040 #define SCI_MARKERDEFINE 2040
#define SCI_MARKERSETFORE 2041 #define SCI_MARKERSETFORE 2041
#define SCI_MARKERSETBACK 2042 #define SCI_MARKERSETBACK 2042
#define SCI_MARKERSETBACKSELECTED 2292
#define SCI_MARKERENABLEHIGHLIGHT 2293
#define SCI_MARKERADD 2043 #define SCI_MARKERADD 2043
#define SCI_MARKERDELETE 2044 #define SCI_MARKERDELETE 2044
#define SCI_MARKERDELETEALL 2045 #define SCI_MARKERDELETEALL 2045
@ -245,6 +248,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define INDIC_HIDDEN 5 #define INDIC_HIDDEN 5
#define INDIC_BOX 6 #define INDIC_BOX 6
#define INDIC_ROUNDBOX 7 #define INDIC_ROUNDBOX 7
#define INDIC_STRAIGHTBOX 8
#define INDIC_DASH 9
#define INDIC_DOTS 10
#define INDIC_SQUIGGLELOW 11
#define INDIC_DOTBOX 12
#define INDIC_MAX 31 #define INDIC_MAX 31
#define INDIC_CONTAINER 8 #define INDIC_CONTAINER 8
#define INDIC0_MASK 0x20 #define INDIC0_MASK 0x20
@ -328,6 +336,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETSELECTIONSTART 2143 #define SCI_GETSELECTIONSTART 2143
#define SCI_SETSELECTIONEND 2144 #define SCI_SETSELECTIONEND 2144
#define SCI_GETSELECTIONEND 2145 #define SCI_GETSELECTIONEND 2145
#define SCI_SETEMPTYSELECTION 2556
#define SCI_SETPRINTMAGNIFICATION 2146 #define SCI_SETPRINTMAGNIFICATION 2146
#define SCI_GETPRINTMAGNIFICATION 2147 #define SCI_GETPRINTMAGNIFICATION 2147
#define SC_PRINT_NORMAL 0 #define SC_PRINT_NORMAL 0
@ -554,7 +563,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MOVECARETINSIDEVIEW 2401 #define SCI_MOVECARETINSIDEVIEW 2401
#define SCI_LINELENGTH 2350 #define SCI_LINELENGTH 2350
#define SCI_BRACEHIGHLIGHT 2351 #define SCI_BRACEHIGHLIGHT 2351
#define SCI_BRACEHIGHLIGHTINDICATOR 2498
#define SCI_BRACEBADLIGHT 2352 #define SCI_BRACEBADLIGHT 2352
#define SCI_BRACEBADLIGHTINDICATOR 2499
#define SCI_BRACEMATCH 2353 #define SCI_BRACEMATCH 2353
#define SCI_GETVIEWEOL 2355 #define SCI_GETVIEWEOL 2355
#define SCI_SETVIEWEOL 2356 #define SCI_SETVIEWEOL 2356
@ -707,6 +718,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETKEYSUNICODE 2522 #define SCI_GETKEYSUNICODE 2522
#define SCI_INDICSETALPHA 2523 #define SCI_INDICSETALPHA 2523
#define SCI_INDICGETALPHA 2524 #define SCI_INDICGETALPHA 2524
#define SCI_INDICSETOUTLINEALPHA 2558
#define SCI_INDICGETOUTLINEALPHA 2559
#define SCI_SETEXTRAASCENT 2525 #define SCI_SETEXTRAASCENT 2525
#define SCI_GETEXTRAASCENT 2526 #define SCI_GETEXTRAASCENT 2526
#define SCI_SETEXTRADESCENT 2527 #define SCI_SETEXTRADESCENT 2527
@ -721,6 +734,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARGINTEXTCLEARALL 2536 #define SCI_MARGINTEXTCLEARALL 2536
#define SCI_MARGINSETSTYLEOFFSET 2537 #define SCI_MARGINSETSTYLEOFFSET 2537
#define SCI_MARGINGETSTYLEOFFSET 2538 #define SCI_MARGINGETSTYLEOFFSET 2538
#define SC_MARGINOPTION_NONE 0
#define SC_MARGINOPTION_SUBLINESELECT 1
#define SCI_SETMARGINOPTIONS 2539
#define SCI_GETMARGINOPTIONS 2557
#define SCI_ANNOTATIONSETTEXT 2540 #define SCI_ANNOTATIONSETTEXT 2540
#define SCI_ANNOTATIONGETTEXT 2541 #define SCI_ANNOTATIONGETTEXT 2541
#define SCI_ANNOTATIONSETSTYLE 2542 #define SCI_ANNOTATIONSETSTYLE 2542
@ -792,6 +809,16 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_CHANGELEXERSTATE 2617 #define SCI_CHANGELEXERSTATE 2617
#define SCI_CONTRACTEDFOLDNEXT 2618 #define SCI_CONTRACTEDFOLDNEXT 2618
#define SCI_VERTICALCENTRECARET 2619 #define SCI_VERTICALCENTRECARET 2619
#define SCI_MOVESELECTEDLINESUP 2620
#define SCI_MOVESELECTEDLINESDOWN 2621
#define SCI_SETIDENTIFIER 2622
#define SCI_GETIDENTIFIER 2623
#define SCI_RGBAIMAGESETWIDTH 2624
#define SCI_RGBAIMAGESETHEIGHT 2625
#define SCI_MARKERDEFINERGBAIMAGE 2626
#define SCI_REGISTERRGBAIMAGE 2627
#define SCI_SCROLLTOSTART 2628
#define SCI_SCROLLTOEND 2629
#define SCI_STARTRECORD 3001 #define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002 #define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001 #define SCI_SETLEXER 4001
@ -868,6 +895,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCMOD_CTRL 2 #define SCMOD_CTRL 2
#define SCMOD_ALT 4 #define SCMOD_ALT 4
#define SCMOD_SUPER 8 #define SCMOD_SUPER 8
#define SCMOD_META 16
#define SCN_STYLENEEDED 2000 #define SCN_STYLENEEDED 2000
#define SCN_CHARADDED 2001 #define SCN_CHARADDED 2001
#define SCN_SAVEPOINTREACHED 2002 #define SCN_SAVEPOINTREACHED 2002
@ -960,11 +988,22 @@ struct Sci_NotifyHeader {
struct SCNotification { struct SCNotification {
struct Sci_NotifyHeader nmhdr; struct Sci_NotifyHeader nmhdr;
int position; /* SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND */ int position;
/* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */
/* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */
/* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */
/* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
/* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
int ch; /* SCN_CHARADDED, SCN_KEY */ int ch; /* SCN_CHARADDED, SCN_KEY */
int modifiers; /* SCN_KEY */ int modifiers;
/* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */
/* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
int modificationType; /* SCN_MODIFIED */ int modificationType; /* SCN_MODIFIED */
const char *text; /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */ const char *text;
/* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */
int length; /* SCN_MODIFIED */ int length; /* SCN_MODIFIED */
int linesAdded; /* SCN_MODIFIED */ int linesAdded; /* SCN_MODIFIED */
int message; /* SCN_MACRORECORD */ int message; /* SCN_MACRORECORD */
@ -978,7 +1017,7 @@ struct SCNotification {
int x; /* SCN_DWELLSTART, SCN_DWELLEND */ int x; /* SCN_DWELLSTART, SCN_DWELLEND */
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; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */
int updated; /* SCN_UPDATEUI */ int updated; /* SCN_UPDATEUI */
}; };

View File

@ -268,6 +268,7 @@ val SC_MARK_FULLRECT=26
val SC_MARK_LEFTRECT=27 val SC_MARK_LEFTRECT=27
val SC_MARK_AVAILABLE=28 val SC_MARK_AVAILABLE=28
val SC_MARK_UNDERLINE=29 val SC_MARK_UNDERLINE=29
val SC_MARK_RGBAIMAGE=30
val SC_MARK_CHARACTER=10000 val SC_MARK_CHARACTER=10000
@ -292,6 +293,12 @@ fun void MarkerSetFore=2041(int markerNumber, colour fore)
# Set the background colour used for a particular marker number. # Set the background colour used for a particular marker number.
fun void MarkerSetBack=2042(int markerNumber, colour back) fun void MarkerSetBack=2042(int markerNumber, colour back)
# Set the background colour used for a particular marker number when its folding block is selected.
fun void MarkerSetBackSelected=2292(int markerNumber, colour back)
# Enable/disable highlight for current folding bloc (smallest one that contains the caret)
fun void MarkerEnableHighlight=2293(bool enabled,)
# Add a marker to a line, returning an ID which can be used to find or delete the marker. # Add a marker to a line, returning an ID which can be used to find or delete the marker.
fun int MarkerAdd=2043(int line, int markerNumber) fun int MarkerAdd=2043(int line, int markerNumber)
@ -544,6 +551,11 @@ val INDIC_STRIKE=4
val INDIC_HIDDEN=5 val INDIC_HIDDEN=5
val INDIC_BOX=6 val INDIC_BOX=6
val INDIC_ROUNDBOX=7 val INDIC_ROUNDBOX=7
val INDIC_STRAIGHTBOX=8
val INDIC_DASH=9
val INDIC_DOTS=10
val INDIC_SQUIGGLELOW=11
val INDIC_DOTBOX=12
val INDIC_MAX=31 val INDIC_MAX=31
val INDIC_CONTAINER=8 val INDIC_CONTAINER=8
val INDIC0_MASK=0x20 val INDIC0_MASK=0x20
@ -791,6 +803,9 @@ set void SetSelectionEnd=2144(position pos,)
# Returns the position at the end of the selection. # Returns the position at the end of the selection.
get position GetSelectionEnd=2145(,) get position GetSelectionEnd=2145(,)
# Set caret to a position, while removing any existing selection.
fun void SetEmptySelection=2556(position pos,)
# Sets the print magnification added to the point size of each style for printing. # Sets the print magnification added to the point size of each style for printing.
set void SetPrintMagnification=2146(int magnification,) set void SetPrintMagnification=2146(int magnification,)
@ -1440,9 +1455,15 @@ fun int LineLength=2350(int line,)
# Highlight the characters at two positions. # Highlight the characters at two positions.
fun void BraceHighlight=2351(position pos1, position pos2) fun void BraceHighlight=2351(position pos1, position pos2)
# Use specified indicator to highlight matching braces instead of changing their style.
fun void BraceHighlightIndicator=2498(bool useBraceHighlightIndicator, int indicator)
# Highlight the character at a position indicating there is no matching brace. # Highlight the character at a position indicating there is no matching brace.
fun void BraceBadLight=2352(position pos,) fun void BraceBadLight=2352(position pos,)
# Use specified indicator to highlight non matching brace instead of changing its style.
fun void BraceBadLightIndicator=2499(bool useBraceBadLightIndicator, int indicator)
# Find the position of a matching brace or INVALID_POSITION if no match. # Find the position of a matching brace or INVALID_POSITION if no match.
fun position BraceMatch=2353(position pos,) fun position BraceMatch=2353(position pos,)
@ -1884,6 +1905,12 @@ set void IndicSetAlpha=2523(int indicator, int alpha)
# Get the alpha fill colour of the given indicator. # Get the alpha fill colour of the given indicator.
get int IndicGetAlpha=2524(int indicator,) get int IndicGetAlpha=2524(int indicator,)
# Set the alpha outline colour of the given indicator.
set void IndicSetOutlineAlpha=2558(int indicator, int alpha)
# Get the alpha outline colour of the given indicator.
get int IndicGetOutlineAlpha=2559(int indicator,)
# Set extra ascent for each line # Set extra ascent for each line
set void SetExtraAscent=2525(int extraAscent,) set void SetExtraAscent=2525(int extraAscent,)
@ -1926,6 +1953,16 @@ set void MarginSetStyleOffset=2537(int style,)
# Get the start of the range of style numbers used for margin text # Get the start of the range of style numbers used for margin text
get int MarginGetStyleOffset=2538(,) get int MarginGetStyleOffset=2538(,)
enu MarginOption=SC_MARGINOPTION_
val SC_MARGINOPTION_NONE=0
val SC_MARGINOPTION_SUBLINESELECT=1
# Set the margin options.
set void SetMarginOptions=2539(int marginOptions,)
# Get the margin options.
get int GetMarginOptions=2557(,)
# Set the annotation text for a line # Set the annotation text for a line
set void AnnotationSetText=2540(int line, string text) set void AnnotationSetText=2540(int line, string text)
@ -2106,6 +2143,38 @@ fun int ContractedFoldNext=2618(int lineStart,)
# Centre current line in window. # Centre current line in window.
fun void VerticalCentreCaret=2619(,) fun void VerticalCentreCaret=2619(,)
# Move the selected lines up one line, shifting the line above after the selection
fun void MoveSelectedLinesUp=2620(,)
# Move the selected lines down one line, shifting the line below before the selection
fun void MoveSelectedLinesDown=2621(,)
# Set the identifier reported as idFrom in notification messages.
set void SetIdentifier=2622(int identifier,)
# Get the identifier.
get int GetIdentifier=2623(,)
# Set the width for future RGBA image data.
set void RGBAImageSetWidth=2624(int width,)
# Set the height for future RGBA image data.
set void RGBAImageSetHeight=2625(int height,)
# Define a marker from RGBA data.
# It has the width and height from RGBAImageSetWidth/Height
fun void MarkerDefineRGBAImage=2626(int markerNumber, string pixels)
# Register an RGBA image for use in autocompletion lists.
# It has the width and height from RGBAImageSetWidth/Height
fun void RegisterRGBAImage=2627(int type, string pixels)
# Scroll to start of document.
fun void ScrollToStart=2628(,)
# Scroll to end of document.
fun void ScrollToEnd=2629(,)
# Start notifying the container of all key presses and commands. # Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,) fun void StartRecord=3001(,)
@ -2247,6 +2316,7 @@ val SCMOD_SHIFT=1
val SCMOD_CTRL=2 val SCMOD_CTRL=2
val SCMOD_ALT=4 val SCMOD_ALT=4
val SCMOD_SUPER=8 val SCMOD_SUPER=8
val SCMOD_META=16
################################################ ################################################
# For SciLexer.h # For SciLexer.h
@ -2613,6 +2683,16 @@ val SCE_PL_POD_VERB=31
val SCE_PL_SUB_PROTOTYPE=40 val SCE_PL_SUB_PROTOTYPE=40
val SCE_PL_FORMAT_IDENT=41 val SCE_PL_FORMAT_IDENT=41
val SCE_PL_FORMAT=42 val SCE_PL_FORMAT=42
val SCE_PL_STRING_VAR=43
val SCE_PL_XLAT=44
val SCE_PL_REGEX_VAR=54
val SCE_PL_REGSUBST_VAR=55
val SCE_PL_BACKTICKS_VAR=57
val SCE_PL_HERE_QQ_VAR=61
val SCE_PL_HERE_QX_VAR=62
val SCE_PL_STRING_QQ_VAR=64
val SCE_PL_STRING_QX_VAR=65
val SCE_PL_STRING_QR_VAR=66
# Lexical states for SCLEX_RUBY # Lexical states for SCLEX_RUBY
lex Ruby=SCLEX_RUBY SCE_RB_ lex Ruby=SCLEX_RUBY SCE_RB_
val SCE_RB_DEFAULT=0 val SCE_RB_DEFAULT=0
@ -2687,6 +2767,14 @@ val SCE_L_COMMAND=1
val SCE_L_TAG=2 val SCE_L_TAG=2
val SCE_L_MATH=3 val SCE_L_MATH=3
val SCE_L_COMMENT=4 val SCE_L_COMMENT=4
val SCE_L_TAG2=5
val SCE_L_MATH2=6
val SCE_L_COMMENT2=7
val SCE_L_VERBATIM=8
val SCE_L_SHORTCMD=9
val SCE_L_SPECIAL=10
val SCE_L_CMDOPT=11
val SCE_L_ERROR=12
# Lexical states for SCLEX_LUA # Lexical states for SCLEX_LUA
lex Lua=SCLEX_LUA SCE_LUA_ lex Lua=SCLEX_LUA SCE_LUA_
val SCE_LUA_DEFAULT=0 val SCE_LUA_DEFAULT=0
@ -2709,6 +2797,7 @@ val SCE_LUA_WORD5=16
val SCE_LUA_WORD6=17 val SCE_LUA_WORD6=17
val SCE_LUA_WORD7=18 val SCE_LUA_WORD7=18
val SCE_LUA_WORD8=19 val SCE_LUA_WORD8=19
val SCE_LUA_LABEL=20
# Lexical states for SCLEX_ERRORLIST # Lexical states for SCLEX_ERRORLIST
lex ErrorList=SCLEX_ERRORLIST SCE_ERR_ lex ErrorList=SCLEX_ERRORLIST SCE_ERR_
val SCE_ERR_DEFAULT=0 val SCE_ERR_DEFAULT=0
@ -3889,22 +3978,22 @@ evt void SavePointLeft=2003(void)
evt void ModifyAttemptRO=2004(void) evt void ModifyAttemptRO=2004(void)
# GTK+ Specific to work around focus and accelerator problems: # GTK+ Specific to work around focus and accelerator problems:
evt void Key=2005(int ch, int modifiers) evt void Key=2005(int ch, int modifiers)
evt void DoubleClick=2006(void) evt void DoubleClick=2006(int modifiers, int position, int line)
evt void UpdateUI=2007(void) evt void UpdateUI=2007(int updated)
evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev) evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev, int token, int annotationLinesAdded)
evt void MacroRecord=2009(int message, int wParam, int lParam) evt void MacroRecord=2009(int message, int wParam, int lParam)
evt void MarginClick=2010(int modifiers, int position, int margin) evt void MarginClick=2010(int modifiers, int position, int margin)
evt void NeedShown=2011(int position, int length) evt void NeedShown=2011(int position, int length)
evt void Painted=2013(void) evt void Painted=2013(void)
evt void UserListSelection=2014(int listType, string text) evt void UserListSelection=2014(int listType, string text, int position)
evt void URIDropped=2015(string text) evt void URIDropped=2015(string text)
evt void DwellStart=2016(int position) evt void DwellStart=2016(int position, int x, int y)
evt void DwellEnd=2017(int position) evt void DwellEnd=2017(int position, int x, int y)
evt void Zoom=2018(void) evt void Zoom=2018(void)
evt void HotSpotClick=2019(int modifiers, int position) evt void HotSpotClick=2019(int modifiers, int position)
evt void HotSpotDoubleClick=2020(int modifiers, int position) evt void HotSpotDoubleClick=2020(int modifiers, int position)
evt void CallTipClick=2021(int position) evt void CallTipClick=2021(int position)
evt void AutoCSelection=2022(string text) evt void AutoCSelection=2022(string text, int position)
evt void IndicatorClick=2023(int modifiers, int position) evt void IndicatorClick=2023(int modifiers, int position)
evt void IndicatorRelease=2024(int modifiers, int position) evt void IndicatorRelease=2024(int modifiers, int position)
evt void AutoCCancelled=2025(void) evt void AutoCCancelled=2025(void)

View File

@ -1,6 +1,7 @@
// Scintilla source code edit control // Scintilla source code edit control
/** @file LexBasic.cxx /** @file LexBasic.cxx
** Lexer for BlitzBasic and PureBasic. ** Lexer for BlitzBasic and PureBasic.
** 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.
@ -21,18 +22,25 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <assert.h> #include <assert.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;
@ -89,8 +97,213 @@ static int LowerCase(int c)
return c; return c;
} }
static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle, static int CheckBlitzFoldPoint(char const *token, int &level) {
WordList *keywordlists[], Accessor &styler, char comment_char) { if (!strcmp(token, "function") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
static int CheckPureFoldPoint(char const *token, int &level) {
if (!strcmp(token, "procedure") ||
!strcmp(token, "enumeration") ||
!strcmp(token, "interface") ||
!strcmp(token, "structure")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "endprocedure") ||
!strcmp(token, "endenumeration") ||
!strcmp(token, "endinterface") ||
!strcmp(token, "endstructure")) {
return -1;
}
return 0;
}
static int CheckFreeFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "sub") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end sub") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
// An individual named option for use in an OptionSet
// Options used for LexerBasic
struct OptionsBasic {
bool fold;
bool foldSyntaxBased;
bool foldCommentExplicit;
std::string foldExplicitStart;
std::string foldExplicitEnd;
bool foldExplicitAnywhere;
bool foldCompact;
OptionsBasic() {
fold = false;
foldSyntaxBased = true;
foldCommentExplicit = false;
foldExplicitStart = "";
foldExplicitEnd = "";
foldExplicitAnywhere = false;
foldCompact = true;
}
};
static const char * const blitzbasicWordListDesc[] = {
"BlitzBasic Keywords",
"user1",
"user2",
"user3",
0
};
static const char * const purebasicWordListDesc[] = {
"PureBasic Keywords",
"PureBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
static const char * const freebasicWordListDesc[] = {
"FreeBasic Keywords",
"FreeBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
struct OptionSetBasic : public OptionSet<OptionsBasic> {
OptionSetBasic(const char * const wordListDescriptions[]) {
DefineProperty("fold", &OptionsBasic::fold);
DefineProperty("fold.basic.syntax.based", &OptionsBasic::foldSyntaxBased,
"Set this property to 0 to disable syntax based folding.");
DefineProperty("fold.basic.comment.explicit", &OptionsBasic::foldCommentExplicit,
"This option enables folding explicit fold points when using the Basic lexer. "
"Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start "
"and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.");
DefineProperty("fold.basic.explicit.start", &OptionsBasic::foldExplicitStart,
"The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).");
DefineProperty("fold.basic.explicit.end", &OptionsBasic::foldExplicitEnd,
"The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).");
DefineProperty("fold.basic.explicit.anywhere", &OptionsBasic::foldExplicitAnywhere,
"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
DefineProperty("fold.compact", &OptionsBasic::foldCompact);
DefineWordListSets(wordListDescriptions);
}
};
class LexerBasic : public ILexer {
char comment_char;
int (*CheckFoldPoint)(char const *, int &);
WordList keywordlists[4];
OptionsBasic options;
OptionSetBasic osBasic;
public:
LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) :
comment_char(comment_char_),
CheckFoldPoint(CheckFoldPoint_),
osBasic(wordListDescriptions) {
}
~LexerBasic() {
}
void SCI_METHOD Release() {
delete this;
}
int SCI_METHOD Version() const {
return lvOriginal;
}
const char * SCI_METHOD PropertyNames() {
return osBasic.PropertyNames();
}
int SCI_METHOD PropertyType(const char *name) {
return osBasic.PropertyType(name);
}
const char * SCI_METHOD DescribeProperty(const char *name) {
return osBasic.DescribeProperty(name);
}
int SCI_METHOD PropertySet(const char *key, const char *val);
const char * SCI_METHOD DescribeWordListSets() {
return osBasic.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 *LexerFactoryBlitzBasic() {
return new LexerBasic(';', CheckBlitzFoldPoint, blitzbasicWordListDesc);
}
static ILexer *LexerFactoryPureBasic() {
return new LexerBasic(';', CheckPureFoldPoint, purebasicWordListDesc);
}
static ILexer *LexerFactoryFreeBasic() {
return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc );
}
};
int SCI_METHOD LexerBasic::PropertySet(const char *key, const char *val) {
if (osBasic.PropertySet(&options, key, val)) {
return 0;
}
return -1;
}
int SCI_METHOD LexerBasic::WordListSet(int n, const char *wl) {
WordList *wordListN = 0;
switch (n) {
case 0:
wordListN = &keywordlists[0];
break;
case 1:
wordListN = &keywordlists[1];
break;
case 2:
wordListN = &keywordlists[2];
break;
case 3:
wordListN = &keywordlists[3];
break;
}
int firstModification = -1;
if (wordListN) {
WordList wlNew;
wlNew.Set(wl);
if (*wordListN != wlNew) {
wordListN->Set(wl);
firstModification = 0;
}
}
return firstModification;
}
void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
LexAccessor styler(pAccess);
bool wasfirst = true, isfirst = true; // true if first token in a line bool wasfirst = true, isfirst = true; // true if first token in a line
styler.StartAt(startPos); styler.StartAt(startPos);
@ -114,7 +327,7 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
}; };
sc.GetCurrentLowered(s, sizeof(s)); sc.GetCurrentLowered(s, sizeof(s));
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
if (keywordlists[i]->InList(s)) { if (keywordlists[i].InList(s)) {
sc.ChangeState(kstates[i]); sc.ChangeState(kstates[i]);
} }
} }
@ -205,66 +418,30 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
sc.Complete(); sc.Complete();
} }
static int CheckBlitzFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
static int CheckPureFoldPoint(char const *token, int &level) { void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) {
if (!strcmp(token, "procedure") ||
!strcmp(token, "enumeration") ||
!strcmp(token, "interface") ||
!strcmp(token, "structure")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "endprocedure") ||
!strcmp(token, "endenumeration") ||
!strcmp(token, "endinterface") ||
!strcmp(token, "endstructure")) {
return -1;
}
return 0;
}
static int CheckFreeFoldPoint(char const *token, int &level) { if (!options.fold)
if (!strcmp(token, "function") || return;
!strcmp(token, "sub") ||
!strcmp(token, "type")) { LexAccessor styler(pAccess);
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end sub") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
static void FoldBasicDoc(unsigned int startPos, int length,
Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {
int line = styler.GetLine(startPos); int line = styler.GetLine(startPos);
int level = styler.LevelAt(line); int level = styler.LevelAt(line);
int go = 0, done = 0; int go = 0, done = 0;
int endPos = startPos + length; int endPos = startPos + length;
char word[256]; char word[256];
int wordlen = 0; int wordlen = 0;
int i; const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; int cNext = styler[startPos];
// Scan for tokens at the start of the line (they may include // Scan for tokens at the start of the line (they may include
// whitespace, for tokens like "End Function" // whitespace, for tokens like "End Function"
for (i = startPos; i < endPos; i++) { for (int i = startPos; i < endPos; i++) {
int c = styler.SafeGetCharAt(i); int c = cNext;
if (!done && !go) { cNext = styler.SafeGetCharAt(i + 1);
bool atEOL = (c == '\r' && cNext != '\n') || (c == '\n');
if (options.foldSyntaxBased && !done && !go) {
if (wordlen) { // are we scanning a token already? if (wordlen) { // are we scanning a token already?
word[wordlen] = static_cast<char>(LowerCase(c)); word[wordlen] = static_cast<char>(LowerCase(c));
if (!IsIdentifier(c)) { // done with token if (!IsIdentifier(c)) { // done with token
@ -294,8 +471,27 @@ static void FoldBasicDoc(unsigned int startPos, int length,
} }
} }
} }
if (c == '\n') { // line end if (options.foldCommentExplicit && ((styler.StyleAt(i) == SCE_B_COMMENT) || options.foldExplicitAnywhere)) {
if (!done && wordlen == 0 && foldCompact) // line was only space if (userDefinedFoldMarkers) {
if (styler.Match(i, options.foldExplicitStart.c_str())) {
level |= SC_FOLDLEVELHEADERFLAG;
go = 1;
} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
go = -1;
}
} else {
if (c == comment_char) {
if (cNext == '{') {
level |= SC_FOLDLEVELHEADERFLAG;
go = 1;
} else if (cNext == '}') {
go = -1;
}
}
}
}
if (atEOL) { // line end
if (!done && wordlen == 0 && options.foldCompact) // line was only space
level |= SC_FOLDLEVELWHITEFLAG; level |= SC_FOLDLEVELWHITEFLAG;
if (level != styler.LevelAt(line)) if (level != styler.LevelAt(line))
styler.SetLevel(line, level); styler.SetLevel(line, level);
@ -311,66 +507,8 @@ static void FoldBasicDoc(unsigned int startPos, int length,
} }
} }
static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle, LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc);
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
}
static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle, LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc);
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
}
static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');
}
static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);
}
static void FoldPureBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);
}
static void FoldFreeBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);
}
static const char * const blitzbasicWordListDesc[] = {
"BlitzBasic Keywords",
"user1",
"user2",
"user3",
0
};
static const char * const purebasicWordListDesc[] = {
"PureBasic Keywords",
"PureBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
static const char * const freebasicWordListDesc[] = {
"FreeBasic Keywords",
"FreeBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",
FoldBlitzBasicDoc, blitzbasicWordListDesc);
LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",
FoldPureBasicDoc, purebasicWordListDesc);
LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",
FoldFreeBasicDoc, freebasicWordListDesc);
LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc);

View File

@ -208,6 +208,14 @@ static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle,
if (isCOBOLwordstart(ch) || (ch == '$' && isascii(chNext) && isalpha(chNext))) { if (isCOBOLwordstart(ch) || (ch == '$' && isascii(chNext) && isalpha(chNext))) {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_IDENTIFIER; state = SCE_C_IDENTIFIER;
} else if (column == 6 && ch == '*') {
// Cobol comment line: asterisk in column 7.
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
} else if (ch == '*' && chNext == '>') {
// Cobol inline comment: asterisk, followed by greater than.
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
} else if (column == 0 && ch == '*' && chNext != '*') { } else if (column == 0 && ch == '*' && chNext != '*') {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE; state = SCE_C_COMMENTLINE;

View File

@ -324,6 +324,7 @@ class LexerCPP : public ILexer {
OptionsCPP options; OptionsCPP options;
OptionSetCPP osCPP; OptionSetCPP osCPP;
SparseState<std::string> rawStringTerminators; SparseState<std::string> rawStringTerminators;
enum { activeFlag = 0x40 };
public: public:
LexerCPP(bool caseSensitive_) : LexerCPP(bool caseSensitive_) :
caseSensitive(caseSensitive_), caseSensitive(caseSensitive_),
@ -368,7 +369,9 @@ public:
static ILexer *LexerFactoryCPPInsensitive() { static ILexer *LexerFactoryCPPInsensitive() {
return new LexerCPP(false); return new LexerCPP(false);
} }
static int MaskActive(int style) {
return style & ~activeFlag;
}
void EvaluateTokens(std::vector<std::string> &tokens); void EvaluateTokens(std::vector<std::string> &tokens);
bool EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions); bool EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions);
}; };
@ -432,7 +435,7 @@ int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
struct After { struct After {
int line; int line;
After(int line_) : line(line_) {} After(int line_) : line(line_) {}
bool operator() (PPDefinition &p) const { bool operator()(PPDefinition &p) const {
return p.line > line; return p.line > line;
} }
}; };
@ -508,11 +511,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
preprocessorDefinitions[itDef->key] = itDef->value; preprocessorDefinitions[itDef->key] = itDef->value;
} }
const int maskActivity = 0x3F;
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1); std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
SparseState<std::string> rawSTNew(lineCurrent); SparseState<std::string> rawSTNew(lineCurrent);
int activitySet = preproc.IsInactive() ? 0x40 : 0; int activitySet = preproc.IsInactive() ? activeFlag : 0;
for (; sc.More(); sc.Forward()) { for (; sc.More(); sc.Forward()) {
@ -528,7 +530,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
lastWordWasUUID = false; lastWordWasUUID = false;
isIncludePreprocessor = false; isIncludePreprocessor = false;
if (preproc.IsInactive()) { if (preproc.IsInactive()) {
activitySet = 0x40; activitySet = activeFlag;
sc.SetState(sc.state | activitySet); sc.SetState(sc.state | activitySet);
} }
if (activitySet) { if (activitySet) {
@ -563,7 +565,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
const bool atLineEndBeforeSwitch = sc.atLineEnd; const bool atLineEndBeforeSwitch = sc.atLineEnd;
// Determine if the current state should terminate. // Determine if the current state should terminate.
switch (sc.state & maskActivity) { switch (MaskActive(sc.state)) {
case SCE_C_OPERATOR: case SCE_C_OPERATOR:
sc.SetState(SCE_C_DEFAULT|activitySet); sc.SetState(SCE_C_DEFAULT|activitySet);
break; break;
@ -739,7 +741,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} }
break; break;
case SCE_C_TRIPLEVERBATIM: case SCE_C_TRIPLEVERBATIM:
if (sc.Match ("\"\"\"")) { if (sc.Match("\"\"\"")) {
while (sc.Match('"')) { while (sc.Match('"')) {
sc.Forward(); sc.Forward();
} }
@ -759,7 +761,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} }
// Determine if a new state should be entered. // Determine if a new state should be entered.
if ((sc.state & maskActivity) == SCE_C_DEFAULT) { if (MaskActive(sc.state) == SCE_C_DEFAULT) {
if (sc.Match('@', '\"')) { if (sc.Match('@', '\"')) {
sc.SetState(SCE_C_VERBATIM|activitySet); sc.SetState(SCE_C_VERBATIM|activitySet);
sc.Forward(); sc.Forward();
@ -801,15 +803,20 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
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 == '\"') {
if (sc.chPrev == 'R') { if (sc.chPrev == 'R') {
sc.SetState(SCE_C_STRINGRAW|activitySet); styler.Flush();
rawStringTerminator = ")"; if (MaskActive(styler.StyleAt(sc.currentPos - 1)) == SCE_C_STRINGRAW) {
for (int termPos = sc.currentPos + 1;;termPos++) { sc.SetState(SCE_C_STRINGRAW|activitySet);
char chTerminator = styler.SafeGetCharAt(termPos, '('); rawStringTerminator = ")";
if (chTerminator == '(') for (int termPos = sc.currentPos + 1;; termPos++) {
break; char chTerminator = styler.SafeGetCharAt(termPos, '(');
rawStringTerminator += chTerminator; if (chTerminator == '(')
break;
rawStringTerminator += chTerminator;
}
rawStringTerminator += '\"';
} else {
sc.SetState(SCE_C_STRING|activitySet);
} }
rawStringTerminator += '\"';
} else { } else {
sc.SetState(SCE_C_STRING|activitySet); sc.SetState(SCE_C_STRING|activitySet);
} }
@ -844,12 +851,12 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} else if (sc.Match("else")) { } else if (sc.Match("else")) {
if (!preproc.CurrentIfTaken()) { if (!preproc.CurrentIfTaken()) {
preproc.InvertCurrentLevel(); preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0; activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet) if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (!preproc.IsInactive()) { } else if (!preproc.IsInactive()) {
preproc.InvertCurrentLevel(); preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0; activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet) if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} }
@ -861,19 +868,19 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions); bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
if (ifGood) { if (ifGood) {
preproc.InvertCurrentLevel(); preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0; activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet) if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} }
} else if (!preproc.IsInactive()) { } else if (!preproc.IsInactive()) {
preproc.InvertCurrentLevel(); preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0; activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet) if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} }
} else if (sc.Match("endif")) { } else if (sc.Match("endif")) {
preproc.EndSection(); preproc.EndSection();
activitySet = preproc.IsInactive() ? 0x40 : 0; activitySet = preproc.IsInactive() ? activeFlag : 0;
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (sc.Match("define")) { } else if (sc.Match("define")) {
if (options.updatePreprocessor && !preproc.IsInactive()) { if (options.updatePreprocessor && !preproc.IsInactive()) {
@ -933,15 +940,15 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
int levelMinCurrent = levelCurrent; int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent; int levelNext = levelCurrent;
char chNext = styler[startPos]; char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos); int styleNext = MaskActive(styler.StyleAt(startPos));
int style = initStyle; int style = MaskActive(initStyle);
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); 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);
int stylePrev = style; int stylePrev = style;
style = styleNext; style = styleNext;
styleNext = styler.StyleAt(i + 1); styleNext = MaskActive(styler.StyleAt(i + 1));
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) { if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) { if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {

View File

@ -57,7 +57,7 @@ inline bool IsOperator(int ch) {
} }
static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) { static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) {
size_t i = 0; unsigned int i = 0;
for (; (i < end - start + 1) && (i < len-1); i++) { for (; (i < end - start + 1) && (i < len-1); i++) {
s[i] = static_cast<char>(MakeLowerCase(styler[start + i])); s[i] = static_cast<char>(MakeLowerCase(styler[start + i]));
} }
@ -66,7 +66,7 @@ static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int en
static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) { static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) {
size_t i = 0; unsigned int i = 0;
for (; i < sLen-1; i++) { for (; i < sLen-1; i++) {
char ch = static_cast<char>(styler.SafeGetCharAt(start + i)); char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
if ((i == 0) && !IsAWordStart(ch)) if ((i == 0) && !IsAWordStart(ch))
@ -318,19 +318,19 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
static void classifyWordHTJS(unsigned int start, unsigned int end, static void classifyWordHTJS(unsigned int start, unsigned int end,
WordList &keywords, Accessor &styler, script_mode inScriptType) { WordList &keywords, Accessor &styler, script_mode inScriptType) {
char s[30 + 1];
unsigned int i = 0;
for (; i < end - start + 1 && i < 30; i++) {
s[i] = styler[start + i];
}
s[i] = '\0';
char chAttr = SCE_HJ_WORD; char chAttr = SCE_HJ_WORD;
bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1]));
if (wordIsNumber) if (wordIsNumber) {
chAttr = SCE_HJ_NUMBER; chAttr = SCE_HJ_NUMBER;
else { } else if (keywords.InList(s)) {
char s[30 + 1]; chAttr = SCE_HJ_KEYWORD;
unsigned int i = 0;
for (; i < end - start + 1 && i < 30; i++) {
s[i] = styler[start + i];
}
s[i] = '\0';
if (keywords.InList(s))
chAttr = SCE_HJ_KEYWORD;
} }
styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
} }
@ -356,7 +356,7 @@ static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keyw
return SCE_HB_DEFAULT; return SCE_HB_DEFAULT;
} }
static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType) { static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType, bool isMako) {
bool wordIsNumber = IsADigit(styler[start]); bool wordIsNumber = IsADigit(styler[start]);
char s[30 + 1]; char s[30 + 1];
unsigned int i = 0; unsigned int i = 0;
@ -373,6 +373,8 @@ static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &key
chAttr = SCE_HP_NUMBER; chAttr = SCE_HP_NUMBER;
else if (keywords.InList(s)) else if (keywords.InList(s))
chAttr = SCE_HP_WORD; chAttr = SCE_HP_WORD;
else if (isMako && 0 == strcmp(s, "block"))
chAttr = SCE_HP_WORD;
styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
strcpy(prevWord, s); strcpy(prevWord, s);
} }
@ -494,7 +496,10 @@ static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType
(0 == strcmp(blockType, "page"))) { (0 == strcmp(blockType, "page"))) {
return ((ch == '/') && (chNext == '>')); return ((ch == '/') && (chNext == '>'));
} else if (0 == strcmp(blockType, "%")) { } else if (0 == strcmp(blockType, "%")) {
return isLineEnd(ch); if (ch == '/' && isLineEnd(chNext))
return 1;
else
return isLineEnd(ch);
} else if (0 == strcmp(blockType, "{")) { } else if (0 == strcmp(blockType, "{")) {
return ch == '}'; return ch == '}';
} else { } else {
@ -588,6 +593,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
int state = stateForPrintState(StateToPrint); int state = stateForPrintState(StateToPrint);
char makoBlockType[200]; char makoBlockType[200];
makoBlockType[0] = '\0'; makoBlockType[0] = '\0';
int makoComment = 0;
char djangoBlockType[2]; char djangoBlockType[2];
djangoBlockType[0] = '\0'; djangoBlockType[0] = '\0';
@ -754,15 +760,15 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
} else if (styler.Match(j, "end")) { } else if (styler.Match(j, "end")) {
levelCurrent--; levelCurrent--;
} }
} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*')) ) { } else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
levelCurrent += ((ch == '{') || (ch == '/') ) ? 1 : -1; 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--;
} }
break; break;
case eScriptPython: case eScriptPython:
if (state != SCE_HP_COMMENTLINE) { if (state != SCE_HP_COMMENTLINE && !isMako) {
if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) { if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) {
levelCurrent++; levelCurrent++;
} else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) { } else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) {
@ -818,6 +824,18 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
lineStartVisibleChars = 0; lineStartVisibleChars = 0;
} }
// handle start of Mako comment line
if (isMako && ch == '#' && chNext == '#') {
makoComment = 1;
}
// handle end of Mako comment line
else if (isMako && makoComment && (ch == '\r' || ch == '\n')) {
makoComment = 0;
styler.ColourTo(i, SCE_HP_COMMENTLINE);
state = SCE_HP_DEFAULT;
}
// Allow falling through to mako handling code if newline is going to end a block // Allow falling through to mako handling code if newline is going to end a block
if (((ch == '\r' && chNext != '\n') || (ch == '\n')) && if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
(!isMako || (0 != strcmp(makoBlockType, "%")))) { (!isMako || (0 != strcmp(makoBlockType, "%")))) {
@ -882,7 +900,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(state != SCE_HPHP_COMMENTLINE) && (state != SCE_HPHP_COMMENTLINE) &&
(ch == '<') && (ch == '<') &&
(chNext == '?') && (chNext == '?') &&
!IsScriptCommentState(state) ) { !IsScriptCommentState(state)) {
beforeLanguage = scriptLanguage;
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP); scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
if (scriptLanguage != eScriptPHP && isStringState(state)) continue; if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
@ -911,9 +930,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
// handle the start Mako template Python code // handle the start Mako template Python code
else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') || else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
(lineStartVisibleChars == 1 && ch == '%') || (lineStartVisibleChars == 1 && ch == '%') ||
(lineStartVisibleChars == 1 && ch == '/' && chNext == '%') ||
(ch == '$' && chNext == '{') || (ch == '$' && chNext == '{') ||
(ch == '<' && chNext == '/' && chNext2 == '%'))) { (ch == '<' && chNext == '/' && chNext2 == '%'))) {
if (ch == '%') if (ch == '%' || ch == '/')
strcpy(makoBlockType, "%"); strcpy(makoBlockType, "%");
else if (ch == '$') else if (ch == '$')
strcpy(makoBlockType, "{"); strcpy(makoBlockType, "{");
@ -938,12 +958,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_HP_START; state = SCE_HP_START;
scriptLanguage = eScriptPython; scriptLanguage = eScriptPython;
styler.ColourTo(i, SCE_H_ASP); styler.ColourTo(i, SCE_H_ASP);
if (foldHTMLPreprocessor && ch == '<')
levelCurrent++;
if (ch != '%' && ch != '$') { if (ch != '%' && ch != '$' && ch != '/') {
i += strlen(makoBlockType); i += static_cast<int>(strlen(makoBlockType));
visibleChars += strlen(makoBlockType); visibleChars += static_cast<int>(strlen(makoBlockType));
if (keywords4.InList(makoBlockType)) if (keywords4.InList(makoBlockType))
styler.ColourTo(i, SCE_HP_WORD); styler.ColourTo(i, SCE_HP_WORD);
else else
@ -954,6 +972,36 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue; continue;
} }
// handle the start/end of Django comment
else if (isDjango && state != SCE_H_COMMENT && (ch == '{' && chNext == '#')) {
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
beforeLanguage = scriptLanguage;
if (inScriptType == eNonHtmlScript)
inScriptType = eNonHtmlScriptPreProc;
else
inScriptType = eNonHtmlPreProc;
i += 1;
visibleChars += 1;
scriptLanguage = eScriptComment;
state = SCE_H_COMMENT;
styler.ColourTo(i, SCE_H_ASP);
ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
continue;
} else if (isDjango && state == SCE_H_COMMENT && (ch == '#' && chNext == '}')) {
styler.ColourTo(i - 1, StateToPrint);
i += 1;
visibleChars += 1;
styler.ColourTo(i, SCE_H_ASP);
state = beforePreProc;
if (inScriptType == eNonHtmlScriptPreProc)
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
scriptLanguage = beforeLanguage;
continue;
}
// handle the start Django template code // handle the start Django template code
else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) { else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) {
if (chNext == '%') if (chNext == '%')
@ -1024,7 +1072,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(ch == '!') && (ch == '!') &&
(StateToPrint != SCE_H_CDATA) && (StateToPrint != SCE_H_CDATA) &&
(!IsCommentState(StateToPrint)) && (!IsCommentState(StateToPrint)) &&
(!IsScriptCommentState(StateToPrint)) ) { (!IsScriptCommentState(StateToPrint))) {
beforePreProc = state; beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint); styler.ColourTo(i - 2, StateToPrint);
if ((chNext == '-') && (chNext2 == '-')) { if ((chNext == '-') && (chNext2 == '-')) {
@ -1054,7 +1102,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.GetStartSegment(), i - 1, aspScript); styler.GetStartSegment(), i - 1, aspScript);
} }
if (state == SCE_HP_WORD) { if (state == SCE_HP_WORD) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType); classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
} else { } else {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
} }
@ -1062,7 +1110,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
i++; i++;
visibleChars++; visibleChars++;
} }
if (0 != strcmp(makoBlockType, "%")) { else if (0 == strcmp(makoBlockType, "%") && ch == '/') {
i++;
visibleChars++;
}
if (0 != strcmp(makoBlockType, "%") || ch == '/') {
styler.ColourTo(i, SCE_H_ASP); styler.ColourTo(i, SCE_H_ASP);
} }
state = beforePreProc; state = beforePreProc;
@ -1070,9 +1122,6 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
inScriptType = eNonHtmlScript; inScriptType = eNonHtmlScript;
else else
inScriptType = eHtml; inScriptType = eHtml;
if (foldHTMLPreprocessor && ch != '\n' && ch != '\r') {
levelCurrent--;
}
scriptLanguage = eScriptNone; scriptLanguage = eScriptNone;
continue; continue;
} }
@ -1087,7 +1136,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.GetStartSegment(), i - 1, aspScript); styler.GetStartSegment(), i - 1, aspScript);
} }
if (state == SCE_HP_WORD) { if (state == SCE_HP_WORD) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType); classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
} else { } else {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
} }
@ -1121,7 +1170,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType); classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
break; break;
case SCE_HP_WORD: case SCE_HP_WORD:
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType); classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
break; break;
case SCE_HPHP_WORD: case SCE_HPHP_WORD:
classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
@ -1154,7 +1203,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) { if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent--; levelCurrent--;
} }
scriptLanguage = eScriptNone; scriptLanguage = beforeLanguage;
continue; continue;
} }
///////////////////////////////////// /////////////////////////////////////
@ -1783,7 +1832,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
break; break;
case SCE_HP_WORD: case SCE_HP_WORD:
if (!IsAWordChar(ch)) { if (!IsAWordChar(ch)) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType); classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
state = SCE_HP_DEFAULT; state = SCE_HP_DEFAULT;
if (ch == '#') { if (ch == '#') {
state = SCE_HP_COMMENTLINE; state = SCE_HP_COMMENTLINE;
@ -1934,7 +1983,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.ColourTo(i, StateToPrint); styler.ColourTo(i, StateToPrint);
state = SCE_HPHP_DEFAULT; state = SCE_HPHP_DEFAULT;
} else if (isLineEnd(chPrev)) { } else if (isLineEnd(chPrev)) {
const int psdLength = strlen(phpStringDelimiter); const int psdLength = static_cast<int>(strlen(phpStringDelimiter));
const char chAfterPsd = styler.SafeGetCharAt(i + psdLength); const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1); const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
if (isLineEnd(chAfterPsd) || if (isLineEnd(chAfterPsd) ||
@ -1957,7 +2006,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_HPHP_DEFAULT; state = SCE_HPHP_DEFAULT;
} }
} else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) { } else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) {
const int psdLength = strlen(phpStringDelimiter); const int psdLength = static_cast<int>(strlen(phpStringDelimiter));
const char chAfterPsd = styler.SafeGetCharAt(i + psdLength); const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1); const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
if (isLineEnd(chAfterPsd) || if (isLineEnd(chAfterPsd) ||
@ -2072,7 +2121,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType); classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType);
break; break;
case SCE_HP_WORD: case SCE_HP_WORD:
classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType); classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType, isMako);
break; break;
case SCE_HPHP_WORD: case SCE_HPHP_WORD:
classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler); classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler);

View File

@ -59,10 +59,11 @@ static void ColouriseLuaDoc(
// Accepts accented characters // Accepts accented characters
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
// 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. [pP] is for hex floats.
CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefABCDEF"); CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP");
CharacterSet setExponent(CharacterSet::setNone, "eEpP");
CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#"); CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#");
CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\"); CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\");
@ -70,12 +71,16 @@ static void ColouriseLuaDoc(
// Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level, // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
// if we are inside such a string. Block comment was introduced in Lua 5.0, // if we are inside such a string. Block comment was introduced in Lua 5.0,
// blocks with separators [=[ ... ]=] in Lua 5.1. // blocks with separators [=[ ... ]=] in Lua 5.1.
// Continuation of a string (\z whitespace escaping) is controlled by stringWs.
int nestLevel = 0; int nestLevel = 0;
int sepCount = 0; int sepCount = 0;
if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) { int stringWs = 0;
if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT ||
initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) {
int lineState = styler.GetLineState(currentLine - 1); int lineState = styler.GetLineState(currentLine - 1);
nestLevel = lineState >> 8; nestLevel = lineState >> 9;
sepCount = lineState & 0xFF; sepCount = lineState & 0xFF;
stringWs = lineState & 0x100;
} }
// Do not leak onto next line // Do not leak onto next line
@ -95,8 +100,10 @@ static void ColouriseLuaDoc(
switch (sc.state) { switch (sc.state) {
case SCE_LUA_LITERALSTRING: case SCE_LUA_LITERALSTRING:
case SCE_LUA_COMMENT: case SCE_LUA_COMMENT:
// Inside a literal string or block comment, we set the line state case SCE_LUA_STRING:
styler.SetLineState(currentLine, (nestLevel << 8) | sepCount); case SCE_LUA_CHARACTER:
// Inside a literal string, block comment or string, we set the line state
styler.SetLineState(currentLine, (nestLevel << 9) | stringWs | sepCount);
break; break;
default: default:
// Reset the line state // Reset the line state
@ -123,21 +130,91 @@ static void ColouriseLuaDoc(
// Determine if the current state should terminate. // Determine if the current state should terminate.
if (sc.state == SCE_LUA_OPERATOR) { if (sc.state == SCE_LUA_OPERATOR) {
if (sc.ch == ':' && sc.chPrev == ':') { // :: <label> :: forward scan
sc.Forward();
int ln = 0, maxln = startPos + length - sc.currentPos;
int c;
while (ln < maxln) { // determine line extent
c = sc.GetRelative(ln);
if (c == '\r' || c == '\n')
break;
ln++;
}
maxln = ln; ln = 0;
while (ln < maxln) { // skip over spaces/tabs
if (!IsASpaceOrTab(sc.GetRelative(ln)))
break;
ln++;
}
int ws1 = ln;
if (setWordStart.Contains(sc.GetRelative(ln))) {
int i = 0;
char s[100];
while (ln < maxln) { // get potential label
c = sc.GetRelative(ln);
if (!setWord.Contains(c))
break;
if (i < 90)
s[i++] = c;
ln++;
}
s[i] = '\0'; int lbl = ln;
if (!keywords.InList(s)) {
while (ln < maxln) { // skip over spaces/tabs
if (!IsASpaceOrTab(sc.GetRelative(ln)))
break;
ln++;
}
int ws2 = ln - lbl;
if (sc.GetRelative(ln) == ':' && sc.GetRelative(ln + 1) == ':') {
// final :: found, complete valid label construct
sc.ChangeState(SCE_LUA_LABEL);
if (ws1) {
sc.SetState(SCE_LUA_DEFAULT);
sc.Forward(ws1);
}
sc.SetState(SCE_LUA_LABEL);
sc.Forward(lbl - ws1);
if (ws2) {
sc.SetState(SCE_LUA_DEFAULT);
sc.Forward(ws2);
}
sc.SetState(SCE_LUA_LABEL);
sc.Forward(2);
}
}
}
}
sc.SetState(SCE_LUA_DEFAULT); sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.state == SCE_LUA_NUMBER) { } else if (sc.state == SCE_LUA_NUMBER) {
// We stop the number definition on non-numerical non-dot non-eE non-sign non-hexdigit char // We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char
if (!setNumber.Contains(sc.ch)) { if (!setNumber.Contains(sc.ch)) {
sc.SetState(SCE_LUA_DEFAULT); sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.ch == '-' || sc.ch == '+') { } else if (sc.ch == '-' || sc.ch == '+') {
if (sc.chPrev != 'E' && sc.chPrev != 'e') if (!setExponent.Contains(sc.chPrev))
sc.SetState(SCE_LUA_DEFAULT); sc.SetState(SCE_LUA_DEFAULT);
} }
} else if (sc.state == SCE_LUA_IDENTIFIER) { } else if (sc.state == SCE_LUA_IDENTIFIER) {
if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) { if (!(setWord.Contains(sc.ch) || sc.ch == '.') || sc.Match('.', '.')) {
char s[100]; char s[100];
sc.GetCurrent(s, sizeof(s)); sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) { if (keywords.InList(s)) {
sc.ChangeState(SCE_LUA_WORD); sc.ChangeState(SCE_LUA_WORD);
if (strcmp(s, "goto") == 0) { // goto <label> forward scan
sc.SetState(SCE_LUA_DEFAULT);
while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
sc.Forward();
if (setWordStart.Contains(sc.ch)) {
sc.SetState(SCE_LUA_LABEL);
sc.Forward();
while (setWord.Contains(sc.ch))
sc.Forward();
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s))
sc.ChangeState(SCE_LUA_WORD);
}
sc.SetState(SCE_LUA_DEFAULT);
}
} else if (keywords2.InList(s)) { } else if (keywords2.InList(s)) {
sc.ChangeState(SCE_LUA_WORD2); sc.ChangeState(SCE_LUA_WORD2);
} else if (keywords3.InList(s)) { } else if (keywords3.InList(s)) {
@ -160,24 +237,38 @@ static void ColouriseLuaDoc(
sc.ForwardSetState(SCE_LUA_DEFAULT); sc.ForwardSetState(SCE_LUA_DEFAULT);
} }
} else if (sc.state == SCE_LUA_STRING) { } else if (sc.state == SCE_LUA_STRING) {
if (stringWs) {
if (!IsASpace(sc.ch))
stringWs = 0;
}
if (sc.ch == '\\') { if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) { if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward(); sc.Forward();
} else if (sc.chNext == 'z') {
sc.Forward();
stringWs = 0x100;
} }
} else if (sc.ch == '\"') { } else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_LUA_DEFAULT); sc.ForwardSetState(SCE_LUA_DEFAULT);
} else if (sc.atLineEnd) { } else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL); sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT); sc.ForwardSetState(SCE_LUA_DEFAULT);
} }
} else if (sc.state == SCE_LUA_CHARACTER) { } else if (sc.state == SCE_LUA_CHARACTER) {
if (stringWs) {
if (!IsASpace(sc.ch))
stringWs = 0;
}
if (sc.ch == '\\') { if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) { if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward(); sc.Forward();
} else if (sc.chNext == 'z') {
sc.Forward();
stringWs = 0x100;
} }
} else if (sc.ch == '\'') { } else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_LUA_DEFAULT); sc.ForwardSetState(SCE_LUA_DEFAULT);
} else if (sc.atLineEnd) { } else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL); sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT); sc.ForwardSetState(SCE_LUA_DEFAULT);
} }
@ -214,8 +305,10 @@ static void ColouriseLuaDoc(
sc.SetState(SCE_LUA_IDENTIFIER); sc.SetState(SCE_LUA_IDENTIFIER);
} else if (sc.ch == '\"') { } else if (sc.ch == '\"') {
sc.SetState(SCE_LUA_STRING); sc.SetState(SCE_LUA_STRING);
stringWs = 0;
} else if (sc.ch == '\'') { } else if (sc.ch == '\'') {
sc.SetState(SCE_LUA_CHARACTER); sc.SetState(SCE_LUA_CHARACTER);
stringWs = 0;
} else if (sc.ch == '[') { } else if (sc.ch == '[') {
sepCount = LongDelimCheck(sc); sepCount = LongDelimCheck(sc);
if (sepCount == 0) { if (sepCount == 0) {
@ -246,7 +339,7 @@ static void ColouriseLuaDoc(
} }
} }
if (setWord.Contains(sc.chPrev)) { if (setWord.Contains(sc.chPrev) || sc.chPrev == '.') {
char s[100]; char s[100];
sc.GetCurrent(s, sizeof(s)); sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) { if (keywords.InList(s)) {

View File

@ -113,6 +113,10 @@ static bool HasPrevLineContent(StyleContext &sc) {
return false; return false;
} }
static bool AtTermStart(StyleContext &sc) {
return sc.currentPos == 0 || isspacechar(sc.chPrev);
}
static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
int c, count = 1; int c, count = 1;
unsigned int i = 0; unsigned int i = 0;
@ -373,35 +377,38 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
} }
} }
// Code - also a special case for alternate inside spacing // Code - also a special case for alternate inside spacing
if (sc.Match("``") && sc.GetRelative(3) != ' ') { if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_CODE2); sc.SetState(SCE_MARKDOWN_CODE2);
sc.Forward(); sc.Forward();
} }
else if (sc.ch == '`' && sc.chNext != ' ') { else if (sc.ch == '`' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_CODE); sc.SetState(SCE_MARKDOWN_CODE);
} }
// Strong // Strong
else if (sc.Match("**") && sc.GetRelative(2) != ' ') { else if (sc.Match("**") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRONG1); sc.SetState(SCE_MARKDOWN_STRONG1);
sc.Forward(); sc.Forward();
} }
else if (sc.Match("__") && sc.GetRelative(2) != ' ') { else if (sc.Match("__") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRONG2); sc.SetState(SCE_MARKDOWN_STRONG2);
sc.Forward(); sc.Forward();
} }
// Emphasis // Emphasis
else if (sc.ch == '*' && sc.chNext != ' ') else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_EM1); sc.SetState(SCE_MARKDOWN_EM1);
else if (sc.ch == '_' && sc.chNext != ' ') }
else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_EM2); sc.SetState(SCE_MARKDOWN_EM2);
}
// Strikeout // Strikeout
else if (sc.Match("~~") && sc.GetRelative(2) != ' ') { else if (sc.Match("~~") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRIKEOUT); sc.SetState(SCE_MARKDOWN_STRIKEOUT);
sc.Forward(); sc.Forward();
} }
// Beginning of line // Beginning of line
else if (IsNewline(sc.ch)) else if (IsNewline(sc.ch)) {
sc.SetState(SCE_MARKDOWN_LINE_BEGIN); sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
}
} }
// Advance if not holding back the cursor for this iteration. // Advance if not holding back the cursor for this iteration.
if (!freezeCursor) if (!freezeCursor)

View File

@ -106,12 +106,12 @@ static void ColouriseMatlabOctaveDoc(
transpose = true; transpose = true;
} }
} else if (sc.state == SCE_MATLAB_STRING) { } else if (sc.state == SCE_MATLAB_STRING) {
if (sc.ch == '\\') { if (sc.ch == '\'') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { if (sc.chNext == '\'') {
sc.Forward(); sc.Forward();
} } else {
} else if (sc.ch == '\'') { sc.ForwardSetState(SCE_MATLAB_DEFAULT);
sc.ForwardSetState(SCE_MATLAB_DEFAULT); }
} }
} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) { } else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
if (sc.ch == '\\') { if (sc.ch == '\\') {

View File

@ -58,7 +58,7 @@ static bool IsBOperator(char ch) {
// Tests for BATCH Separators // Tests for BATCH Separators
static bool IsBSeparator(char ch) { static bool IsBSeparator(char ch) {
return (ch == '\\') || (ch == '.') || (ch == ';') || return (ch == '\\') || (ch == '.') || (ch == ';') ||
(ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')'); (ch == '\"') || (ch == '\'') || (ch == '/');
} }
static void ColouriseBatchLine( static void ColouriseBatchLine(
@ -854,13 +854,17 @@ static void ColouriseMakeLine(
styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR); styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
return; return;
} }
int varCount = 0;
while (i < lengthLine) { while (i < lengthLine) {
if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') { if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
styler.ColourTo(startLine + i - 1, state); styler.ColourTo(startLine + i - 1, state);
state = SCE_MAKE_IDENTIFIER; state = SCE_MAKE_IDENTIFIER;
varCount++;
} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') { } else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
styler.ColourTo(startLine + i, state); if (--varCount == 0) {
state = SCE_MAKE_DEFAULT; styler.ColourTo(startLine + i, state);
state = SCE_MAKE_DEFAULT;
}
} }
// skip identifier and target styling if this is a command line // skip identifier and target styling if this is a command line
@ -1158,21 +1162,71 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi
} }
} }
static int isSpecial(char s) { static bool latexIsSpecial(int ch) {
return (s == '\\') || (s == ',') || (s == ';') || (s == '\'') || (s == ' ') || return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
(s == '\"') || (s == '`') || (s == '^') || (s == '~'); (ch == '{') || (ch == '}') || (ch == ' ');
} }
static int isTag(int start, Accessor &styler) { static bool latexIsBlank(int ch) {
char s[6]; return (ch == ' ') || (ch == '\t');
unsigned int i = 0, e = 1; }
while (i < 5 && e) {
s[i] = styler[start + i]; static bool latexIsBlankAndNL(int ch) {
return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
}
static bool latexIsLetter(int ch) {
return isascii(ch) && isalpha(ch);
}
static bool latexIsTagValid(int &i, int l, Accessor &styler) {
while (i < l) {
if (styler.SafeGetCharAt(i) == '{') {
while (i < l) {
i++;
if (styler.SafeGetCharAt(i) == '}') {
return true;
} else if (!latexIsLetter(styler.SafeGetCharAt(i)) &&
styler.SafeGetCharAt(i)!='*') {
return false;
}
}
} else if (!latexIsBlank(styler.SafeGetCharAt(i))) {
return false;
}
i++; i++;
e = (strchr("{ \t", styler[start + i]) == NULL); }
return false;
}
static bool latexNextNotBlankIs(int i, int l, Accessor &styler, char needle) {
char ch;
while (i < l) {
ch = styler.SafeGetCharAt(i);
if (!latexIsBlankAndNL(ch) && ch != '*') {
if (ch == needle)
return true;
else
return false;
}
i++;
}
return false;
}
static bool latexLastWordIs(int start, Accessor &styler, const char *needle) {
unsigned int i = 0;
unsigned int l = static_cast<unsigned int>(strlen(needle));
int ini = start-l+1;
char s[32];
while (i < l && i < 32) {
s[i] = styler.SafeGetCharAt(ini + i);
i++;
} }
s[i] = '\0'; s[i] = '\0';
return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0);
return (strcmp(s, needle) == 0);
} }
static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle, static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
@ -1181,39 +1235,51 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
styler.StartAt(startPos); styler.StartAt(startPos);
int state = initStyle; int state = initStyle;
char chNext = styler[startPos]; char chNext = styler.SafeGetCharAt(startPos);
styler.StartSegment(startPos); styler.StartSegment(startPos);
int lengthDoc = startPos + length; int lengthDoc = startPos + length;
char chVerbatimDelim = '\0';
for (int i = startPos; i < lengthDoc; i++) { for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext; char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
if (styler.IsLeadByte(ch)) { if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
i++; i++;
chNext = styler.SafeGetCharAt(i + 1);
continue; continue;
} }
switch (state) { switch (state) {
case SCE_L_DEFAULT : case SCE_L_DEFAULT :
switch (ch) { switch (ch) {
case '\\' : case '\\' :
styler.ColourTo(i - 1, state); styler.ColourTo(i - 1, state);
if (isSpecial(styler[i + 1])) { if (latexIsSpecial(chNext)) {
styler.ColourTo(i + 1, SCE_L_COMMAND); state = SCE_L_SPECIAL;
i++;
chNext = styler.SafeGetCharAt(i + 1);
} else { } else {
if (isTag(i + 1, styler)) if (latexIsLetter(chNext)) {
state = SCE_L_TAG;
else
state = SCE_L_COMMAND; state = SCE_L_COMMAND;
} else {
if (chNext == '(' || chNext == '[') {
styler.ColourTo(i-1, state);
styler.ColourTo(i+1, SCE_L_SHORTCMD);
state = SCE_L_MATH;
if (chNext == '[')
state = SCE_L_MATH2;
i++;
chNext = styler.SafeGetCharAt(i+1);
} else {
state = SCE_L_SHORTCMD;
}
}
} }
break; break;
case '$' : case '$' :
styler.ColourTo(i - 1, state); styler.ColourTo(i - 1, state);
state = SCE_L_MATH; state = SCE_L_MATH;
if (chNext == '$') { if (chNext == '$') {
state = SCE_L_MATH2;
i++; i++;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
} }
@ -1224,29 +1290,124 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
break; break;
} }
break; break;
case SCE_L_ERROR:
styler.ColourTo(i-1, state);
state = SCE_L_DEFAULT;
break;
case SCE_L_SPECIAL:
case SCE_L_SHORTCMD:
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
break;
case SCE_L_COMMAND : case SCE_L_COMMAND :
if (chNext == '[' || chNext == '{' || chNext == '}' || if (!latexIsLetter(chNext)) {
chNext == ' ' || chNext == '\r' || chNext == '\n') {
styler.ColourTo(i, state); styler.ColourTo(i, state);
state = SCE_L_DEFAULT; state = SCE_L_DEFAULT;
i++; if (latexNextNotBlankIs(i+1, lengthDoc, styler, '[' )) {
chNext = styler.SafeGetCharAt(i + 1); state = SCE_L_CMDOPT;
} else if (latexLastWordIs(i, styler, "\\begin")) {
state = SCE_L_TAG;
} else if (latexLastWordIs(i, styler, "\\end")) {
state = SCE_L_TAG2;
} else if (latexLastWordIs(i, styler, "\\verb") &&
chNext != '*' && chNext != ' ') {
chVerbatimDelim = chNext;
state = SCE_L_VERBATIM;
}
} }
break; break;
case SCE_L_CMDOPT :
if (ch == ']') {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
}
break;
case SCE_L_TAG : case SCE_L_TAG :
if (ch == '}') { if (latexIsTagValid(i, lengthDoc, styler)) {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
if (latexLastWordIs(i, styler, "{verbatim}")) {
state = SCE_L_VERBATIM;
} else if (latexLastWordIs(i, styler, "{comment}")) {
state = SCE_L_COMMENT2;
} else if (latexLastWordIs(i, styler, "{math}")) {
state = SCE_L_MATH;
} else if (latexLastWordIs(i, styler, "{displaymath}")) {
state = SCE_L_MATH2;
} else if (latexLastWordIs(i, styler, "{equation}")) {
state = SCE_L_MATH2;
}
} else {
state = SCE_L_ERROR;
styler.ColourTo(i, state); styler.ColourTo(i, state);
state = SCE_L_DEFAULT; state = SCE_L_DEFAULT;
} }
chNext = styler.SafeGetCharAt(i+1);
break;
case SCE_L_TAG2 :
if (latexIsTagValid(i, lengthDoc, styler)) {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
} else {
state = SCE_L_ERROR;
}
chNext = styler.SafeGetCharAt(i+1);
break; break;
case SCE_L_MATH : case SCE_L_MATH :
if (ch == '$') { if (ch == '$') {
if (chNext == '$') {
i++;
chNext = styler.SafeGetCharAt(i + 1);
}
styler.ColourTo(i, state); styler.ColourTo(i, state);
state = SCE_L_DEFAULT; state = SCE_L_DEFAULT;
} else if (ch == '\\' && chNext == ')') {
styler.ColourTo(i-1, state);
styler.ColourTo(i+1, SCE_L_SHORTCMD);
i++;
chNext = styler.SafeGetCharAt(i+1);
state = SCE_L_DEFAULT;
} else if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{math}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
}
break;
case SCE_L_MATH2 :
if (ch == '$') {
if (chNext == '$') {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
} else {
styler.ColourTo(i, SCE_L_ERROR);
state = SCE_L_DEFAULT;
}
} else if (ch == '\\' && chNext == ']') {
styler.ColourTo(i-1, state);
styler.ColourTo(i+1, SCE_L_SHORTCMD);
i++;
chNext = styler.SafeGetCharAt(i+1);
state = SCE_L_DEFAULT;
} else if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{displaymath}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
} else if (latexLastWordIs(match, styler, "{equation}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
} }
break; break;
case SCE_L_COMMENT : case SCE_L_COMMENT :
@ -1254,6 +1415,43 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
styler.ColourTo(i - 1, state); styler.ColourTo(i - 1, state);
state = SCE_L_DEFAULT; state = SCE_L_DEFAULT;
} }
break;
case SCE_L_COMMENT2 :
if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{comment}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
}
break;
case SCE_L_VERBATIM :
if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{verbatim}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
} else if (chNext == chVerbatimDelim) {
styler.ColourTo(i+1, state);
state = SCE_L_DEFAULT;
chVerbatimDelim = '\0';
} else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) {
styler.ColourTo(i, SCE_L_ERROR);
state = SCE_L_DEFAULT;
chVerbatimDelim = '\0';
}
break;
} }
} }
styler.ColourTo(lengthDoc-1, state); styler.ColourTo(lengthDoc-1, state);

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ using namespace Scintilla;
#endif #endif
/* kwCDef, kwCTypeName only used for Cython */ /* kwCDef, kwCTypeName only used for Cython */
enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName }; enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };
static const int indicatorWhitespace = 1; static const int indicatorWhitespace = 1;
@ -165,6 +165,11 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
// Set to 1 to allow strings to span newline characters. // Set to 1 to allow strings to span newline characters.
bool stringsOverNewline = styler.GetPropertyInt("lexer.python.strings.over.newline") != 0; bool stringsOverNewline = styler.GetPropertyInt("lexer.python.strings.over.newline") != 0;
// property lexer.python.keywords2.no.sub.identifiers
// When enabled, it will not style keywords2 items that are used as a sub-identifier.
// Example: when set, will not highlight "foo.open" when "open" is a keywords2 item.
const bool keywords2NoSubIdentifiers = styler.GetPropertyInt("lexer.python.keywords2.no.sub.identifiers") != 0;
initStyle = initStyle & 31; initStyle = initStyle & 31;
if (initStyle == SCE_P_STRINGEOL) { if (initStyle == SCE_P_STRINGEOL) {
initStyle = SCE_P_DEFAULT; initStyle = SCE_P_DEFAULT;
@ -246,7 +251,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
style = SCE_P_CLASSNAME; style = SCE_P_CLASSNAME;
} else if (kwLast == kwDef) { } else if (kwLast == kwDef) {
style = SCE_P_DEFNAME; style = SCE_P_DEFNAME;
} else if (kwLast == kwCDef) { } else if (kwLast == kwCDef || kwLast == kwCPDef) {
int pos = sc.currentPos; int pos = sc.currentPos;
unsigned char ch = styler.SafeGetCharAt(pos, '\0'); unsigned char ch = styler.SafeGetCharAt(pos, '\0');
while (ch != '\0') { while (ch != '\0') {
@ -264,7 +269,16 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
} }
} }
} else if (keywords2.InList(s)) { } else if (keywords2.InList(s)) {
style = SCE_P_WORD2; if (keywords2NoSubIdentifiers) {
// We don't want to highlight keywords2
// that are used as a sub-identifier,
// i.e. not open in "foo.open".
int pos = styler.GetStartSegment() - 1;
if (pos < 0 || (styler.SafeGetCharAt(pos, '\0') != '.'))
style = SCE_P_WORD2;
} else {
style = SCE_P_WORD2;
}
} }
sc.ChangeState(style); sc.ChangeState(style);
sc.SetState(SCE_P_DEFAULT); sc.SetState(SCE_P_DEFAULT);
@ -277,11 +291,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
kwLast = kwImport; kwLast = kwImport;
else if (0 == strcmp(s, "cdef")) else if (0 == strcmp(s, "cdef"))
kwLast = kwCDef; kwLast = kwCDef;
else if (0 == strcmp(s, "cpdef"))
kwLast = kwCPDef;
else if (0 == strcmp(s, "cimport")) else if (0 == strcmp(s, "cimport"))
kwLast = kwImport; kwLast = kwImport;
else if (kwLast != kwCDef) else if (kwLast != kwCDef && kwLast != kwCPDef)
kwLast = kwOther; kwLast = kwOther;
} else if (kwLast != kwCDef) { } else if (kwLast != kwCDef && kwLast != kwCPDef) {
kwLast = kwOther; kwLast = kwOther;
} }
} }
@ -337,8 +353,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
indentGood = true; indentGood = true;
} }
// One cdef line, clear kwLast only at end of line // One cdef or cpdef line, clear kwLast only at end of line
if (kwLast == kwCDef && sc.atLineEnd) { if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {
kwLast = kwOther; kwLast = kwOther;
} }
@ -412,12 +428,8 @@ static bool IsQuoteLine(int line, Accessor &styler) {
static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unused*/, static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unused*/,
WordList *[], Accessor &styler) { WordList *[], Accessor &styler) {
const int maxPos = startPos + length; const int maxPos = startPos + length;
const int maxLines = styler.GetLine(maxPos - 1); // Requested last line const int maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1); // Requested last line
const int docLines = styler.GetLine(styler.Length() - 1); // Available last line const int docLines = styler.GetLine(styler.Length()); // Available last line
// property fold.comment.python
// This option enables folding multi-line comments when using the Python lexer.
const bool foldComment = styler.GetPropertyInt("fold.comment.python") != 0;
// property fold.quotes.python // property fold.quotes.python
// This option enables folding multi-line quoted strings when using the Python lexer. // This option enables folding multi-line quoted strings when using the Python lexer.
@ -448,14 +460,11 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
if (lineCurrent >= 1) if (lineCurrent >= 1)
prev_state = styler.StyleAt(startPos - 1) & 31; prev_state = styler.StyleAt(startPos - 1) & 31;
int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE)); int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE));
int prevComment = 0;
if (lineCurrent >= 1)
prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
// Process all characters to end of requested range or end of any triple quote // Process all characters to end of requested range or end of any triple quote
// or comment that hangs over the end of the range. Cap processing in all cases //that hangs over the end of the range. Cap processing in all cases
// to end of document (in case of unclosed quote or comment at end). // to end of document (in case of unclosed quote at end).
while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote || prevComment)) { while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote)) {
// Gather info // Gather info
int lev = indentCurrent; int lev = indentCurrent;
@ -465,16 +474,13 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
if (lineNext <= docLines) { if (lineNext <= docLines) {
// Information about next line is only available if not at end of document // Information about next line is only available if not at end of document
indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
int style = styler.StyleAt(styler.LineStart(lineNext)) & 31; int lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext);
int style = styler.StyleAt(lookAtPos) & 31;
quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE)); quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
} }
const int quote_start = (quote && !prevQuote); const int quote_start = (quote && !prevQuote);
const int quote_continue = (quote && prevQuote); const int quote_continue = (quote && prevQuote);
const int comment = foldComment && IsCommentLine(lineCurrent, styler); if (!quote || !prevQuote)
const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));
const int comment_continue = (comment && prevComment);
if ((!quote || !prevQuote) && !comment)
indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
if (quote) if (quote)
indentNext = indentCurrentLevel; indentNext = indentCurrentLevel;
@ -487,12 +493,6 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
} else if (quote_continue || prevQuote) { } else if (quote_continue || prevQuote) {
// Add level to rest of lines in the string // Add level to rest of lines in the string
lev = lev + 1; lev = lev + 1;
} else if (comment_start) {
// Place fold point at start of a block of comments
lev |= SC_FOLDLEVELHEADERFLAG;
} else if (comment_continue) {
// Add level to rest of lines in the block
lev = lev + 1;
} }
// Skip past any blank lines for next indent level info; we skip also // Skip past any blank lines for next indent level info; we skip also
@ -540,18 +540,17 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
} }
} }
// Set fold header on non-quote/non-comment line // Set fold header on non-quote line
if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { if (!quote && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
lev |= SC_FOLDLEVELHEADERFLAG; lev |= SC_FOLDLEVELHEADERFLAG;
} }
// Keep track of triple quote and block comment state of previous line // Keep track of triple quote state of previous line
prevQuote = quote; prevQuote = quote;
prevComment = comment_start || comment_continue;
// Set fold level for this line and move to next line // Set fold level for this line and move to next line
styler.SetLevel(lineCurrent, lev); styler.SetLevel(lineCurrent, foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);
indentCurrent = indentNext; indentCurrent = indentNext;
lineCurrent = lineNext; lineCurrent = lineNext;
} }

View File

@ -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"
@ -1729,7 +1728,13 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
) { ) {
levelCurrent++; levelCurrent++;
} }
} } else if (style == SCE_RB_HERE_DELIM) {
if (styler.SafeGetCharAt(i-2) == '<' && styler.SafeGetCharAt(i-1) == '<') {
levelCurrent++;
} else if (styleNext == SCE_RB_DEFAULT) {
levelCurrent--;
}
}
if (atEOL) { if (atEOL) {
int lev = levelPrev; int lev = levelPrev;
if (visibleChars == 0 && foldCompact) if (visibleChars == 0 && foldCompact)
@ -1765,4 +1770,4 @@ static const char * const rubyWordListDesc[] = {
0 0
}; };
LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc); LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc, 6);

View File

@ -204,8 +204,8 @@ struct OptionSetSQL : public OptionSet<OptionsSQL> {
OptionSetSQL() { OptionSetSQL() {
DefineProperty("fold", &OptionsSQL::fold); DefineProperty("fold", &OptionsSQL::fold);
DefineProperty("lexer.sql.fold.at.else", &OptionsSQL::foldAtElse, DefineProperty("fold.sql.at.else", &OptionsSQL::foldAtElse,
"This option enables SQL folding on a \"ELSE\" and \"ELSIF\"line of an IF statement."); "This option enables SQL folding on a \"ELSE\" and \"ELSIF\" line of an IF statement.");
DefineProperty("fold.comment", &OptionsSQL::foldComment); DefineProperty("fold.comment", &OptionsSQL::foldComment);
@ -283,6 +283,20 @@ private:
style == SCE_SQL_COMMENTDOCKEYWORDERROR; style == SCE_SQL_COMMENTDOCKEYWORDERROR;
} }
bool IsCommentStyle (int style) {
switch (style) {
case SCE_SQL_COMMENT :
case SCE_SQL_COMMENTDOC :
case SCE_SQL_COMMENTLINE :
case SCE_SQL_COMMENTLINEDOC :
case SCE_SQL_COMMENTDOCKEYWORD :
case SCE_SQL_COMMENTDOCKEYWORDERROR :
return true;
default :
return false;
}
}
OptionsSQL options; OptionsSQL options;
OptionSetSQL osSQL; OptionSetSQL osSQL;
SQLStates sqlStates; SQLStates sqlStates;
@ -521,7 +535,7 @@ void SCI_METHOD LexerSQL::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 (atEOL || (ch == ';')) { if (atEOL || (!IsCommentStyle(style) && ch == ';')) {
if (endFound) { if (endFound) {
//Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;") //Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;")
sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false); sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false);
@ -554,7 +568,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
if (ch == '(') { if (ch == '(') {
if (levelCurrent > levelNext) if (levelCurrent > levelNext)
levelCurrent--; levelCurrent--;
levelNext++; levelNext++;
} else if (ch == ')') { } else if (ch == ')') {
levelNext--; levelNext--;
} else if ((!options.foldOnlyBegin) && ch == ';') { } else if ((!options.foldOnlyBegin) && ch == ';') {

View File

@ -235,7 +235,7 @@ static void FoldNoBoxVHDLDoc(
} }
} }
} }
for(j=j+strlen(prevWord); j<endPos; j++) for(j=j+static_cast<unsigned int>(strlen(prevWord)); j<endPos; j++)
{ {
char ch = styler.SafeGetCharAt(j); char ch = styler.SafeGetCharAt(j);
int style = styler.StyleAt(j); int style = styler.StyleAt(j);

View File

@ -29,7 +29,7 @@ using namespace Scintilla;
#endif #endif
static inline bool IsAWordChar(const int ch) { static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\''); return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\''|| ch == '$');
} }
static inline bool IsAWordStart(const int ch) { static inline bool IsAWordStart(const int ch) {
@ -269,24 +269,36 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
if (styler.Match(j, "case") || if (styler.Match(j, "case") ||
styler.Match(j, "casex") || styler.Match(j, "casex") ||
styler.Match(j, "casez") || styler.Match(j, "casez") ||
styler.Match(j, "class") ||
styler.Match(j, "function") || styler.Match(j, "function") ||
styler.Match(j, "fork") || styler.Match(j, "generate") ||
styler.Match(j, "covergroup") ||
styler.Match(j, "package") ||
styler.Match(j, "primitive") ||
styler.Match(j, "program") ||
styler.Match(j, "sequence") ||
styler.Match(j, "specify") ||
styler.Match(j, "table") || styler.Match(j, "table") ||
styler.Match(j, "task") || styler.Match(j, "task") ||
styler.Match(j, "generate") || styler.Match(j, "fork") ||
styler.Match(j, "specify") ||
styler.Match(j, "primitive") ||
(styler.Match(j, "module") && foldAtModule) || (styler.Match(j, "module") && foldAtModule) ||
styler.Match(j, "begin")) { styler.Match(j, "begin")) {
levelNext++; levelNext++;
} else if (styler.Match(j, "endcase") || } else if (styler.Match(j, "endcase") ||
styler.Match(j, "endclass") ||
styler.Match(j, "endfunction") || styler.Match(j, "endfunction") ||
styler.Match(j, "join") ||
styler.Match(j, "endtask") ||
styler.Match(j, "endgenerate") || styler.Match(j, "endgenerate") ||
styler.Match(j, "endtable") || styler.Match(j, "endgroup") ||
styler.Match(j, "endspecify") || styler.Match(j, "endpackage") ||
styler.Match(j, "endprimitive") || styler.Match(j, "endprimitive") ||
styler.Match(j, "endprogram") ||
styler.Match(j, "endsequence") ||
styler.Match(j, "endspecify") ||
styler.Match(j, "endtable") ||
styler.Match(j, "endtask") ||
styler.Match(j, "join") ||
styler.Match(j, "join_any") ||
styler.Match(j, "join_none") ||
(styler.Match(j, "endmodule") && foldAtModule) || (styler.Match(j, "endmodule") && foldAtModule) ||
(styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) { (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) {
levelNext--; levelNext--;

View File

@ -71,7 +71,7 @@ int Accessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsComment
*flags = spaceFlags; *flags = spaceFlags;
indent += SC_FOLDLEVELBASE; indent += SC_FOLDLEVELBASE;
// if completely empty line or the start of a comment... // if completely empty line or the start of a comment...
if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') || if ((LineStart(line) == Length()) || (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
(pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos))) (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)))
return indent | SC_FOLDLEVELWHITEFLAG; return indent | SC_FOLDLEVELWHITEFLAG;
else else

View File

@ -119,7 +119,6 @@ inline bool iswordstart(int ch) {
inline bool isoperator(int ch) { inline bool isoperator(int ch) {
if (IsASCII(ch) && IsAlphaNumeric(ch)) if (IsASCII(ch) && IsAlphaNumeric(ch))
return false; return false;
// '.' left out as it is used to make up numbers
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '(' || ch == ')' || ch == '-' || ch == '+' || ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
ch == '=' || ch == '|' || ch == '{' || ch == '}' || ch == '=' || ch == '|' || ch == '{' || ch == '}' ||

View File

@ -61,9 +61,10 @@ void PropSetSimple::Set(const char *keyVal) {
endVal++; endVal++;
const char *eqAt = strchr(keyVal, '='); const char *eqAt = strchr(keyVal, '=');
if (eqAt) { if (eqAt) {
Set(keyVal, eqAt + 1, eqAt-keyVal, endVal - eqAt - 1); Set(keyVal, eqAt + 1, static_cast<int>(eqAt-keyVal),
static_cast<int>(endVal - eqAt - 1));
} else if (*keyVal) { // No '=' so assume '=1' } else if (*keyVal) { // No '=' so assume '=1'
Set(keyVal, "1", endVal-keyVal, 1); Set(keyVal, "1", static_cast<int>(endVal-keyVal), 1);
} }
} }
@ -150,7 +151,7 @@ char *PropSetSimple::Expanded(const char *key) const {
int PropSetSimple::GetExpanded(const char *key, char *result) const { int PropSetSimple::GetExpanded(const char *key, char *result) const {
char *val = Expanded(key); char *val = Expanded(key);
const int n = strlen(val); const int n = static_cast<int>(strlen(val));
if (result) { if (result) {
strcpy(result, val); strcpy(result, val);
} }

View File

@ -43,12 +43,12 @@ public:
} }
void Set(int position, T value) { void Set(int position, T value) {
Delete(position); Delete(position);
if ((states.size() == 0) || (value != states[states.size()-1].value)) { if (states.empty() || (value != states[states.size()-1].value)) {
states.push_back(State(position, value)); states.push_back(State(position, value));
} }
} }
T ValueAt(int position) { T ValueAt(int position) {
if (!states.size()) if (states.empty())
return T(); return T();
if (position < states[0].position) if (position < states[0].position)
return T(); return T();
@ -92,7 +92,7 @@ public:
changed = true; changed = true;
} }
typename stateVector::const_iterator startOther = other.states.begin(); typename stateVector::const_iterator startOther = other.states.begin();
if (!states.empty() && states.back().value == startOther->value) if (!states.empty() && !other.states.empty() && states.back().value == startOther->value)
++startOther; ++startOther;
if (startOther != other.states.end()) { if (startOther != other.states.end()) {
states.insert(states.end(), startOther, other.states.end()); states.insert(states.end(), startOther, other.states.end());

View File

@ -55,7 +55,6 @@ public:
styler(styler_), styler(styler_),
endPos(startPos + length), endPos(startPos + length),
currentPos(startPos), currentPos(startPos),
atLineStart(true),
atLineEnd(false), atLineEnd(false),
state(initStyle & chMask), // Mask off all bits which aren't in the chMask. state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
chPrev(0), chPrev(0),
@ -63,6 +62,7 @@ public:
chNext(0) { chNext(0) {
styler.StartAt(startPos, chMask); styler.StartAt(startPos, chMask);
styler.StartSegment(startPos); styler.StartSegment(startPos);
atLineStart = static_cast<unsigned int>(styler.LineStart(styler.GetLine(startPos))) == startPos;
unsigned int pos = currentPos; unsigned int pos = currentPos;
ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos)); ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
if (styler.IsLeadByte(static_cast<char>(ch))) { if (styler.IsLeadByte(static_cast<char>(ch))) {

View File

@ -11,6 +11,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <algorithm>
#include "WordList.h" #include "WordList.h"
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE
@ -86,22 +88,34 @@ void WordList::Clear() {
len = 0; len = 0;
} }
extern "C" int cmpString(const void *a1, const void *a2) { #ifdef _MSC_VER
// Can't work out the correct incantation to use modern casts here
return strcmp(*(char **)(a1), *(char **)(a2)); static bool cmpWords(const char *a, const char *b) {
return strcmp(a, b) == -1;
}
#else
static int cmpWords(const void *a, const void *b) {
return strcmp(*static_cast<const char * const *>(a), *static_cast<const char * const *>(b));
} }
static void SortWordList(char **words, unsigned int len) { static void SortWordList(char **words, unsigned int len) {
qsort(reinterpret_cast<void *>(words), len, sizeof(*words), qsort(reinterpret_cast<void *>(words), len, sizeof(*words), cmpWords);
cmpString);
} }
#endif
void WordList::Set(const char *s) { void WordList::Set(const char *s) {
Clear(); Clear();
list = new char[strlen(s) + 1]; list = new char[strlen(s) + 1];
strcpy(list, s); strcpy(list, s);
words = ArrayFromWordList(list, &len, onlyLineEnds); words = ArrayFromWordList(list, &len, onlyLineEnds);
#ifdef _MSC_VER
std::sort(words, words + len, cmpWords);
#else
SortWordList(words, len); SortWordList(words, len);
#endif
for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++) for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1; starts[k] = -1;
for (int l = len - 1; l >= 0; l--) { for (int l = len - 1; l >= 0; l--) {
@ -121,7 +135,7 @@ bool WordList::InList(const char *s) const {
unsigned char firstChar = s[0]; unsigned char firstChar = s[0];
int j = starts[firstChar]; int j = starts[firstChar];
if (j >= 0) { if (j >= 0) {
while ((unsigned char)words[j][0] == firstChar) { while (static_cast<unsigned char>(words[j][0]) == firstChar) {
if (s[1] == words[j][1]) { if (s[1] == words[j][1]) {
const char *a = words[j] + 1; const char *a = words[j] + 1;
const char *b = s + 1; const char *b = s + 1;
@ -163,7 +177,7 @@ bool WordList::InListAbbreviated(const char *s, const char marker) const {
unsigned char firstChar = s[0]; unsigned char firstChar = s[0];
int j = starts[firstChar]; int j = starts[firstChar];
if (j >= 0) { if (j >= 0) {
while (words[j][0] == firstChar) { while (static_cast<unsigned char>(words[j][0]) == firstChar) {
bool isSubword = false; bool isSubword = false;
int start = 1; int start = 1;
if (words[j][1] == marker) { if (words[j][1] == marker) {

View File

@ -1,4 +1,4 @@
A patch to Scintilla 2.25 containing our changes to Scintilla A patch to Scintilla 2.29 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-10-27 23:15:45.000000000 +0200 --- scintilla_orig/gtk/scintilla-marshal.c 2010-10-27 23:15:45.000000000 +0200

View File

@ -100,7 +100,7 @@ void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
int ends[numEnds + 2]; int ends[numEnds + 2];
for (int i=0; i<len; i++) { for (int i=0; i<len; i++) {
if ((maxEnd < numEnds) && if ((maxEnd < numEnds) &&
(IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) ) { (IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) {
if (i > 0) if (i > 0)
ends[maxEnd++] = i; ends[maxEnd++] = i;
ends[maxEnd++] = i+1; ends[maxEnd++] = i+1;

View File

@ -168,6 +168,14 @@ bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible
} }
} }
bool ContractionState::HiddenLines() const {
if (OneToOne()) {
return false;
} else {
return !visible->AllSameAs(1);
}
}
bool ContractionState::GetExpanded(int lineDoc) const { bool ContractionState::GetExpanded(int lineDoc) const {
if (OneToOne()) { if (OneToOne()) {
return true; return true;
@ -223,7 +231,7 @@ int ContractionState::GetHeight(int lineDoc) const {
bool ContractionState::SetHeight(int lineDoc, int height) { bool ContractionState::SetHeight(int lineDoc, int height) {
if (OneToOne() && (height == 1)) { if (OneToOne() && (height == 1)) {
return false; return false;
} else { } else if (lineDoc < LinesInDoc()) {
EnsureData(); EnsureData();
if (GetHeight(lineDoc) != height) { if (GetHeight(lineDoc) != height) {
if (GetVisible(lineDoc)) { if (GetVisible(lineDoc)) {
@ -236,6 +244,8 @@ bool ContractionState::SetHeight(int lineDoc, int height) {
Check(); Check();
return false; return false;
} }
} else {
return false;
} }
} }

View File

@ -48,6 +48,7 @@ public:
bool GetVisible(int lineDoc) const; bool GetVisible(int lineDoc) const;
bool SetVisible(int lineDocStart, int lineDocEnd, bool visible); bool SetVisible(int lineDocStart, int lineDocEnd, bool visible);
bool HiddenLines() const;
bool GetExpanded(int lineDoc) const; bool GetExpanded(int lineDoc) const;
bool SetExpanded(int lineDoc, bool expanded); bool SetExpanded(int lineDoc, bool expanded);

View File

@ -28,7 +28,7 @@ Decoration::~Decoration() {
} }
bool Decoration::Empty() { bool Decoration::Empty() {
return rs.starts->Partitions() == 1; return rs.Runs() == 1;
} }
DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0), DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0),
@ -126,9 +126,13 @@ bool DecorationList::FillRange(int &position, int value, int &fillLength) {
} }
void DecorationList::InsertSpace(int position, int insertLength) { void DecorationList::InsertSpace(int position, int insertLength) {
const bool atEnd = position == lengthDocument;
lengthDocument += insertLength; lengthDocument += insertLength;
for (Decoration *deco=root; deco; deco = deco->next) { for (Decoration *deco=root; deco; deco = deco->next) {
deco->rs.InsertSpace(position, insertLength); deco->rs.InsertSpace(position, insertLength);
if (atEnd) {
deco->rs.FillRange(position, 0, insertLength);
}
} }
} }

View File

@ -2,7 +2,7 @@
/** @file Document.cxx /** @file Document.cxx
** Text document that handles notifications, DBCS, styling, words and end of line. ** Text document that handles notifications, DBCS, styling, words and end of line.
**/ **/
// Copyright 1998-2003 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>
@ -87,10 +87,10 @@ void LexInterface::Colourise(int start, int end) {
Document::Document() { Document::Document() {
refCount = 0; refCount = 0;
#ifdef __unix__ #ifdef _WIN32
eolMode = SC_EOL_LF;
#else
eolMode = SC_EOL_CRLF; eolMode = SC_EOL_CRLF;
#else
eolMode = SC_EOL_LF;
#endif #endif
dbcsCodePage = 0; dbcsCodePage = 0;
stylingBits = 5; stylingBits = 5;
@ -316,15 +316,18 @@ static bool IsSubordinate(int levelStart, int levelTry) {
return (levelStart & SC_FOLDLEVELNUMBERMASK) < (levelTry & SC_FOLDLEVELNUMBERMASK); return (levelStart & SC_FOLDLEVELNUMBERMASK) < (levelTry & SC_FOLDLEVELNUMBERMASK);
} }
int Document::GetLastChild(int lineParent, int level) { int Document::GetLastChild(int lineParent, int level, int lastLine) {
if (level == -1) if (level == -1)
level = GetLevel(lineParent) & SC_FOLDLEVELNUMBERMASK; level = GetLevel(lineParent) & SC_FOLDLEVELNUMBERMASK;
int maxLine = LinesTotal(); int maxLine = LinesTotal();
int lookLastLine = (lastLine != -1) ? Platform::Minimum(LinesTotal() - 1, lastLine) : -1;
int lineMaxSubord = lineParent; int lineMaxSubord = lineParent;
while (lineMaxSubord < maxLine - 1) { while (lineMaxSubord < maxLine - 1) {
EnsureStyledTo(LineStart(lineMaxSubord + 2)); EnsureStyledTo(LineStart(lineMaxSubord + 2));
if (!IsSubordinate(level, GetLevel(lineMaxSubord + 1))) if (!IsSubordinate(level, GetLevel(lineMaxSubord + 1)))
break; break;
if ((lookLastLine != -1) && (lineMaxSubord >= lookLastLine) && !(GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG))
break;
lineMaxSubord++; lineMaxSubord++;
} }
if (lineMaxSubord > lineParent) { if (lineMaxSubord > lineParent) {
@ -355,6 +358,76 @@ int Document::GetFoldParent(int line) {
} }
} }
void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, int line, int lastLine) {
int level = GetLevel(line);
int lookLastLine = Platform::Maximum(line, lastLine) + 1;
int lookLine = line;
int lookLineLevel = level;
int lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
while ((lookLine > 0) && ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) ||
((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum >= (GetLevel(lookLine + 1) & SC_FOLDLEVELNUMBERMASK))))) {
lookLineLevel = GetLevel(--lookLine);
lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
}
int beginFoldBlock = (lookLineLevel & SC_FOLDLEVELHEADERFLAG) ? lookLine : GetFoldParent(lookLine);
if (beginFoldBlock == -1) {
highlightDelimiter.Clear();
return;
}
int endFoldBlock = GetLastChild(beginFoldBlock, -1, lookLastLine);
int firstChangeableLineBefore = -1;
if (endFoldBlock < line) {
lookLine = beginFoldBlock - 1;
lookLineLevel = GetLevel(lookLine);
lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
while ((lookLine >= 0) && (lookLineLevelNum >= SC_FOLDLEVELBASE)) {
if (lookLineLevel & SC_FOLDLEVELHEADERFLAG) {
if (GetLastChild(lookLine, -1, lookLastLine) == line) {
beginFoldBlock = lookLine;
endFoldBlock = line;
firstChangeableLineBefore = line - 1;
}
}
if ((lookLine > 0) && (lookLineLevelNum == SC_FOLDLEVELBASE) && ((GetLevel(lookLine - 1) & SC_FOLDLEVELNUMBERMASK) > lookLineLevelNum))
break;
lookLineLevel = GetLevel(--lookLine);
lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
}
}
if (firstChangeableLineBefore == -1) {
for (lookLine = line - 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
lookLine >= beginFoldBlock;
lookLineLevel = GetLevel(--lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK) {
if ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) || (lookLineLevelNum > (level & SC_FOLDLEVELNUMBERMASK))) {
firstChangeableLineBefore = lookLine;
break;
}
}
}
if (firstChangeableLineBefore == -1)
firstChangeableLineBefore = beginFoldBlock - 1;
int firstChangeableLineAfter = -1;
for (lookLine = line + 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
lookLine <= endFoldBlock;
lookLineLevel = GetLevel(++lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK) {
if ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum < (GetLevel(lookLine + 1) & SC_FOLDLEVELNUMBERMASK))) {
firstChangeableLineAfter = lookLine;
break;
}
}
if (firstChangeableLineAfter == -1)
firstChangeableLineAfter = endFoldBlock + 1;
highlightDelimiter.beginFoldBlock = beginFoldBlock;
highlightDelimiter.endFoldBlock = endFoldBlock;
highlightDelimiter.firstChangeableLineBefore = firstChangeableLineBefore;
highlightDelimiter.firstChangeableLineAfter = firstChangeableLineAfter;
}
int Document::ClampPositionIntoDocument(int pos) { int Document::ClampPositionIntoDocument(int pos) {
return Platform::Clamp(pos, 0, Length()); return Platform::Clamp(pos, 0, Length());
} }
@ -589,7 +662,8 @@ bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
case 932: case 932:
// Shift_jis // Shift_jis
return ((uch >= 0x81) && (uch <= 0x9F)) || return ((uch >= 0x81) && (uch <= 0x9F)) ||
((uch >= 0xE0) && (uch <= 0xEF)); ((uch >= 0xE0) && (uch <= 0xFC));
// Lead bytes F0 to FC may be a Microsoft addition.
case 936: case 936:
// GBK // GBK
return (uch >= 0x81) && (uch <= 0xFE); return (uch >= 0x81) && (uch <= 0xFE);
@ -609,6 +683,55 @@ bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
return false; return false;
} }
inline bool IsSpaceOrTab(int ch) {
return ch == ' ' || ch == '\t';
}
// Need to break text into segments near lengthSegment but taking into
// account the encoding to not break inside a UTF-8 or DBCS character
// and also trying to avoid breaking inside a pair of combining characters.
// The segment length must always be long enough (more than 4 bytes)
// so that there will be at least one whole character to make a segment.
// For UTF-8, text must consist only of valid whole characters.
// In preference order from best to worst:
// 1) Break after space
// 2) Break before punctuation
// 3) Break after whole character
int Document::SafeSegment(const char *text, int length, int lengthSegment) {
if (length <= lengthSegment)
return length;
int lastSpaceBreak = -1;
int lastPunctuationBreak = -1;
int lastEncodingAllowedBreak = -1;
for (int j=0; j < lengthSegment;) {
unsigned char ch = static_cast<unsigned char>(text[j]);
if (j > 0) {
if (IsSpaceOrTab(text[j - 1]) && !IsSpaceOrTab(text[j])) {
lastSpaceBreak = j;
}
if (ch < 'A') {
lastPunctuationBreak = j;
}
}
lastEncodingAllowedBreak = j;
if (dbcsCodePage == SC_CP_UTF8) {
j += (ch < 0x80) ? 1 : BytesFromLead(ch);
} else if (dbcsCodePage) {
j += IsDBCSLeadByte(ch) ? 2 : 1;
} else {
j++;
}
}
if (lastSpaceBreak >= 0) {
return lastSpaceBreak;
} else if (lastPunctuationBreak >= 0) {
return lastPunctuationBreak;
}
return lastEncodingAllowedBreak;
}
void Document::ModifiedAt(int pos) { void Document::ModifiedAt(int pos) {
if (endStyled > pos) if (endStyled > pos)
endStyled = pos; endStyled = pos;
@ -833,7 +956,7 @@ bool Document::InsertChar(int pos, char ch) {
* Insert a null terminated string. * Insert a null terminated string.
*/ */
bool Document::InsertCString(int position, const char *s) { bool Document::InsertCString(int position, const char *s) {
return InsertString(position, s, strlen(s)); return InsertString(position, s, static_cast<int>(strlen(s)));
} }
void Document::ChangeChar(int pos, char ch) { void Document::ChangeChar(int pos, char ch) {
@ -990,17 +1113,17 @@ void Document::Indent(bool forwards, int lineBottom, int lineTop) {
// Convert line endings for a piece of text to a particular mode. // Convert line endings for a piece of text to a particular mode.
// Stop at len or when a NUL is found. // Stop at len or when a NUL is found.
// Caller must delete the returned pointer. // Caller must delete the returned pointer.
char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode) { char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolModeWanted) {
char *dest = new char[2 * len + 1]; char *dest = new char[2 * len + 1];
const char *sptr = s; const char *sptr = s;
char *dptr = dest; char *dptr = dest;
for (size_t i = 0; (i < len) && (*sptr != '\0'); i++) { for (size_t i = 0; (i < len) && (*sptr != '\0'); i++) {
if (*sptr == '\n' || *sptr == '\r') { if (*sptr == '\n' || *sptr == '\r') {
if (eolMode == SC_EOL_CR) { if (eolModeWanted == SC_EOL_CR) {
*dptr++ = '\r'; *dptr++ = '\r';
} else if (eolMode == SC_EOL_LF) { } else if (eolModeWanted == SC_EOL_LF) {
*dptr++ = '\n'; *dptr++ = '\n';
} else { // eolMode == SC_EOL_CRLF } else { // eolModeWanted == SC_EOL_CRLF
*dptr++ = '\r'; *dptr++ = '\r';
*dptr++ = '\n'; *dptr++ = '\n';
} }
@ -1232,7 +1355,7 @@ size_t Document::ExtractChar(int pos, char *bytes) {
size_t widthChar = UTF8CharLength(ch); size_t widthChar = UTF8CharLength(ch);
bytes[0] = ch; bytes[0] = ch;
for (size_t i=1; i<widthChar; i++) { for (size_t i=1; i<widthChar; i++) {
bytes[i] = cb.CharAt(pos+i); bytes[i] = cb.CharAt(static_cast<int>(pos+i));
if (!GoodTrailByte(static_cast<unsigned char>(bytes[i]))) { // Bad byte if (!GoodTrailByte(static_cast<unsigned char>(bytes[i]))) { // Bad byte
widthChar = 1; widthChar = 1;
} }
@ -1305,7 +1428,6 @@ long Document::FindText(int minPos, int maxPos, const char *search,
// Compute actual search ranges needed // Compute actual search ranges needed
const int lengthFind = (*length == -1) ? static_cast<int>(strlen(search)) : *length; const int lengthFind = (*length == -1) ? static_cast<int>(strlen(search)) : *length;
const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
//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);
@ -1315,6 +1437,7 @@ long Document::FindText(int minPos, int maxPos, const char *search,
pos = NextPosition(pos, increment); pos = NextPosition(pos, increment);
} }
if (caseSensitive) { if (caseSensitive) {
const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
while (forward ? (pos < endSearch) : (pos >= endSearch)) { while (forward ? (pos < endSearch) : (pos >= endSearch)) {
bool found = (pos + lengthFind) <= limitPos; bool found = (pos + lengthFind) <= limitPos;
for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) { for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) {
@ -1330,8 +1453,9 @@ long Document::FindText(int minPos, int maxPos, const char *search,
const size_t maxBytesCharacter = 4; const size_t maxBytesCharacter = 4;
const size_t maxFoldingExpansion = 4; const size_t maxFoldingExpansion = 4;
std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1); std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind); const int lenSearch = static_cast<int>(
while (forward ? (pos < endSearch) : (pos >= endSearch)) { pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind));
while (forward ? (pos < endPos) : (pos >= endPos)) {
int widthFirstCharacter = 0; int widthFirstCharacter = 0;
int indexDocument = 0; int indexDocument = 0;
int indexSearch = 0; int indexSearch = 0;
@ -1341,11 +1465,13 @@ long Document::FindText(int minPos, int maxPos, const char *search,
(indexSearch < lenSearch)) { (indexSearch < lenSearch)) {
char bytes[maxBytesCharacter + 1]; char bytes[maxBytesCharacter + 1];
bytes[maxBytesCharacter] = 0; bytes[maxBytesCharacter] = 0;
const int widthChar = ExtractChar(pos + indexDocument, bytes); const int widthChar = static_cast<int>(ExtractChar(pos + indexDocument, bytes));
if (!widthFirstCharacter) if (!widthFirstCharacter)
widthFirstCharacter = widthChar; widthFirstCharacter = widthChar;
if ((pos + indexDocument + widthChar) > limitPos)
break;
char folded[maxBytesCharacter * maxFoldingExpansion + 1]; char folded[maxBytesCharacter * maxFoldingExpansion + 1];
const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar); const int lenFlat = static_cast<int>(pcf->Fold(folded, sizeof(folded), bytes, widthChar));
folded[lenFlat] = 0; folded[lenFlat] = 0;
// Does folded match the buffer // Does folded match the buffer
characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat); characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
@ -1369,8 +1495,9 @@ long Document::FindText(int minPos, int maxPos, const char *search,
const size_t maxBytesCharacter = 2; const size_t maxBytesCharacter = 2;
const size_t maxFoldingExpansion = 4; const size_t maxFoldingExpansion = 4;
std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1); std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind); const int lenSearch = static_cast<int>(
while (forward ? (pos < endSearch) : (pos >= endSearch)) { pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind));
while (forward ? (pos < endPos) : (pos >= endPos)) {
int indexDocument = 0; int indexDocument = 0;
int indexSearch = 0; int indexSearch = 0;
bool characterMatches = true; bool characterMatches = true;
@ -1382,8 +1509,10 @@ long Document::FindText(int minPos, int maxPos, const char *search,
const int widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1; const int widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1;
if (widthChar == 2) if (widthChar == 2)
bytes[1] = cb.CharAt(pos + indexDocument + 1); bytes[1] = cb.CharAt(pos + indexDocument + 1);
if ((pos + indexDocument + widthChar) > limitPos)
break;
char folded[maxBytesCharacter * maxFoldingExpansion + 1]; char folded[maxBytesCharacter * maxFoldingExpansion + 1];
const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar); const int lenFlat = static_cast<int>(pcf->Fold(folded, sizeof(folded), bytes, widthChar));
folded[lenFlat] = 0; folded[lenFlat] = 0;
// Does folded match the buffer // Does folded match the buffer
characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat); characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
@ -1400,7 +1529,7 @@ long Document::FindText(int minPos, int maxPos, const char *search,
break; break;
} }
} else { } else {
CaseFolderTable caseFolder; const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
std::vector<char> searchThing(lengthFind + 1); std::vector<char> searchThing(lengthFind + 1);
pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind); pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
while (forward ? (pos < endSearch) : (pos >= endSearch)) { while (forward ? (pos < endSearch) : (pos >= endSearch)) {
@ -1950,10 +2079,17 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
// the start position is at end of line or between line end characters. // the start position is at end of line or between line end characters.
lineRangeStart++; lineRangeStart++;
startPos = doc->LineStart(lineRangeStart); startPos = doc->LineStart(lineRangeStart);
} else if ((increment == -1) &&
(startPos <= doc->LineStart(lineRangeStart)) &&
(lineRangeStart > lineRangeEnd)) {
// the start position is at beginning of line.
lineRangeStart--;
startPos = doc->LineEnd(lineRangeStart);
} }
int pos = -1; int pos = -1;
int lenRet = 0; int lenRet = 0;
char searchEnd = s[*length - 1]; char searchEnd = s[*length - 1];
char searchEndPrev = (*length > 1) ? s[*length - 2] : '\0';
int lineRangeBreak = lineRangeEnd + increment; int lineRangeBreak = lineRangeEnd + increment;
for (int line = lineRangeStart; line != lineRangeBreak; line += increment) { for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {
int startOfLine = doc->LineStart(line); int startOfLine = doc->LineStart(line);
@ -1965,7 +2101,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
startOfLine = startPos; startOfLine = startPos;
} }
if (line == lineRangeEnd) { if (line == lineRangeEnd) {
if ((endPos != endOfLine) && (searchEnd == '$')) if ((endPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\'))
continue; // Can't match end of line if end position before end of line continue; // Can't match end of line if end position before end of line
endOfLine = endPos; endOfLine = endPos;
} }
@ -1976,7 +2112,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
startOfLine = endPos; startOfLine = endPos;
} }
if (line == lineRangeStart) { if (line == lineRangeStart) {
if ((startPos != endOfLine) && (searchEnd == '$')) if ((startPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\'))
continue; // Can't match end of line if start position before end of line continue; // Can't match end of line if start position before end of line
endOfLine = startPos; endOfLine = startPos;
} }
@ -1987,7 +2123,8 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
if (success) { if (success) {
pos = search.bopat[0]; pos = search.bopat[0];
lenRet = search.eopat[0] - search.bopat[0]; lenRet = search.eopat[0] - search.bopat[0];
if (increment == -1) { // There can be only one start of a line, so no need to look for last match in line
if ((increment == -1) && (s[0] != '^')) {
// Check for the last match on this line. // Check for the last match on this line.
int repetitions = 1000; // Break out of infinite loop int repetitions = 1000; // Break out of infinite loop
while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) { while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) {

View File

@ -2,7 +2,7 @@
/** @file Document.h /** @file Document.h
** Text document that handles notifications, DBCS, styling, words and end of line. ** Text document that handles notifications, DBCS, styling, words and end of line.
**/ **/
// Copyright 1998-2003 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.
#ifndef DOCUMENT_H #ifndef DOCUMENT_H
@ -115,6 +115,46 @@ struct StyledText {
} }
}; };
class HighlightDelimiter {
public:
HighlightDelimiter() : isEnabled(false) {
Clear();
}
void Clear() {
beginFoldBlock = -1;
endFoldBlock = -1;
firstChangeableLineBefore = -1;
firstChangeableLineAfter = -1;
}
bool NeedsDrawing(int line) {
return isEnabled && (line <= firstChangeableLineBefore || line >= firstChangeableLineAfter);
}
bool IsFoldBlockHighlighted(int line) {
return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock;
}
bool IsHeadOfFoldBlock(int line) {
return beginFoldBlock == line && line < endFoldBlock;
}
bool IsBodyOfFoldBlock(int line) {
return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock;
}
bool IsTailOfFoldBlock(int line) {
return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock;
}
int beginFoldBlock; // Begin of current fold block
int endFoldBlock; // End of current fold block
int firstChangeableLineBefore; // First line that triggers repaint before starting line that determined current fold block
int firstChangeableLineAfter; // First line that triggers repaint after starting line that determined current fold block
bool isEnabled;
};
class CaseFolder { class CaseFolder {
public: public:
virtual ~CaseFolder() { virtual ~CaseFolder() {
@ -234,6 +274,7 @@ public:
bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed
int SCI_METHOD CodePage() const; int SCI_METHOD CodePage() const;
bool SCI_METHOD IsDBCSLeadByte(char ch) const; bool SCI_METHOD IsDBCSLeadByte(char ch) const;
int SafeSegment(const char *text, int length, int lengthSegment);
// Gateways to modifying document // Gateways to modifying document
void ModifiedAt(int pos); void ModifiedAt(int pos);
@ -262,7 +303,7 @@ public:
int GetColumn(int position); int GetColumn(int position);
int FindColumn(int line, int column); int FindColumn(int line, int column);
void Indent(bool forwards, int lineBottom, int lineTop); void Indent(bool forwards, int lineBottom, int lineTop);
static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode); static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolModeWanted);
void ConvertLineEnds(int eolModeSet); void ConvertLineEnds(int eolModeSet);
void SetReadOnly(bool set) { cb.SetReadOnly(set); } void SetReadOnly(bool set) { cb.SetReadOnly(set); }
bool IsReadOnly() { return cb.IsReadOnly(); } bool IsReadOnly() { return cb.IsReadOnly(); }
@ -297,8 +338,9 @@ public:
int SCI_METHOD SetLevel(int line, int level); int SCI_METHOD SetLevel(int line, int level);
int SCI_METHOD GetLevel(int line) const; int SCI_METHOD GetLevel(int line) const;
void ClearLevels(); void ClearLevels();
int GetLastChild(int lineParent, int level=-1); int GetLastChild(int lineParent, int level=-1, int lastLine=-1);
int GetFoldParent(int line); int GetFoldParent(int line);
void GetHighlightDelimiters(HighlightDelimiter &hDelimiter, int line, int lastLine);
void Indent(bool forwards); void Indent(bool forwards);
int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false); int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
/** @file Editor.h /** @file Editor.h
** Defines the main editor class. ** Defines the main editor class.
**/ **/
// Copyright 1998-2003 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.
#ifndef EDITOR_H #ifndef EDITOR_H
@ -131,6 +131,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
* When a style attribute is changed, this cache is flushed. */ * When a style attribute is changed, this cache is flushed. */
bool stylesValid; bool stylesValid;
ViewStyle vs; ViewStyle vs;
Point sizeRGBAImage;
Palette palette; Palette palette;
int printMagnification; int printMagnification;
@ -139,6 +140,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
int cursorMode; int cursorMode;
int controlCharSymbol; int controlCharSymbol;
// Highlight current folding block
HighlightDelimiter highlightDelimiter;
bool hasFocus; bool hasFocus;
bool hideSelection; bool hideSelection;
bool inOverstrike; bool inOverstrike;
@ -160,6 +164,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool verticalScrollBarVisible; bool verticalScrollBarVisible;
bool endAtLastLine; bool endAtLastLine;
int caretSticky; int caretSticky;
int marginOptions;
bool multipleSelection; bool multipleSelection;
bool additionalSelectionTyping; bool additionalSelectionTyping;
int multiPasteMode; int multiPasteMode;
@ -191,7 +196,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int dwellDelay; int dwellDelay;
int ticksToDwell; int ticksToDwell;
bool dwelling; bool dwelling;
enum { selChar, selWord, selLine } selectionType; enum { selChar, selWord, selSubLine, selWholeLine } selectionType;
Point ptMouseLast; Point ptMouseLast;
enum { ddNone, ddInitial, ddDragging } inDragDrop; enum { ddNone, ddInitial, ddDragging } inDragDrop;
bool dropWentOutside; bool dropWentOutside;
@ -199,7 +204,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
SelectionPosition posDrop; SelectionPosition posDrop;
int hotSpotClickPos; int hotSpotClickPos;
int lastXChosen; int lastXChosen;
int lineAnchor; int lineAnchorPos;
int originalAnchorPos; int originalAnchorPos;
int wordSelectAnchorStartPos; int wordSelectAnchorStartPos;
int wordSelectAnchorEndPos; int wordSelectAnchorEndPos;
@ -332,6 +337,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void ScrollText(int linesToMove); virtual void ScrollText(int linesToMove);
void HorizontalScrollTo(int xPos); void HorizontalScrollTo(int xPos);
void VerticalCentreCaret(); void VerticalCentreCaret();
void MoveSelectedLines(int lineDelta);
void MoveSelectedLinesUp();
void MoveSelectedLinesDown();
void MoveCaretInsideView(bool ensureVisible=true); void MoveCaretInsideView(bool ensureVisible=true);
int DisplayFromPosition(int pos); int DisplayFromPosition(int pos);
@ -367,6 +375,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
int line, int lineEnd, int xStart, int subLine, int subLineStart, int line, int lineEnd, int xStart, int subLine, int subLineStart,
bool overrideBackground, ColourAllocated background, bool overrideBackground, ColourAllocated background,
bool drawWrapMark, ColourAllocated wrapColour); bool drawWrapMark, ColourAllocated wrapColour);
void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
int xStart, PRectangle rcLine, LineLayout *ll, int subLine);
void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart, void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under); PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under);
void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart, void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
@ -413,6 +423,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void NotifyChange() = 0; virtual void NotifyChange() = 0;
virtual void NotifyFocus(bool focus); virtual void NotifyFocus(bool focus);
virtual void SetCtrlID(int identifier);
virtual int GetCtrlID() { return ctrlID; } virtual int GetCtrlID() { return ctrlID; }
virtual void NotifyParent(SCNotification scn) = 0; virtual void NotifyParent(SCNotification scn) = 0;
virtual void NotifyStyleToNeeded(int endStyleNeeded); virtual void NotifyStyleToNeeded(int endStyleNeeded);
@ -455,6 +466,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int StartEndDisplayLine(int pos, bool start); int StartEndDisplayLine(int pos, bool start);
virtual int KeyCommand(unsigned int iMessage); virtual int KeyCommand(unsigned int iMessage);
virtual int KeyDefault(int /* key */, int /*modifiers*/); virtual int KeyDefault(int /* key */, int /*modifiers*/);
int KeyDownWithModifiers(int key, int modifiers, bool *consumed);
int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0); int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0);
int GetWhitespaceVisible(); int GetWhitespaceVisible();
@ -484,7 +496,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool PointInSelection(Point pt); bool PointInSelection(Point pt);
bool PointInSelMargin(Point pt); bool PointInSelMargin(Point pt);
Window::Cursor GetMarginCursor(Point pt); Window::Cursor GetMarginCursor(Point pt);
void LineSelection(int lineCurrent_, int lineAnchor_); void LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine);
void WordSelection(int pos); void WordSelection(int pos);
void DwellEnd(bool mouseMoved); void DwellEnd(bool mouseMoved);
void MouseLeave(); void MouseLeave();

View File

@ -5,9 +5,17 @@
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // Copyright 1998-2001 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 <vector>
#include <map>
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#include "Platform.h" #include "Platform.h"
#include "Scintilla.h" #include "Scintilla.h"
#include "XPM.h"
#include "Indicator.h" #include "Indicator.h"
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE
@ -27,6 +35,17 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
y = 2 - y; y = 2 - y;
} }
surface->LineTo(rc.right, rc.top + y); // Finish the line surface->LineTo(rc.right, rc.top + y); // Finish the line
} else if (style == INDIC_SQUIGGLELOW) {
surface->MoveTo(rc.left, rc.top);
int x = rc.left + 3;
int y = 0;
while (x < rc.right) {
surface->LineTo(x-1, rc.top + y);
y = 1 - y;
surface->LineTo(x, rc.top + y);
x += 3;
}
surface->LineTo(rc.right, rc.top + y); // Finish the line
} else if (style == INDIC_TT) { } else if (style == INDIC_TT) {
surface->MoveTo(rc.left, ymid); surface->MoveTo(rc.left, ymid);
int x = rc.left + 5; int x = rc.left + 5;
@ -67,12 +86,47 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
surface->LineTo(rc.right, rcLine.top+1); surface->LineTo(rc.right, rcLine.top+1);
surface->LineTo(rc.left, rcLine.top+1); surface->LineTo(rc.left, rcLine.top+1);
surface->LineTo(rc.left, ymid+1); surface->LineTo(rc.left, ymid+1);
} else if (style == INDIC_ROUNDBOX) { } else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) {
PRectangle rcBox = rcLine; PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1; rcBox.top = rcLine.top + 1;
rcBox.left = rc.left; rcBox.left = rc.left;
rcBox.right = rc.right; rcBox.right = rc.right;
surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, 50, 0); surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore.allocated, fillAlpha, fore.allocated, outlineAlpha, 0);
} else if (style == INDIC_DOTBOX) {
PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1;
rcBox.left = rc.left;
rcBox.right = rc.right;
// Cap width at 4000 to avoid large allocations when mistakes made
int width = Platform::Minimum(rcBox.Width(), 4000);
RGBAImage image(width, rcBox.Height(), 0);
// Draw horizontal lines top and bottom
for (int x=0; x<width; x++) {
for (int y=0; y<rcBox.Height(); y += rcBox.Height()-1) {
image.SetPixel(x, y, fore.desired, ((x + y) % 2) ? outlineAlpha : fillAlpha);
}
}
// Draw vertical lines left and right
for (int y=1; y<rcBox.Height(); y++) {
for (int x=0; x<width; x += width-1) {
image.SetPixel(x, y, fore.desired, ((x + y) % 2) ? outlineAlpha : fillAlpha);
}
}
surface->DrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels());
} else if (style == INDIC_DASH) {
int x = rc.left;
while (x < rc.right) {
surface->MoveTo(x, ymid);
surface->LineTo(Platform::Minimum(x + 4, rc.right), ymid);
x += 7;
}
} else if (style == INDIC_DOTS) {
int x = rc.left;
while (x < rc.right) {
PRectangle rcDot(x, ymid, x+1, ymid+1);
surface->FillRectangle(rcDot, fore.allocated);
x += 2;
}
} else { // Either INDIC_PLAIN or unknown } else { // Either INDIC_PLAIN or unknown
surface->MoveTo(rc.left, ymid); surface->MoveTo(rc.left, ymid);
surface->LineTo(rc.right, ymid); surface->LineTo(rc.right, ymid);

View File

@ -20,7 +20,8 @@ public:
bool under; bool under;
ColourPair fore; ColourPair fore;
int fillAlpha; int fillAlpha;
Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) { int outlineAlpha;
Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30), outlineAlpha(50) {
} }
void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine); void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
}; };

View File

@ -66,14 +66,42 @@ unsigned int KeyMap::Find(int key, int modifiers) {
return 0; return 0;
} }
#if PLAT_GTK_MACOSX
#define OS_X_KEYS 1
#else
#define OS_X_KEYS 0
#endif
// Define a modifier that is exactly Ctrl key on all platforms
// Most uses of Ctrl map to Cmd on OS X but some can't so use SCI_[S]CTRL_META
#if OS_X_KEYS
#define SCI_CTRL_META SCI_META
#define SCI_SCTRL_META (SCI_META | SCI_SHIFT)
#else
#define SCI_CTRL_META SCI_CTRL
#define SCI_SCTRL_META (SCI_CTRL | SCI_SHIFT)
#endif
const KeyToCommand KeyMap::MapDefault[] = { const KeyToCommand KeyMap::MapDefault[] = {
#if OS_X_KEYS
{SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND},
{SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
{SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART},
{SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
{SCK_LEFT, SCI_CTRL, SCI_VCHOME},
{SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND},
{SCK_RIGHT, SCI_CTRL, SCI_LINEEND},
{SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND},
#endif
{SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, {SCK_DOWN, SCI_NORM, SCI_LINEDOWN},
{SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND},
{SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN}, {SCK_DOWN, SCI_CTRL_META, SCI_LINESCROLLDOWN},
{SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND}, {SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND},
{SCK_UP, SCI_NORM, SCI_LINEUP}, {SCK_UP, SCI_NORM, SCI_LINEUP},
{SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND},
{SCK_UP, SCI_CTRL, SCI_LINESCROLLUP}, {SCK_UP, SCI_CTRL_META, SCI_LINESCROLLUP},
{SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND}, {SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND},
{'[', SCI_CTRL, SCI_PARAUP}, {'[', SCI_CTRL, SCI_PARAUP},
{'[', SCI_CSHIFT, SCI_PARAUPEXTEND}, {'[', SCI_CSHIFT, SCI_PARAUPEXTEND},
@ -81,13 +109,13 @@ const KeyToCommand KeyMap::MapDefault[] = {
{']', SCI_CSHIFT, SCI_PARADOWNEXTEND}, {']', SCI_CSHIFT, SCI_PARADOWNEXTEND},
{SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, {SCK_LEFT, SCI_NORM, SCI_CHARLEFT},
{SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND},
{SCK_LEFT, SCI_CTRL, SCI_WORDLEFT}, {SCK_LEFT, SCI_CTRL_META, SCI_WORDLEFT},
{SCK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND}, {SCK_LEFT, SCI_SCTRL_META, SCI_WORDLEFTEXTEND},
{SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND}, {SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND},
{SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT},
{SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND},
{SCK_RIGHT, SCI_CTRL, SCI_WORDRIGHT}, {SCK_RIGHT, SCI_CTRL_META, SCI_WORDRIGHT},
{SCK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND}, {SCK_RIGHT, SCI_SCTRL_META, SCI_WORDRIGHTEXTEND},
{SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND}, {SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND},
{'/', SCI_CTRL, SCI_WORDPARTLEFT}, {'/', SCI_CTRL, SCI_WORDPARTLEFT},
{'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND}, {'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND},
@ -98,14 +126,12 @@ const KeyToCommand KeyMap::MapDefault[] = {
{SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART}, {SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART},
{SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, {SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
{SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY}, {SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY},
// {SCK_HOME, SCI_ASHIFT, SCI_HOMEDISPLAYEXTEND},
{SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND}, {SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND},
{SCK_END, SCI_NORM, SCI_LINEEND}, {SCK_END, SCI_NORM, SCI_LINEEND},
{SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND}, {SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND},
{SCK_END, SCI_CTRL, SCI_DOCUMENTEND}, {SCK_END, SCI_CTRL, SCI_DOCUMENTEND},
{SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, {SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
{SCK_END, SCI_ALT, SCI_LINEENDDISPLAY}, {SCK_END, SCI_ALT, SCI_LINEENDDISPLAY},
// {SCK_END, SCI_ASHIFT, SCI_LINEENDDISPLAYEXTEND},
{SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND}, {SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND},
{SCK_PRIOR, SCI_NORM, SCI_PAGEUP}, {SCK_PRIOR, SCI_NORM, SCI_PAGEUP},
{SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND}, {SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND},
@ -127,7 +153,11 @@ const KeyToCommand KeyMap::MapDefault[] = {
{SCK_BACK, SCI_ALT, SCI_UNDO}, {SCK_BACK, SCI_ALT, SCI_UNDO},
{SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT},
{'Z', SCI_CTRL, SCI_UNDO}, {'Z', SCI_CTRL, SCI_UNDO},
#if OS_X_KEYS
{'Z', SCI_CSHIFT, SCI_REDO},
#else
{'Y', SCI_CTRL, SCI_REDO}, {'Y', SCI_CTRL, SCI_REDO},
#endif
{'X', SCI_CTRL, SCI_CUT}, {'X', SCI_CTRL, SCI_CUT},
{'C', SCI_CTRL, SCI_COPY}, {'C', SCI_CTRL, SCI_COPY},
{'V', SCI_CTRL, SCI_PASTE}, {'V', SCI_CTRL, SCI_PASTE},
@ -139,7 +169,6 @@ const KeyToCommand KeyMap::MapDefault[] = {
{SCK_ADD, SCI_CTRL, SCI_ZOOMIN}, {SCK_ADD, SCI_CTRL, SCI_ZOOMIN},
{SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT}, {SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT},
{SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM}, {SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM},
//'L', SCI_CTRL, SCI_FORMFEED,
{'L', SCI_CTRL, SCI_LINECUT}, {'L', SCI_CTRL, SCI_LINECUT},
{'L', SCI_CSHIFT, SCI_LINEDELETE}, {'L', SCI_CSHIFT, SCI_LINEDELETE},
{'T', SCI_CSHIFT, SCI_LINECOPY}, {'T', SCI_CSHIFT, SCI_LINECOPY},

View File

@ -16,6 +16,7 @@ namespace Scintilla {
#define SCI_SHIFT SCMOD_SHIFT #define SCI_SHIFT SCMOD_SHIFT
#define SCI_CTRL SCMOD_CTRL #define SCI_CTRL SCMOD_CTRL
#define SCI_ALT SCMOD_ALT #define SCI_ALT SCMOD_ALT
#define SCI_META SCMOD_META
#define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT) #define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT)
#define SCI_ASHIFT (SCI_ALT | SCI_SHIFT) #define SCI_ASHIFT (SCI_ALT | SCI_SHIFT)

View File

@ -2,11 +2,14 @@
/** @file LineMarker.cxx /** @file LineMarker.cxx
** Defines the look of a line marker in the margin . ** Defines the look of a line marker in the margin .
**/ **/
// Copyright 1998-2003 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 <string.h> #include <string.h>
#include <vector>
#include <map>
#include "Platform.h" #include "Platform.h"
#include "Scintilla.h" #include "Scintilla.h"
@ -20,6 +23,7 @@ using namespace Scintilla;
void LineMarker::RefreshColourPalette(Palette &pal, bool want) { void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(fore, want); pal.WantFind(fore, want);
pal.WantFind(back, want); pal.WantFind(back, want);
pal.WantFind(backSelected, want);
if (pxpm) { if (pxpm) {
pxpm->RefreshColourPalette(pal, want); pxpm->RefreshColourPalette(pal, want);
} }
@ -37,6 +41,12 @@ void LineMarker::SetXPM(const char *const *linesForm) {
markType = SC_MARK_PIXMAP; markType = SC_MARK_PIXMAP;
} }
void LineMarker::SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage) {
delete image;
image = new RGBAImage(sizeRGBAImage.x, sizeRGBAImage.y, pixelsRGBAImage);
markType = SC_MARK_RGBAIMAGE;
}
static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) { static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
PRectangle rc; PRectangle rc;
rc.left = centreX - armSize; rc.left = centreX - armSize;
@ -67,11 +77,39 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C
surface->FillRectangle(rcH, fore); surface->FillRectangle(rcH, fore);
} }
void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) { void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold) {
ColourPair head = back;
ColourPair body = back;
ColourPair tail = back;
switch (tFold) {
case LineMarker::head :
case LineMarker::headWithTail :
head = backSelected;
tail = backSelected;
break;
case LineMarker::body :
head = backSelected;
body = backSelected;
break;
case LineMarker::tail :
body = backSelected;
tail = backSelected;
break;
default :
// LineMarker::undefined
break;
}
if ((markType == SC_MARK_PIXMAP) && (pxpm)) { if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
pxpm->Draw(surface, rcWhole); pxpm->Draw(surface, rcWhole);
return; return;
} }
if ((markType == SC_MARK_RGBAIMAGE) && (image)) {
surface->DrawRGBAImage(rcWhole, image->GetWidth(), image->GetHeight(), image->Pixels());
return;
}
// Restrict most shapes a bit // Restrict most shapes a bit
PRectangle rc = rcWhole; PRectangle rc = rcWhole;
rc.top++; rc.top++;
@ -159,106 +197,145 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
// An invisible marker so don't draw anything // An invisible marker so don't draw anything
} else if (markType == SC_MARK_VLINE) { } else if (markType == SC_MARK_VLINE) {
surface->PenColour(back.allocated); surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top); surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom); surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_LCORNER) { } else if (markType == SC_MARK_LCORNER) {
surface->PenColour(back.allocated); surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top); surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2); surface->LineTo(centreX, rc.top + dimOn2);
surface->LineTo(rc.right - 2, rc.top + dimOn2); surface->LineTo(rc.right - 2, rc.top + dimOn2);
} else if (markType == SC_MARK_TCORNER) { } else if (markType == SC_MARK_TCORNER) {
surface->PenColour(back.allocated); surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
surface->MoveTo(centreX, rc.top + dimOn2); surface->MoveTo(centreX, rc.top + dimOn2);
surface->LineTo(rc.right - 2, rc.top + dimOn2); surface->LineTo(rc.right - 2, rc.top + dimOn2);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2 + 1);
surface->PenColour(head.allocated);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_LCORNERCURVE) { } else if (markType == SC_MARK_LCORNERCURVE) {
surface->PenColour(back.allocated); surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top); surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2-3); surface->LineTo(centreX, rc.top + dimOn2-3);
surface->LineTo(centreX+3, rc.top + dimOn2); surface->LineTo(centreX+3, rc.top + dimOn2);
surface->LineTo(rc.right - 1, rc.top + dimOn2); surface->LineTo(rc.right - 1, rc.top + dimOn2);
} else if (markType == SC_MARK_TCORNERCURVE) { } else if (markType == SC_MARK_TCORNERCURVE) {
surface->PenColour(back.allocated); surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
surface->MoveTo(centreX, rc.top + dimOn2-3); surface->MoveTo(centreX, rc.top + dimOn2-3);
surface->LineTo(centreX+3, rc.top + dimOn2); surface->LineTo(centreX+3, rc.top + dimOn2);
surface->LineTo(rc.right - 1, rc.top + dimOn2); surface->LineTo(rc.right - 1, rc.top + dimOn2);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2-2);
surface->PenColour(head.allocated);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXPLUS) { } else if (markType == SC_MARK_BOXPLUS) {
surface->PenColour(back.allocated); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
} else if (markType == SC_MARK_BOXPLUSCONNECTED) { } else if (markType == SC_MARK_BOXPLUSCONNECTED) {
surface->PenColour(back.allocated); if (tFold == LineMarker::headWithTail)
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); surface->PenColour(tail.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated); else
surface->PenColour(body.allocated);
surface->MoveTo(centreX, centreY + blobSize); surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom); surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top); surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize); surface->LineTo(centreX, centreY - blobSize);
} else if (markType == SC_MARK_BOXMINUS) { DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
surface->PenColour(back.allocated); DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
if (tFold == LineMarker::body) {
surface->PenColour(tail.allocated);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
} else if (markType == SC_MARK_BOXMINUS) {
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize); surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom); surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXMINUSCONNECTED) { } else if (markType == SC_MARK_BOXMINUSCONNECTED) {
surface->PenColour(back.allocated); DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize); surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom); surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top); surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize); surface->LineTo(centreX, centreY - blobSize);
if (tFold == LineMarker::body) {
surface->PenColour(tail.allocated);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
} else if (markType == SC_MARK_CIRCLEPLUS) { } else if (markType == SC_MARK_CIRCLEPLUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
surface->PenColour(back.allocated); DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) { } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); if (tFold == LineMarker::headWithTail)
surface->PenColour(back.allocated); surface->PenColour(tail.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated); else
surface->PenColour(body.allocated);
surface->MoveTo(centreX, centreY + blobSize); surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom); surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top); surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize); surface->LineTo(centreX, centreY - blobSize);
} else if (markType == SC_MARK_CIRCLEMINUS) { DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
} else if (markType == SC_MARK_CIRCLEMINUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize); surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom); surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) { } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated); DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
surface->PenColour(back.allocated); DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize); surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom); surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top); surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize); surface->LineTo(centreX, centreY - blobSize);

View File

@ -2,7 +2,7 @@
/** @file LineMarker.h /** @file LineMarker.h
** Defines the look of a line marker in the margin . ** Defines the look of a line marker in the margin .
**/ **/
// Copyright 1998-2003 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.
#ifndef LINEMARKER_H #ifndef LINEMARKER_H
@ -12,47 +12,61 @@
namespace Scintilla { namespace Scintilla {
#endif #endif
/** /**
*/ */
class LineMarker { class LineMarker {
public: public:
enum typeOfFold { undefined, head, body, tail, headWithTail };
int markType; int markType;
ColourPair fore; ColourPair fore;
ColourPair back; ColourPair back;
ColourPair backSelected;
int alpha; int alpha;
XPM *pxpm; XPM *pxpm;
RGBAImage *image;
LineMarker() { LineMarker() {
markType = SC_MARK_CIRCLE; markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0); fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff); back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA; alpha = SC_ALPHA_NOALPHA;
pxpm = NULL; pxpm = NULL;
image = NULL;
} }
LineMarker(const LineMarker &) { LineMarker(const LineMarker &) {
// Defined to avoid pxpm being blindly copied, not as real copy constructor // Defined to avoid pxpm being blindly copied, not as real copy constructor
markType = SC_MARK_CIRCLE; markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0); fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff); back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA; alpha = SC_ALPHA_NOALPHA;
pxpm = NULL; pxpm = NULL;
image = NULL;
} }
~LineMarker() { ~LineMarker() {
delete pxpm; delete pxpm;
delete image;
} }
LineMarker &operator=(const LineMarker &) { LineMarker &operator=(const LineMarker &) {
// Defined to avoid pxpm being blindly copied, not as real assignment operator // Defined to avoid pxpm being blindly copied, not as real assignment operator
markType = SC_MARK_CIRCLE; markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0); fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff); back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA; alpha = SC_ALPHA_NOALPHA;
delete pxpm; delete pxpm;
pxpm = NULL; pxpm = NULL;
delete image;
image = NULL;
return *this; return *this;
} }
void RefreshColourPalette(Palette &pal, bool want); void RefreshColourPalette(Palette &pal, bool want);
void SetXPM(const char *textForm); void SetXPM(const char *textForm);
void SetXPM(const char *const *linesForm); void SetXPM(const char *const *linesForm);
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter); void SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage);
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold);
}; };
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE

View File

@ -425,10 +425,10 @@ void LineAnnotation::SetText(int line, const char *text) {
if (annotations[line]) { if (annotations[line]) {
delete []annotations[line]; delete []annotations[line];
} }
annotations[line] = AllocateAnnotation(strlen(text), style); annotations[line] = AllocateAnnotation(static_cast<int>(strlen(text)), style);
AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]); AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
pah->style = static_cast<short>(style); pah->style = static_cast<short>(style);
pah->length = strlen(text); pah->length = static_cast<int>(strlen(text));
pah->lines = static_cast<short>(NumberLines(text)); pah->lines = static_cast<short>(NumberLines(text));
memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length); memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length);
} else { } else {

View File

@ -12,6 +12,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <map>
#include "Platform.h" #include "Platform.h"
@ -151,15 +152,15 @@ void LineLayout::SetLineStart(int line, int start) {
} }
void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[], void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
char bracesMatchStyle, int xHighlight) { char bracesMatchStyle, int xHighlight, bool ignoreStyle) {
if (rangeLine.ContainsCharacter(braces[0])) { if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start; int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) { if (braceOffset < numCharsInLine) {
bracePreviousStyles[0] = styles[braceOffset]; bracePreviousStyles[0] = styles[braceOffset];
styles[braceOffset] = bracesMatchStyle; styles[braceOffset] = bracesMatchStyle;
} }
} }
if (rangeLine.ContainsCharacter(braces[1])) { if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start; int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) { if (braceOffset < numCharsInLine) {
bracePreviousStyles[1] = styles[braceOffset]; bracePreviousStyles[1] = styles[braceOffset];
@ -172,14 +173,14 @@ void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
} }
} }
void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[]) { void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle) {
if (rangeLine.ContainsCharacter(braces[0])) { if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start; int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) { if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[0]; styles[braceOffset] = bracePreviousStyles[0];
} }
} }
if (rangeLine.ContainsCharacter(braces[1])) { if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start; int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) { if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[1]; styles[braceOffset] = bracePreviousStyles[1];
@ -391,18 +392,19 @@ static int NextBadU(const char *s, int p, int len, int &trailBytes) {
return -1; return -1;
} }
BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection) : BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
int xStart, bool breakForSelection, Document *pdoc_) :
ll(ll_), ll(ll_),
lineStart(lineStart_), lineStart(lineStart_),
lineEnd(lineEnd_), lineEnd(lineEnd_),
posLineStart(posLineStart_), posLineStart(posLineStart_),
utf8(utf8_),
nextBreak(lineStart_), nextBreak(lineStart_),
saeSize(0), saeSize(0),
saeLen(0), saeLen(0),
saeCurrentPos(0), saeCurrentPos(0),
saeNext(0), saeNext(0),
subBreak(-1) { subBreak(-1),
pdoc(pdoc_) {
saeSize = 8; saeSize = 8;
selAndEdge = new int[saeSize]; selAndEdge = new int[saeSize];
for (unsigned int j=0; j < saeSize; j++) { for (unsigned int j=0; j < saeSize; j++) {
@ -435,7 +437,7 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
Insert(ll->edgeColumn - 1); Insert(ll->edgeColumn - 1);
Insert(lineEnd - 1); Insert(lineEnd - 1);
if (utf8) { if (pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage)) {
int trailBytes=0; int trailBytes=0;
for (int pos = -1;;) { for (int pos = -1;;) {
pos = NextBadU(ll->chars, pos, lineEnd, trailBytes); pos = NextBadU(ll->chars, pos, lineEnd, trailBytes);
@ -456,10 +458,6 @@ int BreakFinder::First() const {
return nextBreak; return nextBreak;
} }
static bool IsTrailByte(int ch) {
return (ch >= 0x80) && (ch < (0x80 + 0x40));
}
int BreakFinder::Next() { int BreakFinder::Next() {
if (subBreak == -1) { if (subBreak == -1) {
int prev = nextBreak; int prev = nextBreak;
@ -490,34 +488,7 @@ int BreakFinder::Next() {
subBreak = -1; subBreak = -1;
return nextBreak; return nextBreak;
} else { } else {
int lastGoodBreak = -1; subBreak += pdoc->SafeSegment(ll->chars + subBreak, nextBreak-subBreak, lengthEachSubdivision);
int lastOKBreak = -1;
int lastUTF8Break = -1;
int j;
for (j = subBreak + 1; j <= nextBreak; j++) {
if (IsSpaceOrTab(ll->chars[j - 1]) && !IsSpaceOrTab(ll->chars[j])) {
lastGoodBreak = j;
}
if (static_cast<unsigned char>(ll->chars[j]) < 'A') {
lastOKBreak = j;
}
if (utf8 && !IsTrailByte(static_cast<unsigned char>(ll->chars[j]))) {
lastUTF8Break = j;
}
if (((j - subBreak) >= lengthEachSubdivision) &&
((lastGoodBreak >= 0) || (lastOKBreak >= 0) || (lastUTF8Break >= 0))) {
break;
}
}
if (lastGoodBreak >= 0) {
subBreak = lastGoodBreak;
} else if (lastOKBreak >= 0) {
subBreak = lastOKBreak;
} else if (lastUTF8Break >= 0) {
subBreak = lastUTF8Break;
} else {
subBreak = nextBreak;
}
if (subBreak >= nextBreak) { if (subBreak >= nextBreak) {
subBreak = -1; subBreak = -1;
return nextBreak; return nextBreak;
@ -571,16 +542,16 @@ bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, const char *s_,
} }
} }
int PositionCacheEntry::Hash(unsigned int styleNumber, const char *s, unsigned int len) { int PositionCacheEntry::Hash(unsigned int styleNumber_, const char *s, unsigned int len_) {
unsigned int ret = s[0] << 7; unsigned int ret = s[0] << 7;
for (unsigned int i=0; i<len; i++) { for (unsigned int i=0; i<len_; i++) {
ret *= 1000003; ret *= 1000003;
ret ^= s[i]; ret ^= s[i];
} }
ret *= 1000003; ret *= 1000003;
ret ^= len; ret ^= len_;
ret *= 1000003; ret *= 1000003;
ret ^= styleNumber; ret ^= styleNumber_;
return ret; return ret;
} }
@ -624,7 +595,8 @@ void PositionCache::SetSize(size_t size_) {
} }
void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber, void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
const char *s, unsigned int len, int *positions) { const char *s, unsigned int len, int *positions, Document *pdoc) {
allClear = false; allClear = false;
int probe = -1; int probe = -1;
if ((size > 0) && (len < 30)) { if ((size > 0) && (len < 30)) {
@ -633,11 +605,11 @@ void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned
// Two way associative: try two probe positions. // Two way associative: try two probe positions.
int hashValue = PositionCacheEntry::Hash(styleNumber, s, len); int hashValue = PositionCacheEntry::Hash(styleNumber, s, len);
probe = hashValue % size; probe = static_cast<int>(hashValue % size);
if (pces[probe].Retrieve(styleNumber, s, len, positions)) { if (pces[probe].Retrieve(styleNumber, s, len, positions)) {
return; return;
} }
int probe2 = (hashValue * 37) % size; int probe2 = static_cast<int>((hashValue * 37) % size);
if (pces[probe2].Retrieve(styleNumber, s, len, positions)) { if (pces[probe2].Retrieve(styleNumber, s, len, positions)) {
return; return;
} }
@ -646,7 +618,22 @@ void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned
probe = probe2; probe = probe2;
} }
} }
surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions); if (len > BreakFinder::lengthStartSubdivision) {
// Break up into segments
unsigned int startSegment = 0;
int xStartSegment = 0;
while (startSegment < len) {
unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision);
surface->MeasureWidths(vstyle.styles[styleNumber].font, s + startSegment, lenSegment, positions + startSegment);
for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) {
positions[startSegment + inSeg] += xStartSegment;
}
xStartSegment = positions[startSegment + lenSegment - 1];
startSegment += lenSegment;
}
} else {
surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
}
if (probe >= 0) { if (probe >= 0) {
clock++; clock++;
if (clock > 60000) { if (clock > 60000) {

View File

@ -63,8 +63,8 @@ public:
bool InLine(int offset, int line) const; bool InLine(int offset, int line) const;
void SetLineStart(int line, int start); void SetLineStart(int line, int start);
void SetBracesHighlight(Range rangeLine, Position braces[], void SetBracesHighlight(Range rangeLine, Position braces[],
char bracesMatchStyle, int xHighlight); char bracesMatchStyle, int xHighlight, bool ignoreStyle);
void RestoreBracesHighlight(Range rangeLine, Position braces[]); void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle);
int FindBefore(int x, int lower, int upper) const; int FindBefore(int x, int lower, int upper) const;
int EndLineStyle() const; int EndLineStyle() const;
}; };
@ -110,23 +110,17 @@ public:
void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_, unsigned int clock); void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_, unsigned int clock);
void Clear(); void Clear();
bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_) const; bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_) const;
static int Hash(unsigned int styleNumber, const char *s, unsigned int len); static int Hash(unsigned int styleNumber_, const char *s, unsigned int len);
bool NewerThan(const PositionCacheEntry &other) const; bool NewerThan(const PositionCacheEntry &other) const;
void ResetClock(); void ResetClock();
}; };
// Class to break a line of text into shorter runs at sensible places. // Class to break a line of text into shorter runs at sensible places.
class BreakFinder { class BreakFinder {
// If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
enum { lengthStartSubdivision = 300 };
// Try to make each subdivided run lengthEachSubdivision or shorter.
enum { lengthEachSubdivision = 100 };
LineLayout *ll; LineLayout *ll;
int lineStart; int lineStart;
int lineEnd; int lineEnd;
int posLineStart; int posLineStart;
bool utf8;
int nextBreak; int nextBreak;
int *selAndEdge; int *selAndEdge;
unsigned int saeSize; unsigned int saeSize;
@ -134,9 +128,16 @@ class BreakFinder {
unsigned int saeCurrentPos; unsigned int saeCurrentPos;
int saeNext; int saeNext;
int subBreak; int subBreak;
Document *pdoc;
void Insert(int val); void Insert(int val);
public: public:
BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection); // If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
enum { lengthStartSubdivision = 300 };
// Try to make each subdivided run lengthEachSubdivision or shorter.
enum { lengthEachSubdivision = 100 };
BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
int xStart, bool breakForSelection, Document *pdoc_);
~BreakFinder(); ~BreakFinder();
int First() const; int First() const;
int Next(); int Next();
@ -152,9 +153,9 @@ public:
~PositionCache(); ~PositionCache();
void Clear(); void Clear();
void SetSize(size_t size_); void SetSize(size_t size_);
int GetSize() const { return size; } size_t GetSize() const { return size; }
void MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber, void MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
const char *s, unsigned int len, int *positions); const char *s, unsigned int len, int *positions, Document *pdoc);
}; };
inline bool IsSpaceOrTab(int ch) { inline bool IsSpaceOrTab(int ch) {

View File

@ -321,7 +321,7 @@ void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) {
} }
} }
const unsigned char escapeValue(unsigned char ch) { unsigned char escapeValue(unsigned char ch) {
switch (ch) { switch (ch) {
case 'a': return '\a'; case 'a': return '\a';
case 'b': return '\b'; case 'b': return '\b';
@ -888,10 +888,10 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
return NOTFOUND; return NOTFOUND;
break; break;
case BOT: case BOT:
bopat[*ap++] = lp; bopat[static_cast<int>(*ap++)] = lp;
break; break;
case EOT: case EOT:
eopat[*ap++] = lp; eopat[static_cast<int>(*ap++)] = lp;
break; break;
case BOW: case BOW:
if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp))) if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp)))

View File

@ -21,7 +21,7 @@ using namespace Scintilla;
#endif #endif
// Find the first run at a position // Find the first run at a position
int RunStyles::RunFromPosition(int position) { int RunStyles::RunFromPosition(int position) const {
int run = starts->PartitionFromPosition(position); int run = starts->PartitionFromPosition(position);
// Go to first element with this position // Go to first element with this position
while ((run > 0) && (position == starts->PositionFromPartition(run-1))) { while ((run > 0) && (position == starts->PositionFromPartition(run-1))) {
@ -147,6 +147,8 @@ bool RunStyles::FillRange(int &position, int value, int &fillLength) {
runEnd = RunFromPosition(end); runEnd = RunFromPosition(end);
RemoveRunIfSameAsPrevious(runEnd); RemoveRunIfSameAsPrevious(runEnd);
RemoveRunIfSameAsPrevious(runStart); RemoveRunIfSameAsPrevious(runStart);
runEnd = RunFromPosition(end);
RemoveRunIfEmpty(runEnd);
return true; return true;
} else { } else {
return false; return false;
@ -216,3 +218,33 @@ void RunStyles::DeleteRange(int position, int deleteLength) {
} }
} }
int RunStyles::Runs() const {
return starts->Partitions();
}
bool RunStyles::AllSame() const {
for (int run = 1; run < starts->Partitions(); run++) {
if (styles->ValueAt(run) != styles->ValueAt(run - 1))
return false;
}
return true;
}
bool RunStyles::AllSameAs(int value) const {
return AllSame() && (styles->ValueAt(0) == value);
}
int RunStyles::Find(int value, int start) const {
if (start < Length()) {
int run = start ? RunFromPosition(start) : 0;
if (styles->ValueAt(run) == value)
return start;
run++;
while (run < starts->Partitions()) {
if (styles->ValueAt(run) == value)
return starts->PositionFromPartition(run);
run++;
}
}
return -1;
}

View File

@ -15,10 +15,10 @@ namespace Scintilla {
#endif #endif
class RunStyles { class RunStyles {
public: private:
Partitioning *starts; Partitioning *starts;
SplitVector<int> *styles; SplitVector<int> *styles;
int RunFromPosition(int position); int RunFromPosition(int position) const;
int SplitRun(int position); int SplitRun(int position);
void RemoveRun(int run); void RemoveRun(int run);
void RemoveRunIfEmpty(int run); void RemoveRunIfEmpty(int run);
@ -37,6 +37,10 @@ public:
void InsertSpace(int position, int insertLength); void InsertSpace(int position, int insertLength);
void DeleteAll(); void DeleteAll();
void DeleteRange(int position, int deleteLength); void DeleteRange(int position, int deleteLength);
int Runs() const;
bool AllSame() const;
bool AllSameAs(int value) const;
int Find(int value, int start) const;
}; };
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE

View File

@ -13,6 +13,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <map>
#include "Platform.h" #include "Platform.h"
@ -135,16 +136,16 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
AutoCompleteMove(1); AutoCompleteMove(1);
return 0; return 0;
case SCI_LINEUP: case SCI_LINEUP:
AutoCompleteMove( -1); AutoCompleteMove(-1);
return 0; return 0;
case SCI_PAGEDOWN: case SCI_PAGEDOWN:
AutoCompleteMove(5); AutoCompleteMove(5);
return 0; return 0;
case SCI_PAGEUP: case SCI_PAGEUP:
AutoCompleteMove( -5); AutoCompleteMove(-5);
return 0; return 0;
case SCI_VCHOME: case SCI_VCHOME:
AutoCompleteMove( -5000); AutoCompleteMove(-5000);
return 0; return 0;
case SCI_LINEEND: case SCI_LINEEND:
AutoCompleteMove(5000); AutoCompleteMove(5000);
@ -204,7 +205,8 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
if (ac.chooseSingle && (listType == 0)) { if (ac.chooseSingle && (listType == 0)) {
if (list && !strchr(list, ac.GetSeparator())) { if (list && !strchr(list, ac.GetSeparator())) {
const char *typeSep = strchr(list, ac.GetTypesep()); const char *typeSep = strchr(list, ac.GetTypesep());
size_t lenInsert = (typeSep) ? (typeSep-list) : strlen(list); int lenInsert = typeSep ?
static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
if (ac.ignoreCase) { if (ac.ignoreCase) {
SetEmptySelection(sel.MainCaret() - lenEntered); SetEmptySelection(sel.MainCaret() - lenEntered);
pdoc->DeleteChars(sel.MainCaret(), lenEntered); pdoc->DeleteChars(sel.MainCaret(), lenEntered);
@ -349,6 +351,7 @@ void ScintillaBase::AutoCompleteCompleted() {
scn.wParam = listType; scn.wParam = listType;
scn.listType = listType; scn.listType = listType;
Position firstPos = ac.posStart - ac.startLen; Position firstPos = ac.posStart - ac.startLen;
scn.position = firstPos;
scn.lParam = firstPos; scn.lParam = firstPos;
scn.text = selected; scn.text = selected;
NotifyParent(scn); NotifyParent(scn);
@ -392,7 +395,7 @@ int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) {
ac.lb->GetValue(item, selected, sizeof(selected)); ac.lb->GetValue(item, selected, sizeof(selected));
if (buffer != NULL) if (buffer != NULL)
strcpy(buffer, selected); strcpy(buffer, selected);
return strlen(selected); return static_cast<int>(strlen(selected));
} }
} }
if (buffer != NULL) if (buffer != NULL)
@ -759,6 +762,10 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam)); ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam));
break; break;
case SCI_REGISTERRGBAIMAGE:
ac.lb->RegisterRGBAImage(wParam, sizeRGBAImage.x, sizeRGBAImage.y, reinterpret_cast<unsigned char *>(lParam));
break;
case SCI_CLEARREGISTEREDIMAGES: case SCI_CLEARREGISTEREDIMAGES:
ac.lb->ClearRegisteredImages(); ac.lb->ClearRegisteredImages();
break; break;

View File

@ -16,14 +16,51 @@
using namespace Scintilla; using namespace Scintilla;
#endif #endif
Style::Style() { FontAlias::FontAlias() {
aliasOfDefaultFont = true; }
FontAlias::~FontAlias() {
SetID(0);
// ~Font will not release the actual font resource sine it is now 0
}
void FontAlias::MakeAlias(Font &fontOrigin) {
SetID(fontOrigin.GetID());
}
void FontAlias::ClearFont() {
SetID(0);
}
bool FontSpecification::EqualTo(const FontSpecification &other) const {
return bold == other.bold &&
italic == other.italic &&
size == other.size &&
characterSet == other.characterSet &&
fontName == other.fontName;
}
FontMeasurements::FontMeasurements() {
Clear();
}
void FontMeasurements::Clear() {
lineHeight = 2;
ascent = 1;
descent = 1;
externalLeading = 0;
aveCharWidth = 1;
spaceWidth = 1;
sizeZoomed = 2;
}
Style::Style() : FontSpecification() {
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT, Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
false, false, false, false, caseMixed, true, true, false); false, false, false, false, caseMixed, true, true, false);
} }
Style::Style(const Style &source) { Style::Style(const Style &source) : FontSpecification(), FontMeasurements() {
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
0, 0, 0, 0, 0, 0,
false, false, false, false, caseMixed, true, true, false); false, false, false, false, caseMixed, true, true, false);
@ -42,11 +79,6 @@ Style::Style(const Style &source) {
} }
Style::~Style() { Style::~Style() {
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
aliasOfDefaultFont = false;
} }
Style &Style::operator=(const Style &source) { Style &Style::operator=(const Style &source) {
@ -70,10 +102,10 @@ Style &Style::operator=(const Style &source) {
} }
void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_, void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
const char *fontName_, int characterSet_, const char *fontName_, int characterSet_,
bool bold_, bool italic_, bool eolFilled_, bool bold_, bool italic_, bool eolFilled_,
bool underline_, ecaseForced caseForce_, bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_) { bool visible_, bool changeable_, bool hotspot_) {
fore.desired = fore_; fore.desired = fore_;
back.desired = back_; back.desired = back_;
characterSet = characterSet_; characterSet = characterSet_;
@ -87,79 +119,31 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
visible = visible_; visible = visible_;
changeable = changeable_; changeable = changeable_;
hotspot = hotspot_; hotspot = hotspot_;
if (aliasOfDefaultFont) font.ClearFont();
font.SetID(0); FontMeasurements::Clear();
else
font.Release();
aliasOfDefaultFont = false;
sizeZoomed = 2;
lineHeight = 2;
ascent = 1;
descent = 1;
externalLeading = 0;
aveCharWidth = 1;
spaceWidth = 1;
} }
void Style::ClearTo(const Style &source) { void Style::ClearTo(const Style &source) {
Clear( Clear(
source.fore.desired, source.fore.desired,
source.back.desired, source.back.desired,
source.size, source.size,
source.fontName, source.fontName,
source.characterSet, source.characterSet,
source.bold, source.bold,
source.italic, source.italic,
source.eolFilled, source.eolFilled,
source.underline, source.underline,
source.caseForce, source.caseForce,
source.visible, source.visible,
source.changeable, source.changeable,
source.hotspot); source.hotspot);
} }
bool Style::EquivalentFontTo(const Style *other) const { void Style::Copy(Font &font_, const FontMeasurements &fm_) {
if (bold != other->bold || font.MakeAlias(font_);
italic != other->italic || #if PLAT_WX
size != other->size || font.SetAscent(fm_.ascent);
characterSet != other->characterSet) #endif
return false; (FontMeasurements &)(*this) = fm_;
if (fontName == other->fontName)
return true;
if (!fontName)
return false;
if (!other->fontName)
return false;
return strcmp(fontName, other->fontName) == 0;
}
void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, int extraFontFlag) {
sizeZoomed = size + zoomLevel;
if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
sizeZoomed = 2;
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
aliasOfDefaultFont = defaultStyle &&
(EquivalentFontTo(defaultStyle) || !fontName);
if (aliasOfDefaultFont) {
font.SetID(defaultStyle->font.GetID());
} else if (fontName) {
font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
} else {
font.SetID(0);
}
ascent = surface.Ascent(font);
descent = surface.Descent(font);
// Probably more typographically correct to include leading
// but that means more complex drawing as leading must be erased
//lineHeight = surface.ExternalLeading() + surface.Height();
externalLeading = surface.ExternalLeading(font);
lineHeight = surface.Height(font);
aveCharWidth = surface.AverageCharWidth(font);
spaceWidth = surface.WidthChar(font, ' ');
} }

View File

@ -12,18 +12,54 @@
namespace Scintilla { namespace Scintilla {
#endif #endif
/** struct FontSpecification {
*/ const char *fontName;
class Style {
public:
ColourPair fore;
ColourPair back;
bool aliasOfDefaultFont;
bool bold; bool bold;
bool italic; bool italic;
int size; int size;
const char *fontName;
int characterSet; int characterSet;
int extraFontFlag;
FontSpecification() :
fontName(0),
bold(false),
italic(false),
size(10),
characterSet(0),
extraFontFlag(0) {
}
bool EqualTo(const FontSpecification &other) const;
};
// Just like Font but only has a copy of the FontID so should not delete it
class FontAlias : public Font {
// Private so FontAlias objects can not be copied
FontAlias(const FontAlias &);
FontAlias &operator=(const FontAlias &);
public:
FontAlias();
virtual ~FontAlias();
void MakeAlias(Font &fontOrigin);
void ClearFont();
};
struct FontMeasurements {
unsigned int lineHeight;
unsigned int ascent;
unsigned int descent;
unsigned int externalLeading;
unsigned int aveCharWidth;
unsigned int spaceWidth;
int sizeZoomed;
FontMeasurements();
void Clear();
};
/**
*/
class Style : public FontSpecification, public FontMeasurements {
public:
ColourPair fore;
ColourPair back;
bool eolFilled; bool eolFilled;
bool underline; bool underline;
enum ecaseForced {caseMixed, caseUpper, caseLower}; enum ecaseForced {caseMixed, caseUpper, caseLower};
@ -32,14 +68,7 @@ public:
bool changeable; bool changeable;
bool hotspot; bool hotspot;
Font font; FontAlias font;
int sizeZoomed;
unsigned int lineHeight;
unsigned int ascent;
unsigned int descent;
unsigned int externalLeading;
unsigned int aveCharWidth;
unsigned int spaceWidth;
Style(); Style();
Style(const Style &source); Style(const Style &source);
@ -52,8 +81,7 @@ public:
bool underline_, ecaseForced caseForce_, bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_); bool visible_, bool changeable_, bool hotspot_);
void ClearTo(const Style &source); void ClearTo(const Style &source);
bool EquivalentFontTo(const Style *other) const; void Copy(Font &font_, const FontMeasurements &fm_);
void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0);
bool IsProtected() const { return !(changeable && visible);} bool IsProtected() const { return !(changeable && visible);}
}; };

View File

@ -7,6 +7,9 @@
#include <string.h> #include <string.h>
#include <vector>
#include <map>
#include "Platform.h" #include "Platform.h"
#include "Scintilla.h" #include "Scintilla.h"
@ -72,11 +75,66 @@ const char *FontNames::Save(const char *name) {
return names[max-1]; return names[max-1];
} }
FontRealised::FontRealised(const FontSpecification &fs) {
frNext = NULL;
(FontSpecification &)(*this) = fs;
}
FontRealised::~FontRealised() {
font.Release();
delete frNext;
frNext = 0;
}
void FontRealised::Realise(Surface &surface, int zoomLevel) {
PLATFORM_ASSERT(fontName);
sizeZoomed = size + zoomLevel;
if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
sizeZoomed = 2;
int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
ascent = surface.Ascent(font);
descent = surface.Descent(font);
externalLeading = surface.ExternalLeading(font);
lineHeight = surface.Height(font);
aveCharWidth = surface.AverageCharWidth(font);
spaceWidth = surface.WidthChar(font, ' ');
if (frNext) {
frNext->Realise(surface, zoomLevel);
}
}
FontRealised *FontRealised::Find(const FontSpecification &fs) {
if (!fs.fontName)
return this;
FontRealised *fr = this;
while (fr) {
if (fr->EqualTo(fs))
return fr;
fr = fr->frNext;
}
return 0;
}
void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent) {
FontRealised *fr = this;
while (fr) {
if (maxAscent < fr->ascent)
maxAscent = fr->ascent;
if (maxDescent < fr->descent)
maxDescent = fr->descent;
fr = fr->frNext;
}
}
ViewStyle::ViewStyle() { ViewStyle::ViewStyle() {
Init(); Init();
} }
ViewStyle::ViewStyle(const ViewStyle &source) { ViewStyle::ViewStyle(const ViewStyle &source) {
frFirst = NULL;
Init(source.stylesSize); Init(source.stylesSize);
for (unsigned int sty=0; sty<source.stylesSize; sty++) { for (unsigned int sty=0; sty<source.stylesSize; sty++) {
styles[sty] = source.styles[sty]; styles[sty] = source.styles[sty];
@ -150,14 +208,21 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
marginStyleOffset = source.marginStyleOffset; marginStyleOffset = source.marginStyleOffset;
annotationVisible = source.annotationVisible; annotationVisible = source.annotationVisible;
annotationStyleOffset = source.annotationStyleOffset; annotationStyleOffset = source.annotationStyleOffset;
braceHighlightIndicatorSet = source.braceHighlightIndicatorSet;
braceHighlightIndicator = source.braceHighlightIndicator;
braceBadLightIndicatorSet = source.braceBadLightIndicatorSet;
braceBadLightIndicator = source.braceBadLightIndicator;
} }
ViewStyle::~ViewStyle() { ViewStyle::~ViewStyle() {
delete []styles; delete []styles;
styles = NULL; styles = NULL;
delete frFirst;
frFirst = NULL;
} }
void ViewStyle::Init(size_t stylesSize_) { void ViewStyle::Init(size_t stylesSize_) {
frFirst = NULL;
stylesSize = 0; stylesSize = 0;
styles = NULL; styles = NULL;
AllocStyles(stylesSize_); AllocStyles(stylesSize_);
@ -255,6 +320,10 @@ void ViewStyle::Init(size_t stylesSize_) {
marginStyleOffset = 0; marginStyleOffset = 0;
annotationVisible = ANNOTATION_HIDDEN; annotationVisible = ANNOTATION_HIDDEN;
annotationStyleOffset = 0; annotationStyleOffset = 0;
braceHighlightIndicatorSet = false;
braceHighlightIndicator = 0;
braceBadLightIndicatorSet = false;
braceBadLightIndicator = 0;
} }
void ViewStyle::RefreshColourPalette(Palette &pal, bool want) { void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
@ -290,33 +359,59 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(hotspotBackground, want); pal.WantFind(hotspotBackground, want);
} }
void ViewStyle::CreateFont(const FontSpecification &fs) {
if (fs.fontName) {
for (FontRealised *cur=frFirst; cur; cur=cur->frNext) {
if (cur->EqualTo(fs))
return;
if (!cur->frNext) {
cur->frNext = new FontRealised(fs);
return;
}
}
frFirst = new FontRealised(fs);
}
}
void ViewStyle::Refresh(Surface &surface) { void ViewStyle::Refresh(Surface &surface) {
delete frFirst;
frFirst = NULL;
selbar.desired = Platform::Chrome(); selbar.desired = Platform::Chrome();
selbarlight.desired = Platform::ChromeHighlight(); selbarlight.desired = Platform::ChromeHighlight();
styles[STYLE_DEFAULT].Realise(surface, zoomLevel, NULL, extraFontFlag);
maxAscent = styles[STYLE_DEFAULT].ascent; for (unsigned int i=0; i<stylesSize; i++) {
maxDescent = styles[STYLE_DEFAULT].descent; styles[i].extraFontFlag = extraFontFlag;
}
CreateFont(styles[STYLE_DEFAULT]);
for (unsigned int j=0; j<stylesSize; j++) {
CreateFont(styles[j]);
}
frFirst->Realise(surface, zoomLevel);
for (unsigned int k=0; k<stylesSize; k++) {
FontRealised *fr = frFirst->Find(styles[k]);
styles[k].Copy(fr->font, *fr);
}
maxAscent = 1;
maxDescent = 1;
frFirst->FindMaxAscentDescent(maxAscent, maxDescent);
maxAscent += extraAscent;
maxDescent += extraDescent;
lineHeight = maxAscent + maxDescent;
someStylesProtected = false; someStylesProtected = false;
someStylesForceCase = false; someStylesForceCase = false;
for (unsigned int i=0; i<stylesSize; i++) { for (unsigned int l=0; l<stylesSize; l++) {
if (i != STYLE_DEFAULT) { if (styles[l].IsProtected()) {
styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT], extraFontFlag);
if (maxAscent < styles[i].ascent)
maxAscent = styles[i].ascent;
if (maxDescent < styles[i].descent)
maxDescent = styles[i].descent;
}
if (styles[i].IsProtected()) {
someStylesProtected = true; someStylesProtected = true;
} }
if (styles[i].caseForce != Style::caseMixed) { if (styles[l].caseForce != Style::caseMixed) {
someStylesForceCase = true; someStylesForceCase = true;
} }
} }
maxAscent += extraAscent;
maxDescent += extraDescent;
lineHeight = maxAscent + maxDescent;
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth; aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
spaceWidth = styles[STYLE_DEFAULT].spaceWidth; spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
@ -361,10 +456,10 @@ void ViewStyle::EnsureStyle(size_t index) {
void ViewStyle::ResetDefaultStyle() { void ViewStyle::ResetDefaultStyle() {
styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
ColourDesired(0xff,0xff,0xff), ColourDesired(0xff,0xff,0xff),
Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()), Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
SC_CHARSET_DEFAULT, SC_CHARSET_DEFAULT,
false, false, false, false, Style::caseMixed, true, true, false); false, false, false, false, Style::caseMixed, true, true, false);
} }
void ViewStyle::ClearStyles() { void ViewStyle::ClearStyles() {

View File

@ -39,6 +39,20 @@ public:
const char *Save(const char *name); const char *Save(const char *name);
}; };
class FontRealised : public FontSpecification, public FontMeasurements {
// Private so FontRealised objects can not be copied
FontRealised(const FontRealised &);
FontRealised &operator=(const FontRealised &);
public:
Font font;
FontRealised *frNext;
FontRealised(const FontSpecification &fs);
virtual ~FontRealised();
void Realise(Surface &surface, int zoomLevel);
FontRealised *Find(const FontSpecification &fs);
void FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent);
};
enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth}; enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth};
enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2}; enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2};
@ -48,6 +62,7 @@ enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterInden
class ViewStyle { class ViewStyle {
public: public:
FontNames fontNames; FontNames fontNames;
FontRealised *frFirst;
size_t stylesSize; size_t stylesSize;
Style *styles; Style *styles;
LineMarker markers[MARKER_MAX + 1]; LineMarker markers[MARKER_MAX + 1];
@ -114,11 +129,16 @@ public:
int marginStyleOffset; int marginStyleOffset;
int annotationVisible; int annotationVisible;
int annotationStyleOffset; int annotationStyleOffset;
bool braceHighlightIndicatorSet;
int braceHighlightIndicator;
bool braceBadLightIndicatorSet;
int braceBadLightIndicator;
ViewStyle(); ViewStyle();
ViewStyle(const ViewStyle &source); ViewStyle(const ViewStyle &source);
~ViewStyle(); ~ViewStyle();
void Init(size_t stylesSize_=64); void Init(size_t stylesSize_=64);
void CreateFont(const FontSpecification &fs);
void RefreshColourPalette(Palette &pal, bool want); void RefreshColourPalette(Palette &pal, bool want);
void Refresh(Surface &surface); void Refresh(Surface &surface);
void AllocStyles(size_t sizeNew); void AllocStyles(size_t sizeNew);

View File

@ -8,6 +8,13 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#include <vector>
#include <map>
#include "Platform.h" #include "Platform.h"
#include "XPM.h" #include "XPM.h"
@ -38,6 +45,10 @@ static size_t MeasureLength(const char *s) {
return i; return i;
} }
ColourDesired XPM::ColourDesiredFromCode(int ch) const {
return colourCodeTable[ch]->desired;
}
ColourAllocated XPM::ColourFromCode(int ch) const { ColourAllocated XPM::ColourFromCode(int ch) const {
return colourCodeTable[ch]->allocated; return colourCodeTable[ch]->allocated;
#ifdef SLOW #ifdef SLOW
@ -200,6 +211,21 @@ void XPM::Draw(Surface *surface, PRectangle &rc) {
} }
} }
void XPM::PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const {
if (!data || !codes || !colours || !lines || (x<0) || (x >= width) || (y<0) || (y >= height)) {
colour = 0;
transparent = true;
return;
}
int code = lines[y+nColours+1][x];
transparent = code == codeTransparent;
if (transparent) {
colour = 0;
} else {
colour = ColourDesiredFromCode(code).AsLong();
}
}
const char **XPM::LinesFormFromTextForm(const char *textForm) { const char **XPM::LinesFormFromTextForm(const char *textForm) {
// Build the lines form out of the text form // Build the lines form out of the text form
const char **linesForm = 0; const char **linesForm = 0;
@ -261,14 +287,14 @@ void XPMSet::Clear() {
width = -1; width = -1;
} }
void XPMSet::Add(int id, const char *textForm) { void XPMSet::Add(int ident, const char *textForm) {
// Invalidate cached dimensions // Invalidate cached dimensions
height = -1; height = -1;
width = -1; width = -1;
// Replace if this id already present // Replace if this id already present
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (set[i]->GetId() == id) { if (set[i]->GetId() == ident) {
set[i]->Init(textForm); set[i]->Init(textForm);
set[i]->CopyDesiredColours(); set[i]->CopyDesiredColours();
return; return;
@ -278,7 +304,7 @@ void XPMSet::Add(int id, const char *textForm) {
// Not present, so add to end // Not present, so add to end
XPM *pxpm = new XPM(textForm); XPM *pxpm = new XPM(textForm);
if (pxpm) { if (pxpm) {
pxpm->SetId(id); pxpm->SetId(ident);
pxpm->CopyDesiredColours(); pxpm->CopyDesiredColours();
if (len == maximum) { if (len == maximum) {
maximum += 64; maximum += 64;
@ -294,9 +320,9 @@ void XPMSet::Add(int id, const char *textForm) {
} }
} }
XPM *XPMSet::Get(int id) { XPM *XPMSet::Get(int ident) {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (set[i]->GetId() == id) { if (set[i]->GetId() == ident) {
return set[i]; return set[i];
} }
} }
@ -324,3 +350,110 @@ int XPMSet::GetWidth() {
} }
return (width > 0) ? width : 0; return (width > 0) ? width : 0;
} }
RGBAImage::RGBAImage(int width_, int height_, const unsigned char *pixels_) :
height(height_), width(width_) {
if (pixels_) {
pixelBytes.assign(pixels_, pixels_ + CountBytes());
} else {
pixelBytes.resize(CountBytes());
}
}
RGBAImage::RGBAImage(const XPM &xpm) {
height = xpm.GetHeight();
width = xpm.GetWidth();
pixelBytes.resize(CountBytes());
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
ColourDesired colour;
bool transparent = false;
xpm.PixelAt(x, y, colour, transparent);
SetPixel(x, y, colour, transparent ? 0 : 255);
}
}
}
RGBAImage::~RGBAImage() {
}
int RGBAImage::CountBytes() const {
return width * height * 4;
}
const unsigned char *RGBAImage::Pixels() const {
return &pixelBytes[0];
}
void RGBAImage::SetPixel(int x, int y, ColourDesired colour, int alpha) {
unsigned char *pixel = &pixelBytes[0] + (y*width+x) * 4;
// RGBA
pixel[0] = colour.GetRed();
pixel[1] = colour.GetGreen();
pixel[2] = colour.GetBlue();
pixel[3] = alpha;
}
RGBAImageSet::RGBAImageSet() : height(-1), width(-1){
}
RGBAImageSet::~RGBAImageSet() {
Clear();
}
/// Remove all images.
void RGBAImageSet::Clear() {
for (ImageMap::iterator it=images.begin(); it != images.end(); ++it) {
delete it->second;
it->second = 0;
}
images.clear();
height = -1;
width = -1;
}
/// Add an image.
void RGBAImageSet::Add(int ident, RGBAImage *image) {
ImageMap::iterator it=images.find(ident);
if (it == images.end()) {
images[ident] = image;
} else {
delete it->second;
it->second = image;
}
height = -1;
width = -1;
}
/// Get image by id.
RGBAImage *RGBAImageSet::Get(int ident) {
ImageMap::iterator it = images.find(ident);
if (it != images.end()) {
return it->second;
}
return NULL;
}
/// Give the largest height of the set.
int RGBAImageSet::GetHeight() const {
if (height < 0) {
for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) {
if (height < it->second->GetHeight()) {
height = it->second->GetHeight();
}
}
}
return (height > 0) ? height : 0;
}
/// Give the largest width of the set.
int RGBAImageSet::GetWidth() const {
if (width < 0) {
for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) {
if (width < it->second->GetWidth()) {
width = it->second->GetWidth();
}
}
}
return (width > 0) ? width : 0;
}

View File

@ -24,6 +24,7 @@ class XPM {
char codeTransparent; char codeTransparent;
char *codes; char *codes;
ColourPair *colours; ColourPair *colours;
ColourDesired ColourDesiredFromCode(int ch) const;
ColourAllocated ColourFromCode(int ch) const; ColourAllocated ColourFromCode(int ch) const;
void FillRun(Surface *surface, int code, int startX, int y, int x); void FillRun(Surface *surface, int code, int startX, int y, int x);
char **lines; char **lines;
@ -46,6 +47,7 @@ public:
int GetId() const { return pid; } int GetId() const { return pid; }
int GetHeight() const { return height; } int GetHeight() const { return height; }
int GetWidth() const { return width; } int GetWidth() const { return width; }
void PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const;
static const char **LinesFormFromTextForm(const char *textForm); static const char **LinesFormFromTextForm(const char *textForm);
}; };
@ -64,15 +66,59 @@ public:
/// Remove all XPMs. /// Remove all XPMs.
void Clear(); void Clear();
/// Add a XPM. /// Add a XPM.
void Add(int id, const char *textForm); void Add(int ident, const char *textForm);
/// Get XPM by id. /// Get XPM by id.
XPM *Get(int id); XPM *Get(int ident);
/// Give the largest height of the set. /// Give the largest height of the set.
int GetHeight(); int GetHeight();
/// Give the largest width of the set. /// Give the largest width of the set.
int GetWidth(); int GetWidth();
}; };
/**
* An translucent image stoed as a sequence of RGBA bytes.
*/
class RGBAImage {
// Private so RGBAImage objects can not be copied
RGBAImage(const RGBAImage &);
RGBAImage &operator=(const RGBAImage &);
int height;
int width;
std::vector<unsigned char> pixelBytes;
public:
RGBAImage(int width_, int height_, const unsigned char *pixels_);
RGBAImage(const XPM &xpm);
virtual ~RGBAImage();
int GetHeight() const { return height; }
int GetWidth() const { return width; }
int CountBytes() const;
const unsigned char *Pixels() const;
void SetPixel(int x, int y, ColourDesired colour, int alpha=0xff);
};
/**
* A collection of RGBAImage pixmaps indexed by integer id.
*/
class RGBAImageSet {
typedef std::map<int, RGBAImage*> ImageMap;
ImageMap images;
mutable int height; ///< Memorize largest height of the set.
mutable int width; ///< Memorize largest width of the set.
public:
RGBAImageSet();
~RGBAImageSet();
/// Remove all images.
void Clear();
/// Add an image.
void Add(int ident, RGBAImage *image);
/// Get image by id.
RGBAImage *Get(int ident);
/// Give the largest height of the set.
int GetHeight() const;
/// Give the largest width of the set.
int GetWidth() const;
};
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE
} }
#endif #endif

View File

@ -1 +1 @@
225 229

View File

@ -1173,12 +1173,20 @@ static void styleset_erlang(ScintillaObject *sci, gint ft_id)
static void styleset_latex_init(gint ft_id, GKeyFile *config, GKeyFile *config_home) static void styleset_latex_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
{ {
new_styleset(ft_id, 5); new_styleset(ft_id, 13);
get_keyfile_style(config, config_home, "default", &style_sets[ft_id].styling[0]); get_keyfile_style(config, config_home, "default", &style_sets[ft_id].styling[0]);
get_keyfile_style(config, config_home, "command", &style_sets[ft_id].styling[1]); get_keyfile_style(config, config_home, "command", &style_sets[ft_id].styling[1]);
get_keyfile_style(config, config_home, "tag", &style_sets[ft_id].styling[2]); get_keyfile_style(config, config_home, "tag", &style_sets[ft_id].styling[2]);
get_keyfile_style(config, config_home, "math", &style_sets[ft_id].styling[3]); get_keyfile_style(config, config_home, "math", &style_sets[ft_id].styling[3]);
get_keyfile_style(config, config_home, "comment", &style_sets[ft_id].styling[4]); get_keyfile_style(config, config_home, "comment", &style_sets[ft_id].styling[4]);
get_keyfile_style(config, config_home, "tag2", &style_sets[ft_id].styling[5]);
get_keyfile_style(config, config_home, "math2", &style_sets[ft_id].styling[6]);
get_keyfile_style(config, config_home, "comment2", &style_sets[ft_id].styling[7]);
get_keyfile_style(config, config_home, "verbatim", &style_sets[ft_id].styling[8]);
get_keyfile_style(config, config_home, "shortcmd", &style_sets[ft_id].styling[9]);
get_keyfile_style(config, config_home, "special", &style_sets[ft_id].styling[10]);
get_keyfile_style(config, config_home, "cmdopt", &style_sets[ft_id].styling[11]);
get_keyfile_style(config, config_home, "error", &style_sets[ft_id].styling[12]);
style_sets[ft_id].keywords = g_new(gchar*, 2); style_sets[ft_id].keywords = g_new(gchar*, 2);
get_keyfile_keywords(config, config_home, "primary", ft_id, 0); get_keyfile_keywords(config, config_home, "primary", ft_id, 0);
@ -1198,6 +1206,14 @@ static void styleset_latex(ScintillaObject *sci, gint ft_id)
set_sci_style(sci, SCE_L_TAG, ft_id, 2); set_sci_style(sci, SCE_L_TAG, ft_id, 2);
set_sci_style(sci, SCE_L_MATH, ft_id, 3); set_sci_style(sci, SCE_L_MATH, ft_id, 3);
set_sci_style(sci, SCE_L_COMMENT, ft_id, 4); set_sci_style(sci, SCE_L_COMMENT, ft_id, 4);
set_sci_style(sci, SCE_L_TAG2, ft_id, 5);
set_sci_style(sci, SCE_L_MATH2, ft_id, 6);
set_sci_style(sci, SCE_L_COMMENT2, ft_id, 7);
set_sci_style(sci, SCE_L_VERBATIM, ft_id, 8);
set_sci_style(sci, SCE_L_SHORTCMD, ft_id, 9);
set_sci_style(sci, SCE_L_SPECIAL, ft_id, 10);
set_sci_style(sci, SCE_L_CMDOPT, ft_id, 11);
set_sci_style(sci, SCE_L_ERROR, ft_id, 12);
} }
@ -1495,7 +1511,7 @@ static void styleset_java(ScintillaObject *sci, gint ft_id)
static void styleset_perl_init(gint ft_id, GKeyFile *config, GKeyFile *config_home) static void styleset_perl_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
{ {
new_styleset(ft_id, 35); new_styleset(ft_id, 45);
get_keyfile_style(config, config_home, "default", &style_sets[ft_id].styling[0]); get_keyfile_style(config, config_home, "default", &style_sets[ft_id].styling[0]);
get_keyfile_style(config, config_home, "error", &style_sets[ft_id].styling[1]); get_keyfile_style(config, config_home, "error", &style_sets[ft_id].styling[1]);
get_keyfile_style(config, config_home, "commentline", &style_sets[ft_id].styling[2]); get_keyfile_style(config, config_home, "commentline", &style_sets[ft_id].styling[2]);
@ -1531,6 +1547,16 @@ static void styleset_perl_init(gint ft_id, GKeyFile *config, GKeyFile *config_ho
get_keyfile_style(config, config_home, "sub_prototype", &style_sets[ft_id].styling[32]); get_keyfile_style(config, config_home, "sub_prototype", &style_sets[ft_id].styling[32]);
get_keyfile_style(config, config_home, "format_ident", &style_sets[ft_id].styling[33]); get_keyfile_style(config, config_home, "format_ident", &style_sets[ft_id].styling[33]);
get_keyfile_style(config, config_home, "format", &style_sets[ft_id].styling[34]); get_keyfile_style(config, config_home, "format", &style_sets[ft_id].styling[34]);
get_keyfile_style(config, config_home, "string_var", &style_sets[ft_id].styling[35]);
get_keyfile_style(config, config_home, "xlat", &style_sets[ft_id].styling[36]);
get_keyfile_style(config, config_home, "regex_var", &style_sets[ft_id].styling[37]);
get_keyfile_style(config, config_home, "regsubst_var", &style_sets[ft_id].styling[38]);
get_keyfile_style(config, config_home, "backticks_var", &style_sets[ft_id].styling[39]);
get_keyfile_style(config, config_home, "here_qq_var", &style_sets[ft_id].styling[40]);
get_keyfile_style(config, config_home, "here_qx_var", &style_sets[ft_id].styling[41]);
get_keyfile_style(config, config_home, "string_qq_var", &style_sets[ft_id].styling[42]);
get_keyfile_style(config, config_home, "string_qx_var", &style_sets[ft_id].styling[43]);
get_keyfile_style(config, config_home, "string_qr_var", &style_sets[ft_id].styling[44]);
style_sets[ft_id].keywords = g_new(gchar*, 2); style_sets[ft_id].keywords = g_new(gchar*, 2);
@ -1581,6 +1607,16 @@ static void styleset_perl(ScintillaObject *sci, gint ft_id)
set_sci_style(sci, SCE_PL_SUB_PROTOTYPE, ft_id, 32); set_sci_style(sci, SCE_PL_SUB_PROTOTYPE, ft_id, 32);
set_sci_style(sci, SCE_PL_FORMAT_IDENT, ft_id, 33); set_sci_style(sci, SCE_PL_FORMAT_IDENT, ft_id, 33);
set_sci_style(sci, SCE_PL_FORMAT, ft_id, 34); set_sci_style(sci, SCE_PL_FORMAT, ft_id, 34);
set_sci_style(sci, SCE_PL_STRING_VAR, ft_id, 35);
set_sci_style(sci, SCE_PL_XLAT, ft_id, 36);
set_sci_style(sci, SCE_PL_REGEX_VAR, ft_id, 37);
set_sci_style(sci, SCE_PL_REGSUBST_VAR, ft_id, 38);
set_sci_style(sci, SCE_PL_BACKTICKS_VAR, ft_id, 39);
set_sci_style(sci, SCE_PL_HERE_QQ_VAR, ft_id, 40);
set_sci_style(sci, SCE_PL_HERE_QX_VAR, ft_id, 41);
set_sci_style(sci, SCE_PL_STRING_QQ_VAR, ft_id, 42);
set_sci_style(sci, SCE_PL_STRING_QX_VAR, ft_id, 43);
set_sci_style(sci, SCE_PL_STRING_QR_VAR, ft_id, 44);
} }
@ -3065,7 +3101,7 @@ static void styleset_js(ScintillaObject *sci, gint ft_id)
static void styleset_lua_init(gint ft_id, GKeyFile *config, GKeyFile *config_home) static void styleset_lua_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
{ {
new_styleset(ft_id, 20); new_styleset(ft_id, 21);
get_keyfile_style(config, config_home, "default", &style_sets[ft_id].styling[0]); get_keyfile_style(config, config_home, "default", &style_sets[ft_id].styling[0]);
get_keyfile_style(config, config_home, "comment", &style_sets[ft_id].styling[1]); get_keyfile_style(config, config_home, "comment", &style_sets[ft_id].styling[1]);
@ -3087,6 +3123,7 @@ static void styleset_lua_init(gint ft_id, GKeyFile *config, GKeyFile *config_hom
get_keyfile_style(config, config_home, "word6", &style_sets[ft_id].styling[17]); get_keyfile_style(config, config_home, "word6", &style_sets[ft_id].styling[17]);
get_keyfile_style(config, config_home, "word7", &style_sets[ft_id].styling[18]); get_keyfile_style(config, config_home, "word7", &style_sets[ft_id].styling[18]);
get_keyfile_style(config, config_home, "word8", &style_sets[ft_id].styling[19]); get_keyfile_style(config, config_home, "word8", &style_sets[ft_id].styling[19]);
get_keyfile_style(config, config_home, "label", &style_sets[ft_id].styling[20]);
style_sets[ft_id].keywords = g_new(gchar*, 9); style_sets[ft_id].keywords = g_new(gchar*, 9);
get_keyfile_keywords(config, config_home, "keywords", ft_id, 0); get_keyfile_keywords(config, config_home, "keywords", ft_id, 0);
@ -3135,6 +3172,7 @@ static void styleset_lua(ScintillaObject *sci, gint ft_id)
set_sci_style(sci, SCE_LUA_WORD6, ft_id, 17); set_sci_style(sci, SCE_LUA_WORD6, ft_id, 17);
set_sci_style(sci, SCE_LUA_WORD7, ft_id, 18); set_sci_style(sci, SCE_LUA_WORD7, ft_id, 18);
set_sci_style(sci, SCE_LUA_WORD8, ft_id, 19); set_sci_style(sci, SCE_LUA_WORD8, ft_id, 19);
set_sci_style(sci, SCE_LUA_LABEL, ft_id, 20);
} }
@ -3726,7 +3764,7 @@ gboolean highlighting_is_string_style(gint lexer, gint style)
style == SCE_F_STRINGEOL); style == SCE_F_STRINGEOL);
case SCLEX_PERL: case SCLEX_PERL:
return (/*style == SCE_PL_STRING ||*/ /* may want variable autocompletion "$(foo)" */ return (style == SCE_PL_STRING ||
style == SCE_PL_CHARACTER || style == SCE_PL_CHARACTER ||
style == SCE_PL_HERE_DELIM || style == SCE_PL_HERE_DELIM ||
style == SCE_PL_HERE_Q || style == SCE_PL_HERE_Q ||
@ -3738,7 +3776,9 @@ gboolean highlighting_is_string_style(gint lexer, gint style)
style == SCE_PL_STRING_QX || style == SCE_PL_STRING_QX ||
style == SCE_PL_STRING_QR || style == SCE_PL_STRING_QR ||
style == SCE_PL_STRING_QW || style == SCE_PL_STRING_QW ||
style == SCE_PL_POD_VERB); style == SCE_PL_POD_VERB ||
style == SCE_PL_XLAT
/* we don't include any STRING_*_VAR for autocompletion */);
case SCLEX_R: case SCLEX_R:
return (style == SCE_R_STRING); return (style == SCE_R_STRING);
@ -3882,7 +3922,8 @@ gboolean highlighting_is_comment_style(gint lexer, gint style)
return (style == SCE_PO_COMMENT); return (style == SCE_PO_COMMENT);
case SCLEX_LATEX: case SCLEX_LATEX:
return (style == SCE_L_COMMENT); return (style == SCE_L_COMMENT ||
style == SCE_L_COMMENT2);
case SCLEX_MAKEFILE: case SCLEX_MAKEFILE:
return (style == SCE_MAKE_COMMENT); return (style == SCE_MAKE_COMMENT);