Update Scintilla to version 3.4.1

This commit is contained in:
Colomban Wendling 2014-04-14 16:25:01 +02:00
parent d32ae83202
commit 6c5a0dd717
71 changed files with 1019 additions and 688 deletions

View File

@ -69,6 +69,7 @@ lexlib/OptionSet.h \
lexlib/PropSetSimple.cxx \ lexlib/PropSetSimple.cxx \
lexlib/PropSetSimple.h \ lexlib/PropSetSimple.h \
lexlib/SparseState.h \ lexlib/SparseState.h \
lexlib/StringCopy.h \
lexlib/StyleContext.cxx \ lexlib/StyleContext.cxx \
lexlib/StyleContext.h \ lexlib/StyleContext.h \
lexlib/SubStyles.h \ lexlib/SubStyles.h \

View File

@ -51,8 +51,8 @@ public:
// Try allowing approximate transliterations // Try allowing approximate transliterations
if (transliterations) { if (transliterations) {
char fullDest[200]; char fullDest[200];
strcpy(fullDest, charSetDestination); g_strlcpy(fullDest, charSetDestination, sizeof(fullDest));
strcat(fullDest, "//TRANSLIT"); g_strlcat(fullDest, "//TRANSLIT", sizeof(fullDest));
OpenHandle(fullDest, charSetSource); OpenHandle(fullDest, charSetSource);
} }
if (!Succeeded()) { if (!Succeeded()) {

View File

@ -23,8 +23,9 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "ScintillaWidget.h" #include "ScintillaWidget.h"
#include "UniConversion.h" #include "StringCopy.h"
#include "XPM.h" #include "XPM.h"
#include "UniConversion.h"
#if defined(__clang__) #if defined(__clang__)
// Clang 3.0 incorrectly displays sentinel warnings. Fixed by clang 3.1. // Clang 3.0 incorrectly displays sentinel warnings. Fixed by clang 3.1.
@ -48,7 +49,7 @@
static const double kPi = 3.14159265358979323846; static const double kPi = 3.14159265358979323846;
// The Pango version guard for pango_units_from_double and pango_units_to_double // The Pango version guard for pango_units_from_double and pango_units_to_double
// is more complex than simply implementing these here. // is more complex than simply implementing these here.
static int pangoUnitsFromDouble(double d) { static int pangoUnitsFromDouble(double d) {
@ -226,12 +227,12 @@ Point Point::FromLong(long lpoint) {
} }
static void SetLogFont(LOGFONT &lf, const char *faceName, int characterSet, float size, int weight, bool italic) { static void SetLogFont(LOGFONT &lf, const char *faceName, int characterSet, float size, int weight, bool italic) {
memset(&lf, 0, sizeof(lf)); lf = LOGFONT();
lf.size = size; lf.size = size;
lf.weight = weight; lf.weight = weight;
lf.italic = italic; lf.italic = italic;
lf.characterSet = characterSet; lf.characterSet = characterSet;
strncpy(lf.faceName, faceName, sizeof(lf.faceName) - 1); StringCopy(lf.faceName, faceName);
} }
/** /**
@ -253,7 +254,7 @@ class FontCached : Font {
int usage; int usage;
LOGFONT lf; LOGFONT lf;
int hash; int hash;
FontCached(const FontParameters &fp); explicit FontCached(const FontParameters &fp);
~FontCached() {} ~FontCached() {}
bool SameAs(const FontParameters &fp); bool SameAs(const FontParameters &fp);
virtual void Release(); virtual void Release();
@ -339,7 +340,7 @@ void FontCached::ReleaseAll() {
FontID FontCached::CreateNewFont(const FontParameters &fp) { FontID FontCached::CreateNewFont(const FontParameters &fp) {
PangoFontDescription *pfd = pango_font_description_new(); PangoFontDescription *pfd = pango_font_description_new();
if (pfd) { if (pfd) {
pango_font_description_set_family(pfd, pango_font_description_set_family(pfd,
(fp.faceName[0] == '!') ? fp.faceName+1 : fp.faceName); (fp.faceName[0] == '!') ? fp.faceName+1 : fp.faceName);
pango_font_description_set_size(pfd, pangoUnitsFromDouble(fp.size)); pango_font_description_set_size(pfd, pangoUnitsFromDouble(fp.size));
pango_font_description_set_weight(pfd, static_cast<PangoWeight>(fp.weight)); pango_font_description_set_weight(pfd, static_cast<PangoWeight>(fp.weight));
@ -666,7 +667,7 @@ void SurfaceImpl::Polygon(Point *pts, int npts, ColourDesired fore,
ColourDesired back) { ColourDesired back) {
PenColour(back); PenColour(back);
cairo_move_to(context, pts[0].x + 0.5, pts[0].y + 0.5); cairo_move_to(context, pts[0].x + 0.5, pts[0].y + 0.5);
for (int i = 1;i < npts;i++) { for (int i = 1; i < npts; i++) {
cairo_line_to(context, pts[i].x + 0.5, pts[i].y + 0.5); cairo_line_to(context, pts[i].x + 0.5, pts[i].y + 0.5);
} }
cairo_close_path(context); cairo_close_path(context);
@ -734,7 +735,7 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesi
Point(rc.left, rc.bottom - 2), Point(rc.left, rc.bottom - 2),
Point(rc.left, rc.top + 2), Point(rc.left, rc.top + 2),
}; };
Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore, back); Polygon(pts, ELEMENTS(pts), fore, back);
} else { } else {
RectangleDraw(rc, fore, back); RectangleDraw(rc, fore, back);
} }
@ -821,7 +822,7 @@ void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsi
void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) { void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) {
PenColour(back); PenColour(back);
cairo_arc(context, (rc.left + rc.right) / 2 + 0.5, (rc.top + rc.bottom) / 2 + 0.5, cairo_arc(context, (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2,
Platform::Minimum(rc.Width(), rc.Height()) / 2, 0, 2*kPi); Platform::Minimum(rc.Width(), rc.Height()) / 2, 0, 2*kPi);
cairo_fill_preserve(context); cairo_fill_preserve(context);
PenColour(fore); PenColour(fore);
@ -842,7 +843,7 @@ void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
std::string UTF8FromLatin1(const char *s, int len) { std::string UTF8FromLatin1(const char *s, int len) {
std::string utfForm(len*2 + 1, '\0'); std::string utfForm(len*2 + 1, '\0');
size_t lenU = 0; size_t lenU = 0;
for (int i=0;i<len;i++) { for (int i=0; i<len; i++) {
unsigned int uch = static_cast<unsigned char>(s[i]); unsigned int uch = static_cast<unsigned char>(s[i]);
if (uch < 0x80) { if (uch < 0x80) {
utfForm[lenU++] = uch; utfForm[lenU++] = uch;
@ -936,7 +937,7 @@ void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase,
void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len,
ColourDesired fore) { ColourDesired fore) {
// Avoid drawing spaces in transparent mode // Avoid drawing spaces in transparent mode
for (int i=0;i<len;i++) { for (int i=0; i<len; i++) {
if (s[i] != ' ') { if (s[i] != ' ') {
DrawTextBase(rc, font_, ybase, s, len, fore); DrawTextBase(rc, font_, ybase, s, len, fore);
return; return;
@ -1064,7 +1065,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION
int widthLayout = 0; int widthLayout = 0;
pango_layout_get_size(layout, &widthLayout, NULL); pango_layout_get_size(layout, &widthLayout, NULL);
XYPOSITION widthTotal = doubleFromPangoUnits(widthLayout); XYPOSITION widthTotal = doubleFromPangoUnits(widthLayout);
for (int bytePos=0;bytePos<lenPositions; bytePos++) { for (int bytePos=0; bytePos<lenPositions; bytePos++) {
positions[bytePos] = widthTotal / lenPositions * (bytePos + 1); positions[bytePos] = widthTotal / lenPositions * (bytePos + 1);
} }
return; return;
@ -1598,7 +1599,7 @@ PRectangle ListBoxX::GetDesiredRect() {
GtkRequisition req; GtkRequisition req;
#if GTK_CHECK_VERSION(3,0,0) #if GTK_CHECK_VERSION(3,0,0)
// This, apparently unnecessary call, ensures gtk_tree_view_column_cell_get_size // This, apparently unnecessary call, ensures gtk_tree_view_column_cell_get_size
// returns reasonable values. // returns reasonable values.
gtk_widget_get_preferred_size(GTK_WIDGET(scroller), NULL, &req); gtk_widget_get_preferred_size(GTK_WIDGET(scroller), NULL, &req);
#endif #endif
int height; int height;
@ -1830,8 +1831,7 @@ void ListBoxX::GetValue(int n, char *value, int len) {
gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1); gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1);
} }
if (text && len > 0) { if (text && len > 0) {
strncpy(value, text, len); g_strlcpy(value, text, len);
value[len - 1] = '\0';
} else { } else {
value[0] = '\0'; value[0] = '\0';
} }
@ -1963,7 +1963,7 @@ class DynamicLibraryImpl : public DynamicLibrary {
protected: protected:
GModule* m; GModule* m;
public: public:
DynamicLibraryImpl(const char *modulePath) { explicit DynamicLibraryImpl(const char *modulePath) {
m = g_module_open(modulePath, G_MODULE_BIND_LAZY); m = g_module_open(modulePath, G_MODULE_BIND_LAZY);
} }
@ -1981,8 +1981,9 @@ public:
return static_cast<Function>(fn_address); return static_cast<Function>(fn_address);
else else
return NULL; return NULL;
} else } else {
return NULL; return NULL;
}
} }
virtual bool IsValid() { virtual bool IsValid() {
@ -2141,8 +2142,7 @@ bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
void Platform::Assert(const char *c, const char *file, int line) { void Platform::Assert(const char *c, const char *file, int line) {
char buffer[2000]; char buffer[2000];
sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); g_snprintf(buffer, sizeof(buffer), "Assertion [%s] failed at %s %d\r\n", c, file, line);
strcat(buffer, "\r\n");
Platform::DebugDisplay(buffer); Platform::DebugDisplay(buffer);
abort(); abort();
} }

View File

@ -31,6 +31,7 @@
#ifdef SCI_LEXER #ifdef SCI_LEXER
#include "SciLexer.h" #include "SciLexer.h"
#endif #endif
#include "StringCopy.h"
#include "SplitVector.h" #include "SplitVector.h"
#include "Partitioning.h" #include "Partitioning.h"
#include "RunStyles.h" #include "RunStyles.h"
@ -165,7 +166,7 @@ class ScintillaGTK : public ScintillaBase {
ScintillaGTK &operator=(const ScintillaGTK &); ScintillaGTK &operator=(const ScintillaGTK &);
public: public:
ScintillaGTK(_ScintillaObject *sci_); explicit ScintillaGTK(_ScintillaObject *sci_);
virtual ~ScintillaGTK(); virtual ~ScintillaGTK();
static void ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class); static void ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class);
private: private:
@ -338,14 +339,14 @@ static const GtkTargetEntry clipboardCopyTargets[] = {
{ (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING }, { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING },
{ (gchar *) "STRING", 0, TARGET_STRING }, { (gchar *) "STRING", 0, TARGET_STRING },
}; };
static const gint nClipboardCopyTargets = sizeof(clipboardCopyTargets) / sizeof(clipboardCopyTargets[0]); static const gint nClipboardCopyTargets = ELEMENTS(clipboardCopyTargets);
static const GtkTargetEntry clipboardPasteTargets[] = { static const GtkTargetEntry clipboardPasteTargets[] = {
{ (gchar *) "text/uri-list", 0, TARGET_URI }, { (gchar *) "text/uri-list", 0, TARGET_URI },
{ (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING }, { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING },
{ (gchar *) "STRING", 0, TARGET_STRING }, { (gchar *) "STRING", 0, TARGET_STRING },
}; };
static const gint nClipboardPasteTargets = sizeof(clipboardPasteTargets) / sizeof(clipboardPasteTargets[0]); static const gint nClipboardPasteTargets = ELEMENTS(clipboardPasteTargets);
static GtkWidget *PWidget(Window &w) { static GtkWidget *PWidget(Window &w) {
return reinterpret_cast<GtkWidget *>(w.GetID()); return reinterpret_cast<GtkWidget *>(w.GetID());
@ -1126,7 +1127,7 @@ void ScintillaGTK::SetVerticalScrollPos() {
void ScintillaGTK::SetHorizontalScrollPos() { void ScintillaGTK::SetHorizontalScrollPos() {
DwellEnd(true); DwellEnd(true);
gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmenth), xOffset / 2); gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmenth), xOffset);
} }
bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) { bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
@ -1244,7 +1245,7 @@ const char *ScintillaGTK::CharacterSetID() const {
class CaseFolderDBCS : public CaseFolderTable { class CaseFolderDBCS : public CaseFolderTable {
const char *charSet; const char *charSet;
public: public:
CaseFolderDBCS(const char *charSet_) : charSet(charSet_) { explicit CaseFolderDBCS(const char *charSet_) : charSet(charSet_) {
StandardASCII(); StandardASCII();
} }
virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
@ -1334,7 +1335,7 @@ std::string ScintillaGTK::CaseMapString(const std::string &s, int caseMapping) {
if (IsUnicodeMode()) { if (IsUnicodeMode()) {
std::string retMapped(s.length() * maxExpansionCaseConversion, 0); std::string retMapped(s.length() * maxExpansionCaseConversion, 0);
size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(),
(caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower); (caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower);
retMapped.resize(lenMapped); retMapped.resize(lenMapped);
return retMapped; return retMapped;
@ -1769,17 +1770,24 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) {
return FALSE; return FALSE;
} }
bool shift = (event->state & GDK_SHIFT_MASK) != 0;
bool ctrl = (event->state & GDK_CONTROL_MASK) != 0; bool ctrl = (event->state & GDK_CONTROL_MASK) != 0;
// On X, instead of sending literal modifiers use the user specified
// modifier, defaulting to control instead of alt.
// This is because most X window managers grab alt + click for moving
bool alt = (event->state & modifierTranslated(rectangularSelectionModifier)) != 0;
gtk_widget_grab_focus(PWidget(wMain)); gtk_widget_grab_focus(PWidget(wMain));
if (event->button == 1) { if (event->button == 1) {
// On X, instead of sending literal modifiers use the user specified #if PLAT_GTK_MACOSX
// modifier, defaulting to control instead of alt. bool meta = ctrl;
// This is because most X window managers grab alt + click for moving // GDK reports the Command modifer key as GDK_MOD2_MASK for button events,
ButtonDown(pt, event->time, // not GDK_META_MASK like in key events.
(event->state & GDK_SHIFT_MASK) != 0, ctrl = (event->state & GDK_MOD2_MASK) != 0;
(event->state & GDK_CONTROL_MASK) != 0, #else
(event->state & modifierTranslated(rectangularSelectionModifier)) != 0); bool meta = false;
#endif
ButtonDownWithModifiers(pt, event->time, ModifierFlags(shift, ctrl, alt, meta));
} else if (event->button == 2) { } else if (event->button == 2) {
// Grab the primary selection if it exists // Grab the primary selection if it exists
SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace()); SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace());
@ -1807,13 +1815,13 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) {
} else if (event->button == 4) { } else if (event->button == 4) {
// Wheel scrolling up (only GTK 1.x does it this way) // Wheel scrolling up (only GTK 1.x does it this way)
if (ctrl) if (ctrl)
SetAdjustmentValue(adjustmenth, (xOffset / 2) - 6); SetAdjustmentValue(adjustmenth, xOffset - 6);
else else
SetAdjustmentValue(adjustmentv, topLine - 3); SetAdjustmentValue(adjustmentv, topLine - 3);
} else if (event->button == 5) { } else if (event->button == 5) {
// Wheel scrolling down (only GTK 1.x does it this way) // Wheel scrolling down (only GTK 1.x does it this way)
if (ctrl) if (ctrl)
SetAdjustmentValue(adjustmenth, (xOffset / 2) + 6); SetAdjustmentValue(adjustmenth, xOffset + 6);
else else
SetAdjustmentValue(adjustmentv, topLine + 3); SetAdjustmentValue(adjustmentv, topLine + 3);
} }
@ -1950,7 +1958,7 @@ gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) {
GdkModifierType state; GdkModifierType state;
if (event->is_hint) { if (event->is_hint) {
#if GTK_CHECK_VERSION(3,0,0) #if GTK_CHECK_VERSION(3,0,0)
gdk_window_get_device_position(event->window, gdk_window_get_device_position(event->window,
event->device, &x, &y, &state); event->device, &x, &y, &state);
#else #else
gdk_window_get_pointer(event->window, &x, &y, &state); gdk_window_get_pointer(event->window, &x, &y, &state);
@ -2336,9 +2344,12 @@ void ScintillaGTK::RealizeText(GtkWidget *widget, void*) {
} }
} }
static GObjectClass *scintilla_class_parent_class;
void ScintillaGTK::Destroy(GObject *object) { void ScintillaGTK::Destroy(GObject *object) {
try { try {
ScintillaObject *scio = reinterpret_cast<ScintillaObject *>(object); ScintillaObject *scio = reinterpret_cast<ScintillaObject *>(object);
// This avoids a double destruction // This avoids a double destruction
if (!scio->pscin) if (!scio->pscin)
return; return;
@ -2348,6 +2359,7 @@ void ScintillaGTK::Destroy(GObject *object) {
delete sciThis; delete sciThis;
scio->pscin = 0; scio->pscin = 0;
scintilla_class_parent_class->finalize(object);
} catch (...) { } catch (...) {
// Its dead so nowhere to save the status // Its dead so nowhere to save the status
} }
@ -2510,9 +2522,9 @@ void ScintillaGTK::ScrollSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) {
void ScintillaGTK::ScrollHSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) { void ScintillaGTK::ScrollHSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) {
try { try {
#if GTK_CHECK_VERSION(3,0,0) #if GTK_CHECK_VERSION(3,0,0)
sciThis->HorizontalScrollTo(static_cast<int>(gtk_adjustment_get_value(adj) * 2)); sciThis->HorizontalScrollTo(static_cast<int>(gtk_adjustment_get_value(adj)));
#else #else
sciThis->HorizontalScrollTo(static_cast<int>(adj->value * 2)); sciThis->HorizontalScrollTo(static_cast<int>(adj->value));
#endif #endif
} catch (...) { } catch (...) {
sciThis->errorStatus = SC_STATUS_FAILURE; sciThis->errorStatus = SC_STATUS_FAILURE;
@ -2910,7 +2922,7 @@ static void scintilla_class_init(ScintillaClass *klass) {
klass->command = NULL; klass->command = NULL;
klass->notify = NULL; klass->notify = NULL;
scintilla_class_parent_class = G_OBJECT_CLASS(g_type_class_peek_parent(klass));
ScintillaGTK::ClassInit(object_class, widget_class, container_class); ScintillaGTK::ClassInit(object_class, widget_class, container_class);
} catch (...) { } catch (...) {
} }

View File

@ -444,6 +444,16 @@ public:
static DynamicLibrary *Load(const char *modulePath); static DynamicLibrary *Load(const char *modulePath);
}; };
#if defined(__clang__)
# if __has_feature(attribute_analyzer_noreturn)
# define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
# else
# define CLANG_ANALYZER_NORETURN
# endif
#else
# define CLANG_ANALYZER_NORETURN
#endif
/** /**
* Platform class used to retrieve system wide parameters such as double click speed * Platform class used to retrieve system wide parameters such as double click speed
* and chrome colour. Not a creatable object, more of a module with several functions. * and chrome colour. Not a creatable object, more of a module with several functions.
@ -488,7 +498,7 @@ public:
} }
static void DebugPrintf(const char *format, ...); static void DebugPrintf(const char *format, ...);
static bool ShowAssertionPopUps(bool assertionPopUps_); static bool ShowAssertionPopUps(bool assertionPopUps_);
static void Assert(const char *c, const char *file, int line); static void Assert(const char *c, const char *file, int line) CLANG_ANALYZER_NORETURN;
static int Clamp(int val, int minVal, int maxVal); static int Clamp(int val, int minVal, int maxVal);
}; };

View File

@ -124,6 +124,8 @@
#define SCLEX_STTXT 109 #define SCLEX_STTXT 109
#define SCLEX_KVIRC 110 #define SCLEX_KVIRC 110
#define SCLEX_RUST 111 #define SCLEX_RUST 111
#define SCLEX_DMAP 112
#define SCLEX_AS 113
#define SCLEX_AUTOMATIC 1000 #define SCLEX_AUTOMATIC 1000
#define SCE_P_DEFAULT 0 #define SCE_P_DEFAULT 0
#define SCE_P_COMMENTLINE 1 #define SCE_P_COMMENTLINE 1
@ -166,6 +168,7 @@
#define SCE_C_HASHQUOTEDSTRING 22 #define SCE_C_HASHQUOTEDSTRING 22
#define SCE_C_PREPROCESSORCOMMENT 23 #define SCE_C_PREPROCESSORCOMMENT 23
#define SCE_C_PREPROCESSORCOMMENTDOC 24 #define SCE_C_PREPROCESSORCOMMENTDOC 24
#define SCE_C_USERLITERAL 25
#define SCE_D_DEFAULT 0 #define SCE_D_DEFAULT 0
#define SCE_D_COMMENT 1 #define SCE_D_COMMENT 1
#define SCE_D_COMMENTLINE 2 #define SCE_D_COMMENTLINE 2
@ -420,6 +423,10 @@
#define SCE_B_ERROR 16 #define SCE_B_ERROR 16
#define SCE_B_HEXNUMBER 17 #define SCE_B_HEXNUMBER 17
#define SCE_B_BINNUMBER 18 #define SCE_B_BINNUMBER 18
#define SCE_B_COMMENTBLOCK 19
#define SCE_B_DOCLINE 20
#define SCE_B_DOCBLOCK 21
#define SCE_B_DOCKEYWORD 22
#define SCE_PROPS_DEFAULT 0 #define SCE_PROPS_DEFAULT 0
#define SCE_PROPS_COMMENT 1 #define SCE_PROPS_COMMENT 1
#define SCE_PROPS_SECTION 2 #define SCE_PROPS_SECTION 2
@ -1541,7 +1548,6 @@
#define SCE_COFFEESCRIPT_GLOBALCLASS 19 #define SCE_COFFEESCRIPT_GLOBALCLASS 19
#define SCE_COFFEESCRIPT_STRINGRAW 20 #define SCE_COFFEESCRIPT_STRINGRAW 20
#define SCE_COFFEESCRIPT_TRIPLEVERBATIM 21 #define SCE_COFFEESCRIPT_TRIPLEVERBATIM 21
#define SCE_COFFEESCRIPT_HASHQUOTEDSTRING 22
#define SCE_COFFEESCRIPT_COMMENTBLOCK 22 #define SCE_COFFEESCRIPT_COMMENTBLOCK 22
#define SCE_COFFEESCRIPT_VERBOSE_REGEX 23 #define SCE_COFFEESCRIPT_VERBOSE_REGEX 23
#define SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT 24 #define SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT 24
@ -1683,6 +1689,17 @@
#define SCE_RUST_LIFETIME 18 #define SCE_RUST_LIFETIME 18
#define SCE_RUST_MACRO 19 #define SCE_RUST_MACRO 19
#define SCE_RUST_LEXERROR 20 #define SCE_RUST_LEXERROR 20
#define SCE_DMAP_DEFAULT 0
#define SCE_DMAP_COMMENT 1
#define SCE_DMAP_NUMBER 2
#define SCE_DMAP_STRING1 3
#define SCE_DMAP_STRING2 4
#define SCE_DMAP_STRINGEOL 5
#define SCE_DMAP_OPERATOR 6
#define SCE_DMAP_IDENTIFIER 7
#define SCE_DMAP_WORD 8
#define SCE_DMAP_WORD2 9
#define SCE_DMAP_WORD3 10
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */ /* --Autogenerated -- end of section automatically generated from Scintilla.iface */
#endif #endif

View File

@ -125,6 +125,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#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_RGBAIMAGE 30
#define SC_MARK_BOOKMARK 31
#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
@ -358,8 +359,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SC_PRINT_COLOURONWHITEDEFAULTBG 4 #define SC_PRINT_COLOURONWHITEDEFAULTBG 4
#define SCI_SETPRINTCOLOURMODE 2148 #define SCI_SETPRINTCOLOURMODE 2148
#define SCI_GETPRINTCOLOURMODE 2149 #define SCI_GETPRINTCOLOURMODE 2149
#define SCFIND_WHOLEWORD 2 #define SCFIND_WHOLEWORD 0x2
#define SCFIND_MATCHCASE 4 #define SCFIND_MATCHCASE 0x4
#define SCFIND_WORDSTART 0x00100000 #define SCFIND_WORDSTART 0x00100000
#define SCFIND_REGEXP 0x00200000 #define SCFIND_REGEXP 0x00200000
#define SCFIND_POSIX 0x00400000 #define SCFIND_POSIX 0x00400000
@ -417,6 +418,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_CALLTIPCANCEL 2201 #define SCI_CALLTIPCANCEL 2201
#define SCI_CALLTIPACTIVE 2202 #define SCI_CALLTIPACTIVE 2202
#define SCI_CALLTIPPOSSTART 2203 #define SCI_CALLTIPPOSSTART 2203
#define SCI_CALLTIPSETPOSSTART 2214
#define SCI_CALLTIPSETHLT 2204 #define SCI_CALLTIPSETHLT 2204
#define SCI_CALLTIPSETBACK 2205 #define SCI_CALLTIPSETBACK 2205
#define SCI_CALLTIPSETFORE 2206 #define SCI_CALLTIPSETFORE 2206
@ -473,6 +475,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SC_WRAP_NONE 0 #define SC_WRAP_NONE 0
#define SC_WRAP_WORD 1 #define SC_WRAP_WORD 1
#define SC_WRAP_CHAR 2 #define SC_WRAP_CHAR 2
#define SC_WRAP_WHITESPACE 3
#define SCI_SETWRAPMODE 2268 #define SCI_SETWRAPMODE 2268
#define SCI_GETWRAPMODE 2269 #define SCI_GETWRAPMODE 2269
#define SC_WRAPVISUALFLAG_NONE 0x0000 #define SC_WRAPVISUALFLAG_NONE 0x0000
@ -817,6 +820,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_CLEARSELECTIONS 2571 #define SCI_CLEARSELECTIONS 2571
#define SCI_SETSELECTION 2572 #define SCI_SETSELECTION 2572
#define SCI_ADDSELECTION 2573 #define SCI_ADDSELECTION 2573
#define SCI_DROPSELECTIONN 2671
#define SCI_SETMAINSELECTION 2574 #define SCI_SETMAINSELECTION 2574
#define SCI_GETMAINSELECTION 2575 #define SCI_GETMAINSELECTION 2575
#define SCI_SETSELECTIONNCARET 2576 #define SCI_SETSELECTIONNCARET 2576
@ -880,6 +884,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_VCHOMEDISPLAYEXTEND 2653 #define SCI_VCHOMEDISPLAYEXTEND 2653
#define SCI_GETCARETLINEVISIBLEALWAYS 2654 #define SCI_GETCARETLINEVISIBLEALWAYS 2654
#define SCI_SETCARETLINEVISIBLEALWAYS 2655 #define SCI_SETCARETLINEVISIBLEALWAYS 2655
#define SC_LINE_END_TYPE_DEFAULT 0
#define SC_LINE_END_TYPE_UNICODE 1
#define SCI_SETLINEENDTYPESALLOWED 2656
#define SCI_GETLINEENDTYPESALLOWED 2657
#define SCI_GETLINEENDTYPESACTIVE 2658
#define SCI_SETREPRESENTATION 2665 #define SCI_SETREPRESENTATION 2665
#define SCI_GETREPRESENTATION 2666 #define SCI_GETREPRESENTATION 2666
#define SCI_CLEARREPRESENTATION 2667 #define SCI_CLEARREPRESENTATION 2667
@ -906,6 +915,16 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_PROPERTYTYPE 4015 #define SCI_PROPERTYTYPE 4015
#define SCI_DESCRIBEPROPERTY 4016 #define SCI_DESCRIBEPROPERTY 4016
#define SCI_DESCRIBEKEYWORDSETS 4017 #define SCI_DESCRIBEKEYWORDSETS 4017
#define SCI_GETLINEENDTYPESSUPPORTED 4018
#define SCI_ALLOCATESUBSTYLES 4020
#define SCI_GETSUBSTYLESSTART 4021
#define SCI_GETSUBSTYLESLENGTH 4022
#define SCI_GETSTYLEFROMSUBSTYLE 4027
#define SCI_GETPRIMARYSTYLEFROMSTYLE 4028
#define SCI_FREESUBSTYLES 4023
#define SCI_SETIDENTIFIERS 4024
#define SCI_DISTANCETOSECONDARYSTYLES 4025
#define SCI_GETSUBSTYLEBASES 4026
#define SC_MOD_INSERTTEXT 0x1 #define SC_MOD_INSERTTEXT 0x1
#define SC_MOD_DELETETEXT 0x2 #define SC_MOD_DELETETEXT 0x2
#define SC_MOD_CHANGESTYLE 0x4 #define SC_MOD_CHANGESTYLE 0x4
@ -989,23 +1008,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCN_HOTSPOTRELEASECLICK 2027 #define SCN_HOTSPOTRELEASECLICK 2027
#define SCN_FOCUSIN 2028 #define SCN_FOCUSIN 2028
#define SCN_FOCUSOUT 2029 #define SCN_FOCUSOUT 2029
#ifndef SCI_DISABLE_PROVISIONAL
#define SC_LINE_END_TYPE_DEFAULT 0
#define SC_LINE_END_TYPE_UNICODE 1
#define SCI_SETLINEENDTYPESALLOWED 2656
#define SCI_GETLINEENDTYPESALLOWED 2657
#define SCI_GETLINEENDTYPESACTIVE 2658
#define SCI_GETLINEENDTYPESSUPPORTED 4018
#define SCI_ALLOCATESUBSTYLES 4020
#define SCI_GETSUBSTYLESSTART 4021
#define SCI_GETSUBSTYLESLENGTH 4022
#define SCI_GETSTYLEFROMSUBSTYLE 4027
#define SCI_GETPRIMARYSTYLEFROMSTYLE 4028
#define SCI_FREESUBSTYLES 4023
#define SCI_SETIDENTIFIERS 4024
#define SCI_DISTANCETOSECONDARYSTYLES 4025
#define SCI_GETSUBSTYLEBASES 4026
#endif
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */ /* --Autogenerated -- end of section automatically generated from Scintilla.iface */
/* These structures are defined to be exactly the same shape as the Win32 /* These structures are defined to be exactly the same shape as the Win32
@ -1028,7 +1030,7 @@ struct Sci_TextRange {
struct Sci_TextToFind { struct Sci_TextToFind {
struct Sci_CharacterRange chrg; struct Sci_CharacterRange chrg;
char *lpstrText; const char *lpstrText;
struct Sci_CharacterRange chrgText; struct Sci_CharacterRange chrgText;
}; };

View File

@ -268,6 +268,7 @@ 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_RGBAIMAGE=30
val SC_MARK_BOOKMARK=31
val SC_MARK_CHARACTER=10000 val SC_MARK_CHARACTER=10000
@ -856,8 +857,8 @@ set void SetPrintColourMode=2148(int mode,)
get int GetPrintColourMode=2149(,) get int GetPrintColourMode=2149(,)
enu FindOption=SCFIND_ enu FindOption=SCFIND_
val SCFIND_WHOLEWORD=2 val SCFIND_WHOLEWORD=0x2
val SCFIND_MATCHCASE=4 val SCFIND_MATCHCASE=0x4
val SCFIND_WORDSTART=0x00100000 val SCFIND_WORDSTART=0x00100000
val SCFIND_REGEXP=0x00200000 val SCFIND_REGEXP=0x00200000
val SCFIND_POSIX=0x00400000 val SCFIND_POSIX=0x00400000
@ -1042,6 +1043,9 @@ fun bool CallTipActive=2202(,)
# Retrieve the position where the caret was before displaying the call tip. # Retrieve the position where the caret was before displaying the call tip.
fun position CallTipPosStart=2203(,) fun position CallTipPosStart=2203(,)
# Set the start position in order to change when backspacing removes the calltip.
set void CallTipSetPosStart=2214(int posStart,)
# Highlight a segment of the definition. # Highlight a segment of the definition.
fun void CallTipSetHlt=2204(int start, int end) fun void CallTipSetHlt=2204(int start, int end)
@ -1185,6 +1189,7 @@ enu Wrap=SC_WRAP_
val SC_WRAP_NONE=0 val SC_WRAP_NONE=0
val SC_WRAP_WORD=1 val SC_WRAP_WORD=1
val SC_WRAP_CHAR=2 val SC_WRAP_CHAR=2
val SC_WRAP_WHITESPACE=3
# Sets whether text is word wrapped. # Sets whether text is word wrapped.
set void SetWrapMode=2268(int mode,) set void SetWrapMode=2268(int mode,)
@ -2176,6 +2181,9 @@ fun int SetSelection=2572(int caret, int anchor)
# Add a selection # Add a selection
fun int AddSelection=2573(int caret, int anchor) fun int AddSelection=2573(int caret, int anchor)
# Drop one selection
fun void DropSelectionN=2671(int selection,)
# Set the main selection # Set the main selection
set void SetMainSelection=2574(int selection,) set void SetMainSelection=2574(int selection,)
@ -2336,6 +2344,22 @@ get bool GetCaretLineVisibleAlways=2654(,)
# Sets the caret line to always visible. # Sets the caret line to always visible.
set void SetCaretLineVisibleAlways=2655(bool alwaysVisible,) set void SetCaretLineVisibleAlways=2655(bool alwaysVisible,)
# Line end types which may be used in addition to LF, CR, and CRLF
# SC_LINE_END_TYPE_UNICODE includes U+2028 Line Separator,
# U+2029 Paragraph Separator, and U+0085 Next Line
enu LineEndType=SC_LINE_END_TYPE_
val SC_LINE_END_TYPE_DEFAULT=0
val SC_LINE_END_TYPE_UNICODE=1
# Set the line end types that the application wants to use. May not be used if incompatible with lexer or encoding.
set void SetLineEndTypesAllowed=2656(int lineEndBitSet,)
# Get the line end types currently allowed.
get int GetLineEndTypesAllowed=2657(,)
# Get the line end types currently recognised. May be a subset of the allowed types due to lexer limitation.
get int GetLineEndTypesActive=2658(,)
# Set the way a character is drawn. # Set the way a character is drawn.
set void SetRepresentation=2665(string encodedCharacter, string representation) set void SetRepresentation=2665(string encodedCharacter, string representation)
@ -2413,6 +2437,38 @@ fun int DescribeProperty=4016(string name, stringresult description)
# Retrieve a '\n' separated list of descriptions of the keyword sets understood by the current lexer. # Retrieve a '\n' separated list of descriptions of the keyword sets understood by the current lexer.
fun int DescribeKeyWordSets=4017(, stringresult descriptions) fun int DescribeKeyWordSets=4017(, stringresult descriptions)
# Bit set of LineEndType enumertion for which line ends beyond the standard
# LF, CR, and CRLF are supported by the lexer.
get int GetLineEndTypesSupported=4018(,)
# Allocate a set of sub styles for a particular base style, returning start of range
fun int AllocateSubStyles=4020(int styleBase, int numberStyles)
# The starting style number for the sub styles associated with a base style
get int GetSubStylesStart=4021(int styleBase,)
# The number of sub styles associated with a base style
get int GetSubStylesLength=4022(int styleBase,)
# For a sub style, return the base style, else return the argument.
get int GetStyleFromSubStyle=4027(int subStyle,)
# For a secondary style, return the primary style, else return the argument.
get int GetPrimaryStyleFromStyle=4028(int style,)
# Free allocated sub styles
fun void FreeSubStyles=4023(,)
# Set the identifiers that are shown in a particular style
set void SetIdentifiers=4024(int style, string identifiers)
# Where styles are duplicated by a feature such as active/inactive code
# return the distance between the two types.
get int DistanceToSecondaryStyles=4025(,)
# Get the set of base styles that can be extended with sub styles
get int GetSubStyleBases=4026(, stringresult styles)
# Notifications # Notifications
# Type of modification and the action which caused the modification. # Type of modification and the action which caused the modification.
# These are defined as a bit mask to make it easy to specify which notifications are wanted. # These are defined as a bit mask to make it easy to specify which notifications are wanted.
@ -2601,6 +2657,8 @@ val SCLEX_LITERATEHASKELL=108
val SCLEX_STTXT=109 val SCLEX_STTXT=109
val SCLEX_KVIRC=110 val SCLEX_KVIRC=110
val SCLEX_RUST=111 val SCLEX_RUST=111
val SCLEX_DMAP=112
val SCLEX_AS=113
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
# value assigned in sequence from SCLEX_AUTOMATIC+1. # value assigned in sequence from SCLEX_AUTOMATIC+1.
@ -2652,6 +2710,7 @@ val SCE_C_TRIPLEVERBATIM=21
val SCE_C_HASHQUOTEDSTRING=22 val SCE_C_HASHQUOTEDSTRING=22
val SCE_C_PREPROCESSORCOMMENT=23 val SCE_C_PREPROCESSORCOMMENT=23
val SCE_C_PREPROCESSORCOMMENTDOC=24 val SCE_C_PREPROCESSORCOMMENTDOC=24
val SCE_C_USERLITERAL=25
# Lexical states for SCLEX_D # Lexical states for SCLEX_D
lex D=SCLEX_D SCE_D_ lex D=SCLEX_D SCE_D_
val SCE_D_DEFAULT=0 val SCE_D_DEFAULT=0
@ -2704,8 +2763,6 @@ val SCE_TCL_BLOCK_COMMENT=21
# Lexical states for SCLEX_HTML, SCLEX_XML # Lexical states for SCLEX_HTML, SCLEX_XML
lex HTML=SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_ lex HTML=SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
lex XML=SCLEX_XML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_ lex XML=SCLEX_XML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
lex ASP=SCLEX_ASP SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
lex PHP=SCLEX_PHP SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
val SCE_H_DEFAULT=0 val SCE_H_DEFAULT=0
val SCE_H_TAG=1 val SCE_H_TAG=1
val SCE_H_TAGUNKNOWN=2 val SCE_H_TAGUNKNOWN=2
@ -2935,6 +2992,10 @@ val SCE_B_LABEL=15
val SCE_B_ERROR=16 val SCE_B_ERROR=16
val SCE_B_HEXNUMBER=17 val SCE_B_HEXNUMBER=17
val SCE_B_BINNUMBER=18 val SCE_B_BINNUMBER=18
val SCE_B_COMMENTBLOCK=19
val SCE_B_DOCLINE=20
val SCE_B_DOCBLOCK=21
val SCE_B_DOCKEYWORD=22
# Lexical states for SCLEX_PROPERTIES # Lexical states for SCLEX_PROPERTIES
lex Properties=SCLEX_PROPERTIES SCE_PROPS_ lex Properties=SCLEX_PROPERTIES SCE_PROPS_
val SCE_PROPS_DEFAULT=0 val SCE_PROPS_DEFAULT=0
@ -3187,8 +3248,9 @@ val SCE_SCRIPTOL_IDENTIFIER=12
val SCE_SCRIPTOL_TRIPLE=13 val SCE_SCRIPTOL_TRIPLE=13
val SCE_SCRIPTOL_CLASSNAME=14 val SCE_SCRIPTOL_CLASSNAME=14
val SCE_SCRIPTOL_PREPROCESSOR=15 val SCE_SCRIPTOL_PREPROCESSOR=15
# Lexical states for SCLEX_ASM # Lexical states for SCLEX_ASM, SCLEX_AS
lex Asm=SCLEX_ASM SCE_ASM_ lex Asm=SCLEX_ASM SCE_ASM_
lex As=SCLEX_AS SCE_ASM_
val SCE_ASM_DEFAULT=0 val SCE_ASM_DEFAULT=0
val SCE_ASM_COMMENT=1 val SCE_ASM_COMMENT=1
val SCE_ASM_NUMBER=2 val SCE_ASM_NUMBER=2
@ -3945,8 +4007,8 @@ val SCE_R_OPERATOR=8
val SCE_R_IDENTIFIER=9 val SCE_R_IDENTIFIER=9
val SCE_R_INFIX=10 val SCE_R_INFIX=10
val SCE_R_INFIXEOL=11 val SCE_R_INFIXEOL=11
# Lexical state for SCLEX_MAGIKSF # Lexical state for SCLEX_MAGIK
lex MagikSF=SCLEX_MAGIKSF SCE_MAGIK_ lex MagikSF=SCLEX_MAGIK SCE_MAGIK_
val SCE_MAGIK_DEFAULT=0 val SCE_MAGIK_DEFAULT=0
val SCE_MAGIK_COMMENT=1 val SCE_MAGIK_COMMENT=1
val SCE_MAGIK_HYPER_COMMENT=16 val SCE_MAGIK_HYPER_COMMENT=16
@ -4208,7 +4270,6 @@ val SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR=18
val SCE_COFFEESCRIPT_GLOBALCLASS=19 val SCE_COFFEESCRIPT_GLOBALCLASS=19
val SCE_COFFEESCRIPT_STRINGRAW=20 val SCE_COFFEESCRIPT_STRINGRAW=20
val SCE_COFFEESCRIPT_TRIPLEVERBATIM=21 val SCE_COFFEESCRIPT_TRIPLEVERBATIM=21
val SCE_COFFEESCRIPT_HASHQUOTEDSTRING=22
val SCE_COFFEESCRIPT_COMMENTBLOCK=22 val SCE_COFFEESCRIPT_COMMENTBLOCK=22
val SCE_COFFEESCRIPT_VERBOSE_REGEX=23 val SCE_COFFEESCRIPT_VERBOSE_REGEX=23
val SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT=24 val SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT=24
@ -4327,7 +4388,7 @@ val SCE_STTXT_DATETIME=16
val SCE_STTXT_VARS=17 val SCE_STTXT_VARS=17
val SCE_STTXT_PRAGMAS=18 val SCE_STTXT_PRAGMAS=18
# Lexical states for SCLEX_KVIRC # Lexical states for SCLEX_KVIRC
lex KVIrc=SCLEX_KVIRC SCLEX_KVIRC_ lex KVIrc=SCLEX_KVIRC SCE_KVIRC_
val SCE_KVIRC_DEFAULT=0 val SCE_KVIRC_DEFAULT=0
val SCE_KVIRC_COMMENT=1 val SCE_KVIRC_COMMENT=1
val SCE_KVIRC_COMMENTBLOCK=2 val SCE_KVIRC_COMMENTBLOCK=2
@ -4364,6 +4425,19 @@ val SCE_RUST_IDENTIFIER=17
val SCE_RUST_LIFETIME=18 val SCE_RUST_LIFETIME=18
val SCE_RUST_MACRO=19 val SCE_RUST_MACRO=19
val SCE_RUST_LEXERROR=20 val SCE_RUST_LEXERROR=20
# Lexical states for SCLEX_DMAP
lex DMAP=SCLEX_DMAP SCE_DMAP_
val SCE_DMAP_DEFAULT=0
val SCE_DMAP_COMMENT=1
val SCE_DMAP_NUMBER=2
val SCE_DMAP_STRING1=3
val SCE_DMAP_STRING2=4
val SCE_DMAP_STRINGEOL=5
val SCE_DMAP_OPERATOR=6
val SCE_DMAP_IDENTIFIER=7
val SCE_DMAP_WORD=8
val SCE_DMAP_WORD2=9
val SCE_DMAP_WORD3=10
# Events # Events
@ -4398,56 +4472,10 @@ evt void HotSpotReleaseClick=2027(int modifiers, int position)
evt void FocusIn=2028(void) evt void FocusIn=2028(void)
evt void FocusOut=2029(void) evt void FocusOut=2029(void)
# There are no provisional features currently
cat Provisional cat Provisional
# Line end types which may be used in addition to LF, CR, and CRLF
# SC_LINE_END_TYPE_UNICODE includes U+2028 Line Separator,
# U+2029 Paragraph Separator, and U+0085 Next Line
enu LineEndType=SC_LINE_END_TYPE_
val SC_LINE_END_TYPE_DEFAULT=0
val SC_LINE_END_TYPE_UNICODE=1
# Set the line end types that the application wants to use. May not be used if incompatible with lexer or encoding.
set void SetLineEndTypesAllowed=2656(int lineEndBitSet,)
# Get the line end types currently allowed.
get int GetLineEndTypesAllowed=2657(,)
# Get the line end types currently recognised. May be a subset of the allowed types due to lexer limitation.
get int GetLineEndTypesActive=2658(,)
# Bit set of LineEndType enumertion for which line ends beyond the standard
# LF, CR, and CRLF are supported by the lexer.
get int GetLineEndTypesSupported=4018(,)
# Allocate a set of sub styles for a particular base style, returning start of range
fun int AllocateSubStyles=4020(int styleBase, int numberStyles)
# The starting style number for the sub styles associated with a base style
get int GetSubStylesStart=4021(int styleBase,)
# The number of sub styles associated with a base style
get int GetSubStylesLength=4022(int styleBase,)
# For a sub style, return the base style, else return the argument.
get int GetStyleFromSubStyle=4027(int subStyle,)
# For a secondary style, return the primary style, else return the argument.
get int GetPrimaryStyleFromStyle=4028(int style,)
# Free allocated sub styles
fun void FreeSubStyles=4023(,)
# Set the identifiers that are shown in a particular style
set void SetIdentifiers=4024(int style, string identifiers)
# Where styles are duplicated by a feature such as active/inactive code
# return the distance between the two types.
get int DistanceToSecondaryStyles=4025(,)
# Get the set of base styles that can be extended with sub styles
get int GetSubStyleBases=4026(, stringresult styles)
cat Deprecated cat Deprecated
# Deprecated in 2.21 # Deprecated in 2.21

View File

@ -30,10 +30,6 @@
using namespace Scintilla; using namespace Scintilla;
#endif #endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80 && (isalnum(ch) || (ch == '_')));
}
static inline bool IsAKeywordChar(const int ch) { static inline bool IsAKeywordChar(const int ch) {
return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' '))); return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' ')));
} }
@ -42,17 +38,6 @@ static inline bool IsASetChar(const int ch) {
return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-'))); return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-')));
} }
static inline bool IsAnOperator(char ch) {
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
ch == '$' || ch == ':' || ch == '%')
return true;
return false;
}
static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList*[] /* *keywordlists[] */, static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList*[] /* *keywordlists[] */,
Accessor &styler) { Accessor &styler) {
enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \ enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \

View File

@ -150,8 +150,10 @@ class LexerAsm : public ILexer {
WordList directives4foldend; WordList directives4foldend;
OptionsAsm options; OptionsAsm options;
OptionSetAsm osAsm; OptionSetAsm osAsm;
int commentChar;
public: public:
LexerAsm() { LexerAsm(int commentChar_) {
commentChar = commentChar_;
} }
virtual ~LexerAsm() { virtual ~LexerAsm() {
} }
@ -183,7 +185,11 @@ public:
} }
static ILexer *LexerFactoryAsm() { static ILexer *LexerFactoryAsm() {
return new LexerAsm(); return new LexerAsm(';');
}
static ILexer *LexerFactoryAs() {
return new LexerAsm('#');
} }
}; };
@ -342,7 +348,7 @@ void SCI_METHOD LexerAsm::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 == SCE_ASM_DEFAULT) { if (sc.state == SCE_ASM_DEFAULT) {
if (sc.ch == ';'){ if (sc.ch == commentChar){
sc.SetState(SCE_ASM_COMMENT); sc.SetState(SCE_ASM_COMMENT);
} else if (IsASCII(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && IsASCII(sc.chNext) && isdigit(sc.chNext)))) { } else if (IsASCII(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && IsASCII(sc.chNext) && isdigit(sc.chNext)))) {
sc.SetState(SCE_ASM_NUMBER); sc.SetState(SCE_ASM_NUMBER);
@ -457,4 +463,5 @@ void SCI_METHOD LexerAsm::Fold(unsigned int startPos, int length, int initStyle,
} }
LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, "asm", asmWordListDesc); LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, "asm", asmWordListDesc);
LexerModule lmAs(SCLEX_AS, LexerAsm::LexerFactoryAs, "as", asmWordListDesc);

View File

@ -108,6 +108,8 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
CharacterSet setWordStart(CharacterSet::setAlpha, "_"); CharacterSet setWordStart(CharacterSet::setAlpha, "_");
// note that [+-] are often parts of identifiers in shell scripts // note that [+-] are often parts of identifiers in shell scripts
CharacterSet setWord(CharacterSet::setAlphaNum, "._+-"); CharacterSet setWord(CharacterSet::setAlphaNum, "._+-");
CharacterSet setMetaCharacter(CharacterSet::setNone, "|&;()<> \t\r\n");
setMetaCharacter.Add(0);
CharacterSet setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/<?!.~@"); CharacterSet setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/<?!.~@");
CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn"); CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn");
CharacterSet setParam(CharacterSet::setAlphaNum, "$_"); CharacterSet setParam(CharacterSet::setAlphaNum, "$_");
@ -627,7 +629,12 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
} else if (setWordStart.Contains(sc.ch)) { } else if (setWordStart.Contains(sc.ch)) {
sc.SetState(SCE_SH_WORD); sc.SetState(SCE_SH_WORD);
} else if (sc.ch == '#') { } else if (sc.ch == '#') {
sc.SetState(SCE_SH_COMMENTLINE); if (stylePrev != SCE_SH_WORD && stylePrev != SCE_SH_IDENTIFIER &&
(sc.currentPos == 0 || setMetaCharacter.Contains(sc.chPrev))) {
sc.SetState(SCE_SH_COMMENTLINE);
} else {
sc.SetState(SCE_SH_WORD);
}
} else if (sc.ch == '\"') { } else if (sc.ch == '\"') {
sc.SetState(SCE_SH_STRING); sc.SetState(SCE_SH_STRING);
QuoteStack.Start(sc.ch, BASH_DELIM_STRING); QuoteStack.Start(sc.ch, BASH_DELIM_STRING);

View File

@ -49,17 +49,18 @@ using namespace Scintilla;
* 8 - decimal digit * 8 - decimal digit
* 16 - hex digit * 16 - hex digit
* 32 - bin digit * 32 - bin digit
* 64 - letter
*/ */
static int character_classification[128] = static int character_classification[128] =
{ {
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2, 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2,
60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2, 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 2, 2, 2, 68,
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 2, 2, 2, 0
}; };
static bool IsSpace(int c) { static bool IsSpace(int c) {
@ -86,6 +87,10 @@ static bool IsBinDigit(int c) {
return c < 128 && (character_classification[c] & 32); return c < 128 && (character_classification[c] & 32);
} }
static bool IsLetter(int c) {
return c < 128 && (character_classification[c] & 64);
}
static int LowerCase(int c) static int LowerCase(int c)
{ {
if (c >= 'A' && c <= 'Z') if (c >= 'A' && c <= 'Z')
@ -126,13 +131,23 @@ static int CheckPureFoldPoint(char const *token, int &level) {
static int CheckFreeFoldPoint(char const *token, int &level) { static int CheckFreeFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") || if (!strcmp(token, "function") ||
!strcmp(token, "sub") || !strcmp(token, "sub") ||
!strcmp(token, "type")) { !strcmp(token, "enum") ||
!strcmp(token, "type") ||
!strcmp(token, "union") ||
!strcmp(token, "property") ||
!strcmp(token, "destructor") ||
!strcmp(token, "constructor")) {
level |= SC_FOLDLEVELHEADERFLAG; level |= SC_FOLDLEVELHEADERFLAG;
return 1; return 1;
} }
if (!strcmp(token, "end function") || if (!strcmp(token, "end function") ||
!strcmp(token, "end sub") || !strcmp(token, "end sub") ||
!strcmp(token, "end type")) { !strcmp(token, "end enum") ||
!strcmp(token, "end type") ||
!strcmp(token, "end union") ||
!strcmp(token, "end property") ||
!strcmp(token, "end destructor") ||
!strcmp(token, "end constructor")) {
return -1; return -1;
} }
return 0; return 0;
@ -219,9 +234,9 @@ class LexerBasic : public ILexer {
OptionSetBasic osBasic; OptionSetBasic osBasic;
public: public:
LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) : LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) :
comment_char(comment_char_), comment_char(comment_char_),
CheckFoldPoint(CheckFoldPoint_), CheckFoldPoint(CheckFoldPoint_),
osBasic(wordListDescriptions) { osBasic(wordListDescriptions) {
} }
virtual ~LexerBasic() { virtual ~LexerBasic() {
} }
@ -302,6 +317,7 @@ void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle
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);
int styleBeforeKeyword = SCE_B_DEFAULT;
StyleContext sc(startPos, length, initStyle, styler); StyleContext sc(startPos, length, initStyle, styler);
@ -367,14 +383,44 @@ void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle
if (sc.atLineEnd) { if (sc.atLineEnd) {
sc.SetState(SCE_B_DEFAULT); sc.SetState(SCE_B_DEFAULT);
} }
} else if (sc.state == SCE_B_DOCLINE) {
if (sc.atLineEnd) {
sc.SetState(SCE_B_DEFAULT);
} else if (sc.ch == '\\' || sc.ch == '@') {
if (IsLetter(sc.chNext) && sc.chPrev != '\\') {
styleBeforeKeyword = sc.state;
sc.SetState(SCE_B_DOCKEYWORD);
};
}
} else if (sc.state == SCE_B_DOCKEYWORD) {
if (IsSpace(sc.ch)) {
sc.SetState(styleBeforeKeyword);
} else if (sc.atLineEnd && styleBeforeKeyword == SCE_B_DOCLINE) {
sc.SetState(SCE_B_DEFAULT);
}
} else if (sc.state == SCE_B_COMMENTBLOCK) {
if (sc.Match("\'/")) {
sc.Forward();
sc.ForwardSetState(SCE_B_DEFAULT);
}
} else if (sc.state == SCE_B_DOCBLOCK) {
if (sc.Match("\'/")) {
sc.Forward();
sc.ForwardSetState(SCE_B_DEFAULT);
} else if (sc.ch == '\\' || sc.ch == '@') {
if (IsLetter(sc.chNext) && sc.chPrev != '\\') {
styleBeforeKeyword = sc.state;
sc.SetState(SCE_B_DOCKEYWORD);
};
}
} }
if (sc.atLineStart) if (sc.atLineStart)
isfirst = true; isfirst = true;
if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) { if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {
if (isfirst && sc.Match('.')) { if (isfirst && sc.Match('.') && comment_char != '\'') {
sc.SetState(SCE_B_LABEL); sc.SetState(SCE_B_LABEL);
} else if (isfirst && sc.Match('#')) { } else if (isfirst && sc.Match('#')) {
wasfirst = isfirst; wasfirst = isfirst;
sc.SetState(SCE_B_IDENTIFIER); sc.SetState(SCE_B_IDENTIFIER);
@ -383,15 +429,25 @@ void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle
// up in freebasic with SCE_B_PREPROCESSOR. // up in freebasic with SCE_B_PREPROCESSOR.
if (comment_char == '\'' && sc.Match(comment_char, '$')) if (comment_char == '\'' && sc.Match(comment_char, '$'))
sc.SetState(SCE_B_PREPROCESSOR); sc.SetState(SCE_B_PREPROCESSOR);
else else if (sc.Match("\'*") || sc.Match("\'!")) {
sc.SetState(SCE_B_DOCLINE);
} else {
sc.SetState(SCE_B_COMMENT); sc.SetState(SCE_B_COMMENT);
}
} else if (sc.Match("/\'")) {
if (sc.Match("/\'*") || sc.Match("/\'!")) { // Support of gtk-doc/Doxygen doc. style
sc.SetState(SCE_B_DOCBLOCK);
} else {
sc.SetState(SCE_B_COMMENTBLOCK);
}
sc.Forward(); // Eat the ' so it isn't used for the end of the comment
} else if (sc.Match('"')) { } else if (sc.Match('"')) {
sc.SetState(SCE_B_STRING); sc.SetState(SCE_B_STRING);
} else if (IsDigit(sc.ch)) { } else if (IsDigit(sc.ch)) {
sc.SetState(SCE_B_NUMBER); sc.SetState(SCE_B_NUMBER);
} else if (sc.Match('$')) { } else if (sc.Match('$') || sc.Match("&h") || sc.Match("&H") || sc.Match("&o") || sc.Match("&O")) {
sc.SetState(SCE_B_HEXNUMBER); sc.SetState(SCE_B_HEXNUMBER);
} else if (sc.Match('%')) { } else if (sc.Match('%') || sc.Match("&b") || sc.Match("&B")) {
sc.SetState(SCE_B_BINNUMBER); sc.SetState(SCE_B_BINNUMBER);
} else if (sc.Match('#')) { } else if (sc.Match('#')) {
sc.SetState(SCE_B_CONSTANT); sc.SetState(SCE_B_CONSTANT);

View File

@ -336,7 +336,7 @@ class LexerCPP : public ILexerWithSubStyles {
enum { ssIdentifier, ssDocKeyword }; enum { ssIdentifier, ssDocKeyword };
SubStyles subStyles; SubStyles subStyles;
public: public:
LexerCPP(bool caseSensitive_) : explicit LexerCPP(bool caseSensitive_) :
caseSensitive(caseSensitive_), caseSensitive(caseSensitive_),
setWord(CharacterSet::setAlphaNum, "._", 0x80, true), setWord(CharacterSet::setAlphaNum, "._", 0x80, true),
setNegationOp(CharacterSet::setNone, "!"), setNegationOp(CharacterSet::setNone, "!"),
@ -376,7 +376,7 @@ public:
int SCI_METHOD LineEndTypesSupported() { int SCI_METHOD LineEndTypesSupported() {
return SC_LINE_END_TYPE_UNICODE; return SC_LINE_END_TYPE_UNICODE;
}; }
int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) { int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) {
return subStyles.Allocate(styleBase, numberStyles); return subStyles.Allocate(styleBase, numberStyles);
@ -485,7 +485,7 @@ int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
// Functor used to truncate history // Functor used to truncate history
struct After { struct After {
int line; int line;
After(int line_) : line(line_) {} explicit After(int line_) : line(line_) {}
bool operator()(PPDefinition &p) const { bool operator()(PPDefinition &p) const {
return p.line > line; return p.line > line;
} }
@ -515,6 +515,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
bool isIncludePreprocessor = false; bool isIncludePreprocessor = false;
bool isStringInPreprocessor = false; bool isStringInPreprocessor = false;
bool inRERange = false; bool inRERange = false;
bool seenDocKeyBrace = false;
int lineCurrent = styler.GetLine(startPos); int lineCurrent = styler.GetLine(startPos);
if ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) || if ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) ||
@ -633,12 +634,19 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
break; break;
case SCE_C_NUMBER: case SCE_C_NUMBER:
// We accept almost anything because of hex. and number suffixes // We accept almost anything because of hex. and number suffixes
if (!(setWord.Contains(sc.ch) if (sc.ch == '_') {
sc.ChangeState(SCE_C_USERLITERAL|activitySet);
} else if (!(setWord.Contains(sc.ch)
|| (sc.ch == '\'')
|| ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E' || || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E' ||
sc.chPrev == 'p' || sc.chPrev == 'P')))) { sc.chPrev == 'p' || sc.chPrev == 'P')))) {
sc.SetState(SCE_C_DEFAULT|activitySet); sc.SetState(SCE_C_DEFAULT|activitySet);
} }
break; break;
case SCE_C_USERLITERAL:
if (!(setWord.Contains(sc.ch)))
sc.SetState(SCE_C_DEFAULT|activitySet);
break;
case SCE_C_IDENTIFIER: case SCE_C_IDENTIFIER:
if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch) || (sc.ch == '.')) { if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch) || (sc.ch == '.')) {
char s[1000]; char s[1000];
@ -675,9 +683,12 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
sc.ChangeState((raw ? SCE_C_STRINGRAW : SCE_C_STRING)|activitySet); sc.ChangeState((raw ? SCE_C_STRINGRAW : SCE_C_STRING)|activitySet);
else else
sc.ChangeState(SCE_C_CHARACTER|activitySet); sc.ChangeState(SCE_C_CHARACTER|activitySet);
} else {
sc.SetState(SCE_C_DEFAULT | activitySet);
} }
} else {
sc.SetState(SCE_C_DEFAULT|activitySet);
} }
sc.SetState(SCE_C_DEFAULT|activitySet);
} }
break; break;
case SCE_C_PREPROCESSOR: case SCE_C_PREPROCESSOR:
@ -685,7 +696,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
if (IsASpace(sc.ch)) { if (IsASpace(sc.ch)) {
sc.SetState(SCE_C_DEFAULT|activitySet); sc.SetState(SCE_C_DEFAULT|activitySet);
} }
} else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"'))) { } else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"') || sc.atLineEnd)) {
isStringInPreprocessor = false; isStringInPreprocessor = false;
} else if (!isStringInPreprocessor) { } else if (!isStringInPreprocessor) {
if ((isIncludePreprocessor && sc.Match('<')) || sc.Match('\"')) { if ((isIncludePreprocessor && sc.Match('<')) || sc.Match('\"')) {
@ -749,14 +760,18 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR); sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
sc.Forward(); sc.Forward();
sc.ForwardSetState(SCE_C_DEFAULT|activitySet); sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
} else if (!setDoxygen.Contains(sc.ch)) { seenDocKeyBrace = false;
} else if (sc.ch == '[' || sc.ch == '{') {
seenDocKeyBrace = true;
} else if (!setDoxygen.Contains(sc.ch)
&& !(seenDocKeyBrace && (sc.ch == ',' || sc.ch == '.'))) {
char s[100]; char s[100];
if (caseSensitive) { if (caseSensitive) {
sc.GetCurrent(s, sizeof(s)); sc.GetCurrent(s, sizeof(s));
} else { } else {
sc.GetCurrentLowered(s, sizeof(s)); sc.GetCurrentLowered(s, sizeof(s));
} }
if (!IsASpace(sc.ch)) { if (!(IsASpace(sc.ch) || (sc.ch == 0))) {
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet); sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);
} else if (!keywords3.InList(s + 1)) { } else if (!keywords3.InList(s + 1)) {
int subStyleCDKW = classifierDocKeyWords.ValueFor(s+1); int subStyleCDKW = classifierDocKeyWords.ValueFor(s+1);
@ -767,6 +782,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} }
} }
sc.SetState(styleBeforeDCKeyword|activitySet); sc.SetState(styleBeforeDCKeyword|activitySet);
seenDocKeyBrace = false;
} }
break; break;
case SCE_C_STRING: case SCE_C_STRING:
@ -782,7 +798,11 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
sc.Forward(); sc.Forward();
} }
} else if (sc.ch == '\"') { } else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_C_DEFAULT|activitySet); if (sc.chNext == '_') {
sc.ChangeState(SCE_C_USERLITERAL|activitySet);
} else {
sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
}
} }
break; break;
case SCE_C_HASHQUOTEDSTRING: case SCE_C_HASHQUOTEDSTRING:
@ -810,7 +830,11 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
sc.Forward(); sc.Forward();
} }
} else if (sc.ch == '\'') { } else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_C_DEFAULT|activitySet); if (sc.chNext == '_') {
sc.ChangeState(SCE_C_USERLITERAL|activitySet);
} else {
sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
}
} }
break; break;
case SCE_C_REGEX: case SCE_C_REGEX:

View File

@ -226,14 +226,13 @@ static void ColouriseCmakeDoc(unsigned int startPos, int length, int, WordList *
break; break;
case SCE_CMAKE_COMMENT: case SCE_CMAKE_COMMENT:
if ( cNextChar == '\n' || cNextChar == '\r' ) { if ( cCurrChar == '\n' || cCurrChar == '\r' ) {
// Special case: if ( styler.SafeGetCharAt(i-1) == '\\' ) {
if ( cCurrChar == '\\' ) {
styler.ColourTo(i-2,state); styler.ColourTo(i-2,state);
styler.ColourTo(i,SCE_CMAKE_DEFAULT); styler.ColourTo(i-1,SCE_CMAKE_DEFAULT);
} }
else { else {
styler.ColourTo(i,state); styler.ColourTo(i-1,state);
state = SCE_CMAKE_DEFAULT; state = SCE_CMAKE_DEFAULT;
} }
} }
@ -335,10 +334,7 @@ static void ColouriseCmakeDoc(unsigned int startPos, int length, int, WordList *
break; break;
} }
if ( state == SCE_CMAKE_COMMENT) { if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) {
styler.ColourTo(i,state);
}
else if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) {
bool bIngoreNextDollarSign = false; bool bIngoreNextDollarSign = false;
if ( bVarInString && cCurrChar == '$' ) { if ( bVarInString && cCurrChar == '$' ) {

View File

@ -27,15 +27,6 @@
using namespace Scintilla; using namespace Scintilla;
#endif #endif
static inline bool IsAWordChar(int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
ch == '_' || ch == '?' || ch == '"' || ch == '@' ||
ch == '!' || ch == '[' || ch == ']' || ch == '/' ||
ch == '+' || ch == '-' || ch == '*' || ch == '<' ||
ch == '>' || ch == '=' || ch == ';' || ch == '(' ||
ch == ')' );
}
static inline bool IsAWordStart(int ch) { static inline bool IsAWordStart(int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.'); return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
} }

View File

@ -38,15 +38,15 @@ static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch)); return (ch < 0x80) && (isalnum(ch));
} }
/***************************************/ /***************************************/
inline bool IsABlank(unsigned int ch) { static inline bool IsABlank(unsigned int ch) {
return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ; return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
} }
/***************************************/ /***************************************/
inline bool IsALineEnd(char ch) { static inline bool IsALineEnd(char ch) {
return ((ch == '\n') || (ch == '\r')) ; return ((ch == '\n') || (ch == '\r')) ;
} }
/***************************************/ /***************************************/
unsigned int GetContinuedPos(unsigned int pos, Accessor &styler) { static unsigned int GetContinuedPos(unsigned int pos, Accessor &styler) {
while (!IsALineEnd(styler.SafeGetCharAt(pos++))) continue; while (!IsALineEnd(styler.SafeGetCharAt(pos++))) continue;
if (styler.SafeGetCharAt(pos) == '\n') pos++; if (styler.SafeGetCharAt(pos) == '\n') pos++;
while (IsABlank(styler.SafeGetCharAt(pos++))) continue; while (IsABlank(styler.SafeGetCharAt(pos++))) continue;
@ -60,7 +60,7 @@ unsigned int GetContinuedPos(unsigned int pos, Accessor &styler) {
} }
/***************************************/ /***************************************/
static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle, static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler, bool isFixFormat) { WordList *keywordlists[], Accessor &styler, bool isFixFormat) {
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1]; WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2]; WordList &keywords3 = *keywordlists[2];
@ -89,11 +89,11 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
int toLineStart = sc.currentPos - posLineStart; int toLineStart = sc.currentPos - posLineStart;
if (isFixFormat && (toLineStart < 6 || toLineStart >= 72)) { if (isFixFormat && (toLineStart < 6 || toLineStart >= 72)) {
if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') { if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') {
if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") || if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") ||
sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") || sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") ||
sc.MatchIgnoreCase("cms$") || sc.MatchIgnoreCase("*ms$") || sc.MatchIgnoreCase("!ms$") || sc.MatchIgnoreCase("cms$") || sc.MatchIgnoreCase("*ms$") || sc.MatchIgnoreCase("!ms$") ||
sc.chNext == '$') { sc.chNext == '$') {
sc.SetState(SCE_F_PREPROCESSOR); sc.SetState(SCE_F_PREPROCESSOR);
} else { } else {
sc.SetState(SCE_F_COMMENT); sc.SetState(SCE_F_COMMENT);
} }
@ -111,8 +111,8 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
//if (!IsASpace(sc.ch) && sc.ch != '0') { //if (!IsASpace(sc.ch) && sc.ch != '0') {
if (sc.ch != '\r' && sc.ch != '\n') { if (sc.ch != '\r' && sc.ch != '\n') {
sc.SetState(SCE_F_CONTINUATION); sc.SetState(SCE_F_CONTINUATION);
if (!IsASpace(sc.ch) && sc.ch != '0') if (!IsASpace(sc.ch) && sc.ch != '0')
sc.ForwardSetState(prevState); sc.ForwardSetState(prevState);
} else } else
sc.SetState(SCE_F_DEFAULT); sc.SetState(SCE_F_DEFAULT);
} }
@ -122,9 +122,9 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
// Hanndle preprocessor directives // Hanndle preprocessor directives
if (sc.ch == '#' && numNonBlank == 1) if (sc.ch == '#' && numNonBlank == 1)
{ {
sc.SetState(SCE_F_PREPROCESSOR); sc.SetState(SCE_F_PREPROCESSOR);
while (!sc.atLineEnd && sc.More()) while (!sc.atLineEnd && sc.More())
sc.Forward(); // Until line end sc.Forward(); // Until line end
} }
/***************************************/ /***************************************/
// Handle line continuation generically. // Handle line continuation generically.
@ -221,8 +221,8 @@ static void ColouriseFortranDoc(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 == SCE_F_DEFAULT) { if (sc.state == SCE_F_DEFAULT) {
if (sc.ch == '!') { if (sc.ch == '!') {
if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") || if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") ||
sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') { sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
sc.SetState(SCE_F_PREPROCESSOR); sc.SetState(SCE_F_PREPROCESSOR);
} else { } else {
sc.SetState(SCE_F_COMMENT); sc.SetState(SCE_F_COMMENT);
@ -232,7 +232,7 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_F_NUMBER); sc.SetState(SCE_F_NUMBER);
} else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' || } else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' ||
tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) { tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) {
sc.SetState(SCE_F_NUMBER); sc.SetState(SCE_F_NUMBER);
sc.Forward(); sc.Forward();
} else if (sc.ch == '.' && isalpha(sc.chNext)) { } else if (sc.ch == '.' && isalpha(sc.chNext)) {
@ -254,41 +254,48 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
// To determine the folding level depending on keywords // To determine the folding level depending on keywords
static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) { static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) {
int lev = 0; int lev = 0;
if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
return -1; if ((strcmp(prevWord, "module") == 0 && strcmp(s, "subroutine") == 0)
if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0 || (strcmp(prevWord, "module") == 0 && strcmp(s, "function") == 0)) {
|| strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0 lev = 0;
|| strcmp(s, "do") == 0 || strcmp(s, "enum") ==0 } else if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0
|| strcmp(s, "function") == 0 || strcmp(s, "interface") == 0 || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0
|| strcmp(s, "module") == 0 || strcmp(s, "program") == 0 || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0
|| strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0 || strcmp(s, "function") == 0 || strcmp(s, "interface") == 0
|| (strcmp(s, "type") == 0 && chNextNonBlank != '(') || strcmp(s, "module") == 0 || strcmp(s, "program") == 0
|| strcmp(s, "critical") == 0){ || strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0
if (strcmp(prevWord, "end") == 0) || (strcmp(s, "type") == 0 && chNextNonBlank != '(')
lev = 0; || strcmp(s, "critical") == 0 || strcmp(s, "submodule") == 0){
else if (strcmp(prevWord, "end") == 0)
lev = 1;
} else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=')
|| strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
|| strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
|| strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
|| strcmp(s, "endif") == 0 || strcmp(s, "endforall") == 0
|| strcmp(s, "endfunction") == 0 || strcmp(s, "endinterface") == 0
|| strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0
|| strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
|| strcmp(s, "endwhere") == 0 || strcmp(s, "endcritical") == 0
|| (strcmp(s, "procedure") == 0 && strcmp(prevWord, "module") == 0) ) { // Take care of the "module procedure" statement
lev = -1;
} else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
lev = 0; lev = 0;
else
lev = 1;
} else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=')
|| strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
|| strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
|| strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
|| strcmp(s, "endif") == 0 || strcmp(s, "endforall") == 0
|| strcmp(s, "endfunction") == 0 || strcmp(s, "endinterface") == 0
|| strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0
|| strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
|| strcmp(s, "endwhere") == 0 || strcmp(s, "endcritical") == 0
|| (strcmp(prevWord, "module") == 0 && strcmp(s, "procedure") == 0) // Take care of the "module procedure" statement
|| strcmp(s, "endsubmodule") == 0) {
lev = -1;
} else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
lev = 0;
} else if (strcmp(prevWord, "type") == 0 && strcmp(s, "is") == 0){ // type is } else if (strcmp(prevWord, "type") == 0 && strcmp(s, "is") == 0){ // type is
lev = -1; lev = -1;
} } else if ((strcmp(prevWord, "end") == 0 && strcmp(s, "procedure") == 0)
|| strcmp(s, "endprocedure") == 0) {
lev = 1; // level back to 0, because no folding support for "module procedure" in submodule
}
return lev; return lev;
} }
/***************************************/
// Folding the code // Folding the code
static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
Accessor &styler, bool isFixFormat) { Accessor &styler, bool isFixFormat) {
// //
// bool foldComment = styler.GetPropertyInt("fold.comment") != 0; // bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
// Do not know how to fold the comment at the moment. // Do not know how to fold the comment at the moment.
@ -297,35 +304,51 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
unsigned int endPos = startPos + length; unsigned int endPos = startPos + length;
int visibleChars = 0; int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos); int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent;
int levelCurrent = levelPrev; bool isPrevLine;
if (lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
isPrevLine = true;
} else {
levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
isPrevLine = false;
}
char chNext = styler[startPos]; char chNext = styler[startPos];
char chNextNonBlank;
int styleNext = styler.StyleAt(startPos); int styleNext = styler.StyleAt(startPos);
int style = initStyle; int style = initStyle;
int levelDeltaNext = 0;
/***************************************/ /***************************************/
int lastStart = 0; int lastStart = 0;
char prevWord[32] = ""; char prevWord[32] = "";
char Label[6] = "";
// Variables for do label folding.
static int doLabels[100];
static int posLabel=-1;
/***************************************/ /***************************************/
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);
chNextNonBlank = chNext; char chNextNonBlank = chNext;
bool nextEOL = false;
if (IsALineEnd(chNextNonBlank)) {
nextEOL = true;
}
unsigned int j=i+1; unsigned int j=i+1;
while(IsABlank(chNextNonBlank) && j<endPos) { while(IsABlank(chNextNonBlank) && j<endPos) {
j ++ ; j ++ ;
chNextNonBlank = styler.SafeGetCharAt(j); chNextNonBlank = styler.SafeGetCharAt(j);
if (IsALineEnd(chNextNonBlank)) {
nextEOL = true;
}
}
if (!nextEOL && j == endPos) {
nextEOL = true;
} }
int stylePrev = style; int stylePrev = style;
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 (((isFixFormat && stylePrev == SCE_F_CONTINUATION) || stylePrev == SCE_F_DEFAULT || stylePrev == SCE_F_OPERATOR) && (style == SCE_F_WORD || style == SCE_F_LABEL)) { if (((isFixFormat && stylePrev == SCE_F_CONTINUATION) || stylePrev == SCE_F_DEFAULT
|| stylePrev == SCE_F_OPERATOR) && (style == SCE_F_WORD || style == SCE_F_LABEL)) {
// Store last word and label start point. // Store last word and label start point.
lastStart = i; lastStart = i;
} }
@ -339,7 +362,7 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
} }
s[k] = '\0'; s[k] = '\0';
// Handle the forall and where statement and structure. // Handle the forall and where statement and structure.
if (strcmp(s, "forall") == 0 || strcmp(s, "where") == 0) { if (strcmp(s, "forall") == 0 || (strcmp(s, "where") == 0 && strcmp(prevWord, "else") != 0)) {
if (strcmp(prevWord, "end") != 0) { if (strcmp(prevWord, "end") != 0) {
j = i + 1; j = i + 1;
char chBrace = '(', chSeek = ')', ch1 = styler.SafeGetCharAt(j); char chBrace = '(', chSeek = ')', ch1 = styler.SafeGetCharAt(j);
@ -362,22 +385,25 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
if (depth == 0) break; if (depth == 0) break;
} }
} }
int tmpLineCurrent = lineCurrent;
while (j<endPos) { while (j<endPos) {
j++; j++;
chAtPos = styler.SafeGetCharAt(j); chAtPos = styler.SafeGetCharAt(j);
styAtPos = styler.StyleAt(j); styAtPos = styler.StyleAt(j);
if (styAtPos == SCE_F_COMMENT || IsABlank(chAtPos)) continue; if (!IsALineEnd(chAtPos) && (styAtPos == SCE_F_COMMENT || IsABlank(chAtPos))) continue;
if (isFixFormat) { if (isFixFormat) {
if (!IsALineEnd(chAtPos)) { if (!IsALineEnd(chAtPos)) {
break; break;
} else { } else {
if (lineCurrent < styler.GetLine(styler.Length()-1)) { if (tmpLineCurrent < styler.GetLine(styler.Length()-1)) {
j = styler.LineStart(lineCurrent+1); tmpLineCurrent++;
if (styler.StyleAt(j+5) == SCE_F_CONTINUATION) { j = styler.LineStart(tmpLineCurrent);
if (styler.StyleAt(j+5) == SCE_F_CONTINUATION
&& !IsABlank(styler.SafeGetCharAt(j+5)) && styler.SafeGetCharAt(j+5) != '0') {
j += 5; j += 5;
continue; continue;
} else { } else {
levelCurrent++; levelDeltaNext++;
break; break;
} }
} }
@ -387,7 +413,7 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
j = GetContinuedPos(j+1, styler); j = GetContinuedPos(j+1, styler);
continue; continue;
} else if (IsALineEnd(chAtPos)) { } else if (IsALineEnd(chAtPos)) {
levelCurrent ++; levelDeltaNext++;
break; break;
} else { } else {
break; break;
@ -396,61 +422,64 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
} }
} }
} else { } else {
levelCurrent += classifyFoldPointFortran(s, prevWord, chNextNonBlank); int wordLevelDelta = classifyFoldPointFortran(s, prevWord, chNextNonBlank);
// Store the do Labels into array levelDeltaNext += wordLevelDelta;
if (strcmp(s, "do") == 0 && IsADigit(chNextNonBlank)) { if (((strcmp(s, "else") == 0) && (nextEOL || chNextNonBlank == '!')) ||
unsigned int k = 0; (strcmp(prevWord, "else") == 0 && strcmp(s, "where") == 0) || strcmp(s, "elsewhere") == 0) {
for (i=j; (i<j+5 && i<endPos); i++) { if (!isPrevLine) {
ch = styler.SafeGetCharAt(i); levelCurrent--;
if (IsADigit(ch))
Label[k++] = ch;
else
break;
} }
Label[k] = '\0'; levelDeltaNext++;
posLabel ++; } else if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0) {
doLabels[posLabel] = atoi(Label); if (!isPrevLine) {
levelCurrent--;
}
} else if ((strcmp(prevWord, "select") == 0 && strcmp(s, "case") == 0) || strcmp(s, "selectcase") == 0 ||
(strcmp(prevWord, "select") == 0 && strcmp(s, "type") == 0) || strcmp(s, "selecttype") == 0) {
levelDeltaNext += 2;
} else if ((strcmp(s, "case") == 0 && chNextNonBlank == '(') || (strcmp(prevWord, "case") == 0 && strcmp(s, "default") == 0) ||
(strcmp(prevWord, "type") == 0 && strcmp(s, "is") == 0) ||
(strcmp(prevWord, "class") == 0 && strcmp(s, "is") == 0) ||
(strcmp(prevWord, "class") == 0 && strcmp(s, "default") == 0) ) {
if (!isPrevLine) {
levelCurrent--;
}
levelDeltaNext++;
} else if ((strcmp(prevWord, "end") == 0 && strcmp(s, "select") == 0) || strcmp(s, "endselect") == 0) {
levelDeltaNext -= 2;
}
// There are multiple forms of "do" loop. The older form with a label "do 100 i=1,10" would require matching
// labels to ensure the folding level does not decrease too far when labels are used for other purposes.
// Since this is difficult, do-label constructs are not folded.
if (strcmp(s, "do") == 0 && IsADigit(chNextNonBlank)) {
// Remove delta for do-label
levelDeltaNext -= wordLevelDelta;
} }
} }
strcpy(prevWord, s); strcpy(prevWord, s);
} }
} else if (style == SCE_F_LABEL) {
if(IsADigit(ch) && !IsADigit(chNext)) {
for(j = 0; ( j < 5 ) && ( j < i-lastStart+1 ); j++) {
ch = styler.SafeGetCharAt(lastStart + j);
if (IsADigit(ch) && styler.StyleAt(lastStart+j) == SCE_F_LABEL)
Label[j] = ch;
else
break;
}
Label[j] = '\0';
while (doLabels[posLabel] == atoi(Label) && posLabel > -1) {
levelCurrent--;
posLabel--;
}
}
} }
if (atEOL) { if (atEOL) {
int lev = levelPrev; int lev = levelCurrent;
if (visibleChars == 0 && foldCompact) if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG; lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0)) if ((levelDeltaNext > 0) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG; lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) { if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev); styler.SetLevel(lineCurrent, lev);
}
lineCurrent++; lineCurrent++;
levelPrev = levelCurrent; levelCurrent += levelDeltaNext;
levelDeltaNext = 0;
visibleChars = 0; visibleChars = 0;
strcpy(prevWord, ""); strcpy(prevWord, "");
isPrevLine = false;
} }
/***************************************/ /***************************************/
if (!isspacechar(ch)) visibleChars++; if (!isspacechar(ch)) visibleChars++;
} }
/***************************************/ /***************************************/
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
} }
/***************************************/ /***************************************/
static const char * const FortranWordLists[] = { static const char * const FortranWordLists[] = {
@ -461,22 +490,22 @@ static const char * const FortranWordLists[] = {
}; };
/***************************************/ /***************************************/
static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) { Accessor &styler) {
ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false); ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);
} }
/***************************************/ /***************************************/
static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) { Accessor &styler) {
ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true); ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);
} }
/***************************************/ /***************************************/
static void FoldFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, static void FoldFortranDocFreeFormat(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) { WordList *[], Accessor &styler) {
FoldFortranDoc(startPos, length, initStyle,styler, false); FoldFortranDoc(startPos, length, initStyle,styler, false);
} }
/***************************************/ /***************************************/
static void FoldFortranDocFixFormat(unsigned int startPos, int length, int initStyle, static void FoldFortranDocFixFormat(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) { WordList *[], Accessor &styler) {
FoldFortranDoc(startPos, length, initStyle,styler, true); FoldFortranDoc(startPos, length, initStyle,styler, true);
} }
/***************************************/ /***************************************/

View File

@ -16,6 +16,7 @@
#include "Scintilla.h" #include "Scintilla.h"
#include "SciLexer.h" #include "SciLexer.h"
#include "StringCopy.h"
#include "WordList.h" #include "WordList.h"
#include "LexAccessor.h" #include "LexAccessor.h"
#include "Accessor.h" #include "Accessor.h"
@ -339,9 +340,9 @@ static void classifyWordHTJS(unsigned int start, unsigned int end,
static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, script_mode inScriptType) { static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, script_mode inScriptType) {
char chAttr = SCE_HB_IDENTIFIER; char chAttr = SCE_HB_IDENTIFIER;
bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.'); bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
if (wordIsNumber) if (wordIsNumber) {
chAttr = SCE_HB_NUMBER; chAttr = SCE_HB_NUMBER;
else { } else {
char s[100]; char s[100];
GetTextSegment(styler, start, end, s, sizeof(s)); GetTextSegment(styler, start, end, s, sizeof(s));
if (keywords.InList(s)) { if (keywords.InList(s)) {
@ -385,9 +386,9 @@ static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &key
static void classifyWordHTPHP(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { static void classifyWordHTPHP(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char chAttr = SCE_HPHP_DEFAULT; char chAttr = SCE_HPHP_DEFAULT;
bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.' && start+1 <= end && IsADigit(styler[start+1])); bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.' && start+1 <= end && IsADigit(styler[start+1]));
if (wordIsNumber) if (wordIsNumber) {
chAttr = SCE_HPHP_NUMBER; chAttr = SCE_HPHP_NUMBER;
else { } else {
char s[100]; char s[100];
GetTextSegment(styler, start, end, s, sizeof(s)); GetTextSegment(styler, start, end, s, sizeof(s));
if (keywords.InList(s)) if (keywords.InList(s))
@ -823,14 +824,14 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if (isMako && ch == '#' && chNext == '#') { if (isMako && ch == '#' && chNext == '#') {
makoComment = 1; makoComment = 1;
} }
// handle end of Mako comment line // handle end of Mako comment line
else if (isMako && makoComment && (ch == '\r' || ch == '\n')) { else if (isMako && makoComment && (ch == '\r' || ch == '\n')) {
makoComment = 0; makoComment = 0;
styler.ColourTo(i, SCE_HP_COMMENTLINE); styler.ColourTo(i, SCE_HP_COMMENTLINE);
state = SCE_HP_DEFAULT; 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, "%")))) {
@ -929,9 +930,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(ch == '$' && chNext == '{') || (ch == '$' && chNext == '{') ||
(ch == '<' && chNext == '/' && chNext2 == '%'))) { (ch == '<' && chNext == '/' && chNext2 == '%'))) {
if (ch == '%' || ch == '/') if (ch == '%' || ch == '/')
strcpy(makoBlockType, "%"); StringCopy(makoBlockType, "%");
else if (ch == '$') else if (ch == '$')
strcpy(makoBlockType, "{"); StringCopy(makoBlockType, "{");
else if (chNext == '/') else if (chNext == '/')
GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType)); GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType));
else else
@ -1000,9 +1001,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
// 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 == '%')
strcpy(djangoBlockType, "%"); StringCopy(djangoBlockType, "%");
else else
strcpy(djangoBlockType, "{"); StringCopy(djangoBlockType, "{");
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state; beforePreProc = state;
if (inScriptType == eNonHtmlScript) if (inScriptType == eNonHtmlScript)
@ -1917,7 +1918,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_HPHP_COMMENTLINE; state = SCE_HPHP_COMMENTLINE;
} else if (ch == '\"') { } else if (ch == '\"') {
state = SCE_HPHP_HSTRING; state = SCE_HPHP_HSTRING;
strcpy(phpStringDelimiter, "\""); StringCopy(phpStringDelimiter, "\"");
} else if (styler.Match(i, "<<<")) { } else if (styler.Match(i, "<<<")) {
bool isSimpleString = false; bool isSimpleString = false;
i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString); i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
@ -1927,7 +1928,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
} }
} else if (ch == '\'') { } else if (ch == '\'') {
state = SCE_HPHP_SIMPLESTRING; state = SCE_HPHP_SIMPLESTRING;
strcpy(phpStringDelimiter, "\'"); StringCopy(phpStringDelimiter, "\'");
} else if (ch == '$' && IsPhpWordStart(chNext)) { } else if (ch == '$' && IsPhpWordStart(chNext)) {
state = SCE_HPHP_VARIABLE; state = SCE_HPHP_VARIABLE;
} else if (IsOperator(ch)) { } else if (IsOperator(ch)) {
@ -2047,7 +2048,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_HPHP_COMMENTLINE; state = SCE_HPHP_COMMENTLINE;
} else if (ch == '\"') { } else if (ch == '\"') {
state = SCE_HPHP_HSTRING; state = SCE_HPHP_HSTRING;
strcpy(phpStringDelimiter, "\""); StringCopy(phpStringDelimiter, "\"");
} else if (styler.Match(i, "<<<")) { } else if (styler.Match(i, "<<<")) {
bool isSimpleString = false; bool isSimpleString = false;
i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString); i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
@ -2057,7 +2058,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
} }
} else if (ch == '\'') { } else if (ch == '\'') {
state = SCE_HPHP_SIMPLESTRING; state = SCE_HPHP_SIMPLESTRING;
strcpy(phpStringDelimiter, "\'"); StringCopy(phpStringDelimiter, "\'");
} else if (ch == '$' && IsPhpWordStart(chNext)) { } else if (ch == '$' && IsPhpWordStart(chNext)) {
state = SCE_HPHP_VARIABLE; state = SCE_HPHP_VARIABLE;
} else if (IsOperator(ch)) { } else if (IsOperator(ch)) {

View File

@ -118,10 +118,11 @@ static bool AtTermStart(StyleContext &sc) {
} }
static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
int c, count = 1; int count = 1;
unsigned int i = 0; unsigned int i = 0;
while (++i) { for (;;) {
c = sc.GetRelative(i); ++i;
int c = sc.GetRelative(i);
if (c == sc.ch) if (c == sc.ch)
++count; ++count;
// hit a terminating character // hit a terminating character
@ -140,7 +141,6 @@ static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
} }
} }
} }
return false;
} }
static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle, static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle,

View File

@ -57,7 +57,8 @@ static bool IsOctaveComment(Accessor &styler, int pos, int len) {
static void ColouriseMatlabOctaveDoc( static void ColouriseMatlabOctaveDoc(
unsigned int startPos, int length, int initStyle, unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler, WordList *keywordlists[], Accessor &styler,
bool (*IsCommentChar)(int)) { bool (*IsCommentChar)(int),
bool ismatlab) {
WordList &keywords = *keywordlists[0]; WordList &keywords = *keywordlists[0];
@ -199,7 +200,11 @@ static void ColouriseMatlabOctaveDoc(
styler.SetLineState(curLine, commentDepth); styler.SetLineState(curLine, commentDepth);
sc.SetState(SCE_MATLAB_COMMENT); sc.SetState(SCE_MATLAB_COMMENT);
} else if (sc.ch == '!' && sc.chNext != '=' ) { } else if (sc.ch == '!' && sc.chNext != '=' ) {
sc.SetState(SCE_MATLAB_COMMAND); if(ismatlab) {
sc.SetState(SCE_MATLAB_COMMAND);
} else {
sc.SetState(SCE_MATLAB_OPERATOR);
}
} else if (sc.ch == '\'') { } else if (sc.ch == '\'') {
if (transpose) { if (transpose) {
sc.SetState(SCE_MATLAB_OPERATOR); sc.SetState(SCE_MATLAB_OPERATOR);
@ -229,12 +234,12 @@ static void ColouriseMatlabOctaveDoc(
static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle, static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) { WordList *keywordlists[], Accessor &styler) {
ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar); ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar, true);
} }
static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle, static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) { WordList *keywordlists[], Accessor &styler) {
ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar); ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar, false);
} }
static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int, static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,

View File

@ -1037,8 +1037,9 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
!CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") || !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") ||
!CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) { !CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) {
state = stMsVc; state = stMsVc;
} else } else {
state = stUnrecognized; state = stUnrecognized;
}
} else { } else {
state = stUnrecognized; state = stUnrecognized;
} }

View File

@ -1185,7 +1185,7 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle,
} }
switch (HereDoc.Quote) { switch (HereDoc.Quote) {
case '\'': case '\'':
st_new = SCE_PL_HERE_Q ; st_new = SCE_PL_HERE_Q;
break; break;
case '"' : case '"' :
st_new = SCE_PL_HERE_QQ; st_new = SCE_PL_HERE_QQ;

View File

@ -643,7 +643,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
break; break;
} }
} }
int levelNext = levelCurrent; int levelNext = levelCurrent;
char chNext = styler[startPos]; char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos); int styleNext = styler.StyleAt(startPos);

View File

@ -78,10 +78,11 @@ static bool HasPrevLineContent(StyleContext &sc) {
// Separator line // Separator line
static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
int c, count = 1; int count = 1;
unsigned int i = 0; unsigned int i = 0;
while (++i) { for (;;) {
c = sc.GetRelative(i); ++i;
int c = sc.GetRelative(i);
if (c == sc.ch) if (c == sc.ch)
++count; ++count;
// hit a terminating character // hit a terminating character
@ -100,7 +101,6 @@ static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
} }
} }
} }
return false;
} }
static void ColorizeTxt2tagsDoc(unsigned int startPos, int length, int initStyle, static void ColorizeTxt2tagsDoc(unsigned int startPos, int length, int initStyle,

View File

@ -51,7 +51,7 @@ static inline bool IsAWordStart(const int ch) {
} }
/***************************************/ /***************************************/
inline bool IsABlank(unsigned int ch) { static inline bool IsABlank(unsigned int ch) {
return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ; return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
} }

View File

@ -12,7 +12,7 @@
namespace Scintilla { namespace Scintilla {
#endif #endif
enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8}; enum { wsSpace=1, wsTab=2, wsSpaceTab=4, wsInconsistent=8 };
class Accessor; class Accessor;
class WordList; class WordList;

View File

@ -9,6 +9,7 @@
#include <algorithm> #include <algorithm>
#include "StringCopy.h"
#include "CharacterCategory.h" #include "CharacterCategory.h"
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE
@ -3275,7 +3276,7 @@ const int catRanges[] = {
const int maxUnicode = 0x10ffff; const int maxUnicode = 0x10ffff;
const int maskCategory = 0x1F; const int maskCategory = 0x1F;
const int nRanges = sizeof(catRanges) / sizeof(catRanges[0]); const int nRanges = ELEMENTS(catRanges);
} }

View File

@ -53,13 +53,13 @@ private:
} }
public: public:
LexAccessor(IDocument *pAccess_) : explicit LexAccessor(IDocument *pAccess_) :
pAccess(pAccess_), startPos(extremePosition), endPos(0), pAccess(pAccess_), startPos(extremePosition), endPos(0),
codePage(pAccess->CodePage()), codePage(pAccess->CodePage()),
encodingType(enc8bit), encodingType(enc8bit),
lenDoc(pAccess->Length()), lenDoc(pAccess->Length()),
mask(127), validLen(0), chFlags(0), chWhile(0), mask(127), validLen(0), chFlags(0), chWhile(0),
startSeg(0), startPosStyling(0), startSeg(0), startPosStyling(0),
documentVersion(pAccess->Version()) { documentVersion(pAccess->Version()) {
switch (codePage) { switch (codePage) {
case 65001: case 65001:
@ -139,7 +139,6 @@ public:
return lenDoc; return lenDoc;
} }
void Flush() { void Flush() {
startPos = extremePosition;
if (validLen > 0) { if (validLen > 0) {
pAccess->SetStyles(validLen, styleBuf); pAccess->SetStyles(validLen, styleBuf);
startPosStyling += validLen; startPosStyling += validLen;

View File

@ -79,7 +79,7 @@ const char *LexerModule::GetWordListDescription(int index) const {
return ""; return "";
} else { } else {
return wordListDescriptions[index]; return wordListDescriptions[index];
} }
} }
int LexerModule::GetStyleBitsNeeded() const { int LexerModule::GetStyleBitsNeeded() const {

View File

@ -17,7 +17,7 @@ class LexerSimple : public LexerBase {
const LexerModule *module; const LexerModule *module;
std::string wordLists; std::string wordLists;
public: public:
LexerSimple(const LexerModule *module_); explicit LexerSimple(const LexerModule *module_);
const char * SCI_METHOD DescribeWordListSets(); const char * SCI_METHOD DescribeWordListSets();
void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess); void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);

View File

@ -61,7 +61,7 @@ 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, static_cast<int>(eqAt-keyVal), Set(keyVal, eqAt + 1, static_cast<int>(eqAt-keyVal),
static_cast<int>(endVal - eqAt - 1)); static_cast<int>(endVal - eqAt - 1));
} else if (*keyVal) { // No '=' so assume '=1' } else if (*keyVal) { // No '=' so assume '=1'
Set(keyVal, "1", static_cast<int>(endVal-keyVal), 1); Set(keyVal, "1", static_cast<int>(endVal-keyVal), 1);
@ -146,7 +146,7 @@ int PropSetSimple::GetExpanded(const char *key, char *result) const {
ExpandAllInPlace(*this, val, 100, VarChain(key)); ExpandAllInPlace(*this, val, 100, VarChain(key));
const int n = static_cast<int>(val.size()); const int n = static_cast<int>(val.size());
if (result) { if (result) {
strcpy(result, val.c_str()); memcpy(result, val.c_str(), n+1);
} }
return n; // Not including NUL return n; // Not including NUL
} }

View File

@ -38,7 +38,7 @@ class SparseState {
} }
public: public:
SparseState(int positionFirst_=-1) { explicit SparseState(int positionFirst_=-1) {
positionFirst = positionFirst_; positionFirst = positionFirst_;
} }
void Set(int position, T value) { void Set(int position, T value) {

View File

@ -0,0 +1,36 @@
// Scintilla source code edit control
/** @file StringCopy.h
** Safe string copy function which always NUL terminates.
** ELEMENTS macro for determining array sizes.
**/
// Copyright 2013 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef STRINGCOPY_H
#define STRINGCOPY_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// Safer version of string copy functions like strcpy, wcsncpy, etc.
// Instantiate over fixed length strings of both char and wchar_t.
// May truncate if source doesn't fit into dest with room for NUL.
template <typename T, size_t count>
void StringCopy(T (&dest)[count], const T* source) {
for (size_t i=0; i<count; i++) {
dest[i] = source[i];
if (!source[i])
break;
}
dest[count-1] = 0;
}
#define ELEMENTS(a) (sizeof(a) / sizeof(a[0]))
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@ -28,7 +28,7 @@ class StyleContext {
IDocumentWithLineEnd *multiByteAccess; IDocumentWithLineEnd *multiByteAccess;
unsigned int endPos; unsigned int endPos;
unsigned int lengthDocument; unsigned int lengthDocument;
// Used for optimizing GetRelativeCharacter // Used for optimizing GetRelativeCharacter
unsigned int posRelative; unsigned int posRelative;
unsigned int currentPosLastRelative; unsigned int currentPosLastRelative;
@ -43,7 +43,7 @@ class StyleContext {
chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+width, 0)); chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+width, 0));
widthNext = 1; widthNext = 1;
} }
// End of line determined from line end position, allowing CR, LF, // End of line determined from line end position, allowing CR, LF,
// CRLF and Unicode line ends as set by document. // CRLF and Unicode line ends as set by document.
if (currentLine < lineDocEnd) if (currentLine < lineDocEnd)
atLineEnd = static_cast<int>(currentPos) >= (lineStartNext-1); atLineEnd = static_cast<int>(currentPos) >= (lineStartNext-1);

View File

@ -20,7 +20,7 @@ class WordClassifier {
public: public:
WordClassifier(int baseStyle_) : baseStyle(baseStyle_), firstStyle(0), lenStyles(0) { explicit WordClassifier(int baseStyle_) : baseStyle(baseStyle_), firstStyle(0), lenStyles(0) {
} }
void Allocate(int firstStyle_, int lenStyles_) { void Allocate(int firstStyle_, int lenStyles_) {

View File

@ -13,6 +13,7 @@
#include <algorithm> #include <algorithm>
#include "StringCopy.h"
#include "WordList.h" #include "WordList.h"
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE
@ -70,7 +71,7 @@ WordList::WordList(bool onlyLineEnds_) :
words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) { words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) {
} }
WordList::~WordList() { WordList::~WordList() {
Clear(); Clear();
} }
@ -122,15 +123,16 @@ static void SortWordList(char **words, unsigned int len) {
void WordList::Set(const char *s) { void WordList::Set(const char *s) {
Clear(); Clear();
list = new char[strlen(s) + 1]; const size_t lenS = strlen(s) + 1;
strcpy(list, s); list = new char[lenS];
memcpy(list, s, lenS);
words = ArrayFromWordList(list, &len, onlyLineEnds); words = ArrayFromWordList(list, &len, onlyLineEnds);
#ifdef _MSC_VER #ifdef _MSC_VER
std::sort(words, words + len, cmpWords); std::sort(words, words + len, cmpWords);
#else #else
SortWordList(words, len); SortWordList(words, len);
#endif #endif
for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++) for (unsigned int k = 0; k < ELEMENTS(starts); k++)
starts[k] = -1; starts[k] = -1;
for (int l = len - 1; l >= 0; l--) { for (int l = len - 1; l >= 0; l--) {
unsigned char indexChar = words[l][0]; unsigned char indexChar = words[l][0];

View File

@ -22,7 +22,7 @@ class WordList {
bool onlyLineEnds; ///< Delimited by any white space or only line ends bool onlyLineEnds; ///< Delimited by any white space or only line ends
int starts[256]; int starts[256];
public: public:
WordList(bool onlyLineEnds_ = false); explicit WordList(bool onlyLineEnds_ = false);
~WordList(); ~WordList();
operator bool() const; operator bool() const;
bool operator!=(const WordList &other) const; bool operator!=(const WordList &other) const;

View File

@ -28,10 +28,10 @@ diff -Naur scintilla_orig/gtk/scintilla-marshal.c scintilla/gtk/scintilla-marsha
{ {
typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1, typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1,
diff --git b/scintilla/src/Catalogue.cxx a/scintilla/src/Catalogue.cxx diff --git b/scintilla/src/Catalogue.cxx a/scintilla/src/Catalogue.cxx
index e728f34..85116a5 100644 index 41d5d54..70ce3bc 100644
+++ scintilla/src/Catalogue.cxx
--- scintilla/src/Catalogue.cxx --- scintilla/src/Catalogue.cxx
@@ -76,112 +76,48 @@ int Scintilla_LinkLexers() { +++ scintilla/src/Catalogue.cxx
@@ -76,114 +76,48 @@ int Scintilla_LinkLexers() {
//++Autogenerated -- run scripts/LexGen.py to regenerate //++Autogenerated -- run scripts/LexGen.py to regenerate
//**\(\tLINK_LEXER(\*);\n\) //**\(\tLINK_LEXER(\*);\n\)
@ -39,6 +39,7 @@ index e728f34..85116a5 100644
LINK_LEXER(lmAbaqus); LINK_LEXER(lmAbaqus);
LINK_LEXER(lmAda); LINK_LEXER(lmAda);
- LINK_LEXER(lmAPDL); - LINK_LEXER(lmAPDL);
- LINK_LEXER(lmAs);
LINK_LEXER(lmAsm); LINK_LEXER(lmAsm);
- LINK_LEXER(lmAsn1); - LINK_LEXER(lmAsn1);
- LINK_LEXER(lmASY); - LINK_LEXER(lmASY);
@ -63,6 +64,7 @@ index e728f34..85116a5 100644
LINK_LEXER(lmCss); LINK_LEXER(lmCss);
LINK_LEXER(lmD); LINK_LEXER(lmD);
LINK_LEXER(lmDiff); LINK_LEXER(lmDiff);
- LINK_LEXER(lmDMAP);
- LINK_LEXER(lmECL); - LINK_LEXER(lmECL);
- LINK_LEXER(lmEiffel); - LINK_LEXER(lmEiffel);
- LINK_LEXER(lmEiffelkw); - LINK_LEXER(lmEiffelkw);

View File

@ -16,9 +16,9 @@
#include "Platform.h" #include "Platform.h"
#include "Scintilla.h"
#include "CharacterSet.h" #include "CharacterSet.h"
#include "AutoComplete.h" #include "AutoComplete.h"
#include "Scintilla.h"
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE
using namespace Scintilla; using namespace Scintilla;
@ -41,8 +41,6 @@ AutoComplete::AutoComplete() :
heightLBDefault(100), heightLBDefault(100),
autoSort(SC_ORDER_PRESORTED) { autoSort(SC_ORDER_PRESORTED) {
lb = ListBox::Allocate(); lb = ListBox::Allocate();
stopChars[0] = '\0';
fillUpChars[0] = '\0';
} }
AutoComplete::~AutoComplete() { AutoComplete::~AutoComplete() {
@ -71,21 +69,19 @@ void AutoComplete::Start(Window &parent, int ctrlID,
} }
void AutoComplete::SetStopChars(const char *stopChars_) { void AutoComplete::SetStopChars(const char *stopChars_) {
strncpy(stopChars, stopChars_, sizeof(stopChars)); stopChars = stopChars_;
stopChars[sizeof(stopChars) - 1] = '\0';
} }
bool AutoComplete::IsStopChar(char ch) { bool AutoComplete::IsStopChar(char ch) {
return ch && strchr(stopChars, ch); return ch && (stopChars.find(ch) != std::string::npos);
} }
void AutoComplete::SetFillUpChars(const char *fillUpChars_) { void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars)); fillUpChars = fillUpChars_;
fillUpChars[sizeof(fillUpChars) - 1] = '\0';
} }
bool AutoComplete::IsFillUpChar(char ch) { bool AutoComplete::IsFillUpChar(char ch) {
return ch && strchr(fillUpChars, ch); return ch && (fillUpChars.find(ch) != std::string::npos);
} }
void AutoComplete::SetSeparator(char separator_) { void AutoComplete::SetSeparator(char separator_) {

View File

@ -16,8 +16,8 @@ namespace Scintilla {
*/ */
class AutoComplete { class AutoComplete {
bool active; bool active;
char stopChars[256]; std::string stopChars;
char fillUpChars[256]; std::string fillUpChars;
char separator; char separator;
char typesep; // Type seperator char typesep; // Type seperator
enum { maxItemLen=1000 }; enum { maxItemLen=1000 };
@ -71,7 +71,7 @@ public:
/// The list string contains a sequence of words separated by the separator character /// The list string contains a sequence of words separated by the separator character
void SetList(const char *list); void SetList(const char *list);
/// Return the position of the currently selected list item /// Return the position of the currently selected list item
int GetSelection() const; int GetSelection() const;

View File

@ -14,6 +14,8 @@
#include "Platform.h" #include "Platform.h"
#include "Scintilla.h" #include "Scintilla.h"
#include "StringCopy.h"
#include "CallTip.h" #include "CallTip.h"
#ifdef SCI_NAMESPACE #ifdef SCI_NAMESPACE
@ -125,16 +127,14 @@ void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
Point(centreX + halfWidth, centreY + halfWidth / 2), Point(centreX + halfWidth, centreY + halfWidth / 2),
Point(centreX, centreY - halfWidth + halfWidth / 2), Point(centreX, centreY - halfWidth + halfWidth / 2),
}; };
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), surface->Polygon(pts, ELEMENTS(pts), colourBG, colourBG);
colourBG, colourBG);
} else { // Down arrow } else { // Down arrow
Point pts[] = { Point pts[] = {
Point(centreX - halfWidth, centreY - halfWidth / 2), Point(centreX - halfWidth, centreY - halfWidth / 2),
Point(centreX + halfWidth, centreY - halfWidth / 2), Point(centreX + halfWidth, centreY - halfWidth / 2),
Point(centreX, centreY + halfWidth - halfWidth / 2), Point(centreX, centreY + halfWidth - halfWidth / 2),
}; };
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), surface->Polygon(pts, ELEMENTS(pts), colourBG, colourBG);
colourBG, colourBG);
} }
} }
xEnd = rcClient.right; xEnd = rcClient.right;

View File

@ -13,6 +13,7 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include "StringCopy.h"
#include "CaseConvert.h" #include "CaseConvert.h"
#include "UniConversion.h" #include "UniConversion.h"
#include "UnicodeFromUTF8.h" #include "UnicodeFromUTF8.h"
@ -367,6 +368,9 @@ class CaseConverter : public ICaseConverter {
enum { maxConversionLength=6 }; enum { maxConversionLength=6 };
struct ConversionString { struct ConversionString {
char conversion[maxConversionLength+1]; char conversion[maxConversionLength+1];
ConversionString() {
conversion[0] = '\0';
}
}; };
// Conversions are initially store in a vector of structs but then decomposed into // Conversions are initially store in a vector of structs but then decomposed into
// parallel arrays as that is about 10% faster to search. // parallel arrays as that is about 10% faster to search.
@ -374,7 +378,7 @@ class CaseConverter : public ICaseConverter {
int character; int character;
ConversionString conversion; ConversionString conversion;
CharacterConversion(int character_=0, const char *conversion_="") : character(character_) { CharacterConversion(int character_=0, const char *conversion_="") : character(character_) {
strcpy(conversion.conversion, conversion_); StringCopy(conversion.conversion, conversion_);
} }
bool operator<(const CharacterConversion &other) const { bool operator<(const CharacterConversion &other) const {
return character < other.character; return character < other.character;
@ -505,17 +509,17 @@ void AddSymmetric(enum CaseConversion conversion, int lower,int upper) {
void SetupConversions(enum CaseConversion conversion) { void SetupConversions(enum CaseConversion conversion) {
// First initialize for the symmetric ranges // First initialize for the symmetric ranges
for (size_t i=0; i<sizeof(symmetricCaseConversionRanges)/sizeof(symmetricCaseConversionRanges[0]);) { for (size_t i=0; i<ELEMENTS(symmetricCaseConversionRanges);) {
int lower = symmetricCaseConversionRanges[i++]; int lower = symmetricCaseConversionRanges[i++];
int upper = symmetricCaseConversionRanges[i++]; int upper = symmetricCaseConversionRanges[i++];
int length = symmetricCaseConversionRanges[i++]; int length = symmetricCaseConversionRanges[i++];
int pitch = symmetricCaseConversionRanges[i++]; int pitch = symmetricCaseConversionRanges[i++];
for (int j=0;j<length*pitch;j+=pitch) { for (int j=0; j<length*pitch; j+=pitch) {
AddSymmetric(conversion, lower+j, upper+j); AddSymmetric(conversion, lower+j, upper+j);
} }
} }
// Add the symmetric singletons // Add the symmetric singletons
for (size_t i=0; i<sizeof(symmetricCaseConversions)/sizeof(symmetricCaseConversions[0]);) { for (size_t i=0; i<ELEMENTS(symmetricCaseConversions);) {
int lower = symmetricCaseConversions[i++]; int lower = symmetricCaseConversions[i++];
int upper = symmetricCaseConversions[i++]; int upper = symmetricCaseConversions[i++];
AddSymmetric(conversion, lower, upper); AddSymmetric(conversion, lower, upper);

View File

@ -190,6 +190,10 @@ const char *UndoHistory::AppendAction(actionType at, int position, const char *d
} }
// See if current action can be coalesced into previous action // See if current action can be coalesced into previous action
// Will work if both are inserts or deletes and position is same // Will work if both are inserts or deletes and position is same
#if defined(_MSC_VER) && defined(_PREFAST_)
// Visual Studio 2013 Code Analysis wrongly believes actions can be NULL at its next reference
__analysis_assume(actions);
#endif
if (currentAction == savePoint) { if (currentAction == savePoint) {
currentAction++; currentAction++;
} else if (!actions[currentAction].mayCoalesce) { } else if (!actions[currentAction].mayCoalesce) {

View File

@ -17,8 +17,8 @@ class PerLine {
public: public:
virtual ~PerLine() {} virtual ~PerLine() {}
virtual void Init()=0; virtual void Init()=0;
virtual void InsertLine(int)=0; virtual void InsertLine(int line)=0;
virtual void RemoveLine(int)=0; virtual void RemoveLine(int line)=0;
}; };
/** /**

View File

@ -17,7 +17,7 @@ public:
RunStyles rs; RunStyles rs;
int indicator; int indicator;
Decoration(int indicator_); explicit Decoration(int indicator_);
~Decoration(); ~Decoration();
bool Empty() const; bool Empty() const;

View File

@ -955,7 +955,7 @@ bool Document::InsertString(int position, const char *s, int insertLength) {
int SCI_METHOD Document::AddData(char *data, int length) { int SCI_METHOD Document::AddData(char *data, int length) {
try { try {
int position = Length(); int position = Length();
InsertString(position,data, length); InsertString(position, data, length);
} catch (std::bad_alloc &) { } catch (std::bad_alloc &) {
return SC_STATUS_BADALLOC; return SC_STATUS_BADALLOC;
} catch (...) { } catch (...) {
@ -1892,7 +1892,7 @@ void SCI_METHOD Document::DecorationFillRange(int position, int value, int fillL
bool Document::AddWatcher(DocWatcher *watcher, void *userData) { bool Document::AddWatcher(DocWatcher *watcher, void *userData) {
WatcherWithUserData wwud(watcher, userData); WatcherWithUserData wwud(watcher, userData);
std::vector<WatcherWithUserData>::iterator it = std::vector<WatcherWithUserData>::iterator it =
std::find(watchers.begin(), watchers.end(), wwud); std::find(watchers.begin(), watchers.end(), wwud);
if (it != watchers.end()) if (it != watchers.end())
return false; return false;
@ -1901,7 +1901,7 @@ bool Document::AddWatcher(DocWatcher *watcher, void *userData) {
} }
bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) { bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) {
std::vector<WatcherWithUserData>::iterator it = std::vector<WatcherWithUserData>::iterator it =
std::find(watchers.begin(), watchers.end(), WatcherWithUserData(watcher, userData)); std::find(watchers.begin(), watchers.end(), WatcherWithUserData(watcher, userData));
if (it != watchers.end()) { if (it != watchers.end()) {
watchers.erase(it); watchers.erase(it);
@ -2103,7 +2103,7 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) {
*/ */
class BuiltinRegex : public RegexSearchBase { class BuiltinRegex : public RegexSearchBase {
public: public:
BuiltinRegex(CharClassify *charClassTable) : search(charClassTable) {} explicit BuiltinRegex(CharClassify *charClassTable) : search(charClassTable) {}
virtual ~BuiltinRegex() { virtual ~BuiltinRegex() {
} }

View File

@ -32,7 +32,7 @@ public:
Position start; Position start;
Position end; Position end;
Range(Position pos=0) : explicit Range(Position pos=0) :
start(pos), end(pos) { start(pos), end(pos) {
} }
Range(Position start_, Position end_) : Range(Position start_, Position end_) :
@ -165,7 +165,7 @@ protected:
ILexer *instance; ILexer *instance;
bool performingStyle; ///< Prevent reentrance bool performingStyle; ///< Prevent reentrance
public: public:
LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(0), performingStyle(false) { explicit LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(0), performingStyle(false) {
} }
virtual ~LexInterface() { virtual ~LexInterface() {
} }
@ -443,12 +443,12 @@ public:
*/ */
class DocModification { class DocModification {
public: public:
int modificationType; int modificationType;
int position; int position;
int length; int length;
int linesAdded; /**< Negative if lines deleted. */ int linesAdded; /**< Negative if lines deleted. */
const char *text; /**< Only valid for changes to text, not for changes to style. */ const char *text; /**< Only valid for changes to text, not for changes to style. */
int line; int line;
int foldLevelNow; int foldLevelNow;
int foldLevelPrev; int foldLevelPrev;
int annotationLinesAdded; int annotationLinesAdded;

View File

@ -23,6 +23,7 @@
#include "ILexer.h" #include "ILexer.h"
#include "Scintilla.h" #include "Scintilla.h"
#include "StringCopy.h"
#include "SplitVector.h" #include "SplitVector.h"
#include "Partitioning.h" #include "Partitioning.h"
#include "RunStyles.h" #include "RunStyles.h"
@ -87,6 +88,10 @@ Timer::Timer() :
Idler::Idler() : Idler::Idler() :
state(false), idlerID(0) {} state(false), idlerID(0) {}
static int RoundXYPosition(XYPOSITION xyPos) {
return int(xyPos+0.5);
}
static inline bool IsControlCharacter(int ch) { static inline bool IsControlCharacter(int ch) {
// iscntrl returns true for lots of chars > 127 which are displayable // iscntrl returns true for lots of chars > 127 which are displayable
return ch >= 0 && ch < ' '; return ch >= 0 && ch < ' ';
@ -250,7 +255,7 @@ void Editor::SetRepresentations() {
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
}; };
for (size_t j=0; j < (sizeof(reps) / sizeof(reps[0])); j++) { for (size_t j=0; j < ELEMENTS(reps); j++) {
char c[2] = { static_cast<char>(j), 0 }; char c[2] = { static_cast<char>(j), 0 };
reprs.SetRepresentation(c, reps[j]); reprs.SetRepresentation(c, reps[j]);
} }
@ -264,10 +269,12 @@ void Editor::SetRepresentations() {
"DCS", "PU1", "PU2", "STS", "CCH", "MW", "SPA", "EPA", "DCS", "PU1", "PU2", "STS", "CCH", "MW", "SPA", "EPA",
"SOS", "SGCI", "SCI", "CSI", "ST", "OSC", "PM", "APC" "SOS", "SGCI", "SCI", "CSI", "ST", "OSC", "PM", "APC"
}; };
for (size_t j=0; j < (sizeof(repsC1) / sizeof(repsC1[0])); j++) { for (size_t j=0; j < ELEMENTS(repsC1); j++) {
char c1[3] = { '\xc2', static_cast<char>(0x80+j), 0 }; char c1[3] = { '\xc2', static_cast<char>(0x80+j), 0 };
reprs.SetRepresentation(c1, repsC1[j]); reprs.SetRepresentation(c1, repsC1[j]);
} }
reprs.SetRepresentation("\xe2\x80\xa8", "LS");
reprs.SetRepresentation("\xe2\x80\xa9", "PS");
} }
// UTF-8 invalid bytes // UTF-8 invalid bytes
@ -381,6 +388,10 @@ PRectangle Editor::GetClientRectangle() {
return wMain.GetClientPosition(); return wMain.GetClientPosition();
} }
PRectangle Editor::GetClientDrawingRectangle() {
return GetClientRectangle();
}
PRectangle Editor::GetTextRectangle() { PRectangle Editor::GetTextRectangle() {
PRectangle rc = GetClientRectangle(); PRectangle rc = GetClientRectangle();
rc.left += vs.textStart; rc.left += vs.textStart;
@ -426,7 +437,7 @@ const char *ControlCharacterString(unsigned char ch) {
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
}; };
if (ch < (sizeof(reps) / sizeof(reps[0]))) { if (ch < ELEMENTS(reps)) {
return reps[ch]; return reps[ch];
} else { } else {
return "BAD"; return "BAD";
@ -476,36 +487,17 @@ Point Editor::LocationFromPosition(SelectionPosition pos) {
RefreshStyleData(); RefreshStyleData();
if (pos.Position() == INVALID_POSITION) if (pos.Position() == INVALID_POSITION)
return pt; return pt;
int line = pdoc->LineFromPosition(pos.Position()); const int line = pdoc->LineFromPosition(pos.Position());
int lineVisible = cs.DisplayFromDoc(line); const int lineVisible = cs.DisplayFromDoc(line);
//Platform::DebugPrintf("line=%d\n", line); //Platform::DebugPrintf("line=%d\n", line);
AutoSurface surface(this); AutoSurface surface(this);
AutoLineLayout ll(llc, RetrieveLineLayout(line)); AutoLineLayout ll(llc, RetrieveLineLayout(line));
if (surface && ll) { if (surface && ll) {
// -1 because of adding in for visible lines in following loop. const int posLineStart = pdoc->LineStart(line);
pt.y = (lineVisible - topLine - 1) * vs.lineHeight;
pt.x = 0;
unsigned int posLineStart = pdoc->LineStart(line);
LayoutLine(line, surface, vs, ll, wrapWidth); LayoutLine(line, surface, vs, ll, wrapWidth);
int posInLine = pos.Position() - posLineStart; const int posInLine = pos.Position() - posLineStart;
// In case of very long line put x at arbitrary large position pt = ll->PointFromPosition(posInLine, vs.lineHeight);
if (posInLine > ll->maxLineLength) { pt.y += (lineVisible - topLine) * vs.lineHeight;
pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)];
}
for (int subLine = 0; subLine < ll->lines; subLine++) {
if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) {
pt.x = ll->positions[posInLine] - ll->positions[ll->LineStart(subLine)];
if (ll->wrapIndent != 0) {
int lineStart = ll->LineStart(subLine);
if (lineStart != 0) // Wrapped
pt.x += ll->wrapIndent;
}
}
if (posInLine >= ll->LineStart(subLine)) {
pt.y += vs.lineHeight;
}
}
pt.x += vs.textStart - xOffset; pt.x += vs.textStart - xOffset;
} }
pt.x += pos.VirtualSpace() * vs.styles[ll->EndLineStyle()].spaceWidth; pt.x += pos.VirtualSpace() * vs.styles[ll->EndLineStyle()].spaceWidth;
@ -557,58 +549,44 @@ SelectionPosition Editor::SPositionFromLocation(Point pt, bool canReturnInvalid,
int visibleLine = floor(pt.y / vs.lineHeight); int visibleLine = floor(pt.y / vs.lineHeight);
if (!canReturnInvalid && (visibleLine < 0)) if (!canReturnInvalid && (visibleLine < 0))
visibleLine = 0; visibleLine = 0;
int lineDoc = cs.DocFromDisplay(visibleLine); const int lineDoc = cs.DocFromDisplay(visibleLine);
if (canReturnInvalid && (lineDoc < 0)) if (canReturnInvalid && (lineDoc < 0))
return SelectionPosition(INVALID_POSITION); return SelectionPosition(INVALID_POSITION);
if (lineDoc >= pdoc->LinesTotal()) if (lineDoc >= pdoc->LinesTotal())
return SelectionPosition(canReturnInvalid ? INVALID_POSITION : pdoc->Length()); return SelectionPosition(canReturnInvalid ? INVALID_POSITION : pdoc->Length());
unsigned int posLineStart = pdoc->LineStart(lineDoc); const int posLineStart = pdoc->LineStart(lineDoc);
SelectionPosition retVal(canReturnInvalid ? INVALID_POSITION : static_cast<int>(posLineStart));
AutoSurface surface(this); AutoSurface surface(this);
AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
if (surface && ll) { if (surface && ll) {
LayoutLine(lineDoc, surface, vs, ll, wrapWidth); LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
int lineStartSet = cs.DisplayFromDoc(lineDoc); const int lineStartSet = cs.DisplayFromDoc(lineDoc);
int subLine = visibleLine - lineStartSet; const int subLine = visibleLine - lineStartSet;
if (subLine < ll->lines) { if (subLine < ll->lines) {
int lineStart = ll->LineStart(subLine); const Range rangeSubLine = ll->SubLineRange(subLine);
int lineEnd = ll->LineLastVisible(subLine); const XYPOSITION subLineStart = ll->positions[rangeSubLine.start];
XYPOSITION subLineStart = ll->positions[lineStart]; if (subLine > 0) // Wrapped
pt.x -= ll->wrapIndent;
if (ll->wrapIndent != 0) { const int positionInLine = ll->FindPositionFromX(pt.x + subLineStart, rangeSubLine, charPosition);
if (lineStart != 0) // Wrapped if (positionInLine < rangeSubLine.end) {
pt.x -= ll->wrapIndent; return SelectionPosition(pdoc->MovePositionOutsideChar(positionInLine + posLineStart, 1));
}
int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd);
while (i < lineEnd) {
if (charPosition) {
if ((pt.x + subLineStart) < (ll->positions[i + 1])) {
return SelectionPosition(pdoc->MovePositionOutsideChar(i + posLineStart, 1));
}
} else {
if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
return SelectionPosition(pdoc->MovePositionOutsideChar(i + posLineStart, 1));
}
}
i++;
} }
if (virtualSpace) { if (virtualSpace) {
const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth; const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth;
int spaceOffset = (pt.x + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / const int spaceOffset = (pt.x + subLineStart - ll->positions[rangeSubLine.end] + spaceWidth / 2) /
spaceWidth; spaceWidth;
return SelectionPosition(lineEnd + posLineStart, spaceOffset); return SelectionPosition(rangeSubLine.end + posLineStart, spaceOffset);
} else if (canReturnInvalid) { } else if (canReturnInvalid) {
if (pt.x < (ll->positions[lineEnd] - subLineStart)) { if (pt.x < (ll->positions[rangeSubLine.end] - subLineStart)) {
return SelectionPosition(pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1)); return SelectionPosition(pdoc->MovePositionOutsideChar(rangeSubLine.end + posLineStart, 1));
} }
} else { } else {
return SelectionPosition(lineEnd + posLineStart); return SelectionPosition(rangeSubLine.end + posLineStart);
} }
} }
if (!canReturnInvalid) if (!canReturnInvalid)
return SelectionPosition(ll->numCharsInLine + posLineStart); return SelectionPosition(ll->numCharsInLine + posLineStart);
} }
return retVal; return SelectionPosition(canReturnInvalid ? INVALID_POSITION : posLineStart);
} }
int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) { int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) {
@ -618,6 +596,7 @@ int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosit
/** /**
* Find the document position corresponding to an x coordinate on a particular document line. * Find the document position corresponding to an x coordinate on a particular document line.
* Ensure is between whole characters when document is in multi-byte or UTF-8 mode. * Ensure is between whole characters when document is in multi-byte or UTF-8 mode.
* This method is used for rectangular selections and does not work on wrapped lines.
*/ */
SelectionPosition Editor::SPositionFromLineX(int lineDoc, int x) { SelectionPosition Editor::SPositionFromLineX(int lineDoc, int x) {
RefreshStyleData(); RefreshStyleData();
@ -626,33 +605,20 @@ SelectionPosition Editor::SPositionFromLineX(int lineDoc, int x) {
//Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
AutoSurface surface(this); AutoSurface surface(this);
AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
int retVal = 0;
if (surface && ll) { if (surface && ll) {
unsigned int posLineStart = pdoc->LineStart(lineDoc); const int posLineStart = pdoc->LineStart(lineDoc);
LayoutLine(lineDoc, surface, vs, ll, wrapWidth); LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
int subLine = 0; const Range rangeSubLine = ll->SubLineRange(0);
int lineStart = ll->LineStart(subLine); const XYPOSITION subLineStart = ll->positions[rangeSubLine.start];
int lineEnd = ll->LineLastVisible(subLine); const int positionInLine = ll->FindPositionFromX(x + subLineStart, rangeSubLine, false);
XYPOSITION subLineStart = ll->positions[lineStart]; if (positionInLine < rangeSubLine.end) {
XYPOSITION newX = x; return SelectionPosition(pdoc->MovePositionOutsideChar(positionInLine + posLineStart, 1));
if (ll->wrapIndent != 0) {
if (lineStart != 0) // Wrapped
newX -= ll->wrapIndent;
}
int i = ll->FindBefore(newX + subLineStart, lineStart, lineEnd);
while (i < lineEnd) {
if ((newX + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);
return SelectionPosition(retVal);
}
i++;
} }
const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth; const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth;
int spaceOffset = (newX + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / spaceWidth; const int spaceOffset = (x + subLineStart - ll->positions[rangeSubLine.end] + spaceWidth / 2) / spaceWidth;
return SelectionPosition(lineEnd + posLineStart, spaceOffset); return SelectionPosition(rangeSubLine.end + posLineStart, spaceOffset);
} }
return SelectionPosition(retVal); return SelectionPosition(0);
} }
int Editor::PositionFromLineX(int lineDoc, int x) { int Editor::PositionFromLineX(int lineDoc, int x) {
@ -689,6 +655,10 @@ void Editor::RedrawRect(PRectangle rc) {
} }
} }
void Editor::DiscardOverdraw() {
// Overridden on platforms that may draw outside visible area.
}
void Editor::Redraw() { void Editor::Redraw() {
//Platform::DebugPrintf("Redraw all\n"); //Platform::DebugPrintf("Redraw all\n");
PRectangle rcClient = GetClientRectangle(); PRectangle rcClient = GetClientRectangle();
@ -699,7 +669,10 @@ void Editor::Redraw() {
} }
void Editor::RedrawSelMargin(int line, bool allAfter) { void Editor::RedrawSelMargin(int line, bool allAfter) {
if (!AbandonPaint()) { bool abandonDraw = false;
if (!wMargin.GetID()) // Margin in main window so may need to abandon and retry
abandonDraw = AbandonPaint();
if (!abandonDraw) {
if (vs.maskInLine) { if (vs.maskInLine) {
Redraw(); Redraw();
} else { } else {
@ -1278,7 +1251,7 @@ slop | strict | jumps | even | Caret can go to the margin | When
1 | 1 | 1 | 1 | No, kept out of UZ | moved to put caret at 3UZ of the margin 1 | 1 | 1 | 1 | No, kept out of UZ | moved to put caret at 3UZ of the margin
*/ */
Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange range, const XYScrollOptions options) { Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options) {
PRectangle rcClient = GetTextRectangle(); PRectangle rcClient = GetTextRectangle();
Point pt = LocationFromPosition(range.caret); Point pt = LocationFromPosition(range.caret);
Point ptAnchor = LocationFromPosition(range.anchor); Point ptAnchor = LocationFromPosition(range.anchor);
@ -1488,9 +1461,9 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange rang
} }
// In case of a jump (find result) largely out of display, adjust the offset to display the caret // In case of a jump (find result) largely out of display, adjust the offset to display the caret
if (pt.x + xOffset < rcClient.left + newXY.xOffset) { if (pt.x + xOffset < rcClient.left + newXY.xOffset) {
newXY.xOffset = pt.x + xOffset - rcClient.left; newXY.xOffset = pt.x + xOffset - rcClient.left - 2;
} else if (pt.x + xOffset >= rcClient.right + newXY.xOffset) { } else if (pt.x + xOffset >= rcClient.right + newXY.xOffset) {
newXY.xOffset = pt.x + xOffset - rcClient.right + 1; newXY.xOffset = pt.x + xOffset - rcClient.right + 2;
if (vs.caretStyle == CARETSTYLE_BLOCK) { if (vs.caretStyle == CARETSTYLE_BLOCK) {
// Ensure we can see a good portion of the block caret // Ensure we can see a good portion of the block caret
newXY.xOffset += static_cast<int>(vs.aveCharWidth); newXY.xOffset += static_cast<int>(vs.aveCharWidth);
@ -1988,7 +1961,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
} }
} else if (levelNum > SC_FOLDLEVELBASE) { } else if (levelNum > SC_FOLDLEVELBASE) {
marks |= 1 << SC_MARKNUM_FOLDERSUB; marks |= 1 << SC_MARKNUM_FOLDERSUB;
} }
} else { } else {
if (levelNum < levelNextNum) { if (levelNum < levelNextNum) {
if (cs.GetExpanded(lineDoc)) { if (cs.GetExpanded(lineDoc)) {
@ -1998,7 +1971,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
} }
} else if (levelNum > SC_FOLDLEVELBASE) { } else if (levelNum > SC_FOLDLEVELBASE) {
marks |= 1 << SC_MARKNUM_FOLDERSUB; marks |= 1 << SC_MARKNUM_FOLDERSUB;
} }
} }
needWhiteClosure = false; needWhiteClosure = false;
int firstFollowupLine = cs.DocFromDisplay(cs.DisplayFromDoc(lineDoc + 1)); int firstFollowupLine = cs.DocFromDisplay(cs.DisplayFromDoc(lineDoc + 1));
@ -2300,7 +2273,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
posCache.MeasureWidths(surface, vstyle, STYLE_CONTROLCHAR, ts.representation->stringRep.c_str(), posCache.MeasureWidths(surface, vstyle, STYLE_CONTROLCHAR, ts.representation->stringRep.c_str(),
static_cast<unsigned int>(ts.representation->stringRep.length()), positionsRepr, pdoc); static_cast<unsigned int>(ts.representation->stringRep.length()), positionsRepr, pdoc);
representationWidth = positionsRepr[ts.representation->stringRep.length()-1] + vstyle.ctrlCharPadding; representationWidth = positionsRepr[ts.representation->stringRep.length()-1] + vstyle.ctrlCharPadding;
} }
} }
for (int ii=0; ii < ts.length; ii++) for (int ii=0; ii < ts.length; ii++)
ll->positions[ts.start + 1 + ii] = representationWidth; ll->positions[ts.start + 1 + ii] = representationWidth;
@ -2399,7 +2372,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
- posLineStart; - posLineStart;
p = pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart; p = pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart;
continue; continue;
} else if (ll->styles[p] != ll->styles[p - 1]) { } else if ((vstyle.wrapState == eWrapWord) && (ll->styles[p] != ll->styles[p - 1])) {
lastGoodBreak = p; lastGoodBreak = p;
} else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) { } else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) {
lastGoodBreak = p; lastGoodBreak = p;
@ -2584,14 +2557,20 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
char hexits[4]; char hexits[4];
const char *ctrlChar; const char *ctrlChar;
unsigned char chEOL = ll->chars[eolPos]; unsigned char chEOL = ll->chars[eolPos];
int styleMain = ll->styles[eolPos];
ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, eolInSelection, false, styleMain, eolPos, ll);
if (UTF8IsAscii(chEOL)) { if (UTF8IsAscii(chEOL)) {
ctrlChar = ControlCharacterString(chEOL); ctrlChar = ControlCharacterString(chEOL);
} else { } else {
sprintf(hexits, "x%2X", chEOL); Representation *repr = reprs.RepresentationFromCharacter(ll->chars + eolPos, ll->numCharsInLine - eolPos);
ctrlChar = hexits; if (repr) {
ctrlChar = repr->stringRep.c_str();
eolPos = ll->numCharsInLine;
} else {
sprintf(hexits, "x%2X", chEOL);
ctrlChar = hexits;
}
} }
int styleMain = ll->styles[eolPos];
ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, eolInSelection, false, styleMain, eolPos, ll);
ColourDesired textFore = vsDraw.styles[styleMain].fore; ColourDesired textFore = vsDraw.styles[styleMain].fore;
if (eolInSelection && vsDraw.selColours.fore.isSet) { if (eolInSelection && vsDraw.selColours.fore.isSet) {
textFore = (eolInSelection == 1) ? vsDraw.selColours.fore : vsDraw.selAdditionalForeground; textFore = (eolInSelection == 1) ? vsDraw.selColours.fore : vsDraw.selAdditionalForeground;
@ -2731,7 +2710,10 @@ void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int x
endPos = posLineEnd; endPos = posLineEnd;
DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart, DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart,
surface, vsDraw, xStart, rcLine, ll, subLine); surface, vsDraw, xStart, rcLine, ll, subLine);
startPos = deco->rs.EndRun(endPos); startPos = endPos;
if (!deco->rs.ValueAt(startPos)) {
startPos = deco->rs.EndRun(startPos);
}
} }
} }
} }
@ -2766,14 +2748,19 @@ void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int x
const StyledText stAnnotation = pdoc->AnnotationStyledText(line); const StyledText stAnnotation = pdoc->AnnotationStyledText(line);
if (stAnnotation.text && ValidStyledText(vsDraw, vsDraw.annotationStyleOffset, stAnnotation)) { if (stAnnotation.text && ValidStyledText(vsDraw, vsDraw.annotationStyleOffset, stAnnotation)) {
surface->FillRectangle(rcSegment, vsDraw.styles[0].back); surface->FillRectangle(rcSegment, vsDraw.styles[0].back);
if (vs.annotationVisible == ANNOTATION_BOXED) { rcSegment.left = xStart;
// Only care about calculating width if need to draw box if (trackLineWidth || (vs.annotationVisible == ANNOTATION_BOXED)) {
// Only care about calculating width if tracking or need to draw box
int widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset, stAnnotation); int widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset, stAnnotation);
widthAnnotation += vsDraw.spaceWidth * 2; // Margins if (vs.annotationVisible == ANNOTATION_BOXED) {
rcSegment.left = xStart + indent; widthAnnotation += vsDraw.spaceWidth * 2; // Margins
rcSegment.right = rcSegment.left + widthAnnotation; }
} else { if (widthAnnotation > lineWidthMaxSeen)
rcSegment.left = xStart; lineWidthMaxSeen = widthAnnotation;
if (vs.annotationVisible == ANNOTATION_BOXED) {
rcSegment.left = xStart + indent;
rcSegment.right = rcSegment.left + widthAnnotation;
}
} }
const int annotationLines = pdoc->AnnotationLines(line); const int annotationLines = pdoc->AnnotationLines(line);
size_t start = 0; size_t start = 0;
@ -3453,10 +3440,10 @@ void Editor::DrawCarets(Surface *surface, ViewStyle &vsDraw, int lineDoc, int xS
bool caretAtEOL = false; bool caretAtEOL = false;
bool drawBlockCaret = false; bool drawBlockCaret = false;
XYPOSITION widthOverstrikeCaret; XYPOSITION widthOverstrikeCaret;
int caretWidthOffset = 0; XYPOSITION caretWidthOffset = 0;
PRectangle rcCaret = rcLine; PRectangle rcCaret = rcLine;
if (posCaret.Position() == pdoc->Length()) { // At end of document if (posCaret.Position() == pdoc->Length()) { // At end of document
caretAtEOF = true; caretAtEOF = true;
widthOverstrikeCaret = vsDraw.aveCharWidth; widthOverstrikeCaret = vsDraw.aveCharWidth;
} else if ((posCaret.Position() - posLineStart) >= ll->numCharsInLine) { // At end of line } else if ((posCaret.Position() - posLineStart) >= ll->numCharsInLine) { // At end of line
@ -3469,11 +3456,11 @@ void Editor::DrawCarets(Surface *surface, ViewStyle &vsDraw, int lineDoc, int xS
widthOverstrikeCaret = 3; widthOverstrikeCaret = 3;
if (xposCaret > 0) if (xposCaret > 0)
caretWidthOffset = 1; // Move back so overlaps both character cells. caretWidthOffset = 0.51f; // Move back so overlaps both character cells.
xposCaret += xStart; xposCaret += xStart;
if (posDrag.IsValid()) { if (posDrag.IsValid()) {
/* Dragging text, use a line caret */ /* Dragging text, use a line caret */
rcCaret.left = xposCaret - caretWidthOffset; rcCaret.left = RoundXYPosition(xposCaret - caretWidthOffset);
rcCaret.right = rcCaret.left + vsDraw.caretWidth; rcCaret.right = rcCaret.left + vsDraw.caretWidth;
} else if (inOverstrike && drawOverstrikeCaret) { } else if (inOverstrike && drawOverstrikeCaret) {
/* Overstrike (insert mode), use a modified bar caret */ /* Overstrike (insert mode), use a modified bar caret */
@ -3491,7 +3478,7 @@ void Editor::DrawCarets(Surface *surface, ViewStyle &vsDraw, int lineDoc, int xS
} }
} else { } else {
/* Line caret */ /* Line caret */
rcCaret.left = xposCaret - caretWidthOffset; rcCaret.left = RoundXYPosition(xposCaret - caretWidthOffset);
rcCaret.right = rcCaret.left + vsDraw.caretWidth; rcCaret.right = rcCaret.left + vsDraw.caretWidth;
} }
ColourDesired caretColour = mainCaret ? vsDraw.caretcolour : vsDraw.additionalCaretColour; ColourDesired caretColour = mainCaret ? vsDraw.caretcolour : vsDraw.additionalCaretColour;
@ -4198,7 +4185,7 @@ void Editor::ClearSelection(bool retainMultipleSelections) {
sel.Range(r).End().Position())) { sel.Range(r).End().Position())) {
pdoc->DeleteChars(sel.Range(r).Start().Position(), pdoc->DeleteChars(sel.Range(r).Start().Position(),
sel.Range(r).Length()); sel.Range(r).Length());
sel.Range(r) = sel.Range(r).Start(); sel.Range(r) = SelectionRange(sel.Range(r).Start());
} }
} }
} }
@ -4316,9 +4303,9 @@ void Editor::Clear() {
if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) { if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
if (sel.Range(r).Start().VirtualSpace()) { if (sel.Range(r).Start().VirtualSpace()) {
if (sel.Range(r).anchor < sel.Range(r).caret) if (sel.Range(r).anchor < sel.Range(r).caret)
sel.Range(r) = SelectionPosition(InsertSpace(sel.Range(r).anchor.Position(), sel.Range(r).anchor.VirtualSpace())); sel.Range(r) = SelectionRange(InsertSpace(sel.Range(r).anchor.Position(), sel.Range(r).anchor.VirtualSpace()));
else else
sel.Range(r) = SelectionPosition(InsertSpace(sel.Range(r).caret.Position(), sel.Range(r).caret.VirtualSpace())); sel.Range(r) = SelectionRange(InsertSpace(sel.Range(r).caret.Position(), sel.Range(r).caret.VirtualSpace()));
} }
if ((sel.Count() == 1) || !pdoc->IsPositionInLineEnd(sel.Range(r).caret.Position())) { if ((sel.Count() == 1) || !pdoc->IsPositionInLineEnd(sel.Range(r).caret.Position())) {
pdoc->DelChar(sel.Range(r).caret.Position()); pdoc->DelChar(sel.Range(r).caret.Position());
@ -4414,6 +4401,14 @@ void Editor::DelCharBack(bool allowLineStartDeletion) {
ShowCaretAtCurrentPosition(); ShowCaretAtCurrentPosition();
} }
int Editor::ModifierFlags(bool shift, bool ctrl, bool alt, bool meta) {
return
(shift ? SCI_SHIFT : 0) |
(ctrl ? SCI_CTRL : 0) |
(alt ? SCI_ALT : 0) |
(meta ? SCI_META : 0);
}
void Editor::NotifyFocus(bool focus) { void Editor::NotifyFocus(bool focus) {
SCNotification scn = {}; SCNotification scn = {};
scn.nmhdr.code = focus ? SCN_FOCUSIN : SCN_FOCUSOUT; scn.nmhdr.code = focus ? SCN_FOCUSIN : SCN_FOCUSOUT;
@ -4465,41 +4460,53 @@ void Editor::NotifyModifyAttempt() {
NotifyParent(scn); NotifyParent(scn);
} }
void Editor::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) { void Editor::NotifyDoubleClick(Point pt, int modifiers) {
SCNotification scn = {}; SCNotification scn = {};
scn.nmhdr.code = SCN_DOUBLECLICK; scn.nmhdr.code = SCN_DOUBLECLICK;
scn.line = LineFromLocation(pt); scn.line = LineFromLocation(pt);
scn.position = PositionFromLocation(pt, true); scn.position = PositionFromLocation(pt, true);
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | scn.modifiers = modifiers;
(alt ? SCI_ALT : 0); NotifyParent(scn);
}
void Editor::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) {
NotifyDoubleClick(pt, ModifierFlags(shift, ctrl, alt));
}
void Editor::NotifyHotSpotDoubleClicked(int position, int modifiers) {
SCNotification scn = {};
scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK;
scn.position = position;
scn.modifiers = modifiers;
NotifyParent(scn); NotifyParent(scn);
} }
void Editor::NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt) { void Editor::NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt) {
NotifyHotSpotDoubleClicked(position, ModifierFlags(shift, ctrl, alt));
}
void Editor::NotifyHotSpotClicked(int position, int modifiers) {
SCNotification scn = {}; SCNotification scn = {};
scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK; scn.nmhdr.code = SCN_HOTSPOTCLICK;
scn.position = position; scn.position = position;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | scn.modifiers = modifiers;
(alt ? SCI_ALT : 0);
NotifyParent(scn); NotifyParent(scn);
} }
void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt) { void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt) {
NotifyHotSpotClicked(position, ModifierFlags(shift, ctrl, alt));
}
void Editor::NotifyHotSpotReleaseClick(int position, int modifiers) {
SCNotification scn = {}; SCNotification scn = {};
scn.nmhdr.code = SCN_HOTSPOTCLICK; scn.nmhdr.code = SCN_HOTSPOTRELEASECLICK;
scn.position = position; scn.position = position;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | scn.modifiers = modifiers;
(alt ? SCI_ALT : 0);
NotifyParent(scn); NotifyParent(scn);
} }
void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt) { void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt) {
SCNotification scn = {}; NotifyHotSpotReleaseClick(position, ModifierFlags(shift, ctrl, alt));
scn.nmhdr.code = SCN_HOTSPOTRELEASECLICK;
scn.position = position;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
(alt ? SCI_ALT : 0);
NotifyParent(scn);
} }
bool Editor::NotifyUpdateUI() { bool Editor::NotifyUpdateUI() {
@ -4520,19 +4527,23 @@ void Editor::NotifyPainted() {
NotifyParent(scn); NotifyParent(scn);
} }
void Editor::NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt) { void Editor::NotifyIndicatorClick(bool click, int position, int modifiers) {
int mask = pdoc->decorations.AllOnFor(position); int mask = pdoc->decorations.AllOnFor(position);
if ((click && mask) || pdoc->decorations.clickNotified) { if ((click && mask) || pdoc->decorations.clickNotified) {
SCNotification scn = {}; SCNotification scn = {};
pdoc->decorations.clickNotified = click; pdoc->decorations.clickNotified = click;
scn.nmhdr.code = click ? SCN_INDICATORCLICK : SCN_INDICATORRELEASE; scn.nmhdr.code = click ? SCN_INDICATORCLICK : SCN_INDICATORRELEASE;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); scn.modifiers = modifiers;
scn.position = position; scn.position = position;
NotifyParent(scn); NotifyParent(scn);
} }
} }
bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) { void Editor::NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt) {
NotifyIndicatorClick(click, position, ModifierFlags(shift, ctrl, alt));
}
bool Editor::NotifyMarginClick(Point pt, int modifiers) {
int marginClicked = -1; int marginClicked = -1;
int x = vs.textStart - vs.fixedColumnWidth; int x = vs.textStart - vs.fixedColumnWidth;
for (int margin = 0; margin <= SC_MAX_MARGIN; margin++) { for (int margin = 0; margin <= SC_MAX_MARGIN; margin++) {
@ -4543,6 +4554,8 @@ bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) {
if ((marginClicked >= 0) && vs.ms[marginClicked].sensitive) { if ((marginClicked >= 0) && vs.ms[marginClicked].sensitive) {
int position = pdoc->LineStart(LineFromLocation(pt)); int position = pdoc->LineStart(LineFromLocation(pt));
if ((vs.ms[marginClicked].mask & SC_MASK_FOLDERS) && (foldAutomatic & SC_AUTOMATICFOLD_CLICK)) { if ((vs.ms[marginClicked].mask & SC_MASK_FOLDERS) && (foldAutomatic & SC_AUTOMATICFOLD_CLICK)) {
const bool ctrl = (modifiers & SCI_CTRL) != 0;
const bool shift = (modifiers & SCI_SHIFT) != 0;
int lineClick = pdoc->LineFromPosition(position); int lineClick = pdoc->LineFromPosition(position);
if (shift && ctrl) { if (shift && ctrl) {
FoldAll(SC_FOLDACTION_TOGGLE); FoldAll(SC_FOLDACTION_TOGGLE);
@ -4564,8 +4577,7 @@ bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) {
} }
SCNotification scn = {}; SCNotification scn = {};
scn.nmhdr.code = SCN_MARGINCLICK; scn.nmhdr.code = SCN_MARGINCLICK;
scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | scn.modifiers = modifiers;
(alt ? SCI_ALT : 0);
scn.position = position; scn.position = position;
scn.margin = marginClicked; scn.margin = marginClicked;
NotifyParent(scn); NotifyParent(scn);
@ -4575,6 +4587,10 @@ bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) {
} }
} }
bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) {
return NotifyMarginClick(pt, ModifierFlags(shift, ctrl, alt));
}
void Editor::NotifyNeedShown(int pos, int len) { void Editor::NotifyNeedShown(int pos, int len) {
SCNotification scn = {}; SCNotification scn = {};
scn.nmhdr.code = SCN_NEEDSHOWN; scn.nmhdr.code = SCN_NEEDSHOWN;
@ -4923,7 +4939,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
case SCI_NEWLINE: case SCI_NEWLINE:
default: default:
// printf("Filtered out %ld of macro recording\n", iMessage); // printf("Filtered out %ld of macro recording\n", iMessage);
return ; return;
} }
// Send notification // Send notification
@ -5097,6 +5113,7 @@ void Editor::NewLine() {
// Remove non-main ranges // Remove non-main ranges
InvalidateSelection(sel.RangeMain(), true); InvalidateSelection(sel.RangeMain(), true);
sel.SetSelection(sel.RangeMain()); sel.SetSelection(sel.RangeMain());
sel.RangeMain().ClearVirtualSpace();
// Clear main range and insert line end // Clear main range and insert line end
bool needGroupUndo = !sel.Empty(); bool needGroupUndo = !sel.Empty();
@ -5747,9 +5764,7 @@ int Editor::KeyDownWithModifiers(int key, int modifiers, bool *consumed) {
} }
int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed) { int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed) {
int modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | return KeyDownWithModifiers(key, ModifierFlags(shift, ctrl, alt), consumed);
(alt ? SCI_ALT : 0);
return KeyDownWithModifiers(key, modifiers, consumed);
} }
void Editor::Indent(bool forwards) { void Editor::Indent(bool forwards) {
@ -5823,6 +5838,7 @@ void Editor::Indent(bool forwards) {
} }
} }
} }
ContainerNeedsUpdate(SC_UPDATE_SELECTION);
} }
class CaseFolderASCII : public CaseFolderTable { class CaseFolderASCII : public CaseFolderTable {
@ -6286,18 +6302,23 @@ static bool AllowVirtualSpace(int virtualSpaceOptions, bool rectangular) {
|| (rectangular && ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) != 0)); || (rectangular && ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) != 0));
} }
void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) {
//Platform::DebugPrintf("ButtonDown %d %d = %d alt=%d %d\n", curTime, lastClickTime, curTime - lastClickTime, alt, inDragDrop); //Platform::DebugPrintf("ButtonDown %d %d = %d alt=%d %d\n", curTime, lastClickTime, curTime - lastClickTime, alt, inDragDrop);
ptMouseLast = pt; ptMouseLast = pt;
const bool ctrl = (modifiers & SCI_CTRL) != 0;
const bool shift = (modifiers & SCI_SHIFT) != 0;
const bool alt = (modifiers & SCI_ALT) != 0;
SelectionPosition newPos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, alt)); SelectionPosition newPos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, alt));
newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position()); newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position());
SelectionPosition newCharPos = SPositionFromLocation(pt, false, true, false);
newCharPos = MovePositionOutsideChar(newCharPos, -1);
inDragDrop = ddNone; inDragDrop = ddNone;
sel.SetMoveExtends(false); sel.SetMoveExtends(false);
if (NotifyMarginClick(pt, shift, ctrl, alt)) if (NotifyMarginClick(pt, modifiers))
return; return;
NotifyIndicatorClick(true, newPos.Position(), shift, ctrl, alt); NotifyIndicatorClick(true, newPos.Position(), modifiers);
bool inSelMargin = PointInSelMargin(pt); bool inSelMargin = PointInSelMargin(pt);
// In margin ctrl+(double)click should always select everything // In margin ctrl+(double)click should always select everything
@ -6380,9 +6401,9 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
} }
//Platform::DebugPrintf("Double click: %d - %d\n", anchor, currentPos); //Platform::DebugPrintf("Double click: %d - %d\n", anchor, currentPos);
if (doubleClick) { if (doubleClick) {
NotifyDoubleClick(pt, shift, ctrl, alt); NotifyDoubleClick(pt, modifiers);
if (PositionIsHotspot(newPos.Position())) if (PositionIsHotspot(newCharPos.Position()))
NotifyHotSpotDoubleClicked(newPos.Position(), shift, ctrl, alt); NotifyHotSpotDoubleClicked(newCharPos.Position(), modifiers);
} }
} else { // Single click } else { // Single click
if (inSelMargin) { if (inSelMargin) {
@ -6411,8 +6432,8 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
SetMouseCapture(true); SetMouseCapture(true);
} else { } else {
if (PointIsHotspot(pt)) { if (PointIsHotspot(pt)) {
NotifyHotSpotClicked(newPos.Position(), shift, ctrl, alt); NotifyHotSpotClicked(newCharPos.Position(), modifiers);
hotSpotClickPos = PositionFromLocation(pt,true,false); hotSpotClickPos = newCharPos.Position();
} }
if (!shift) { if (!shift) {
if (PointInSelection(pt) && !SelectionEmpty()) if (PointInSelection(pt) && !SelectionEmpty())
@ -6456,12 +6477,16 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
ShowCaretAtCurrentPosition(); ShowCaretAtCurrentPosition();
} }
void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
return ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt));
}
bool Editor::PositionIsHotspot(int position) const { bool Editor::PositionIsHotspot(int position) const {
return vs.styles[pdoc->StyleAt(position) & pdoc->stylingBitsMask].hotspot; return vs.styles[pdoc->StyleAt(position) & pdoc->stylingBitsMask].hotspot;
} }
bool Editor::PointIsHotspot(Point pt) { bool Editor::PointIsHotspot(Point pt) {
int pos = PositionFromLocation(pt, true); int pos = PositionFromLocation(pt, true, true);
if (pos == INVALID_POSITION) if (pos == INVALID_POSITION)
return false; return false;
return PositionIsHotspot(pos); return PositionIsHotspot(pos);
@ -6469,7 +6494,7 @@ bool Editor::PointIsHotspot(Point pt) {
void Editor::SetHotSpotRange(Point *pt) { void Editor::SetHotSpotRange(Point *pt) {
if (pt) { if (pt) {
int pos = PositionFromLocation(*pt); int pos = PositionFromLocation(*pt, false, true);
// If we don't limit this to word characters then the // If we don't limit this to word characters then the
// range can encompass more than the run range and then // range can encompass more than the run range and then
@ -6589,10 +6614,10 @@ void Editor::ButtonMoveWithModifiers(Point pt, int modifiers) {
} }
EnsureCaretVisible(false, false, true); EnsureCaretVisible(false, false, true);
if (hsStart != -1 && !PositionIsHotspot(movePos.Position())) if (hsStart != -1 && !PointIsHotspot(pt))
SetHotSpotRange(NULL); SetHotSpotRange(NULL);
if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,false) != hotSpotClickPos) { if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,true) != hotSpotClickPos) {
if (inDragDrop == ddNone) { if (inDragDrop == ddNone) {
DisplayCursor(Window::cursorText); DisplayCursor(Window::cursorText);
} }
@ -6637,7 +6662,9 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
} }
if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) { if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) {
hotSpotClickPos = INVALID_POSITION; hotSpotClickPos = INVALID_POSITION;
NotifyHotSpotReleaseClick(newPos.Position(), false, ctrl, false); SelectionPosition newCharPos = SPositionFromLocation(pt, false, true, false);
newCharPos = MovePositionOutsideChar(newCharPos, -1);
NotifyHotSpotReleaseClick(newCharPos.Position(), ctrl ? SCI_CTRL : 0);
} }
if (HaveMouseCapture()) { if (HaveMouseCapture()) {
if (PointInSelMargin(pt)) { if (PointInSelMargin(pt)) {
@ -6648,7 +6675,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
} }
ptMouseLast = pt; ptMouseLast = pt;
SetMouseCapture(false); SetMouseCapture(false);
NotifyIndicatorClick(false, newPos.Position(), false, false, false); NotifyIndicatorClick(false, newPos.Position(), 0);
if (inDragDrop == ddDragging) { if (inDragDrop == ddDragging) {
SelectionPosition selStart = SelectionStart(); SelectionPosition selStart = SelectionStart();
SelectionPosition selEnd = SelectionEnd(); SelectionPosition selEnd = SelectionEnd();
@ -6772,7 +6799,7 @@ int Editor::PositionAfterArea(PRectangle rcArea) const {
// The start of the document line after the display line after the area // The start of the document line after the display line after the area
// This often means that the line after a modification is restyled which helps // This often means that the line after a modification is restyled which helps
// detect multiline comment additions and heals single line comments // detect multiline comment additions and heals single line comments
int lineAfter = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1; int lineAfter = TopLineOfMain() + (rcArea.bottom - 1) / vs.lineHeight + 1;
if (lineAfter < cs.LinesDisplayed()) if (lineAfter < cs.LinesDisplayed())
return pdoc->LineStart(cs.DocFromDisplay(lineAfter) + 1); return pdoc->LineStart(cs.DocFromDisplay(lineAfter) + 1);
else else
@ -6782,7 +6809,7 @@ int Editor::PositionAfterArea(PRectangle rcArea) const {
// Style to a position within the view. If this causes a change at end of last line then // Style to a position within the view. If this causes a change at end of last line then
// affects later lines so style all the viewed text. // affects later lines so style all the viewed text.
void Editor::StyleToPositionInView(Position pos) { void Editor::StyleToPositionInView(Position pos) {
int endWindow = (vs.marginInside) ? (PositionAfterArea(GetClientRectangle())) : (pdoc->Length()); int endWindow = PositionAfterArea(GetClientDrawingRectangle());
if (pos > endWindow) if (pos > endWindow)
pos = endWindow; pos = endWindow;
int styleAtEnd = pdoc->StyleAt(pos-1); int styleAtEnd = pdoc->StyleAt(pos-1);
@ -6790,6 +6817,9 @@ void Editor::StyleToPositionInView(Position pos) {
if ((endWindow > pos) && (styleAtEnd != pdoc->StyleAt(pos-1))) { if ((endWindow > pos) && (styleAtEnd != pdoc->StyleAt(pos-1))) {
// Style at end of line changed so is multi-line change like starting a comment // Style at end of line changed so is multi-line change like starting a comment
// so require rest of window to be styled. // so require rest of window to be styled.
DiscardOverdraw(); // Prepared bitmaps may be invalid
// DiscardOverdraw may have truncated client drawing area so recalculate endWindow
endWindow = PositionAfterArea(GetClientDrawingRectangle());
pdoc->EnsureStyledTo(endWindow); pdoc->EnsureStyledTo(endWindow);
} }
} }
@ -6972,7 +7002,7 @@ void Editor::SetFoldExpanded(int lineDoc, bool expanded) {
void Editor::FoldLine(int line, int action) { void Editor::FoldLine(int line, int action) {
if (line >= 0) { if (line >= 0) {
if (action == SC_FOLDACTION_TOGGLE) { if (action == SC_FOLDACTION_TOGGLE) {
if ((pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) == 0) { if ((pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) == 0) {
line = pdoc->GetFoldParent(line); line = pdoc->GetFoldParent(line);
if (line < 0) if (line < 0)
return; return;
@ -7340,11 +7370,7 @@ sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lPar
case SCI_STYLEGETSIZEFRACTIONAL: case SCI_STYLEGETSIZEFRACTIONAL:
return vs.styles[wParam].size; return vs.styles[wParam].size;
case SCI_STYLEGETFONT: case SCI_STYLEGETFONT:
if (!vs.styles[wParam].fontName) return StringResult(lParam, vs.styles[wParam].fontName);
return 0;
if (lParam != 0)
strcpy(CharPtrFromSPtr(lParam), vs.styles[wParam].fontName);
return strlen(vs.styles[wParam].fontName);
case SCI_STYLEGETUNDERLINE: case SCI_STYLEGETUNDERLINE:
return vs.styles[wParam].underline ? 1 : 0; return vs.styles[wParam].underline ? 1 : 0;
case SCI_STYLEGETCASE: case SCI_STYLEGETCASE:
@ -7362,12 +7388,27 @@ sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lPar
} }
sptr_t Editor::StringResult(sptr_t lParam, const char *val) { sptr_t Editor::StringResult(sptr_t lParam, const char *val) {
const size_t n = strlen(val); const size_t len = val ? strlen(val) : 0;
if (lParam != 0) { if (lParam) {
char *ptr = reinterpret_cast<char *>(lParam); char *ptr = CharPtrFromSPtr(lParam);
strcpy(ptr, val); if (val)
memcpy(ptr, val, len+1);
else
*ptr = 0;
} }
return n; // Not including NUL return len; // Not including NUL
}
sptr_t Editor::BytesResult(sptr_t lParam, const unsigned char *val, size_t len) {
// No NUL termination: len is number of valid/displayed bytes
if (lParam) {
char *ptr = CharPtrFromSPtr(lParam);
if (val)
memcpy(ptr, val, len);
else
*ptr = 0;
}
return val ? len : 0;
} }
sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
@ -8399,7 +8440,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
if (wParam <= MARKER_MAX) { if (wParam <= MARKER_MAX) {
vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam)); vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam));
vs.CalcLargestMarkerHeight(); vs.CalcLargestMarkerHeight();
}; }
InvalidateStyleData(); InvalidateStyleData();
RedrawSelMargin(); RedrawSelMargin();
break; break;
@ -8420,7 +8461,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
if (wParam <= MARKER_MAX) { if (wParam <= MARKER_MAX) {
vs.markers[wParam].SetRGBAImage(sizeRGBAImage, scaleRGBAImage / 100.0, reinterpret_cast<unsigned char *>(lParam)); vs.markers[wParam].SetRGBAImage(sizeRGBAImage, scaleRGBAImage / 100.0, reinterpret_cast<unsigned char *>(lParam));
vs.CalcLargestMarkerHeight(); vs.CalcLargestMarkerHeight();
}; }
InvalidateStyleData(); InvalidateStyleData();
RedrawSelMargin(); RedrawSelMargin();
break; break;
@ -9186,9 +9227,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
Representation *repr = reprs.RepresentationFromCharacter( Representation *repr = reprs.RepresentationFromCharacter(
reinterpret_cast<const char *>(wParam), UTF8MaxBytes); reinterpret_cast<const char *>(wParam), UTF8MaxBytes);
if (repr) { if (repr) {
if (lParam != 0) return StringResult(lParam, repr->stringRep.c_str());
strcpy(CharPtrFromSPtr(lParam), repr->stringRep.c_str());
return repr->stringRep.size();
} }
return 0; return 0;
} }
@ -9304,13 +9343,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_MARGINGETTEXT: { case SCI_MARGINGETTEXT: {
const StyledText st = pdoc->MarginStyledText(wParam); const StyledText st = pdoc->MarginStyledText(wParam);
if (lParam) { return BytesResult(lParam, reinterpret_cast<const unsigned char *>(st.text), st.length);
if (st.text)
memcpy(CharPtrFromSPtr(lParam), st.text, st.length);
else
strcpy(CharPtrFromSPtr(lParam), "");
}
return st.length;
} }
case SCI_MARGINSETSTYLE: case SCI_MARGINSETSTYLE:
@ -9328,13 +9361,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_MARGINGETSTYLES: { case SCI_MARGINGETSTYLES: {
const StyledText st = pdoc->MarginStyledText(wParam); const StyledText st = pdoc->MarginStyledText(wParam);
if (lParam) { return BytesResult(lParam, st.styles, st.length);
if (st.styles)
memcpy(CharPtrFromSPtr(lParam), st.styles, st.length);
else
strcpy(CharPtrFromSPtr(lParam), "");
}
return st.styles ? st.length : 0;
} }
case SCI_MARGINTEXTCLEARALL: case SCI_MARGINTEXTCLEARALL:
@ -9347,13 +9374,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_ANNOTATIONGETTEXT: { case SCI_ANNOTATIONGETTEXT: {
const StyledText st = pdoc->AnnotationStyledText(wParam); const StyledText st = pdoc->AnnotationStyledText(wParam);
if (lParam) { return BytesResult(lParam, reinterpret_cast<const unsigned char *>(st.text), st.length);
if (st.text)
memcpy(CharPtrFromSPtr(lParam), st.text, st.length);
else
strcpy(CharPtrFromSPtr(lParam), "");
}
return st.length;
} }
case SCI_ANNOTATIONGETSTYLE: { case SCI_ANNOTATIONGETSTYLE: {
@ -9371,13 +9392,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_ANNOTATIONGETSTYLES: { case SCI_ANNOTATIONGETSTYLES: {
const StyledText st = pdoc->AnnotationStyledText(wParam); const StyledText st = pdoc->AnnotationStyledText(wParam);
if (lParam) { return BytesResult(lParam, st.styles, st.length);
if (st.styles)
memcpy(CharPtrFromSPtr(lParam), st.styles, st.length);
else
strcpy(CharPtrFromSPtr(lParam), "");
}
return st.styles ? st.length : 0;
} }
case SCI_ANNOTATIONGETLINES: case SCI_ANNOTATIONGETLINES:
@ -9480,6 +9495,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
Redraw(); Redraw();
break; break;
case SCI_DROPSELECTIONN:
sel.DropSelection(wParam);
Redraw();
break;
case SCI_SETMAINSELECTION: case SCI_SETMAINSELECTION:
sel.SetMain(wParam); sel.SetMain(wParam);
Redraw(); Redraw();

View File

@ -119,7 +119,7 @@ public:
} }
private: private:
void FixSelectionForClipboard() { void FixSelectionForClipboard() {
// To avoid truncating the contents of the clipboard when pasted where the // To avoid truncating the contents of the clipboard when pasted where the
// clipboard contains NUL characters, replace NUL characters by spaces. // clipboard contains NUL characters, replace NUL characters by spaces.
std::replace(s.begin(), s.end(), '\0', ' '); std::replace(s.begin(), s.end(), '\0', ' ');
} }
@ -338,6 +338,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
Point DocumentPointFromView(Point ptView); // Convert a point from view space to document Point DocumentPointFromView(Point ptView); // Convert a point from view space to document
int TopLineOfMain() const; // Return the line at Main's y coordinate 0 int TopLineOfMain() const; // Return the line at Main's y coordinate 0
virtual PRectangle GetClientRectangle(); virtual PRectangle GetClientRectangle();
virtual PRectangle GetClientDrawingRectangle();
PRectangle GetTextRectangle(); PRectangle GetTextRectangle();
int LinesOnScreen(); int LinesOnScreen();
@ -356,8 +357,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
void SetTopLine(int topLineNew); void SetTopLine(int topLineNew);
bool AbandonPaint(); bool AbandonPaint();
void RedrawRect(PRectangle rc); virtual void RedrawRect(PRectangle rc);
void Redraw(); virtual void DiscardOverdraw();
virtual void Redraw();
void RedrawSelMargin(int line=-1, bool allAfter=false); void RedrawSelMargin(int line=-1, bool allAfter=false);
PRectangle RectangleFromRange(int start, int end); PRectangle RectangleFromRange(int start, int end);
void InvalidateRange(int start, int end); void InvalidateRange(int start, int end);
@ -412,7 +414,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
xysVertical=0x2, xysVertical=0x2,
xysHorizontal=0x4, xysHorizontal=0x4,
xysDefault=xysUseMargin|xysVertical|xysHorizontal}; xysDefault=xysUseMargin|xysVertical|xysHorizontal};
XYScrollPosition XYScrollToMakeVisible(const SelectionRange range, const XYScrollOptions options); XYScrollPosition XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options);
void SetXYScroll(XYScrollPosition newXY); void SetXYScroll(XYScrollPosition newXY);
void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true); void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true);
void ScrollRange(SelectionRange range); void ScrollRange(SelectionRange range);
@ -437,12 +439,12 @@ protected: // ScintillaBase subclass needs access to much of Editor
ColourDesired SelectionBackground(ViewStyle &vsDraw, bool main) const; ColourDesired SelectionBackground(ViewStyle &vsDraw, bool main) const;
ColourDesired TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourDesired background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) const; ColourDesired TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourDesired background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) const;
void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight); void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight);
void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour); static void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour);
void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll, void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
int line, int lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart, int line, int lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart,
bool overrideBackground, ColourDesired background, bool overrideBackground, ColourDesired background,
bool drawWrapMark, ColourDesired wrapColour); bool drawWrapMark, ColourDesired wrapColour);
void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw, static void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
int xStart, PRectangle rcLine, LineLayout *ll, int subLine); 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);
@ -488,6 +490,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void DelCharBack(bool allowLineStartDeletion); void DelCharBack(bool allowLineStartDeletion);
virtual void ClaimSelection() = 0; virtual void ClaimSelection() = 0;
static int ModifierFlags(bool shift, bool ctrl, bool alt, bool meta=false);
virtual void NotifyChange() = 0; virtual void NotifyChange() = 0;
virtual void NotifyFocus(bool focus); virtual void NotifyFocus(bool focus);
virtual void SetCtrlID(int identifier); virtual void SetCtrlID(int identifier);
@ -497,13 +500,19 @@ protected: // ScintillaBase subclass needs access to much of Editor
void NotifyChar(int ch); void NotifyChar(int ch);
void NotifySavePoint(bool isSavePoint); void NotifySavePoint(bool isSavePoint);
void NotifyModifyAttempt(); void NotifyModifyAttempt();
virtual void NotifyDoubleClick(Point pt, int modifiers);
virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt); virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt);
void NotifyHotSpotClicked(int position, int modifiers);
void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt); void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt);
void NotifyHotSpotDoubleClicked(int position, int modifiers);
void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt); void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt);
void NotifyHotSpotReleaseClick(int position, int modifiers);
void NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt); void NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt);
bool NotifyUpdateUI(); bool NotifyUpdateUI();
void NotifyPainted(); void NotifyPainted();
void NotifyIndicatorClick(bool click, int position, int modifiers);
void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt); void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt);
bool NotifyMarginClick(Point pt, int modifiers);
bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt);
void NotifyNeedShown(int pos, int len); void NotifyNeedShown(int pos, int len);
void NotifyDwelling(Point pt, bool state); void NotifyDwelling(Point pt, bool state);
@ -566,6 +575,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void WordSelection(int pos); void WordSelection(int pos);
void DwellEnd(bool mouseMoved); void DwellEnd(bool mouseMoved);
void MouseLeave(); void MouseLeave();
virtual void ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers);
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
void ButtonMoveWithModifiers(Point pt, int modifiers); void ButtonMoveWithModifiers(Point pt, int modifiers);
void ButtonMove(Point pt); void ButtonMove(Point pt);
@ -624,6 +634,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
static const char *StringFromEOLMode(int eolMode); static const char *StringFromEOLMode(int eolMode);
static sptr_t StringResult(sptr_t lParam, const char *val); static sptr_t StringResult(sptr_t lParam, const char *val);
static sptr_t BytesResult(sptr_t lParam, const unsigned char *val, size_t len);
public: public:
// Public so the COM thunks can access it. // Public so the COM thunks can access it.

View File

@ -66,14 +66,12 @@ LexerLibrary::LexerLibrary(const char *ModuleName) {
GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName"); GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory"); GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory");
// Assign a buffer for the lexer name.
char lexname[100];
strcpy(lexname, "");
int nl = GetLexerCount(); int nl = GetLexerCount();
for (int i = 0; i < nl; i++) { for (int i = 0; i < nl; i++) {
GetLexerName(i, lexname, 100); // Assign a buffer for the lexer name.
char lexname[100] = "";
GetLexerName(i, lexname, sizeof(lexname));
lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL); lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
Catalogue::AddLexerModule(lex); Catalogue::AddLexerModule(lex);

View File

@ -27,15 +27,13 @@ typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned i
class ExternalLexerModule : public LexerModule { class ExternalLexerModule : public LexerModule {
protected: protected:
GetLexerFactoryFunction fneFactory; GetLexerFactoryFunction fneFactory;
char name[100]; std::string name;
public: public:
ExternalLexerModule(int language_, LexerFunction fnLexer_, ExternalLexerModule(int language_, LexerFunction fnLexer_,
const char *languageName_=0, LexerFunction fnFolder_=0) : const char *languageName_=0, LexerFunction fnFolder_=0) :
LexerModule(language_, fnLexer_, 0, fnFolder_), LexerModule(language_, fnLexer_, 0, fnFolder_),
fneFactory(0) { fneFactory(0), name(languageName_){
strncpy(name, languageName_, sizeof(name)); languageName = name.c_str();
name[sizeof(name)-1] = '\0';
languageName = name;
} }
virtual void SetExternal(GetLexerFactoryFunction fFactory, int index); virtual void SetExternal(GetLexerFactoryFunction fFactory, int index);
}; };
@ -54,7 +52,7 @@ class LexerLibrary {
LexerMinder *last; LexerMinder *last;
public: public:
LexerLibrary(const char *ModuleName); explicit LexerLibrary(const char *ModuleName);
~LexerLibrary(); ~LexerLibrary();
void Release(); void Release();

View File

@ -1,6 +1,7 @@
// Scintilla source code edit control // Scintilla source code edit control
/** @file FontQuality.h /** @file FontQuality.h
** Definitions to control font anti-aliasing. ** Definitions to control font anti-aliasing.
** Redefine constants from Scintilla.h to avoid including Scintilla.h in PlatWin.cxx.
**/ **/
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org> // Copyright 1998-2009 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.
@ -12,12 +13,14 @@
namespace Scintilla { namespace Scintilla {
#endif #endif
// These definitions match Scintilla.h
#define SC_EFF_QUALITY_MASK 0xF #define SC_EFF_QUALITY_MASK 0xF
#define SC_EFF_QUALITY_DEFAULT 0 #define SC_EFF_QUALITY_DEFAULT 0
#define SC_EFF_QUALITY_NON_ANTIALIASED 1 #define SC_EFF_QUALITY_NON_ANTIALIASED 1
#define SC_EFF_QUALITY_ANTIALIASED 2 #define SC_EFF_QUALITY_ANTIALIASED 2
#define SC_EFF_QUALITY_LCD_OPTIMIZED 3 #define SC_EFF_QUALITY_LCD_OPTIMIZED 3
// These definitions must match SC_TECHNOLOGY_* in Scintilla.h
#define SCWIN_TECH_GDI 0 #define SCWIN_TECH_GDI 0
#define SCWIN_TECH_DIRECTWRITE 1 #define SCWIN_TECH_DIRECTWRITE 1

View File

@ -8,6 +8,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <vector> #include <vector>
#include <map>
#include "Platform.h" #include "Platform.h"
@ -36,26 +37,12 @@ void KeyMap::Clear() {
} }
void KeyMap::AssignCmdKey(int key, int modifiers, unsigned int msg) { void KeyMap::AssignCmdKey(int key, int modifiers, unsigned int msg) {
for (size_t keyIndex = 0; keyIndex < kmap.size(); keyIndex++) { kmap[KeyModifiers(key, modifiers)] = msg;
if ((key == kmap[keyIndex].key) && (modifiers == kmap[keyIndex].modifiers)) {
kmap[keyIndex].msg = msg;
return;
}
}
KeyToCommand ktc;
ktc.key = key;
ktc.modifiers = modifiers;
ktc.msg = msg;
kmap.push_back(ktc);
} }
unsigned int KeyMap::Find(int key, int modifiers) const { unsigned int KeyMap::Find(int key, int modifiers) const {
for (size_t i = 0; i < kmap.size(); i++) { std::map<KeyModifiers, unsigned int>::const_iterator it = kmap.find(KeyModifiers(key, modifiers));
if ((key == kmap[i].key) && (modifiers == kmap[i].modifiers)) { return (it == kmap.end()) ? 0 : it->second;
return kmap[i].msg;
}
}
return 0;
} }
#if PLAT_GTK_MACOSX #if PLAT_GTK_MACOSX

View File

@ -20,6 +20,22 @@ namespace Scintilla {
#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)
/**
*/
class KeyModifiers {
public:
int key;
int modifiers;
KeyModifiers(int key_, int modifiers_) : key(key_), modifiers(modifiers_) {
}
bool operator<(const KeyModifiers &other) const {
if (key == other.key)
return modifiers < other.modifiers;
else
return key < other.key;
}
};
/** /**
*/ */
class KeyToCommand { class KeyToCommand {
@ -32,7 +48,7 @@ public:
/** /**
*/ */
class KeyMap { class KeyMap {
std::vector<KeyToCommand> kmap; std::map<KeyModifiers, unsigned int> kmap;
static const KeyToCommand MapDefault[]; static const KeyToCommand MapDefault[];
public: public:

View File

@ -1,6 +1,6 @@
// Scintilla source code edit control // Scintilla source code edit control
/** @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-2011 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.
@ -14,6 +14,8 @@
#include "Platform.h" #include "Platform.h"
#include "Scintilla.h" #include "Scintilla.h"
#include "StringCopy.h"
#include "XPM.h" #include "XPM.h"
#include "LineMarker.h" #include "LineMarker.h"
@ -141,8 +143,7 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
Point(centreX - dimOn4, centreY + dimOn2), Point(centreX - dimOn4, centreY + dimOn2),
Point(centreX + dimOn2 - dimOn4, centreY), Point(centreX + dimOn2 - dimOn4, centreY),
}; };
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), surface->Polygon(pts, ELEMENTS(pts), fore, back);
fore, back);
} else if (markType == SC_MARK_ARROWDOWN) { } else if (markType == SC_MARK_ARROWDOWN) {
Point pts[] = { Point pts[] = {
@ -150,8 +151,7 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
Point(centreX + dimOn2, centreY - dimOn4), Point(centreX + dimOn2, centreY - dimOn4),
Point(centreX, centreY + dimOn2 - dimOn4), Point(centreX, centreY + dimOn2 - dimOn4),
}; };
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), surface->Polygon(pts, ELEMENTS(pts), fore, back);
fore, back);
} else if (markType == SC_MARK_PLUS) { } else if (markType == SC_MARK_PLUS) {
Point pts[] = { Point pts[] = {
@ -168,8 +168,7 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
Point(centreX - 1, centreY + 1), Point(centreX - 1, centreY + 1),
Point(centreX - armSize, centreY + 1), Point(centreX - armSize, centreY + 1),
}; };
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), surface->Polygon(pts, ELEMENTS(pts), fore, back);
fore, back);
} else if (markType == SC_MARK_MINUS) { } else if (markType == SC_MARK_MINUS) {
Point pts[] = { Point pts[] = {
@ -178,8 +177,7 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
Point(centreX + armSize, centreY +1), Point(centreX + armSize, centreY +1),
Point(centreX - armSize, centreY + 1), Point(centreX - armSize, centreY + 1),
}; };
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), surface->Polygon(pts, ELEMENTS(pts), fore, back);
fore, back);
} else if (markType == SC_MARK_SMALLRECT) { } else if (markType == SC_MARK_SMALLRECT) {
PRectangle rcSmall; PRectangle rcSmall;
@ -317,17 +315,14 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
DrawPlus(surface, centreX, centreY, blobSize, tail); DrawPlus(surface, centreX, centreY, blobSize, tail);
} else if (markType == SC_MARK_CIRCLEMINUS) { } else if (markType == SC_MARK_CIRCLEMINUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore, head);
DrawMinus(surface, centreX, centreY, blobSize, tail);
surface->PenColour(head); surface->PenColour(head);
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) {
DrawCircle(surface, centreX, centreY, blobSize, fore, head); DrawCircle(surface, centreX, centreY, blobSize, fore, head);
DrawMinus(surface, centreX, centreY, blobSize, tail); DrawMinus(surface, centreX, centreY, blobSize, tail);
} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
surface->PenColour(head); surface->PenColour(head);
surface->MoveTo(centreX, centreY + blobSize); surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom); surface->LineTo(centreX, rcWhole.bottom);
@ -336,6 +331,9 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
surface->MoveTo(centreX, rcWhole.top); surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize); surface->LineTo(centreX, centreY - blobSize);
DrawCircle(surface, centreX, centreY, blobSize, fore, head);
DrawMinus(surface, centreX, centreY, blobSize, tail);
} else if (markType >= SC_MARK_CHARACTER) { } else if (markType >= SC_MARK_CHARACTER) {
char character[1]; char character[1];
character[0] = static_cast<char>(markType - SC_MARK_CHARACTER); character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
@ -355,10 +353,12 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
} else if (markType == SC_MARK_ARROWS) { } else if (markType == SC_MARK_ARROWS) {
surface->PenColour(fore); surface->PenColour(fore);
int right = centreX - 2; int right = centreX - 2;
for (int b=0; b<3; b++) { const int armLength = dimOn2 - 1;
surface->MoveTo(right - 4, centreY - 4); for (int b = 0; b<3; b++) {
surface->LineTo(right, centreY); surface->MoveTo(right, centreY);
surface->LineTo(right - 5, centreY + 5); surface->LineTo(right - armLength, centreY - armLength);
surface->MoveTo(right, centreY);
surface->LineTo(right - armLength, centreY + armLength);
right += 4; right += 4;
} }
} else if (markType == SC_MARK_SHORTARROW) { } else if (markType == SC_MARK_SHORTARROW) {
@ -372,12 +372,21 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
Point(centreX, centreY + dimOn4), Point(centreX, centreY + dimOn4),
Point(centreX, centreY + dimOn2), Point(centreX, centreY + dimOn2),
}; };
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), surface->Polygon(pts, ELEMENTS(pts), fore, back);
fore, back);
} else if (markType == SC_MARK_LEFTRECT) { } else if (markType == SC_MARK_LEFTRECT) {
PRectangle rcLeft = rcWhole; PRectangle rcLeft = rcWhole;
rcLeft.right = rcLeft.left + 4; rcLeft.right = rcLeft.left + 4;
surface->FillRectangle(rcLeft, back); surface->FillRectangle(rcLeft, back);
} else if (markType == SC_MARK_BOOKMARK) {
int halfHeight = minDim / 3;
Point pts[] = {
Point(rc.left, centreY-halfHeight),
Point(rc.right-3, centreY-halfHeight),
Point(rc.right-3-halfHeight, centreY),
Point(rc.right-3, centreY+halfHeight),
Point(rc.left, centreY+halfHeight),
};
surface->Polygon(pts, ELEMENTS(pts), fore, back);
} else { // SC_MARK_FULLRECT } else { // SC_MARK_FULLRECT
surface->FillRectangle(rcWhole, back); surface->FillRectangle(rcWhole, back);
} }

View File

@ -18,7 +18,7 @@ namespace Scintilla {
class SplitVectorWithRangeAdd : public SplitVector<int> { class SplitVectorWithRangeAdd : public SplitVector<int> {
public: public:
SplitVectorWithRangeAdd(int growSize_) { explicit SplitVectorWithRangeAdd(int growSize_) {
SetGrowSize(growSize_); SetGrowSize(growSize_);
ReAllocate(growSize_); ReAllocate(growSize_);
} }
@ -88,7 +88,7 @@ private:
} }
public: public:
Partitioning(int growSize) { explicit Partitioning(int growSize) {
Allocate(growSize); Allocate(growSize);
} }

View File

@ -98,7 +98,7 @@ bool MarkerHandleSet::RemoveNumber(int markerNum, bool all) {
delete mhn; delete mhn;
performedDeletion = true; performedDeletion = true;
if (!all) if (!all)
break; break;
} else { } else {
pmhn = &((*pmhn)->next); pmhn = &((*pmhn)->next);
} }
@ -370,9 +370,9 @@ void LineAnnotation::InsertLine(int line) {
} }
void LineAnnotation::RemoveLine(int line) { void LineAnnotation::RemoveLine(int line) {
if (annotations.Length() && (line < annotations.Length())) { if (annotations.Length() && (line > 0) && (line <= annotations.Length())) {
delete []annotations[line]; delete []annotations[line-1];
annotations.Delete(line); annotations.Delete(line-1);
} }
} }

View File

@ -43,11 +43,6 @@
using namespace Scintilla; using namespace Scintilla;
#endif #endif
static inline bool IsControlCharacter(int ch) {
// iscntrl returns true for lots of chars > 127 which are displayable
return ch >= 0 && ch < ' ';
}
LineLayout::LineLayout(int maxLineLength_) : LineLayout::LineLayout(int maxLineLength_) :
lineStarts(0), lineStarts(0),
lenLineStarts(0), lenLineStarts(0),
@ -132,6 +127,10 @@ int LineLayout::LineLastVisible(int line) const {
} }
} }
Range LineLayout::SubLineRange(int subLine) const {
return Range(LineStart(subLine), LineLastVisible(subLine));
}
bool LineLayout::InLine(int offset, int line) const { bool LineLayout::InLine(int offset, int line) const {
return ((offset >= LineStart(line)) && (offset < LineStart(line + 1))) || return ((offset >= LineStart(line)) && (offset < LineStart(line + 1))) ||
((offset == numCharsInLine) && (line == (lines-1))); ((offset == numCharsInLine) && (line == (lines-1)));
@ -205,6 +204,47 @@ int LineLayout::FindBefore(XYPOSITION x, int lower, int upper) const {
return lower; return lower;
} }
int LineLayout::FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const {
int pos = FindBefore(x, range.start, range.end);
while (pos < range.end) {
if (charPosition) {
if (x < (positions[pos + 1])) {
return pos;
}
} else {
if (x < ((positions[pos] + positions[pos + 1]) / 2)) {
return pos;
}
}
pos++;
}
return range.end;
}
Point LineLayout::PointFromPosition(int posInLine, int lineHeight) const {
Point pt;
// In case of very long line put x at arbitrary large position
if (posInLine > maxLineLength) {
pt.x = positions[maxLineLength] - positions[LineStart(lines)];
}
for (int subLine = 0; subLine < lines; subLine++) {
const Range rangeSubLine = SubLineRange(subLine);
if (posInLine >= rangeSubLine.start) {
pt.y = subLine*lineHeight;
if (posInLine <= rangeSubLine.end) {
pt.x = positions[posInLine] - positions[rangeSubLine.start];
if (rangeSubLine.start != 0) // Wrapped lines may be indented
pt.x += wrapIndent;
}
} else {
break;
}
}
return pt;
}
int LineLayout::EndLineStyle() const { int LineLayout::EndLineStyle() const {
return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0]; return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0];
} }
@ -359,7 +399,7 @@ void SpecialRepresentations::SetRepresentation(const char *charBytes, const char
// New entry so increment for first byte // New entry so increment for first byte
startByteHasReprs[static_cast<unsigned char>(charBytes[0])]++; startByteHasReprs[static_cast<unsigned char>(charBytes[0])]++;
} }
mapReprs[KeyFromString(charBytes, UTF8MaxBytes)] = value; mapReprs[KeyFromString(charBytes, UTF8MaxBytes)] = Representation(value);
} }
void SpecialRepresentations::ClearRepresentation(const char *charBytes) { void SpecialRepresentations::ClearRepresentation(const char *charBytes) {
@ -454,7 +494,7 @@ BreakFinder::~BreakFinder() {
TextSegment BreakFinder::Next() { TextSegment BreakFinder::Next() {
if (subBreak == -1) { if (subBreak == -1) {
int prev = nextBreak; int prev = nextBreak;
while (nextBreak < lineEnd) { while (nextBreak < lineEnd) {
int charWidth = 1; int charWidth = 1;
if (encodingFamily == efUnicode) if (encodingFamily == efUnicode)
charWidth = UTF8DrawBytes(reinterpret_cast<unsigned char *>(ll->chars) + nextBreak, lineEnd - nextBreak); charWidth = UTF8DrawBytes(reinterpret_cast<unsigned char *>(ll->chars) + nextBreak, lineEnd - nextBreak);

View File

@ -53,19 +53,22 @@ public:
int lines; int lines;
XYPOSITION wrapIndent; // In pixels XYPOSITION wrapIndent; // In pixels
LineLayout(int maxLineLength_); explicit LineLayout(int maxLineLength_);
virtual ~LineLayout(); virtual ~LineLayout();
void Resize(int maxLineLength_); void Resize(int maxLineLength_);
void Free(); void Free();
void Invalidate(validLevel validity_); void Invalidate(validLevel validity_);
int LineStart(int line) const; int LineStart(int line) const;
int LineLastVisible(int line) const; int LineLastVisible(int line) const;
Range SubLineRange(int line) const;
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, bool ignoreStyle); char bracesMatchStyle, int xHighlight, bool ignoreStyle);
void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle); void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle);
int FindBefore(XYPOSITION x, int lower, int upper) const; int FindBefore(XYPOSITION x, int lower, int upper) const;
int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const;
Point PointFromPosition(int posInLine, int lineHeight) const;
int EndLineStyle() const; int EndLineStyle() const;
}; };
@ -116,7 +119,7 @@ public:
class Representation { class Representation {
public: public:
std::string stringRep; std::string stringRep;
Representation(const char *value="") : stringRep(value) { explicit Representation(const char *value="") : stringRep(value) {
} }
}; };

View File

@ -333,16 +333,18 @@ static int GetHexaChar(unsigned char hd1, unsigned char hd2) {
hexValue += 16 * (hd1 - 'A' + 10); hexValue += 16 * (hd1 - 'A' + 10);
} else if (hd1 >= 'a' && hd1 <= 'f') { } else if (hd1 >= 'a' && hd1 <= 'f') {
hexValue += 16 * (hd1 - 'a' + 10); hexValue += 16 * (hd1 - 'a' + 10);
} else } else {
return -1; return -1;
}
if (hd2 >= '0' && hd2 <= '9') { if (hd2 >= '0' && hd2 <= '9') {
hexValue += hd2 - '0'; hexValue += hd2 - '0';
} else if (hd2 >= 'A' && hd2 <= 'F') { } else if (hd2 >= 'A' && hd2 <= 'F') {
hexValue += hd2 - 'A' + 10; hexValue += hd2 - 'A' + 10;
} else if (hd2 >= 'a' && hd2 <= 'f') { } else if (hd2 >= 'a' && hd2 <= 'f') {
hexValue += hd2 - 'a' + 10; hexValue += hd2 - 'a' + 10;
} else } else {
return -1; return -1;
}
return hexValue; return hexValue;
} }
@ -472,18 +474,18 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
break; break;
case '^': /* match beginning */ case '^': /* match beginning */
if (p == pattern) if (p == pattern) {
*mp++ = BOL; *mp++ = BOL;
else { } else {
*mp++ = CHR; *mp++ = CHR;
*mp++ = *p; *mp++ = *p;
} }
break; break;
case '$': /* match endofline */ case '$': /* match endofline */
if (!*(p+1)) if (!*(p+1)) {
*mp++ = EOL; *mp++ = EOL;
else { } else {
*mp++ = CHR; *mp++ = CHR;
*mp++ = *p; *mp++ = *p;
} }
@ -498,8 +500,9 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
mask = '\377'; mask = '\377';
i++; i++;
p++; p++;
} else } else {
mask = 0; mask = 0;
}
if (*p == '-') { /* real dash */ if (*p == '-') { /* real dash */
i++; i++;
@ -523,9 +526,9 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
i++; i++;
c2 = static_cast<unsigned char>(*++p); c2 = static_cast<unsigned char>(*++p);
if (c2 == '\\') { if (c2 == '\\') {
if (!*(p+1)) // End of RE if (!*(p+1)) { // End of RE
return badpat("Missing ]"); return badpat("Missing ]");
else { } else {
i++; i++;
p++; p++;
int incr; int incr;
@ -654,8 +657,9 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
if (tagc > n) { if (tagc > n) {
*mp++ = static_cast<char>(REF); *mp++ = static_cast<char>(REF);
*mp++ = static_cast<char>(n); *mp++ = static_cast<char>(n);
} else } else {
return badpat("Undetermined reference"); return badpat("Undetermined reference");
}
break; break;
default: default:
if (!posix && *p == '(') { if (!posix && *p == '(') {
@ -663,16 +667,18 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
tagstk[++tagi] = tagc; tagstk[++tagi] = tagc;
*mp++ = BOT; *mp++ = BOT;
*mp++ = static_cast<char>(tagc++); *mp++ = static_cast<char>(tagc++);
} else } else {
return badpat("Too many \\(\\) pairs"); return badpat("Too many \\(\\) pairs");
}
} else if (!posix && *p == ')') { } else if (!posix && *p == ')') {
if (*sp == BOT) if (*sp == BOT)
return badpat("Null pattern inside \\(\\)"); return badpat("Null pattern inside \\(\\)");
if (tagi > 0) { if (tagi > 0) {
*mp++ = static_cast<char>(EOT); *mp++ = static_cast<char>(EOT);
*mp++ = static_cast<char>(tagstk[tagi--]); *mp++ = static_cast<char>(tagstk[tagi--]);
} else } else {
return badpat("Unmatched \\)"); return badpat("Unmatched \\)");
}
} else { } else {
int incr; int incr;
int c = GetBackslashExpression(p, incr); int c = GetBackslashExpression(p, incr);
@ -697,16 +703,18 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
tagstk[++tagi] = tagc; tagstk[++tagi] = tagc;
*mp++ = BOT; *mp++ = BOT;
*mp++ = static_cast<char>(tagc++); *mp++ = static_cast<char>(tagc++);
} else } else {
return badpat("Too many () pairs"); return badpat("Too many () pairs");
}
} else if (posix && *p == ')') { } else if (posix && *p == ')') {
if (*sp == BOT) if (*sp == BOT)
return badpat("Null pattern inside ()"); return badpat("Null pattern inside ()");
if (tagi > 0) { if (tagi > 0) {
*mp++ = static_cast<char>(EOT); *mp++ = static_cast<char>(EOT);
*mp++ = static_cast<char>(tagstk[tagi--]); *mp++ = static_cast<char>(tagstk[tagi--]);
} else } else {
return badpat("Unmatched )"); return badpat("Unmatched )");
}
} else { } else {
unsigned char c = *p; unsigned char c = *p;
if (!c) // End of RE if (!c) // End of RE

View File

@ -31,7 +31,7 @@ public:
class RESearch { class RESearch {
public: public:
RESearch(CharClassify *charClassTable); explicit RESearch(CharClassify *charClassTable);
~RESearch(); ~RESearch();
void GrabMatches(CharacterIndexer &ci); void GrabMatches(CharacterIndexer &ci);
const char *Compile(const char *pattern, int length, bool caseSensitive, bool posix); const char *Compile(const char *pattern, int length, bool caseSensitive, bool posix);

View File

@ -209,7 +209,7 @@ 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());
int lenInsert = typeSep ? int lenInsert = typeSep ?
static_cast<int>(typeSep-list) : static_cast<int>(strlen(list)); static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
if (ac.ignoreCase) { if (ac.ignoreCase) {
// May need to convert the case before invocation, so remove lenEntered characters // May need to convert the case before invocation, so remove lenEntered characters
@ -381,7 +381,7 @@ int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) const {
if (item != -1) { if (item != -1) {
const std::string selected = ac.GetValue(item); const std::string selected = ac.GetValue(item);
if (buffer != NULL) if (buffer != NULL)
strcpy(buffer, selected.c_str()); memcpy(buffer, selected.c_str(), selected.length()+1);
return static_cast<int>(selected.length()); return static_cast<int>(selected.length());
} }
} }
@ -417,16 +417,16 @@ void ScintillaBase::CallTipShow(Point pt, const char *defn) {
// space // space
PRectangle rcClient = GetClientRectangle(); PRectangle rcClient = GetClientRectangle();
int offset = vs.lineHeight + rc.Height(); int offset = vs.lineHeight + rc.Height();
// adjust so it displays below the text.
if (rc.top < rcClient.top) {
rc.top += offset;
rc.bottom += offset;
}
// adjust so it displays above the text. // adjust so it displays above the text.
if (rc.bottom > rcClient.bottom) { if (rc.bottom > rcClient.bottom) {
rc.top -= offset; rc.top -= offset;
rc.bottom -= offset; rc.bottom -= offset;
} }
// adjust so it displays below the text.
if (rc.top < rcClient.top) {
rc.top += offset;
rc.bottom += offset;
}
// Now display the window. // Now display the window.
CreateCallTipWindow(rc); CreateCallTipWindow(rc);
ct.wCallTip.SetPositionRelative(rc, wMain); ct.wCallTip.SetPositionRelative(rc, wMain);
@ -463,9 +463,13 @@ void ScintillaBase::CancelModes() {
Editor::CancelModes(); Editor::CancelModes();
} }
void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { void ScintillaBase::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) {
CancelModes(); CancelModes();
Editor::ButtonDown(pt, curTime, shift, ctrl, alt); Editor::ButtonDownWithModifiers(pt, curTime, modifiers);
}
void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt));
} }
#ifdef SCI_LEXER #ifdef SCI_LEXER
@ -482,7 +486,7 @@ class LexState : public LexInterface {
public: public:
int lexLanguage; int lexLanguage;
LexState(Document *pdoc_); explicit LexState(Document *pdoc_);
virtual ~LexState(); virtual ~LexState();
void SetLexer(uptr_t wParam); void SetLexer(uptr_t wParam);
void SetLexerLanguage(const char *languageName); void SetLexerLanguage(const char *languageName);
@ -889,6 +893,10 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
case SCI_CALLTIPPOSSTART: case SCI_CALLTIPPOSSTART:
return ct.posStartCallTip; return ct.posStartCallTip;
case SCI_CALLTIPSETPOSSTART:
ct.posStartCallTip = wParam;
break;
case SCI_CALLTIPSETHLT: case SCI_CALLTIPSETHLT:
ct.SetHighlight(wParam, lParam); ct.SetHighlight(wParam, lParam);
break; break;

View File

@ -83,6 +83,7 @@ protected:
virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0; virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0;
void ContextMenu(Point pt); void ContextMenu(Point pt);
virtual void ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers);
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
void NotifyStyleToNeeded(int endStyleNeeded); void NotifyStyleToNeeded(int endStyleNeeded);

View File

@ -166,7 +166,7 @@ void SelectionRange::MinimizeVirtualSpace() {
} }
Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) { Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) {
AddSelection(SelectionPosition(0)); AddSelection(SelectionRange(SelectionPosition(0)));
} }
Selection::~Selection() { Selection::~Selection() {
@ -305,6 +305,21 @@ void Selection::AddSelectionWithoutTrim(SelectionRange range) {
mainRange = ranges.size() - 1; mainRange = ranges.size() - 1;
} }
void Selection::DropSelection(size_t r) {
if ((ranges.size() > 1) && (r < ranges.size())) {
size_t mainNew = mainRange;
if (mainNew >= r) {
if (mainNew == 0) {
mainNew = ranges.size() - 2;
} else {
mainNew--;
}
}
ranges.erase(ranges.begin() + r);
mainRange = mainNew;
}
}
void Selection::TentativeSelection(SelectionRange range) { void Selection::TentativeSelection(SelectionRange range) {
if (!tentativeMain) { if (!tentativeMain) {
rangesSaved = ranges; rangesSaved = ranges;

View File

@ -88,9 +88,9 @@ struct SelectionRange {
SelectionRange() : caret(), anchor() { SelectionRange() : caret(), anchor() {
} }
SelectionRange(SelectionPosition single) : caret(single), anchor(single) { explicit SelectionRange(SelectionPosition single) : caret(single), anchor(single) {
} }
SelectionRange(int single) : caret(single), anchor(single) { explicit SelectionRange(int single) : caret(single), anchor(single) {
} }
SelectionRange(SelectionPosition caret_, SelectionPosition anchor_) : caret(caret_), anchor(anchor_) { SelectionRange(SelectionPosition caret_, SelectionPosition anchor_) : caret(caret_), anchor(anchor_) {
} }
@ -167,6 +167,7 @@ public:
void SetSelection(SelectionRange range); void SetSelection(SelectionRange range);
void AddSelection(SelectionRange range); void AddSelection(SelectionRange range);
void AddSelectionWithoutTrim(SelectionRange range); void AddSelectionWithoutTrim(SelectionRange range);
void DropSelection(size_t r);
void TentativeSelection(SelectionRange range); void TentativeSelection(SelectionRange range);
void CommitTentative(); void CommitTentative();
int CharacterInSelection(int posCharacter) const; int CharacterInSelection(int posCharacter) const;

View File

@ -272,7 +272,7 @@ public:
GapTo(position); GapTo(position);
return body + position + gapLength; return body + position + gapLength;
} else { } else {
return body + position ; return body + position;
} }
} else { } else {
return body + position + gapLength; return body + position + gapLength;
@ -280,7 +280,7 @@ public:
} }
int GapPosition() const { int GapPosition() const {
return part1Length; return part1Length;
} }
}; };

View File

@ -159,7 +159,7 @@ static int BytesFromLead(int leadByte) {
void UTF8BytesOfLeadInitialise() { void UTF8BytesOfLeadInitialise() {
if (!initialisedBytesOfLead) { if (!initialisedBytesOfLead) {
for (int i=0;i<256;i++) { for (int i=0; i<256; i++) {
UTF8BytesOfLead[i] = BytesFromLead(i); UTF8BytesOfLead[i] = BytesFromLead(i);
} }
initialisedBytesOfLead = true; initialisedBytesOfLead = true;

View File

@ -55,8 +55,9 @@ const char *FontNames::Save(const char *name) {
return *it; return *it;
} }
} }
char *nameSave = new char[strlen(name) + 1]; const size_t lenName = strlen(name) + 1;
strcpy(nameSave, name); char *nameSave = new char[lenName];
memcpy(nameSave, name, lenName);
names.push_back(nameSave); names.push_back(nameSave);
return nameSave; return nameSave;
} }
@ -309,9 +310,9 @@ void ViewStyle::Refresh(Surface &surface, int tabInChars) {
styles[i].extraFontFlag = extraFontFlag; styles[i].extraFontFlag = extraFontFlag;
} }
CreateFont(styles[STYLE_DEFAULT]); CreateAndAddFont(styles[STYLE_DEFAULT]);
for (unsigned int j=0; j<styles.size(); j++) { for (unsigned int j=0; j<styles.size(); j++) {
CreateFont(styles[j]); CreateAndAddFont(styles[j]);
} }
for (FontMap::iterator it = fonts.begin(); it != fonts.end(); ++it) { for (FontMap::iterator it = fonts.begin(); it != fonts.end(); ++it) {
@ -449,6 +450,9 @@ bool ViewStyle::SetWrapState(int wrapState_) {
case SC_WRAP_CHAR: case SC_WRAP_CHAR:
wrapStateWanted = eWrapChar; wrapStateWanted = eWrapChar;
break; break;
case SC_WRAP_WHITESPACE:
wrapStateWanted = eWrapWhitespace;
break;
default: default:
wrapStateWanted = eWrapNone; wrapStateWanted = eWrapNone;
break; break;
@ -494,7 +498,7 @@ void ViewStyle::AllocStyles(size_t sizeNew) {
} }
} }
void ViewStyle::CreateFont(const FontSpecification &fs) { void ViewStyle::CreateAndAddFont(const FontSpecification &fs) {
if (fs.fontName) { if (fs.fontName) {
FontMap::iterator it = fonts.find(fs); FontMap::iterator it = fonts.find(fs);
if (it == fonts.end()) { if (it == fonts.end()) {

View File

@ -56,7 +56,7 @@ enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterInden
typedef std::map<FontSpecification, FontRealised *> FontMap; typedef std::map<FontSpecification, FontRealised *> FontMap;
enum WrapMode { eWrapNone, eWrapWord, eWrapChar }; enum WrapMode { eWrapNone, eWrapWord, eWrapChar, eWrapWhitespace };
class ColourOptional : public ColourDesired { class ColourOptional : public ColourDesired {
public: public:
@ -178,7 +178,7 @@ public:
private: private:
void AllocStyles(size_t sizeNew); void AllocStyles(size_t sizeNew);
void CreateFont(const FontSpecification &fs); void CreateAndAddFont(const FontSpecification &fs);
FontRealised *Find(const FontSpecification &fs); FontRealised *Find(const FontSpecification &fs);
void FindMaxAscentDescent(); void FindMaxAscentDescent();
// Private so can only be copied through copy constructor which ensures font names initialised correctly // Private so can only be copied through copy constructor which ensures font names initialised correctly

View File

@ -61,11 +61,9 @@ XPM::XPM(const char *const *linesForm) {
} }
XPM::~XPM() { XPM::~XPM() {
Clear();
} }
void XPM::Init(const char *textForm) { void XPM::Init(const char *textForm) {
Clear();
// Test done is two parts to avoid possibility of overstepping the memory // Test done is two parts to avoid possibility of overstepping the memory
// if memcmp implemented strangely. Must be 4 bytes at least at destination. // if memcmp implemented strangely. Must be 4 bytes at least at destination.
if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) { if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) {
@ -81,7 +79,6 @@ void XPM::Init(const char *textForm) {
} }
void XPM::Init(const char *const *linesForm) { void XPM::Init(const char *const *linesForm) {
Clear();
height = 1; height = 1;
width = 1; width = 1;
nColours = 1; nColours = 1;
@ -120,14 +117,11 @@ void XPM::Init(const char *const *linesForm) {
for (int y=0; y<height; y++) { for (int y=0; y<height; y++) {
const char *lform = linesForm[y+nColours+1]; const char *lform = linesForm[y+nColours+1];
size_t len = MeasureLength(lform); size_t len = MeasureLength(lform);
for (size_t x = 0; x<len; x++) for (size_t x = 0; x<len; x++)
pixels[y * width + x] = static_cast<unsigned char>(lform[x]); pixels[y * width + x] = static_cast<unsigned char>(lform[x]);
} }
} }
void XPM::Clear() {
}
void XPM::Draw(Surface *surface, PRectangle &rc) { void XPM::Draw(Surface *surface, PRectangle &rc) {
if (pixels.empty()) { if (pixels.empty()) {
return; return;
@ -244,7 +238,7 @@ void RGBAImage::SetPixel(int x, int y, ColourDesired colour, int alpha) {
pixel[3] = static_cast<unsigned char>(alpha); pixel[3] = static_cast<unsigned char>(alpha);
} }
RGBAImageSet::RGBAImageSet() : height(-1), width(-1){ RGBAImageSet::RGBAImageSet() : height(-1), width(-1) {
} }
RGBAImageSet::~RGBAImageSet() { RGBAImageSet::~RGBAImageSet() {

View File

@ -25,12 +25,11 @@ class XPM {
ColourDesired ColourFromCode(int ch) const; ColourDesired 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);
public: public:
XPM(const char *textForm); explicit XPM(const char *textForm);
XPM(const char *const *linesForm); explicit XPM(const char *const *linesForm);
~XPM(); ~XPM();
void Init(const char *textForm); void Init(const char *textForm);
void Init(const char *const *linesForm); void Init(const char *const *linesForm);
void Clear();
/// Decompose image into runs and use FillRectangle for each run /// Decompose image into runs and use FillRectangle for each run
void Draw(Surface *surface, PRectangle &rc); void Draw(Surface *surface, PRectangle &rc);
int GetHeight() const { return height; } int GetHeight() const { return height; }
@ -53,7 +52,7 @@ class RGBAImage {
std::vector<unsigned char> pixelBytes; std::vector<unsigned char> pixelBytes;
public: public:
RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_); RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_);
RGBAImage(const XPM &xpm); explicit RGBAImage(const XPM &xpm);
virtual ~RGBAImage(); virtual ~RGBAImage();
int GetHeight() const { return height; } int GetHeight() const { return height; }
int GetWidth() const { return width; } int GetWidth() const { return width; }
@ -62,7 +61,7 @@ public:
float GetScaledWidth() const { return width / scale; } float GetScaledWidth() const { return width / scale; }
int CountBytes() const; int CountBytes() const;
const unsigned char *Pixels() const; const unsigned char *Pixels() const;
void SetPixel(int x, int y, ColourDesired colour, int alpha=0xff); void SetPixel(int x, int y, ColourDesired colour, int alpha=0xff);
}; };
/** /**

View File

@ -1 +1 @@
336 341