diff --git a/scintilla/Makefile.am b/scintilla/Makefile.am index a0673ce9c..aa156de21 100644 --- a/scintilla/Makefile.am +++ b/scintilla/Makefile.am @@ -69,6 +69,7 @@ lexlib/OptionSet.h \ lexlib/PropSetSimple.cxx \ lexlib/PropSetSimple.h \ lexlib/SparseState.h \ +lexlib/StringCopy.h \ lexlib/StyleContext.cxx \ lexlib/StyleContext.h \ lexlib/SubStyles.h \ diff --git a/scintilla/gtk/Converter.h b/scintilla/gtk/Converter.h index fe9e23199..be530341f 100644 --- a/scintilla/gtk/Converter.h +++ b/scintilla/gtk/Converter.h @@ -51,8 +51,8 @@ public: // Try allowing approximate transliterations if (transliterations) { char fullDest[200]; - strcpy(fullDest, charSetDestination); - strcat(fullDest, "//TRANSLIT"); + g_strlcpy(fullDest, charSetDestination, sizeof(fullDest)); + g_strlcat(fullDest, "//TRANSLIT", sizeof(fullDest)); OpenHandle(fullDest, charSetSource); } if (!Succeeded()) { diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx index 427f08ec3..c1e5566e5 100644 --- a/scintilla/gtk/PlatGTK.cxx +++ b/scintilla/gtk/PlatGTK.cxx @@ -23,8 +23,9 @@ #include "Scintilla.h" #include "ScintillaWidget.h" -#include "UniConversion.h" +#include "StringCopy.h" #include "XPM.h" +#include "UniConversion.h" #if defined(__clang__) // Clang 3.0 incorrectly displays sentinel warnings. Fixed by clang 3.1. @@ -48,7 +49,7 @@ 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. 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) { - memset(&lf, 0, sizeof(lf)); + lf = LOGFONT(); lf.size = size; lf.weight = weight; lf.italic = italic; lf.characterSet = characterSet; - strncpy(lf.faceName, faceName, sizeof(lf.faceName) - 1); + StringCopy(lf.faceName, faceName); } /** @@ -253,7 +254,7 @@ class FontCached : Font { int usage; LOGFONT lf; int hash; - FontCached(const FontParameters &fp); + explicit FontCached(const FontParameters &fp); ~FontCached() {} bool SameAs(const FontParameters &fp); virtual void Release(); @@ -339,7 +340,7 @@ void FontCached::ReleaseAll() { FontID FontCached::CreateNewFont(const FontParameters &fp) { PangoFontDescription *pfd = pango_font_description_new(); if (pfd) { - pango_font_description_set_family(pfd, + pango_font_description_set_family(pfd, (fp.faceName[0] == '!') ? fp.faceName+1 : fp.faceName); pango_font_description_set_size(pfd, pangoUnitsFromDouble(fp.size)); pango_font_description_set_weight(pfd, static_cast(fp.weight)); @@ -666,7 +667,7 @@ void SurfaceImpl::Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back) { PenColour(back); 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_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.top + 2), }; - Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore, back); + Polygon(pts, ELEMENTS(pts), fore, back); } else { 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) { 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); cairo_fill_preserve(context); 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 utfForm(len*2 + 1, '\0'); size_t lenU = 0; - for (int i=0;i(s[i]); if (uch < 0x80) { 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, ColourDesired fore) { // Avoid drawing spaces in transparent mode - for (int i=0;i 0) { - strncpy(value, text, len); - value[len - 1] = '\0'; + g_strlcpy(value, text, len); } else { value[0] = '\0'; } @@ -1963,7 +1963,7 @@ class DynamicLibraryImpl : public DynamicLibrary { protected: GModule* m; public: - DynamicLibraryImpl(const char *modulePath) { + explicit DynamicLibraryImpl(const char *modulePath) { m = g_module_open(modulePath, G_MODULE_BIND_LAZY); } @@ -1981,8 +1981,9 @@ public: return static_cast(fn_address); else return NULL; - } else + } else { return NULL; + } } virtual bool IsValid() { @@ -2141,8 +2142,7 @@ bool Platform::ShowAssertionPopUps(bool assertionPopUps_) { void Platform::Assert(const char *c, const char *file, int line) { char buffer[2000]; - sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); - strcat(buffer, "\r\n"); + g_snprintf(buffer, sizeof(buffer), "Assertion [%s] failed at %s %d\r\n", c, file, line); Platform::DebugDisplay(buffer); abort(); } diff --git a/scintilla/gtk/ScintillaGTK.cxx b/scintilla/gtk/ScintillaGTK.cxx index 91c1250fc..ee0758bcd 100644 --- a/scintilla/gtk/ScintillaGTK.cxx +++ b/scintilla/gtk/ScintillaGTK.cxx @@ -31,6 +31,7 @@ #ifdef SCI_LEXER #include "SciLexer.h" #endif +#include "StringCopy.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" @@ -165,7 +166,7 @@ class ScintillaGTK : public ScintillaBase { ScintillaGTK &operator=(const ScintillaGTK &); public: - ScintillaGTK(_ScintillaObject *sci_); + explicit ScintillaGTK(_ScintillaObject *sci_); virtual ~ScintillaGTK(); static void ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class); private: @@ -338,14 +339,14 @@ static const GtkTargetEntry clipboardCopyTargets[] = { { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_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[] = { { (gchar *) "text/uri-list", 0, TARGET_URI }, { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_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) { return reinterpret_cast(w.GetID()); @@ -1126,7 +1127,7 @@ void ScintillaGTK::SetVerticalScrollPos() { void ScintillaGTK::SetHorizontalScrollPos() { 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) { @@ -1244,7 +1245,7 @@ const char *ScintillaGTK::CharacterSetID() const { class CaseFolderDBCS : public CaseFolderTable { const char *charSet; public: - CaseFolderDBCS(const char *charSet_) : charSet(charSet_) { + explicit CaseFolderDBCS(const char *charSet_) : charSet(charSet_) { StandardASCII(); } 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()) { 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); retMapped.resize(lenMapped); return retMapped; @@ -1769,17 +1770,24 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) { return FALSE; } + bool shift = (event->state & GDK_SHIFT_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)); if (event->button == 1) { - // 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 - ButtonDown(pt, event->time, - (event->state & GDK_SHIFT_MASK) != 0, - (event->state & GDK_CONTROL_MASK) != 0, - (event->state & modifierTranslated(rectangularSelectionModifier)) != 0); +#if PLAT_GTK_MACOSX + bool meta = ctrl; + // GDK reports the Command modifer key as GDK_MOD2_MASK for button events, + // not GDK_META_MASK like in key events. + ctrl = (event->state & GDK_MOD2_MASK) != 0; +#else + bool meta = false; +#endif + ButtonDownWithModifiers(pt, event->time, ModifierFlags(shift, ctrl, alt, meta)); } else if (event->button == 2) { // Grab the primary selection if it exists SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace()); @@ -1807,13 +1815,13 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) { } else if (event->button == 4) { // Wheel scrolling up (only GTK 1.x does it this way) if (ctrl) - SetAdjustmentValue(adjustmenth, (xOffset / 2) - 6); + SetAdjustmentValue(adjustmenth, xOffset - 6); else SetAdjustmentValue(adjustmentv, topLine - 3); } else if (event->button == 5) { // Wheel scrolling down (only GTK 1.x does it this way) if (ctrl) - SetAdjustmentValue(adjustmenth, (xOffset / 2) + 6); + SetAdjustmentValue(adjustmenth, xOffset + 6); else SetAdjustmentValue(adjustmentv, topLine + 3); } @@ -1950,7 +1958,7 @@ gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) { GdkModifierType state; if (event->is_hint) { #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); #else 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) { try { ScintillaObject *scio = reinterpret_cast(object); + // This avoids a double destruction if (!scio->pscin) return; @@ -2348,6 +2359,7 @@ void ScintillaGTK::Destroy(GObject *object) { delete sciThis; scio->pscin = 0; + scintilla_class_parent_class->finalize(object); } catch (...) { // 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) { try { #if GTK_CHECK_VERSION(3,0,0) - sciThis->HorizontalScrollTo(static_cast(gtk_adjustment_get_value(adj) * 2)); + sciThis->HorizontalScrollTo(static_cast(gtk_adjustment_get_value(adj))); #else - sciThis->HorizontalScrollTo(static_cast(adj->value * 2)); + sciThis->HorizontalScrollTo(static_cast(adj->value)); #endif } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; @@ -2910,7 +2922,7 @@ static void scintilla_class_init(ScintillaClass *klass) { klass->command = 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); } catch (...) { } diff --git a/scintilla/include/Platform.h b/scintilla/include/Platform.h index 3920f7321..d83e7f26c 100644 --- a/scintilla/include/Platform.h +++ b/scintilla/include/Platform.h @@ -444,6 +444,16 @@ public: 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 * 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 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); }; diff --git a/scintilla/include/SciLexer.h b/scintilla/include/SciLexer.h index 1378c8ee8..cb4079b8c 100644 --- a/scintilla/include/SciLexer.h +++ b/scintilla/include/SciLexer.h @@ -124,6 +124,8 @@ #define SCLEX_STTXT 109 #define SCLEX_KVIRC 110 #define SCLEX_RUST 111 +#define SCLEX_DMAP 112 +#define SCLEX_AS 113 #define SCLEX_AUTOMATIC 1000 #define SCE_P_DEFAULT 0 #define SCE_P_COMMENTLINE 1 @@ -166,6 +168,7 @@ #define SCE_C_HASHQUOTEDSTRING 22 #define SCE_C_PREPROCESSORCOMMENT 23 #define SCE_C_PREPROCESSORCOMMENTDOC 24 +#define SCE_C_USERLITERAL 25 #define SCE_D_DEFAULT 0 #define SCE_D_COMMENT 1 #define SCE_D_COMMENTLINE 2 @@ -420,6 +423,10 @@ #define SCE_B_ERROR 16 #define SCE_B_HEXNUMBER 17 #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_COMMENT 1 #define SCE_PROPS_SECTION 2 @@ -1541,7 +1548,6 @@ #define SCE_COFFEESCRIPT_GLOBALCLASS 19 #define SCE_COFFEESCRIPT_STRINGRAW 20 #define SCE_COFFEESCRIPT_TRIPLEVERBATIM 21 -#define SCE_COFFEESCRIPT_HASHQUOTEDSTRING 22 #define SCE_COFFEESCRIPT_COMMENTBLOCK 22 #define SCE_COFFEESCRIPT_VERBOSE_REGEX 23 #define SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT 24 @@ -1683,6 +1689,17 @@ #define SCE_RUST_LIFETIME 18 #define SCE_RUST_MACRO 19 #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 */ #endif diff --git a/scintilla/include/Scintilla.h b/scintilla/include/Scintilla.h index b50d20260..462f5b5c3 100644 --- a/scintilla/include/Scintilla.h +++ b/scintilla/include/Scintilla.h @@ -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_UNDERLINE 29 #define SC_MARK_RGBAIMAGE 30 +#define SC_MARK_BOOKMARK 31 #define SC_MARK_CHARACTER 10000 #define SC_MARKNUM_FOLDEREND 25 #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 SCI_SETPRINTCOLOURMODE 2148 #define SCI_GETPRINTCOLOURMODE 2149 -#define SCFIND_WHOLEWORD 2 -#define SCFIND_MATCHCASE 4 +#define SCFIND_WHOLEWORD 0x2 +#define SCFIND_MATCHCASE 0x4 #define SCFIND_WORDSTART 0x00100000 #define SCFIND_REGEXP 0x00200000 #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_CALLTIPACTIVE 2202 #define SCI_CALLTIPPOSSTART 2203 +#define SCI_CALLTIPSETPOSSTART 2214 #define SCI_CALLTIPSETHLT 2204 #define SCI_CALLTIPSETBACK 2205 #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_WORD 1 #define SC_WRAP_CHAR 2 +#define SC_WRAP_WHITESPACE 3 #define SCI_SETWRAPMODE 2268 #define SCI_GETWRAPMODE 2269 #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_SETSELECTION 2572 #define SCI_ADDSELECTION 2573 +#define SCI_DROPSELECTIONN 2671 #define SCI_SETMAINSELECTION 2574 #define SCI_GETMAINSELECTION 2575 #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_GETCARETLINEVISIBLEALWAYS 2654 #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_GETREPRESENTATION 2666 #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_DESCRIBEPROPERTY 4016 #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_DELETETEXT 0x2 #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_FOCUSIN 2028 #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 */ /* 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_CharacterRange chrg; - char *lpstrText; + const char *lpstrText; struct Sci_CharacterRange chrgText; }; diff --git a/scintilla/include/Scintilla.iface b/scintilla/include/Scintilla.iface index d1cc6afb1..7040b63a9 100644 --- a/scintilla/include/Scintilla.iface +++ b/scintilla/include/Scintilla.iface @@ -268,6 +268,7 @@ val SC_MARK_LEFTRECT=27 val SC_MARK_AVAILABLE=28 val SC_MARK_UNDERLINE=29 val SC_MARK_RGBAIMAGE=30 +val SC_MARK_BOOKMARK=31 val SC_MARK_CHARACTER=10000 @@ -856,8 +857,8 @@ set void SetPrintColourMode=2148(int mode,) get int GetPrintColourMode=2149(,) enu FindOption=SCFIND_ -val SCFIND_WHOLEWORD=2 -val SCFIND_MATCHCASE=4 +val SCFIND_WHOLEWORD=0x2 +val SCFIND_MATCHCASE=0x4 val SCFIND_WORDSTART=0x00100000 val SCFIND_REGEXP=0x00200000 val SCFIND_POSIX=0x00400000 @@ -1042,6 +1043,9 @@ fun bool CallTipActive=2202(,) # Retrieve the position where the caret was before displaying the call tip. 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. fun void CallTipSetHlt=2204(int start, int end) @@ -1185,6 +1189,7 @@ enu Wrap=SC_WRAP_ val SC_WRAP_NONE=0 val SC_WRAP_WORD=1 val SC_WRAP_CHAR=2 +val SC_WRAP_WHITESPACE=3 # Sets whether text is word wrapped. set void SetWrapMode=2268(int mode,) @@ -2176,6 +2181,9 @@ fun int SetSelection=2572(int caret, int anchor) # Add a selection fun int AddSelection=2573(int caret, int anchor) +# Drop one selection +fun void DropSelectionN=2671(int selection,) + # Set the main selection set void SetMainSelection=2574(int selection,) @@ -2336,6 +2344,22 @@ get bool GetCaretLineVisibleAlways=2654(,) # Sets the caret line to always visible. 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 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. 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 # 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. @@ -2601,6 +2657,8 @@ val SCLEX_LITERATEHASKELL=108 val SCLEX_STTXT=109 val SCLEX_KVIRC=110 val SCLEX_RUST=111 +val SCLEX_DMAP=112 +val SCLEX_AS=113 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # 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_PREPROCESSORCOMMENT=23 val SCE_C_PREPROCESSORCOMMENTDOC=24 +val SCE_C_USERLITERAL=25 # Lexical states for SCLEX_D lex D=SCLEX_D SCE_D_ val SCE_D_DEFAULT=0 @@ -2704,8 +2763,6 @@ val SCE_TCL_BLOCK_COMMENT=21 # 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 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_TAG=1 val SCE_H_TAGUNKNOWN=2 @@ -2935,6 +2992,10 @@ val SCE_B_LABEL=15 val SCE_B_ERROR=16 val SCE_B_HEXNUMBER=17 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 lex Properties=SCLEX_PROPERTIES SCE_PROPS_ val SCE_PROPS_DEFAULT=0 @@ -3187,8 +3248,9 @@ val SCE_SCRIPTOL_IDENTIFIER=12 val SCE_SCRIPTOL_TRIPLE=13 val SCE_SCRIPTOL_CLASSNAME=14 val SCE_SCRIPTOL_PREPROCESSOR=15 -# Lexical states for SCLEX_ASM +# Lexical states for SCLEX_ASM, SCLEX_AS lex Asm=SCLEX_ASM SCE_ASM_ +lex As=SCLEX_AS SCE_ASM_ val SCE_ASM_DEFAULT=0 val SCE_ASM_COMMENT=1 val SCE_ASM_NUMBER=2 @@ -3945,8 +4007,8 @@ val SCE_R_OPERATOR=8 val SCE_R_IDENTIFIER=9 val SCE_R_INFIX=10 val SCE_R_INFIXEOL=11 -# Lexical state for SCLEX_MAGIKSF -lex MagikSF=SCLEX_MAGIKSF SCE_MAGIK_ +# Lexical state for SCLEX_MAGIK +lex MagikSF=SCLEX_MAGIK SCE_MAGIK_ val SCE_MAGIK_DEFAULT=0 val SCE_MAGIK_COMMENT=1 val SCE_MAGIK_HYPER_COMMENT=16 @@ -4208,7 +4270,6 @@ val SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR=18 val SCE_COFFEESCRIPT_GLOBALCLASS=19 val SCE_COFFEESCRIPT_STRINGRAW=20 val SCE_COFFEESCRIPT_TRIPLEVERBATIM=21 -val SCE_COFFEESCRIPT_HASHQUOTEDSTRING=22 val SCE_COFFEESCRIPT_COMMENTBLOCK=22 val SCE_COFFEESCRIPT_VERBOSE_REGEX=23 val SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT=24 @@ -4327,7 +4388,7 @@ val SCE_STTXT_DATETIME=16 val SCE_STTXT_VARS=17 val SCE_STTXT_PRAGMAS=18 # 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_COMMENT=1 val SCE_KVIRC_COMMENTBLOCK=2 @@ -4364,6 +4425,19 @@ val SCE_RUST_IDENTIFIER=17 val SCE_RUST_LIFETIME=18 val SCE_RUST_MACRO=19 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 @@ -4398,56 +4472,10 @@ evt void HotSpotReleaseClick=2027(int modifiers, int position) evt void FocusIn=2028(void) evt void FocusOut=2029(void) +# There are no provisional features currently + 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 # Deprecated in 2.21 diff --git a/scintilla/lexers/LexAbaqus.cxx b/scintilla/lexers/LexAbaqus.cxx index 134170071..d93aa503d 100644 --- a/scintilla/lexers/LexAbaqus.cxx +++ b/scintilla/lexers/LexAbaqus.cxx @@ -30,10 +30,6 @@ using namespace Scintilla; #endif -static inline bool IsAWordChar(const int ch) { - return (ch < 0x80 && (isalnum(ch) || (ch == '_'))); -} - static inline bool IsAKeywordChar(const int 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 == '-'))); } -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[] */, Accessor &styler) { enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \ diff --git a/scintilla/lexers/LexAsm.cxx b/scintilla/lexers/LexAsm.cxx index b327ce5f2..37a4efe35 100644 --- a/scintilla/lexers/LexAsm.cxx +++ b/scintilla/lexers/LexAsm.cxx @@ -150,8 +150,10 @@ class LexerAsm : public ILexer { WordList directives4foldend; OptionsAsm options; OptionSetAsm osAsm; + int commentChar; public: - LexerAsm() { + LexerAsm(int commentChar_) { + commentChar = commentChar_; } virtual ~LexerAsm() { } @@ -183,7 +185,11 @@ public: } 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. if (sc.state == SCE_ASM_DEFAULT) { - if (sc.ch == ';'){ + if (sc.ch == commentChar){ sc.SetState(SCE_ASM_COMMENT); } else if (IsASCII(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && IsASCII(sc.chNext) && isdigit(sc.chNext)))) { 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 lmAs(SCLEX_AS, LexerAsm::LexerFactoryAs, "as", asmWordListDesc); diff --git a/scintilla/lexers/LexBash.cxx b/scintilla/lexers/LexBash.cxx index 5f582e401..b85d01a7d 100644 --- a/scintilla/lexers/LexBash.cxx +++ b/scintilla/lexers/LexBash.cxx @@ -108,6 +108,8 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle, CharacterSet setWordStart(CharacterSet::setAlpha, "_"); // note that [+-] are often parts of identifiers in shell scripts CharacterSet setWord(CharacterSet::setAlphaNum, "._+-"); + CharacterSet setMetaCharacter(CharacterSet::setNone, "|&;()<> \t\r\n"); + setMetaCharacter.Add(0); CharacterSet setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/= 'A' && c <= 'Z') @@ -126,13 +131,23 @@ static int CheckPureFoldPoint(char const *token, int &level) { static int CheckFreeFoldPoint(char const *token, int &level) { if (!strcmp(token, "function") || !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; return 1; } if (!strcmp(token, "end function") || !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 0; @@ -219,9 +234,9 @@ class LexerBasic : public ILexer { OptionSetBasic osBasic; public: LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) : - comment_char(comment_char_), - CheckFoldPoint(CheckFoldPoint_), - osBasic(wordListDescriptions) { + comment_char(comment_char_), + CheckFoldPoint(CheckFoldPoint_), + osBasic(wordListDescriptions) { } 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 styler.StartAt(startPos); + int styleBeforeKeyword = SCE_B_DEFAULT; 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) { 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) isfirst = true; if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) { - if (isfirst && sc.Match('.')) { - sc.SetState(SCE_B_LABEL); + if (isfirst && sc.Match('.') && comment_char != '\'') { + sc.SetState(SCE_B_LABEL); } else if (isfirst && sc.Match('#')) { wasfirst = isfirst; 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. if (comment_char == '\'' && sc.Match(comment_char, '$')) sc.SetState(SCE_B_PREPROCESSOR); - else + else if (sc.Match("\'*") || sc.Match("\'!")) { + sc.SetState(SCE_B_DOCLINE); + } else { 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('"')) { sc.SetState(SCE_B_STRING); } else if (IsDigit(sc.ch)) { 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); - } else if (sc.Match('%')) { + } else if (sc.Match('%') || sc.Match("&b") || sc.Match("&B")) { sc.SetState(SCE_B_BINNUMBER); } else if (sc.Match('#')) { sc.SetState(SCE_B_CONSTANT); diff --git a/scintilla/lexers/LexCPP.cxx b/scintilla/lexers/LexCPP.cxx index 6f7afc23d..76a47e058 100644 --- a/scintilla/lexers/LexCPP.cxx +++ b/scintilla/lexers/LexCPP.cxx @@ -336,7 +336,7 @@ class LexerCPP : public ILexerWithSubStyles { enum { ssIdentifier, ssDocKeyword }; SubStyles subStyles; public: - LexerCPP(bool caseSensitive_) : + explicit LexerCPP(bool caseSensitive_) : caseSensitive(caseSensitive_), setWord(CharacterSet::setAlphaNum, "._", 0x80, true), setNegationOp(CharacterSet::setNone, "!"), @@ -376,7 +376,7 @@ public: int SCI_METHOD LineEndTypesSupported() { return SC_LINE_END_TYPE_UNICODE; - }; + } int SCI_METHOD AllocateSubStyles(int styleBase, int 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 struct After { int line; - After(int line_) : line(line_) {} + explicit After(int line_) : line(line_) {} bool operator()(PPDefinition &p) const { return p.line > line; } @@ -515,6 +515,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle, bool isIncludePreprocessor = false; bool isStringInPreprocessor = false; bool inRERange = false; + bool seenDocKeyBrace = false; int lineCurrent = styler.GetLine(startPos); if ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) || @@ -633,12 +634,19 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle, break; case SCE_C_NUMBER: // 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.chPrev == 'p' || sc.chPrev == 'P')))) { sc.SetState(SCE_C_DEFAULT|activitySet); } break; + case SCE_C_USERLITERAL: + if (!(setWord.Contains(sc.ch))) + sc.SetState(SCE_C_DEFAULT|activitySet); + break; case SCE_C_IDENTIFIER: if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch) || (sc.ch == '.')) { 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); else 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; case SCE_C_PREPROCESSOR: @@ -685,7 +696,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle, if (IsASpace(sc.ch)) { sc.SetState(SCE_C_DEFAULT|activitySet); } - } else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"'))) { + } else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"') || sc.atLineEnd)) { isStringInPreprocessor = false; } else if (!isStringInPreprocessor) { 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.Forward(); 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]; if (caseSensitive) { sc.GetCurrent(s, sizeof(s)); } else { sc.GetCurrentLowered(s, sizeof(s)); } - if (!IsASpace(sc.ch)) { + if (!(IsASpace(sc.ch) || (sc.ch == 0))) { sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet); } else if (!keywords3.InList(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); + seenDocKeyBrace = false; } break; case SCE_C_STRING: @@ -782,7 +798,11 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle, sc.Forward(); } } 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; case SCE_C_HASHQUOTEDSTRING: @@ -810,7 +830,11 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle, sc.Forward(); } } 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; case SCE_C_REGEX: diff --git a/scintilla/lexers/LexCmake.cxx b/scintilla/lexers/LexCmake.cxx index 70e9dee98..fb79abf26 100644 --- a/scintilla/lexers/LexCmake.cxx +++ b/scintilla/lexers/LexCmake.cxx @@ -226,14 +226,13 @@ static void ColouriseCmakeDoc(unsigned int startPos, int length, int, WordList * break; case SCE_CMAKE_COMMENT: - if ( cNextChar == '\n' || cNextChar == '\r' ) { - // Special case: - if ( cCurrChar == '\\' ) { + if ( cCurrChar == '\n' || cCurrChar == '\r' ) { + if ( styler.SafeGetCharAt(i-1) == '\\' ) { styler.ColourTo(i-2,state); - styler.ColourTo(i,SCE_CMAKE_DEFAULT); + styler.ColourTo(i-1,SCE_CMAKE_DEFAULT); } else { - styler.ColourTo(i,state); + styler.ColourTo(i-1,state); state = SCE_CMAKE_DEFAULT; } } @@ -335,10 +334,7 @@ static void ColouriseCmakeDoc(unsigned int startPos, int length, int, WordList * break; } - if ( state == SCE_CMAKE_COMMENT) { - styler.ColourTo(i,state); - } - else if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) { + if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) { bool bIngoreNextDollarSign = false; if ( bVarInString && cCurrChar == '$' ) { diff --git a/scintilla/lexers/LexForth.cxx b/scintilla/lexers/LexForth.cxx index c9c72624e..7b41aaf8e 100644 --- a/scintilla/lexers/LexForth.cxx +++ b/scintilla/lexers/LexForth.cxx @@ -27,15 +27,6 @@ using namespace Scintilla; #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) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.'); } diff --git a/scintilla/lexers/LexFortran.cxx b/scintilla/lexers/LexFortran.cxx index bfbe301a2..280250c29 100644 --- a/scintilla/lexers/LexFortran.cxx +++ b/scintilla/lexers/LexFortran.cxx @@ -38,15 +38,15 @@ static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch)); } /***************************************/ -inline bool IsABlank(unsigned int ch) { - return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ; +static inline bool IsABlank(unsigned int ch) { + return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ; } /***************************************/ -inline bool IsALineEnd(char ch) { - return ((ch == '\n') || (ch == '\r')) ; +static inline bool IsALineEnd(char ch) { + 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; if (styler.SafeGetCharAt(pos) == '\n') pos++; 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, - WordList *keywordlists[], Accessor &styler, bool isFixFormat) { + WordList *keywordlists[], Accessor &styler, bool isFixFormat) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; @@ -89,11 +89,11 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle int toLineStart = sc.currentPos - posLineStart; if (isFixFormat && (toLineStart < 6 || toLineStart >= 72)) { if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') { - if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") || - sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") || - sc.MatchIgnoreCase("cms$") || sc.MatchIgnoreCase("*ms$") || sc.MatchIgnoreCase("!ms$") || - sc.chNext == '$') { - sc.SetState(SCE_F_PREPROCESSOR); + if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") || + sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") || + sc.MatchIgnoreCase("cms$") || sc.MatchIgnoreCase("*ms$") || sc.MatchIgnoreCase("!ms$") || + sc.chNext == '$') { + sc.SetState(SCE_F_PREPROCESSOR); } else { 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 (sc.ch != '\r' && sc.ch != '\n') { sc.SetState(SCE_F_CONTINUATION); - if (!IsASpace(sc.ch) && sc.ch != '0') - sc.ForwardSetState(prevState); + if (!IsASpace(sc.ch) && sc.ch != '0') + sc.ForwardSetState(prevState); } else sc.SetState(SCE_F_DEFAULT); } @@ -122,9 +122,9 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle // Hanndle preprocessor directives if (sc.ch == '#' && numNonBlank == 1) { - sc.SetState(SCE_F_PREPROCESSOR); - while (!sc.atLineEnd && sc.More()) - sc.Forward(); // Until line end + sc.SetState(SCE_F_PREPROCESSOR); + while (!sc.atLineEnd && sc.More()) + sc.Forward(); // Until line end } /***************************************/ // 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. if (sc.state == SCE_F_DEFAULT) { if (sc.ch == '!') { - if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") || - sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') { + if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") || + sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') { sc.SetState(SCE_F_PREPROCESSOR); } else { 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))) { sc.SetState(SCE_F_NUMBER); } 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.Forward(); } 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 static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) { int lev = 0; - if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0) - return -1; - if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0 - || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0 - || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0 - || strcmp(s, "function") == 0 || strcmp(s, "interface") == 0 - || strcmp(s, "module") == 0 || strcmp(s, "program") == 0 - || strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0 - || (strcmp(s, "type") == 0 && chNextNonBlank != '(') - || strcmp(s, "critical") == 0){ - if (strcmp(prevWord, "end") == 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(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 + + if ((strcmp(prevWord, "module") == 0 && strcmp(s, "subroutine") == 0) + || (strcmp(prevWord, "module") == 0 && strcmp(s, "function") == 0)) { + lev = 0; + } else if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0 + || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0 + || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0 + || strcmp(s, "function") == 0 || strcmp(s, "interface") == 0 + || strcmp(s, "module") == 0 || strcmp(s, "program") == 0 + || strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0 + || (strcmp(s, "type") == 0 && chNextNonBlank != '(') + || strcmp(s, "critical") == 0 || strcmp(s, "submodule") == 0){ + if (strcmp(prevWord, "end") == 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 - 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; } +/***************************************/ // Folding the code 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; // 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; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; + int levelCurrent; + 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 chNextNonBlank; int styleNext = styler.StyleAt(startPos); int style = initStyle; + int levelDeltaNext = 0; /***************************************/ int lastStart = 0; 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++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); - chNextNonBlank = chNext; + char chNextNonBlank = chNext; + bool nextEOL = false; + if (IsALineEnd(chNextNonBlank)) { + nextEOL = true; + } unsigned int j=i+1; while(IsABlank(chNextNonBlank) && j -1) { - levelCurrent--; - posLabel--; - } - } } if (atEOL) { - int lev = levelPrev; + int lev = levelCurrent; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; - if ((levelCurrent > levelPrev) && (visibleChars > 0)) + if ((levelDeltaNext > 0) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; - if (lev != styler.LevelAt(lineCurrent)) { + if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); - } + lineCurrent++; - levelPrev = levelCurrent; + levelCurrent += levelDeltaNext; + levelDeltaNext = 0; visibleChars = 0; strcpy(prevWord, ""); + isPrevLine = false; } /***************************************/ 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[] = { @@ -461,22 +490,22 @@ static const char * const FortranWordLists[] = { }; /***************************************/ static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], - Accessor &styler) { + Accessor &styler) { ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false); } /***************************************/ static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], - Accessor &styler) { + Accessor &styler) { ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true); } /***************************************/ static void FoldFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, - WordList *[], Accessor &styler) { + WordList *[], Accessor &styler) { FoldFortranDoc(startPos, length, initStyle,styler, false); } /***************************************/ static void FoldFortranDocFixFormat(unsigned int startPos, int length, int initStyle, - WordList *[], Accessor &styler) { + WordList *[], Accessor &styler) { FoldFortranDoc(startPos, length, initStyle,styler, true); } /***************************************/ diff --git a/scintilla/lexers/LexHTML.cxx b/scintilla/lexers/LexHTML.cxx index 58862b4c8..5ea24d481 100644 --- a/scintilla/lexers/LexHTML.cxx +++ b/scintilla/lexers/LexHTML.cxx @@ -16,6 +16,7 @@ #include "Scintilla.h" #include "SciLexer.h" +#include "StringCopy.h" #include "WordList.h" #include "LexAccessor.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) { char chAttr = SCE_HB_IDENTIFIER; bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.'); - if (wordIsNumber) + if (wordIsNumber) { chAttr = SCE_HB_NUMBER; - else { + } else { char s[100]; GetTextSegment(styler, start, end, s, sizeof(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) { char chAttr = SCE_HPHP_DEFAULT; bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.' && start+1 <= end && IsADigit(styler[start+1])); - if (wordIsNumber) + if (wordIsNumber) { chAttr = SCE_HPHP_NUMBER; - else { + } else { char s[100]; GetTextSegment(styler, start, end, s, sizeof(s)); if (keywords.InList(s)) @@ -823,14 +824,14 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty if (isMako && ch == '#' && chNext == '#') { makoComment = 1; } - + // handle end of Mako comment line else if (isMako && makoComment && (ch == '\r' || ch == '\n')) { makoComment = 0; styler.ColourTo(i, SCE_HP_COMMENTLINE); state = SCE_HP_DEFAULT; } - + // Allow falling through to mako handling code if newline is going to end a block if (((ch == '\r' && chNext != '\n') || (ch == '\n')) && (!isMako || (0 != strcmp(makoBlockType, "%")))) { @@ -929,9 +930,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty (ch == '$' && chNext == '{') || (ch == '<' && chNext == '/' && chNext2 == '%'))) { if (ch == '%' || ch == '/') - strcpy(makoBlockType, "%"); + StringCopy(makoBlockType, "%"); else if (ch == '$') - strcpy(makoBlockType, "{"); + StringCopy(makoBlockType, "{"); else if (chNext == '/') GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType)); else @@ -1000,9 +1001,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty // handle the start Django template code else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) { if (chNext == '%') - strcpy(djangoBlockType, "%"); + StringCopy(djangoBlockType, "%"); else - strcpy(djangoBlockType, "{"); + StringCopy(djangoBlockType, "{"); styler.ColourTo(i - 1, StateToPrint); beforePreProc = state; if (inScriptType == eNonHtmlScript) @@ -1917,7 +1918,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HPHP_COMMENTLINE; } else if (ch == '\"') { state = SCE_HPHP_HSTRING; - strcpy(phpStringDelimiter, "\""); + StringCopy(phpStringDelimiter, "\""); } else if (styler.Match(i, "<<<")) { bool isSimpleString = false; 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 == '\'') { state = SCE_HPHP_SIMPLESTRING; - strcpy(phpStringDelimiter, "\'"); + StringCopy(phpStringDelimiter, "\'"); } else if (ch == '$' && IsPhpWordStart(chNext)) { state = SCE_HPHP_VARIABLE; } else if (IsOperator(ch)) { @@ -2047,7 +2048,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty state = SCE_HPHP_COMMENTLINE; } else if (ch == '\"') { state = SCE_HPHP_HSTRING; - strcpy(phpStringDelimiter, "\""); + StringCopy(phpStringDelimiter, "\""); } else if (styler.Match(i, "<<<")) { bool isSimpleString = false; 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 == '\'') { state = SCE_HPHP_SIMPLESTRING; - strcpy(phpStringDelimiter, "\'"); + StringCopy(phpStringDelimiter, "\'"); } else if (ch == '$' && IsPhpWordStart(chNext)) { state = SCE_HPHP_VARIABLE; } else if (IsOperator(ch)) { diff --git a/scintilla/lexers/LexMarkdown.cxx b/scintilla/lexers/LexMarkdown.cxx index a92697707..c774b736f 100644 --- a/scintilla/lexers/LexMarkdown.cxx +++ b/scintilla/lexers/LexMarkdown.cxx @@ -118,10 +118,11 @@ static bool AtTermStart(StyleContext &sc) { } static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { - int c, count = 1; + int count = 1; unsigned int i = 0; - while (++i) { - c = sc.GetRelative(i); + for (;;) { + ++i; + int c = sc.GetRelative(i); if (c == sc.ch) ++count; // 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, diff --git a/scintilla/lexers/LexMatlab.cxx b/scintilla/lexers/LexMatlab.cxx index c59b8f94c..a8ac03cc7 100644 --- a/scintilla/lexers/LexMatlab.cxx +++ b/scintilla/lexers/LexMatlab.cxx @@ -57,7 +57,8 @@ static bool IsOctaveComment(Accessor &styler, int pos, int len) { static void ColouriseMatlabOctaveDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler, - bool (*IsCommentChar)(int)) { + bool (*IsCommentChar)(int), + bool ismatlab) { WordList &keywords = *keywordlists[0]; @@ -199,7 +200,11 @@ static void ColouriseMatlabOctaveDoc( styler.SetLineState(curLine, commentDepth); sc.SetState(SCE_MATLAB_COMMENT); } 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 == '\'') { if (transpose) { sc.SetState(SCE_MATLAB_OPERATOR); @@ -229,12 +234,12 @@ static void ColouriseMatlabOctaveDoc( static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle, 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, 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, diff --git a/scintilla/lexers/LexOthers.cxx b/scintilla/lexers/LexOthers.cxx index f87e79275..f1e828dc8 100644 --- a/scintilla/lexers/LexOthers.cxx +++ b/scintilla/lexers/LexOthers.cxx @@ -1037,8 +1037,9 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") || !CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) { state = stMsVc; - } else + } else { state = stUnrecognized; + } } else { state = stUnrecognized; } diff --git a/scintilla/lexers/LexPerl.cxx b/scintilla/lexers/LexPerl.cxx index d6fa7446c..5a7447af3 100644 --- a/scintilla/lexers/LexPerl.cxx +++ b/scintilla/lexers/LexPerl.cxx @@ -1185,7 +1185,7 @@ void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, } switch (HereDoc.Quote) { case '\'': - st_new = SCE_PL_HERE_Q ; + st_new = SCE_PL_HERE_Q; break; case '"' : st_new = SCE_PL_HERE_QQ; diff --git a/scintilla/lexers/LexSQL.cxx b/scintilla/lexers/LexSQL.cxx index 4d895352f..fa22f8e63 100644 --- a/scintilla/lexers/LexSQL.cxx +++ b/scintilla/lexers/LexSQL.cxx @@ -643,7 +643,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle, break; } } - + int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); diff --git a/scintilla/lexers/LexTxt2tags.cxx b/scintilla/lexers/LexTxt2tags.cxx index 8f8e181ba..fd4a96c33 100644 --- a/scintilla/lexers/LexTxt2tags.cxx +++ b/scintilla/lexers/LexTxt2tags.cxx @@ -78,10 +78,11 @@ static bool HasPrevLineContent(StyleContext &sc) { // Separator line static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { - int c, count = 1; + int count = 1; unsigned int i = 0; - while (++i) { - c = sc.GetRelative(i); + for (;;) { + ++i; + int c = sc.GetRelative(i); if (c == sc.ch) ++count; // 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, diff --git a/scintilla/lexers/LexVHDL.cxx b/scintilla/lexers/LexVHDL.cxx index ee9d6628f..88d8efb27 100644 --- a/scintilla/lexers/LexVHDL.cxx +++ b/scintilla/lexers/LexVHDL.cxx @@ -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) ; } diff --git a/scintilla/lexlib/Accessor.h b/scintilla/lexlib/Accessor.h index 9789f2b4a..1bb86c53b 100644 --- a/scintilla/lexlib/Accessor.h +++ b/scintilla/lexlib/Accessor.h @@ -12,7 +12,7 @@ namespace Scintilla { #endif -enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8}; +enum { wsSpace=1, wsTab=2, wsSpaceTab=4, wsInconsistent=8 }; class Accessor; class WordList; diff --git a/scintilla/lexlib/CharacterCategory.cxx b/scintilla/lexlib/CharacterCategory.cxx index a83776028..765469a3f 100644 --- a/scintilla/lexlib/CharacterCategory.cxx +++ b/scintilla/lexlib/CharacterCategory.cxx @@ -9,6 +9,7 @@ #include +#include "StringCopy.h" #include "CharacterCategory.h" #ifdef SCI_NAMESPACE @@ -3275,7 +3276,7 @@ const int catRanges[] = { const int maxUnicode = 0x10ffff; const int maskCategory = 0x1F; -const int nRanges = sizeof(catRanges) / sizeof(catRanges[0]); +const int nRanges = ELEMENTS(catRanges); } diff --git a/scintilla/lexlib/LexAccessor.h b/scintilla/lexlib/LexAccessor.h index e29bbc923..45a3a0a93 100644 --- a/scintilla/lexlib/LexAccessor.h +++ b/scintilla/lexlib/LexAccessor.h @@ -53,13 +53,13 @@ private: } public: - LexAccessor(IDocument *pAccess_) : + explicit LexAccessor(IDocument *pAccess_) : pAccess(pAccess_), startPos(extremePosition), endPos(0), - codePage(pAccess->CodePage()), + codePage(pAccess->CodePage()), encodingType(enc8bit), lenDoc(pAccess->Length()), mask(127), validLen(0), chFlags(0), chWhile(0), - startSeg(0), startPosStyling(0), + startSeg(0), startPosStyling(0), documentVersion(pAccess->Version()) { switch (codePage) { case 65001: @@ -139,7 +139,6 @@ public: return lenDoc; } void Flush() { - startPos = extremePosition; if (validLen > 0) { pAccess->SetStyles(validLen, styleBuf); startPosStyling += validLen; diff --git a/scintilla/lexlib/LexerModule.cxx b/scintilla/lexlib/LexerModule.cxx index 532d09626..c77b31775 100644 --- a/scintilla/lexlib/LexerModule.cxx +++ b/scintilla/lexlib/LexerModule.cxx @@ -79,7 +79,7 @@ const char *LexerModule::GetWordListDescription(int index) const { return ""; } else { return wordListDescriptions[index]; - } + } } int LexerModule::GetStyleBitsNeeded() const { diff --git a/scintilla/lexlib/LexerSimple.h b/scintilla/lexlib/LexerSimple.h index 89631936f..e9fa9003f 100644 --- a/scintilla/lexlib/LexerSimple.h +++ b/scintilla/lexlib/LexerSimple.h @@ -17,7 +17,7 @@ class LexerSimple : public LexerBase { const LexerModule *module; std::string wordLists; public: - LexerSimple(const LexerModule *module_); + explicit LexerSimple(const LexerModule *module_); const char * SCI_METHOD DescribeWordListSets(); 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); diff --git a/scintilla/lexlib/PropSetSimple.cxx b/scintilla/lexlib/PropSetSimple.cxx index 9197fb642..6f4553a07 100644 --- a/scintilla/lexlib/PropSetSimple.cxx +++ b/scintilla/lexlib/PropSetSimple.cxx @@ -61,7 +61,7 @@ void PropSetSimple::Set(const char *keyVal) { endVal++; const char *eqAt = strchr(keyVal, '='); if (eqAt) { - Set(keyVal, eqAt + 1, static_cast(eqAt-keyVal), + Set(keyVal, eqAt + 1, static_cast(eqAt-keyVal), static_cast(endVal - eqAt - 1)); } else if (*keyVal) { // No '=' so assume '=1' Set(keyVal, "1", static_cast(endVal-keyVal), 1); @@ -146,7 +146,7 @@ int PropSetSimple::GetExpanded(const char *key, char *result) const { ExpandAllInPlace(*this, val, 100, VarChain(key)); const int n = static_cast(val.size()); if (result) { - strcpy(result, val.c_str()); + memcpy(result, val.c_str(), n+1); } return n; // Not including NUL } diff --git a/scintilla/lexlib/SparseState.h b/scintilla/lexlib/SparseState.h index 08ff104d3..e767d6710 100644 --- a/scintilla/lexlib/SparseState.h +++ b/scintilla/lexlib/SparseState.h @@ -38,7 +38,7 @@ class SparseState { } public: - SparseState(int positionFirst_=-1) { + explicit SparseState(int positionFirst_=-1) { positionFirst = positionFirst_; } void Set(int position, T value) { diff --git a/scintilla/lexlib/StringCopy.h b/scintilla/lexlib/StringCopy.h new file mode 100644 index 000000000..1812b4e35 --- /dev/null +++ b/scintilla/lexlib/StringCopy.h @@ -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 +// 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 +void StringCopy(T (&dest)[count], const T* source) { + for (size_t i=0; i(styler.SafeGetCharAt(currentPos+width, 0)); 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. if (currentLine < lineDocEnd) atLineEnd = static_cast(currentPos) >= (lineStartNext-1); diff --git a/scintilla/lexlib/SubStyles.h b/scintilla/lexlib/SubStyles.h index 961715c3c..579107819 100644 --- a/scintilla/lexlib/SubStyles.h +++ b/scintilla/lexlib/SubStyles.h @@ -20,7 +20,7 @@ class WordClassifier { 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_) { diff --git a/scintilla/lexlib/WordList.cxx b/scintilla/lexlib/WordList.cxx index a325833d4..10b6fe349 100644 --- a/scintilla/lexlib/WordList.cxx +++ b/scintilla/lexlib/WordList.cxx @@ -13,6 +13,7 @@ #include +#include "StringCopy.h" #include "WordList.h" #ifdef SCI_NAMESPACE @@ -70,7 +71,7 @@ WordList::WordList(bool onlyLineEnds_) : words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) { } -WordList::~WordList() { +WordList::~WordList() { Clear(); } @@ -122,15 +123,16 @@ static void SortWordList(char **words, unsigned int len) { void WordList::Set(const char *s) { Clear(); - list = new char[strlen(s) + 1]; - strcpy(list, s); + const size_t lenS = strlen(s) + 1; + list = new char[lenS]; + memcpy(list, s, lenS); words = ArrayFromWordList(list, &len, onlyLineEnds); #ifdef _MSC_VER std::sort(words, words + len, cmpWords); #else SortWordList(words, len); #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; for (int l = len - 1; l >= 0; l--) { unsigned char indexChar = words[l][0]; diff --git a/scintilla/lexlib/WordList.h b/scintilla/lexlib/WordList.h index 9c8285ece..382be2812 100644 --- a/scintilla/lexlib/WordList.h +++ b/scintilla/lexlib/WordList.h @@ -22,7 +22,7 @@ class WordList { bool onlyLineEnds; ///< Delimited by any white space or only line ends int starts[256]; public: - WordList(bool onlyLineEnds_ = false); + explicit WordList(bool onlyLineEnds_ = false); ~WordList(); operator bool() const; bool operator!=(const WordList &other) const; diff --git a/scintilla/scintilla_changes.patch b/scintilla/scintilla_changes.patch index 3b754f82f..da3161d8d 100644 --- a/scintilla/scintilla_changes.patch +++ b/scintilla/scintilla_changes.patch @@ -28,10 +28,10 @@ diff -Naur scintilla_orig/gtk/scintilla-marshal.c scintilla/gtk/scintilla-marsha { typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1, diff --git b/scintilla/src/Catalogue.cxx a/scintilla/src/Catalogue.cxx -index e728f34..85116a5 100644 -+++ scintilla/src/Catalogue.cxx +index 41d5d54..70ce3bc 100644 --- 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 //**\(\tLINK_LEXER(\*);\n\) @@ -39,6 +39,7 @@ index e728f34..85116a5 100644 LINK_LEXER(lmAbaqus); LINK_LEXER(lmAda); - LINK_LEXER(lmAPDL); +- LINK_LEXER(lmAs); LINK_LEXER(lmAsm); - LINK_LEXER(lmAsn1); - LINK_LEXER(lmASY); @@ -63,6 +64,7 @@ index e728f34..85116a5 100644 LINK_LEXER(lmCss); LINK_LEXER(lmD); LINK_LEXER(lmDiff); +- LINK_LEXER(lmDMAP); - LINK_LEXER(lmECL); - LINK_LEXER(lmEiffel); - LINK_LEXER(lmEiffelkw); diff --git a/scintilla/src/AutoComplete.cxx b/scintilla/src/AutoComplete.cxx index c33d0c3a8..d154a913a 100644 --- a/scintilla/src/AutoComplete.cxx +++ b/scintilla/src/AutoComplete.cxx @@ -16,9 +16,9 @@ #include "Platform.h" +#include "Scintilla.h" #include "CharacterSet.h" #include "AutoComplete.h" -#include "Scintilla.h" #ifdef SCI_NAMESPACE using namespace Scintilla; @@ -41,8 +41,6 @@ AutoComplete::AutoComplete() : heightLBDefault(100), autoSort(SC_ORDER_PRESORTED) { lb = ListBox::Allocate(); - stopChars[0] = '\0'; - fillUpChars[0] = '\0'; } AutoComplete::~AutoComplete() { @@ -71,21 +69,19 @@ void AutoComplete::Start(Window &parent, int ctrlID, } void AutoComplete::SetStopChars(const char *stopChars_) { - strncpy(stopChars, stopChars_, sizeof(stopChars)); - stopChars[sizeof(stopChars) - 1] = '\0'; + stopChars = stopChars_; } bool AutoComplete::IsStopChar(char ch) { - return ch && strchr(stopChars, ch); + return ch && (stopChars.find(ch) != std::string::npos); } void AutoComplete::SetFillUpChars(const char *fillUpChars_) { - strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars)); - fillUpChars[sizeof(fillUpChars) - 1] = '\0'; + fillUpChars = fillUpChars_; } bool AutoComplete::IsFillUpChar(char ch) { - return ch && strchr(fillUpChars, ch); + return ch && (fillUpChars.find(ch) != std::string::npos); } void AutoComplete::SetSeparator(char separator_) { diff --git a/scintilla/src/AutoComplete.h b/scintilla/src/AutoComplete.h index 9977196a2..6838e4306 100644 --- a/scintilla/src/AutoComplete.h +++ b/scintilla/src/AutoComplete.h @@ -16,8 +16,8 @@ namespace Scintilla { */ class AutoComplete { bool active; - char stopChars[256]; - char fillUpChars[256]; + std::string stopChars; + std::string fillUpChars; char separator; char typesep; // Type seperator enum { maxItemLen=1000 }; @@ -71,7 +71,7 @@ public: /// The list string contains a sequence of words separated by the separator character void SetList(const char *list); - + /// Return the position of the currently selected list item int GetSelection() const; diff --git a/scintilla/src/CallTip.cxx b/scintilla/src/CallTip.cxx index c12a6e8eb..7dc23a4ac 100644 --- a/scintilla/src/CallTip.cxx +++ b/scintilla/src/CallTip.cxx @@ -14,6 +14,8 @@ #include "Platform.h" #include "Scintilla.h" + +#include "StringCopy.h" #include "CallTip.h" #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, centreY - halfWidth + halfWidth / 2), }; - surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), - colourBG, colourBG); + surface->Polygon(pts, ELEMENTS(pts), colourBG, colourBG); } else { // Down arrow Point pts[] = { Point(centreX - halfWidth, centreY - halfWidth / 2), Point(centreX + halfWidth, centreY - halfWidth / 2), Point(centreX, centreY + halfWidth - halfWidth / 2), }; - surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), - colourBG, colourBG); + surface->Polygon(pts, ELEMENTS(pts), colourBG, colourBG); } } xEnd = rcClient.right; diff --git a/scintilla/src/CaseConvert.cxx b/scintilla/src/CaseConvert.cxx index 59819bcf6..e8f533d5c 100644 --- a/scintilla/src/CaseConvert.cxx +++ b/scintilla/src/CaseConvert.cxx @@ -13,6 +13,7 @@ #include #include +#include "StringCopy.h" #include "CaseConvert.h" #include "UniConversion.h" #include "UnicodeFromUTF8.h" @@ -367,6 +368,9 @@ class CaseConverter : public ICaseConverter { enum { maxConversionLength=6 }; struct ConversionString { char conversion[maxConversionLength+1]; + ConversionString() { + conversion[0] = '\0'; + } }; // Conversions are initially store in a vector of structs but then decomposed into // parallel arrays as that is about 10% faster to search. @@ -374,7 +378,7 @@ class CaseConverter : public ICaseConverter { int character; ConversionString conversion; CharacterConversion(int character_=0, const char *conversion_="") : character(character_) { - strcpy(conversion.conversion, conversion_); + StringCopy(conversion.conversion, conversion_); } bool operator<(const CharacterConversion &other) const { return character < other.character; @@ -505,17 +509,17 @@ void AddSymmetric(enum CaseConversion conversion, int lower,int upper) { void SetupConversions(enum CaseConversion conversion) { // First initialize for the symmetric ranges - for (size_t i=0; i::iterator it = + std::vector::iterator it = std::find(watchers.begin(), watchers.end(), wwud); if (it != watchers.end()) return false; @@ -1901,7 +1901,7 @@ bool Document::AddWatcher(DocWatcher *watcher, void *userData) { } bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) { - std::vector::iterator it = + std::vector::iterator it = std::find(watchers.begin(), watchers.end(), WatcherWithUserData(watcher, userData)); if (it != watchers.end()) { watchers.erase(it); @@ -2103,7 +2103,7 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) { */ class BuiltinRegex : public RegexSearchBase { public: - BuiltinRegex(CharClassify *charClassTable) : search(charClassTable) {} + explicit BuiltinRegex(CharClassify *charClassTable) : search(charClassTable) {} virtual ~BuiltinRegex() { } diff --git a/scintilla/src/Document.h b/scintilla/src/Document.h index d02025cb5..effdd5fe5 100644 --- a/scintilla/src/Document.h +++ b/scintilla/src/Document.h @@ -32,7 +32,7 @@ public: Position start; Position end; - Range(Position pos=0) : + explicit Range(Position pos=0) : start(pos), end(pos) { } Range(Position start_, Position end_) : @@ -165,7 +165,7 @@ protected: ILexer *instance; bool performingStyle; ///< Prevent reentrance public: - LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(0), performingStyle(false) { + explicit LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(0), performingStyle(false) { } virtual ~LexInterface() { } @@ -443,12 +443,12 @@ public: */ class DocModification { public: - int modificationType; + int modificationType; int position; - int length; - int linesAdded; /**< Negative if lines deleted. */ - const char *text; /**< Only valid for changes to text, not for changes to style. */ - int line; + int length; + int linesAdded; /**< Negative if lines deleted. */ + const char *text; /**< Only valid for changes to text, not for changes to style. */ + int line; int foldLevelNow; int foldLevelPrev; int annotationLinesAdded; diff --git a/scintilla/src/Editor.cxx b/scintilla/src/Editor.cxx index 8fda6b9ba..1337a0e05 100644 --- a/scintilla/src/Editor.cxx +++ b/scintilla/src/Editor.cxx @@ -23,6 +23,7 @@ #include "ILexer.h" #include "Scintilla.h" +#include "StringCopy.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" @@ -87,6 +88,10 @@ Timer::Timer() : Idler::Idler() : state(false), idlerID(0) {} +static int RoundXYPosition(XYPOSITION xyPos) { + return int(xyPos+0.5); +} + static inline bool IsControlCharacter(int ch) { // iscntrl returns true for lots of chars > 127 which are displayable return ch >= 0 && ch < ' '; @@ -250,7 +255,7 @@ void Editor::SetRepresentations() { "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "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(j), 0 }; reprs.SetRepresentation(c, reps[j]); } @@ -264,10 +269,12 @@ void Editor::SetRepresentations() { "DCS", "PU1", "PU2", "STS", "CCH", "MW", "SPA", "EPA", "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(0x80+j), 0 }; reprs.SetRepresentation(c1, repsC1[j]); } + reprs.SetRepresentation("\xe2\x80\xa8", "LS"); + reprs.SetRepresentation("\xe2\x80\xa9", "PS"); } // UTF-8 invalid bytes @@ -381,6 +388,10 @@ PRectangle Editor::GetClientRectangle() { return wMain.GetClientPosition(); } +PRectangle Editor::GetClientDrawingRectangle() { + return GetClientRectangle(); +} + PRectangle Editor::GetTextRectangle() { PRectangle rc = GetClientRectangle(); rc.left += vs.textStart; @@ -426,7 +437,7 @@ const char *ControlCharacterString(unsigned char ch) { "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" }; - if (ch < (sizeof(reps) / sizeof(reps[0]))) { + if (ch < ELEMENTS(reps)) { return reps[ch]; } else { return "BAD"; @@ -476,36 +487,17 @@ Point Editor::LocationFromPosition(SelectionPosition pos) { RefreshStyleData(); if (pos.Position() == INVALID_POSITION) return pt; - int line = pdoc->LineFromPosition(pos.Position()); - int lineVisible = cs.DisplayFromDoc(line); + const int line = pdoc->LineFromPosition(pos.Position()); + const int lineVisible = cs.DisplayFromDoc(line); //Platform::DebugPrintf("line=%d\n", line); AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(line)); if (surface && ll) { - // -1 because of adding in for visible lines in following loop. - pt.y = (lineVisible - topLine - 1) * vs.lineHeight; - pt.x = 0; - unsigned int posLineStart = pdoc->LineStart(line); + const int posLineStart = pdoc->LineStart(line); LayoutLine(line, surface, vs, ll, wrapWidth); - int posInLine = pos.Position() - posLineStart; - // In case of very long line put x at arbitrary large position - if (posInLine > ll->maxLineLength) { - 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; - } - } + const int posInLine = pos.Position() - posLineStart; + pt = ll->PointFromPosition(posInLine, vs.lineHeight); + pt.y += (lineVisible - topLine) * vs.lineHeight; pt.x += vs.textStart - xOffset; } 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); if (!canReturnInvalid && (visibleLine < 0)) visibleLine = 0; - int lineDoc = cs.DocFromDisplay(visibleLine); + const int lineDoc = cs.DocFromDisplay(visibleLine); if (canReturnInvalid && (lineDoc < 0)) return SelectionPosition(INVALID_POSITION); if (lineDoc >= pdoc->LinesTotal()) return SelectionPosition(canReturnInvalid ? INVALID_POSITION : pdoc->Length()); - unsigned int posLineStart = pdoc->LineStart(lineDoc); - SelectionPosition retVal(canReturnInvalid ? INVALID_POSITION : static_cast(posLineStart)); + const int posLineStart = pdoc->LineStart(lineDoc); AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); if (surface && ll) { LayoutLine(lineDoc, surface, vs, ll, wrapWidth); - int lineStartSet = cs.DisplayFromDoc(lineDoc); - int subLine = visibleLine - lineStartSet; + const int lineStartSet = cs.DisplayFromDoc(lineDoc); + const int subLine = visibleLine - lineStartSet; if (subLine < ll->lines) { - int lineStart = ll->LineStart(subLine); - int lineEnd = ll->LineLastVisible(subLine); - XYPOSITION subLineStart = ll->positions[lineStart]; - - if (ll->wrapIndent != 0) { - if (lineStart != 0) // Wrapped - pt.x -= ll->wrapIndent; - } - 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++; + const Range rangeSubLine = ll->SubLineRange(subLine); + const XYPOSITION subLineStart = ll->positions[rangeSubLine.start]; + if (subLine > 0) // Wrapped + pt.x -= ll->wrapIndent; + const int positionInLine = ll->FindPositionFromX(pt.x + subLineStart, rangeSubLine, charPosition); + if (positionInLine < rangeSubLine.end) { + return SelectionPosition(pdoc->MovePositionOutsideChar(positionInLine + posLineStart, 1)); } if (virtualSpace) { 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; - return SelectionPosition(lineEnd + posLineStart, spaceOffset); + return SelectionPosition(rangeSubLine.end + posLineStart, spaceOffset); } else if (canReturnInvalid) { - if (pt.x < (ll->positions[lineEnd] - subLineStart)) { - return SelectionPosition(pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1)); + if (pt.x < (ll->positions[rangeSubLine.end] - subLineStart)) { + return SelectionPosition(pdoc->MovePositionOutsideChar(rangeSubLine.end + posLineStart, 1)); } } else { - return SelectionPosition(lineEnd + posLineStart); + return SelectionPosition(rangeSubLine.end + posLineStart); } } if (!canReturnInvalid) return SelectionPosition(ll->numCharsInLine + posLineStart); } - return retVal; + return SelectionPosition(canReturnInvalid ? INVALID_POSITION : posLineStart); } 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. * 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) { 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); AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); - int retVal = 0; if (surface && ll) { - unsigned int posLineStart = pdoc->LineStart(lineDoc); + const int posLineStart = pdoc->LineStart(lineDoc); LayoutLine(lineDoc, surface, vs, ll, wrapWidth); - int subLine = 0; - int lineStart = ll->LineStart(subLine); - int lineEnd = ll->LineLastVisible(subLine); - XYPOSITION subLineStart = ll->positions[lineStart]; - XYPOSITION newX = x; - - 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 Range rangeSubLine = ll->SubLineRange(0); + const XYPOSITION subLineStart = ll->positions[rangeSubLine.start]; + const int positionInLine = ll->FindPositionFromX(x + subLineStart, rangeSubLine, false); + if (positionInLine < rangeSubLine.end) { + return SelectionPosition(pdoc->MovePositionOutsideChar(positionInLine + posLineStart, 1)); } const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth; - int spaceOffset = (newX + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / spaceWidth; - return SelectionPosition(lineEnd + posLineStart, spaceOffset); + const int spaceOffset = (x + subLineStart - ll->positions[rangeSubLine.end] + spaceWidth / 2) / spaceWidth; + return SelectionPosition(rangeSubLine.end + posLineStart, spaceOffset); } - return SelectionPosition(retVal); + return SelectionPosition(0); } 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() { //Platform::DebugPrintf("Redraw all\n"); PRectangle rcClient = GetClientRectangle(); @@ -699,7 +669,10 @@ void Editor::Redraw() { } 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) { Redraw(); } 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 */ -Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange range, const XYScrollOptions options) { +Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options) { PRectangle rcClient = GetTextRectangle(); Point pt = LocationFromPosition(range.caret); 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 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) { - newXY.xOffset = pt.x + xOffset - rcClient.right + 1; + newXY.xOffset = pt.x + xOffset - rcClient.right + 2; if (vs.caretStyle == CARETSTYLE_BLOCK) { // Ensure we can see a good portion of the block caret newXY.xOffset += static_cast(vs.aveCharWidth); @@ -1988,7 +1961,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { } } else if (levelNum > SC_FOLDLEVELBASE) { marks |= 1 << SC_MARKNUM_FOLDERSUB; - } + } } else { if (levelNum < levelNextNum) { if (cs.GetExpanded(lineDoc)) { @@ -1998,7 +1971,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { } } else if (levelNum > SC_FOLDLEVELBASE) { marks |= 1 << SC_MARKNUM_FOLDERSUB; - } + } } needWhiteClosure = false; 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(), static_cast(ts.representation->stringRep.length()), positionsRepr, pdoc); representationWidth = positionsRepr[ts.representation->stringRep.length()-1] + vstyle.ctrlCharPadding; - } + } } for (int ii=0; ii < ts.length; ii++) ll->positions[ts.start + 1 + ii] = representationWidth; @@ -2399,7 +2372,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou - posLineStart; p = pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart; continue; - } else if (ll->styles[p] != ll->styles[p - 1]) { + } else if ((vstyle.wrapState == eWrapWord) && (ll->styles[p] != ll->styles[p - 1])) { lastGoodBreak = p; } else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) { lastGoodBreak = p; @@ -2584,14 +2557,20 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin char hexits[4]; const char *ctrlChar; 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)) { ctrlChar = ControlCharacterString(chEOL); } else { - sprintf(hexits, "x%2X", chEOL); - ctrlChar = hexits; + Representation *repr = reprs.RepresentationFromCharacter(ll->chars + eolPos, ll->numCharsInLine - eolPos); + 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; if (eolInSelection && vsDraw.selColours.fore.isSet) { 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; DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart, 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); if (stAnnotation.text && ValidStyledText(vsDraw, vsDraw.annotationStyleOffset, stAnnotation)) { surface->FillRectangle(rcSegment, vsDraw.styles[0].back); - if (vs.annotationVisible == ANNOTATION_BOXED) { - // Only care about calculating width if need to draw box + rcSegment.left = xStart; + 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); - widthAnnotation += vsDraw.spaceWidth * 2; // Margins - rcSegment.left = xStart + indent; - rcSegment.right = rcSegment.left + widthAnnotation; - } else { - rcSegment.left = xStart; + if (vs.annotationVisible == ANNOTATION_BOXED) { + widthAnnotation += vsDraw.spaceWidth * 2; // Margins + } + if (widthAnnotation > lineWidthMaxSeen) + lineWidthMaxSeen = widthAnnotation; + if (vs.annotationVisible == ANNOTATION_BOXED) { + rcSegment.left = xStart + indent; + rcSegment.right = rcSegment.left + widthAnnotation; + } } const int annotationLines = pdoc->AnnotationLines(line); size_t start = 0; @@ -3453,10 +3440,10 @@ void Editor::DrawCarets(Surface *surface, ViewStyle &vsDraw, int lineDoc, int xS bool caretAtEOL = false; bool drawBlockCaret = false; XYPOSITION widthOverstrikeCaret; - int caretWidthOffset = 0; + XYPOSITION caretWidthOffset = 0; PRectangle rcCaret = rcLine; - if (posCaret.Position() == pdoc->Length()) { // At end of document + if (posCaret.Position() == pdoc->Length()) { // At end of document caretAtEOF = true; widthOverstrikeCaret = vsDraw.aveCharWidth; } 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; if (xposCaret > 0) - caretWidthOffset = 1; // Move back so overlaps both character cells. + caretWidthOffset = 0.51f; // Move back so overlaps both character cells. xposCaret += xStart; if (posDrag.IsValid()) { /* Dragging text, use a line caret */ - rcCaret.left = xposCaret - caretWidthOffset; + rcCaret.left = RoundXYPosition(xposCaret - caretWidthOffset); rcCaret.right = rcCaret.left + vsDraw.caretWidth; } else if (inOverstrike && drawOverstrikeCaret) { /* Overstrike (insert mode), use a modified bar caret */ @@ -3491,7 +3478,7 @@ void Editor::DrawCarets(Surface *surface, ViewStyle &vsDraw, int lineDoc, int xS } } else { /* Line caret */ - rcCaret.left = xposCaret - caretWidthOffset; + rcCaret.left = RoundXYPosition(xposCaret - caretWidthOffset); rcCaret.right = rcCaret.left + vsDraw.caretWidth; } ColourDesired caretColour = mainCaret ? vsDraw.caretcolour : vsDraw.additionalCaretColour; @@ -4198,7 +4185,7 @@ void Editor::ClearSelection(bool retainMultipleSelections) { sel.Range(r).End().Position())) { pdoc->DeleteChars(sel.Range(r).Start().Position(), 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 (sel.Range(r).Start().VirtualSpace()) { 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 - 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())) { pdoc->DelChar(sel.Range(r).caret.Position()); @@ -4414,6 +4401,14 @@ void Editor::DelCharBack(bool allowLineStartDeletion) { 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) { SCNotification scn = {}; scn.nmhdr.code = focus ? SCN_FOCUSIN : SCN_FOCUSOUT; @@ -4465,41 +4460,53 @@ void Editor::NotifyModifyAttempt() { NotifyParent(scn); } -void Editor::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) { +void Editor::NotifyDoubleClick(Point pt, int modifiers) { SCNotification scn = {}; scn.nmhdr.code = SCN_DOUBLECLICK; scn.line = LineFromLocation(pt); scn.position = PositionFromLocation(pt, true); - scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | - (alt ? SCI_ALT : 0); + scn.modifiers = modifiers; + 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); } 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 = {}; - scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK; + scn.nmhdr.code = SCN_HOTSPOTCLICK; scn.position = position; - scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | - (alt ? SCI_ALT : 0); + scn.modifiers = modifiers; NotifyParent(scn); } 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 = {}; - scn.nmhdr.code = SCN_HOTSPOTCLICK; + scn.nmhdr.code = SCN_HOTSPOTRELEASECLICK; scn.position = position; - scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | - (alt ? SCI_ALT : 0); + scn.modifiers = modifiers; NotifyParent(scn); } void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_HOTSPOTRELEASECLICK; - scn.position = position; - scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | - (alt ? SCI_ALT : 0); - NotifyParent(scn); + NotifyHotSpotReleaseClick(position, ModifierFlags(shift, ctrl, alt)); } bool Editor::NotifyUpdateUI() { @@ -4520,19 +4527,23 @@ void Editor::NotifyPainted() { 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); if ((click && mask) || pdoc->decorations.clickNotified) { SCNotification scn = {}; pdoc->decorations.clickNotified = click; 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; 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 x = vs.textStart - vs.fixedColumnWidth; 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) { int position = pdoc->LineStart(LineFromLocation(pt)); 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); if (shift && ctrl) { FoldAll(SC_FOLDACTION_TOGGLE); @@ -4564,8 +4577,7 @@ bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) { } SCNotification scn = {}; scn.nmhdr.code = SCN_MARGINCLICK; - scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | - (alt ? SCI_ALT : 0); + scn.modifiers = modifiers; scn.position = position; scn.margin = marginClicked; 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) { SCNotification scn = {}; scn.nmhdr.code = SCN_NEEDSHOWN; @@ -4923,7 +4939,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar case SCI_NEWLINE: default: // printf("Filtered out %ld of macro recording\n", iMessage); - return ; + return; } // Send notification @@ -5097,6 +5113,7 @@ void Editor::NewLine() { // Remove non-main ranges InvalidateSelection(sel.RangeMain(), true); sel.SetSelection(sel.RangeMain()); + sel.RangeMain().ClearVirtualSpace(); // Clear main range and insert line end 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 modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | - (alt ? SCI_ALT : 0); - return KeyDownWithModifiers(key, modifiers, consumed); + return KeyDownWithModifiers(key, ModifierFlags(shift, ctrl, alt), consumed); } void Editor::Indent(bool forwards) { @@ -5823,6 +5838,7 @@ void Editor::Indent(bool forwards) { } } } + ContainerNeedsUpdate(SC_UPDATE_SELECTION); } class CaseFolderASCII : public CaseFolderTable { @@ -6286,18 +6302,23 @@ static bool AllowVirtualSpace(int virtualSpaceOptions, bool rectangular) { || (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); 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)); newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position()); + SelectionPosition newCharPos = SPositionFromLocation(pt, false, true, false); + newCharPos = MovePositionOutsideChar(newCharPos, -1); inDragDrop = ddNone; sel.SetMoveExtends(false); - if (NotifyMarginClick(pt, shift, ctrl, alt)) + if (NotifyMarginClick(pt, modifiers)) return; - NotifyIndicatorClick(true, newPos.Position(), shift, ctrl, alt); + NotifyIndicatorClick(true, newPos.Position(), modifiers); bool inSelMargin = PointInSelMargin(pt); // 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); if (doubleClick) { - NotifyDoubleClick(pt, shift, ctrl, alt); - if (PositionIsHotspot(newPos.Position())) - NotifyHotSpotDoubleClicked(newPos.Position(), shift, ctrl, alt); + NotifyDoubleClick(pt, modifiers); + if (PositionIsHotspot(newCharPos.Position())) + NotifyHotSpotDoubleClicked(newCharPos.Position(), modifiers); } } else { // Single click if (inSelMargin) { @@ -6411,8 +6432,8 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b SetMouseCapture(true); } else { if (PointIsHotspot(pt)) { - NotifyHotSpotClicked(newPos.Position(), shift, ctrl, alt); - hotSpotClickPos = PositionFromLocation(pt,true,false); + NotifyHotSpotClicked(newCharPos.Position(), modifiers); + hotSpotClickPos = newCharPos.Position(); } if (!shift) { if (PointInSelection(pt) && !SelectionEmpty()) @@ -6456,12 +6477,16 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b 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 { return vs.styles[pdoc->StyleAt(position) & pdoc->stylingBitsMask].hotspot; } bool Editor::PointIsHotspot(Point pt) { - int pos = PositionFromLocation(pt, true); + int pos = PositionFromLocation(pt, true, true); if (pos == INVALID_POSITION) return false; return PositionIsHotspot(pos); @@ -6469,7 +6494,7 @@ bool Editor::PointIsHotspot(Point pt) { void Editor::SetHotSpotRange(Point *pt) { if (pt) { - int pos = PositionFromLocation(*pt); + int pos = PositionFromLocation(*pt, false, true); // If we don't limit this to word characters then the // 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); - if (hsStart != -1 && !PositionIsHotspot(movePos.Position())) + if (hsStart != -1 && !PointIsHotspot(pt)) SetHotSpotRange(NULL); - if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,false) != hotSpotClickPos) { + if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,true) != hotSpotClickPos) { if (inDragDrop == ddNone) { DisplayCursor(Window::cursorText); } @@ -6637,7 +6662,9 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { } if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) { 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 (PointInSelMargin(pt)) { @@ -6648,7 +6675,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { } ptMouseLast = pt; SetMouseCapture(false); - NotifyIndicatorClick(false, newPos.Position(), false, false, false); + NotifyIndicatorClick(false, newPos.Position(), 0); if (inDragDrop == ddDragging) { SelectionPosition selStart = SelectionStart(); 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 // This often means that the line after a modification is restyled which helps // 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()) return pdoc->LineStart(cs.DocFromDisplay(lineAfter) + 1); 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 // affects later lines so style all the viewed text. void Editor::StyleToPositionInView(Position pos) { - int endWindow = (vs.marginInside) ? (PositionAfterArea(GetClientRectangle())) : (pdoc->Length()); + int endWindow = PositionAfterArea(GetClientDrawingRectangle()); if (pos > endWindow) pos = endWindow; int styleAtEnd = pdoc->StyleAt(pos-1); @@ -6790,6 +6817,9 @@ void Editor::StyleToPositionInView(Position pos) { if ((endWindow > pos) && (styleAtEnd != pdoc->StyleAt(pos-1))) { // Style at end of line changed so is multi-line change like starting a comment // 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); } } @@ -6972,7 +7002,7 @@ void Editor::SetFoldExpanded(int lineDoc, bool expanded) { void Editor::FoldLine(int line, int action) { if (line >= 0) { if (action == SC_FOLDACTION_TOGGLE) { - if ((pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) == 0) { + if ((pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) == 0) { line = pdoc->GetFoldParent(line); if (line < 0) return; @@ -7340,11 +7370,7 @@ sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lPar case SCI_STYLEGETSIZEFRACTIONAL: return vs.styles[wParam].size; case SCI_STYLEGETFONT: - if (!vs.styles[wParam].fontName) - return 0; - if (lParam != 0) - strcpy(CharPtrFromSPtr(lParam), vs.styles[wParam].fontName); - return strlen(vs.styles[wParam].fontName); + return StringResult(lParam, vs.styles[wParam].fontName); case SCI_STYLEGETUNDERLINE: return vs.styles[wParam].underline ? 1 : 0; 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) { - const size_t n = strlen(val); - if (lParam != 0) { - char *ptr = reinterpret_cast(lParam); - strcpy(ptr, val); + const size_t len = val ? strlen(val) : 0; + if (lParam) { + char *ptr = CharPtrFromSPtr(lParam); + 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) { @@ -8399,7 +8440,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { if (wParam <= MARKER_MAX) { vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam)); vs.CalcLargestMarkerHeight(); - }; + } InvalidateStyleData(); RedrawSelMargin(); break; @@ -8420,7 +8461,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { if (wParam <= MARKER_MAX) { vs.markers[wParam].SetRGBAImage(sizeRGBAImage, scaleRGBAImage / 100.0, reinterpret_cast(lParam)); vs.CalcLargestMarkerHeight(); - }; + } InvalidateStyleData(); RedrawSelMargin(); break; @@ -9186,9 +9227,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { Representation *repr = reprs.RepresentationFromCharacter( reinterpret_cast(wParam), UTF8MaxBytes); if (repr) { - if (lParam != 0) - strcpy(CharPtrFromSPtr(lParam), repr->stringRep.c_str()); - return repr->stringRep.size(); + return StringResult(lParam, repr->stringRep.c_str()); } return 0; } @@ -9304,13 +9343,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_MARGINGETTEXT: { const StyledText st = pdoc->MarginStyledText(wParam); - if (lParam) { - if (st.text) - memcpy(CharPtrFromSPtr(lParam), st.text, st.length); - else - strcpy(CharPtrFromSPtr(lParam), ""); - } - return st.length; + return BytesResult(lParam, reinterpret_cast(st.text), st.length); } case SCI_MARGINSETSTYLE: @@ -9328,13 +9361,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_MARGINGETSTYLES: { const StyledText st = pdoc->MarginStyledText(wParam); - if (lParam) { - if (st.styles) - memcpy(CharPtrFromSPtr(lParam), st.styles, st.length); - else - strcpy(CharPtrFromSPtr(lParam), ""); - } - return st.styles ? st.length : 0; + return BytesResult(lParam, st.styles, st.length); } case SCI_MARGINTEXTCLEARALL: @@ -9347,13 +9374,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_ANNOTATIONGETTEXT: { const StyledText st = pdoc->AnnotationStyledText(wParam); - if (lParam) { - if (st.text) - memcpy(CharPtrFromSPtr(lParam), st.text, st.length); - else - strcpy(CharPtrFromSPtr(lParam), ""); - } - return st.length; + return BytesResult(lParam, reinterpret_cast(st.text), st.length); } case SCI_ANNOTATIONGETSTYLE: { @@ -9371,13 +9392,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_ANNOTATIONGETSTYLES: { const StyledText st = pdoc->AnnotationStyledText(wParam); - if (lParam) { - if (st.styles) - memcpy(CharPtrFromSPtr(lParam), st.styles, st.length); - else - strcpy(CharPtrFromSPtr(lParam), ""); - } - return st.styles ? st.length : 0; + return BytesResult(lParam, st.styles, st.length); } case SCI_ANNOTATIONGETLINES: @@ -9480,6 +9495,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { Redraw(); break; + case SCI_DROPSELECTIONN: + sel.DropSelection(wParam); + Redraw(); + break; + case SCI_SETMAINSELECTION: sel.SetMain(wParam); Redraw(); diff --git a/scintilla/src/Editor.h b/scintilla/src/Editor.h index 20877b29e..810175b58 100644 --- a/scintilla/src/Editor.h +++ b/scintilla/src/Editor.h @@ -119,7 +119,7 @@ public: } private: 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. 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 int TopLineOfMain() const; // Return the line at Main's y coordinate 0 virtual PRectangle GetClientRectangle(); + virtual PRectangle GetClientDrawingRectangle(); PRectangle GetTextRectangle(); int LinesOnScreen(); @@ -356,8 +357,9 @@ protected: // ScintillaBase subclass needs access to much of Editor void SetTopLine(int topLineNew); bool AbandonPaint(); - void RedrawRect(PRectangle rc); - void Redraw(); + virtual void RedrawRect(PRectangle rc); + virtual void DiscardOverdraw(); + virtual void Redraw(); void RedrawSelMargin(int line=-1, bool allAfter=false); PRectangle RectangleFromRange(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, xysHorizontal=0x4, 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 EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true); 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 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 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, int line, int lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart, bool overrideBackground, ColourDesired background, 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); void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart, 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); virtual void ClaimSelection() = 0; + static int ModifierFlags(bool shift, bool ctrl, bool alt, bool meta=false); virtual void NotifyChange() = 0; virtual void NotifyFocus(bool focus); virtual void SetCtrlID(int identifier); @@ -497,13 +500,19 @@ protected: // ScintillaBase subclass needs access to much of Editor void NotifyChar(int ch); void NotifySavePoint(bool isSavePoint); void NotifyModifyAttempt(); + virtual void NotifyDoubleClick(Point pt, int modifiers); 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 NotifyHotSpotDoubleClicked(int position, int modifiers); 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); bool NotifyUpdateUI(); void NotifyPainted(); + void NotifyIndicatorClick(bool click, int position, int modifiers); 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); void NotifyNeedShown(int pos, int len); void NotifyDwelling(Point pt, bool state); @@ -566,6 +575,7 @@ protected: // ScintillaBase subclass needs access to much of Editor void WordSelection(int pos); void DwellEnd(bool mouseMoved); 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); void ButtonMoveWithModifiers(Point pt, int modifiers); void ButtonMove(Point pt); @@ -624,6 +634,7 @@ protected: // ScintillaBase subclass needs access to much of Editor static const char *StringFromEOLMode(int eolMode); 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 so the COM thunks can access it. diff --git a/scintilla/src/ExternalLexer.cxx b/scintilla/src/ExternalLexer.cxx index d1d26201d..682320889 100644 --- a/scintilla/src/ExternalLexer.cxx +++ b/scintilla/src/ExternalLexer.cxx @@ -66,14 +66,12 @@ LexerLibrary::LexerLibrary(const char *ModuleName) { GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName"); GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory"); - // Assign a buffer for the lexer name. - char lexname[100]; - strcpy(lexname, ""); - int nl = GetLexerCount(); 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); Catalogue::AddLexerModule(lex); diff --git a/scintilla/src/ExternalLexer.h b/scintilla/src/ExternalLexer.h index bf175a631..a85213e31 100644 --- a/scintilla/src/ExternalLexer.h +++ b/scintilla/src/ExternalLexer.h @@ -27,15 +27,13 @@ typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned i class ExternalLexerModule : public LexerModule { protected: GetLexerFactoryFunction fneFactory; - char name[100]; + std::string name; public: ExternalLexerModule(int language_, LexerFunction fnLexer_, const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_), - fneFactory(0) { - strncpy(name, languageName_, sizeof(name)); - name[sizeof(name)-1] = '\0'; - languageName = name; + fneFactory(0), name(languageName_){ + languageName = name.c_str(); } virtual void SetExternal(GetLexerFactoryFunction fFactory, int index); }; @@ -54,7 +52,7 @@ class LexerLibrary { LexerMinder *last; public: - LexerLibrary(const char *ModuleName); + explicit LexerLibrary(const char *ModuleName); ~LexerLibrary(); void Release(); diff --git a/scintilla/src/FontQuality.h b/scintilla/src/FontQuality.h index ee9426171..a0ae207f8 100644 --- a/scintilla/src/FontQuality.h +++ b/scintilla/src/FontQuality.h @@ -1,6 +1,7 @@ // Scintilla source code edit control /** @file FontQuality.h ** 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 // The License.txt file describes the conditions under which this software may be distributed. @@ -12,12 +13,14 @@ namespace Scintilla { #endif +// These definitions match Scintilla.h #define SC_EFF_QUALITY_MASK 0xF #define SC_EFF_QUALITY_DEFAULT 0 #define SC_EFF_QUALITY_NON_ANTIALIASED 1 #define SC_EFF_QUALITY_ANTIALIASED 2 #define SC_EFF_QUALITY_LCD_OPTIMIZED 3 +// These definitions must match SC_TECHNOLOGY_* in Scintilla.h #define SCWIN_TECH_GDI 0 #define SCWIN_TECH_DIRECTWRITE 1 diff --git a/scintilla/src/KeyMap.cxx b/scintilla/src/KeyMap.cxx index 740776104..cb6f2b8d4 100644 --- a/scintilla/src/KeyMap.cxx +++ b/scintilla/src/KeyMap.cxx @@ -8,6 +8,7 @@ #include #include +#include #include "Platform.h" @@ -36,26 +37,12 @@ void KeyMap::Clear() { } void KeyMap::AssignCmdKey(int key, int modifiers, unsigned int msg) { - for (size_t keyIndex = 0; keyIndex < kmap.size(); keyIndex++) { - 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); + kmap[KeyModifiers(key, modifiers)] = msg; } unsigned int KeyMap::Find(int key, int modifiers) const { - for (size_t i = 0; i < kmap.size(); i++) { - if ((key == kmap[i].key) && (modifiers == kmap[i].modifiers)) { - return kmap[i].msg; - } - } - return 0; + std::map::const_iterator it = kmap.find(KeyModifiers(key, modifiers)); + return (it == kmap.end()) ? 0 : it->second; } #if PLAT_GTK_MACOSX diff --git a/scintilla/src/KeyMap.h b/scintilla/src/KeyMap.h index 2f14e2488..b102b356f 100644 --- a/scintilla/src/KeyMap.h +++ b/scintilla/src/KeyMap.h @@ -20,6 +20,22 @@ namespace Scintilla { #define SCI_CSHIFT (SCI_CTRL | 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 { @@ -32,7 +48,7 @@ public: /** */ class KeyMap { - std::vector kmap; + std::map kmap; static const KeyToCommand MapDefault[]; public: diff --git a/scintilla/src/LineMarker.cxx b/scintilla/src/LineMarker.cxx index 94513f5d0..708e6a320 100644 --- a/scintilla/src/LineMarker.cxx +++ b/scintilla/src/LineMarker.cxx @@ -1,6 +1,6 @@ // Scintilla source code edit control /** @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 // The License.txt file describes the conditions under which this software may be distributed. @@ -14,6 +14,8 @@ #include "Platform.h" #include "Scintilla.h" + +#include "StringCopy.h" #include "XPM.h" #include "LineMarker.h" @@ -141,8 +143,7 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac Point(centreX - dimOn4, centreY + dimOn2), Point(centreX + dimOn2 - dimOn4, centreY), }; - surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), - fore, back); + surface->Polygon(pts, ELEMENTS(pts), fore, back); } else if (markType == SC_MARK_ARROWDOWN) { Point pts[] = { @@ -150,8 +151,7 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac Point(centreX + dimOn2, centreY - dimOn4), Point(centreX, centreY + dimOn2 - dimOn4), }; - surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), - fore, back); + surface->Polygon(pts, ELEMENTS(pts), fore, back); } else if (markType == SC_MARK_PLUS) { Point pts[] = { @@ -168,8 +168,7 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac Point(centreX - 1, centreY + 1), Point(centreX - armSize, centreY + 1), }; - surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), - fore, back); + surface->Polygon(pts, ELEMENTS(pts), fore, back); } else if (markType == SC_MARK_MINUS) { 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), }; - surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), - fore, back); + surface->Polygon(pts, ELEMENTS(pts), fore, back); } else if (markType == SC_MARK_SMALLRECT) { PRectangle rcSmall; @@ -317,17 +315,14 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac DrawPlus(surface, centreX, centreY, blobSize, tail); } else if (markType == SC_MARK_CIRCLEMINUS) { - DrawCircle(surface, centreX, centreY, blobSize, fore, head); - DrawMinus(surface, centreX, centreY, blobSize, tail); - surface->PenColour(head); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); - } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) { DrawCircle(surface, centreX, centreY, blobSize, fore, head); DrawMinus(surface, centreX, centreY, blobSize, tail); + } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) { surface->PenColour(head); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); @@ -336,6 +331,9 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); + DrawCircle(surface, centreX, centreY, blobSize, fore, head); + DrawMinus(surface, centreX, centreY, blobSize, tail); + } else if (markType >= SC_MARK_CHARACTER) { char character[1]; character[0] = static_cast(markType - SC_MARK_CHARACTER); @@ -355,10 +353,12 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac } else if (markType == SC_MARK_ARROWS) { surface->PenColour(fore); int right = centreX - 2; - for (int b=0; b<3; b++) { - surface->MoveTo(right - 4, centreY - 4); - surface->LineTo(right, centreY); - surface->LineTo(right - 5, centreY + 5); + const int armLength = dimOn2 - 1; + for (int b = 0; b<3; b++) { + surface->MoveTo(right, centreY); + surface->LineTo(right - armLength, centreY - armLength); + surface->MoveTo(right, centreY); + surface->LineTo(right - armLength, centreY + armLength); right += 4; } } 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 + dimOn2), }; - surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), - fore, back); + surface->Polygon(pts, ELEMENTS(pts), fore, back); } else if (markType == SC_MARK_LEFTRECT) { PRectangle rcLeft = rcWhole; rcLeft.right = rcLeft.left + 4; 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 surface->FillRectangle(rcWhole, back); } diff --git a/scintilla/src/Partitioning.h b/scintilla/src/Partitioning.h index 18bcbc004..688b38d7d 100644 --- a/scintilla/src/Partitioning.h +++ b/scintilla/src/Partitioning.h @@ -18,7 +18,7 @@ namespace Scintilla { class SplitVectorWithRangeAdd : public SplitVector { public: - SplitVectorWithRangeAdd(int growSize_) { + explicit SplitVectorWithRangeAdd(int growSize_) { SetGrowSize(growSize_); ReAllocate(growSize_); } @@ -88,7 +88,7 @@ private: } public: - Partitioning(int growSize) { + explicit Partitioning(int growSize) { Allocate(growSize); } diff --git a/scintilla/src/PerLine.cxx b/scintilla/src/PerLine.cxx index a066bd647..8b0dbc44b 100644 --- a/scintilla/src/PerLine.cxx +++ b/scintilla/src/PerLine.cxx @@ -98,7 +98,7 @@ bool MarkerHandleSet::RemoveNumber(int markerNum, bool all) { delete mhn; performedDeletion = true; if (!all) - break; + break; } else { pmhn = &((*pmhn)->next); } @@ -370,9 +370,9 @@ void LineAnnotation::InsertLine(int line) { } void LineAnnotation::RemoveLine(int line) { - if (annotations.Length() && (line < annotations.Length())) { - delete []annotations[line]; - annotations.Delete(line); + if (annotations.Length() && (line > 0) && (line <= annotations.Length())) { + delete []annotations[line-1]; + annotations.Delete(line-1); } } diff --git a/scintilla/src/PositionCache.cxx b/scintilla/src/PositionCache.cxx index 7201ff548..f197a6559 100644 --- a/scintilla/src/PositionCache.cxx +++ b/scintilla/src/PositionCache.cxx @@ -43,11 +43,6 @@ using namespace Scintilla; #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_) : lineStarts(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 { return ((offset >= LineStart(line)) && (offset < LineStart(line + 1))) || ((offset == numCharsInLine) && (line == (lines-1))); @@ -205,6 +204,47 @@ int LineLayout::FindBefore(XYPOSITION x, int lower, int upper) const { 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 { 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 startByteHasReprs[static_cast(charBytes[0])]++; } - mapReprs[KeyFromString(charBytes, UTF8MaxBytes)] = value; + mapReprs[KeyFromString(charBytes, UTF8MaxBytes)] = Representation(value); } void SpecialRepresentations::ClearRepresentation(const char *charBytes) { @@ -454,7 +494,7 @@ BreakFinder::~BreakFinder() { TextSegment BreakFinder::Next() { if (subBreak == -1) { int prev = nextBreak; - while (nextBreak < lineEnd) { + while (nextBreak < lineEnd) { int charWidth = 1; if (encodingFamily == efUnicode) charWidth = UTF8DrawBytes(reinterpret_cast(ll->chars) + nextBreak, lineEnd - nextBreak); diff --git a/scintilla/src/PositionCache.h b/scintilla/src/PositionCache.h index 6d14cf0a3..871bb6e46 100644 --- a/scintilla/src/PositionCache.h +++ b/scintilla/src/PositionCache.h @@ -53,19 +53,22 @@ public: int lines; XYPOSITION wrapIndent; // In pixels - LineLayout(int maxLineLength_); + explicit LineLayout(int maxLineLength_); virtual ~LineLayout(); void Resize(int maxLineLength_); void Free(); void Invalidate(validLevel validity_); int LineStart(int line) const; int LineLastVisible(int line) const; + Range SubLineRange(int line) const; bool InLine(int offset, int line) const; void SetLineStart(int line, int start); void SetBracesHighlight(Range rangeLine, Position braces[], char bracesMatchStyle, int xHighlight, bool ignoreStyle); void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle); 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; }; @@ -116,7 +119,7 @@ public: class Representation { public: std::string stringRep; - Representation(const char *value="") : stringRep(value) { + explicit Representation(const char *value="") : stringRep(value) { } }; diff --git a/scintilla/src/RESearch.cxx b/scintilla/src/RESearch.cxx index efa23eb84..81eddf013 100644 --- a/scintilla/src/RESearch.cxx +++ b/scintilla/src/RESearch.cxx @@ -333,16 +333,18 @@ static int GetHexaChar(unsigned char hd1, unsigned char hd2) { hexValue += 16 * (hd1 - 'A' + 10); } else if (hd1 >= 'a' && hd1 <= 'f') { hexValue += 16 * (hd1 - 'a' + 10); - } else + } else { return -1; + } if (hd2 >= '0' && hd2 <= '9') { hexValue += hd2 - '0'; } else if (hd2 >= 'A' && hd2 <= 'F') { hexValue += hd2 - 'A' + 10; } else if (hd2 >= 'a' && hd2 <= 'f') { hexValue += hd2 - 'a' + 10; - } else + } else { return -1; + } return hexValue; } @@ -472,18 +474,18 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv break; case '^': /* match beginning */ - if (p == pattern) + if (p == pattern) { *mp++ = BOL; - else { + } else { *mp++ = CHR; *mp++ = *p; } break; case '$': /* match endofline */ - if (!*(p+1)) + if (!*(p+1)) { *mp++ = EOL; - else { + } else { *mp++ = CHR; *mp++ = *p; } @@ -498,8 +500,9 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv mask = '\377'; i++; p++; - } else + } else { mask = 0; + } if (*p == '-') { /* real dash */ i++; @@ -523,9 +526,9 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv i++; c2 = static_cast(*++p); if (c2 == '\\') { - if (!*(p+1)) // End of RE + if (!*(p+1)) { // End of RE return badpat("Missing ]"); - else { + } else { i++; p++; int incr; @@ -654,8 +657,9 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv if (tagc > n) { *mp++ = static_cast(REF); *mp++ = static_cast(n); - } else + } else { return badpat("Undetermined reference"); + } break; default: if (!posix && *p == '(') { @@ -663,16 +667,18 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv tagstk[++tagi] = tagc; *mp++ = BOT; *mp++ = static_cast(tagc++); - } else + } else { return badpat("Too many \\(\\) pairs"); + } } else if (!posix && *p == ')') { if (*sp == BOT) return badpat("Null pattern inside \\(\\)"); if (tagi > 0) { *mp++ = static_cast(EOT); *mp++ = static_cast(tagstk[tagi--]); - } else + } else { return badpat("Unmatched \\)"); + } } else { int incr; int c = GetBackslashExpression(p, incr); @@ -697,16 +703,18 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv tagstk[++tagi] = tagc; *mp++ = BOT; *mp++ = static_cast(tagc++); - } else + } else { return badpat("Too many () pairs"); + } } else if (posix && *p == ')') { if (*sp == BOT) return badpat("Null pattern inside ()"); if (tagi > 0) { *mp++ = static_cast(EOT); *mp++ = static_cast(tagstk[tagi--]); - } else + } else { return badpat("Unmatched )"); + } } else { unsigned char c = *p; if (!c) // End of RE diff --git a/scintilla/src/RESearch.h b/scintilla/src/RESearch.h index 702259d52..48533a41c 100644 --- a/scintilla/src/RESearch.h +++ b/scintilla/src/RESearch.h @@ -31,7 +31,7 @@ public: class RESearch { public: - RESearch(CharClassify *charClassTable); + explicit RESearch(CharClassify *charClassTable); ~RESearch(); void GrabMatches(CharacterIndexer &ci); const char *Compile(const char *pattern, int length, bool caseSensitive, bool posix); diff --git a/scintilla/src/ScintillaBase.cxx b/scintilla/src/ScintillaBase.cxx index b06f72836..dc154ec6d 100644 --- a/scintilla/src/ScintillaBase.cxx +++ b/scintilla/src/ScintillaBase.cxx @@ -209,7 +209,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { if (ac.chooseSingle && (listType == 0)) { if (list && !strchr(list, ac.GetSeparator())) { const char *typeSep = strchr(list, ac.GetTypesep()); - int lenInsert = typeSep ? + int lenInsert = typeSep ? static_cast(typeSep-list) : static_cast(strlen(list)); if (ac.ignoreCase) { // 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) { const std::string selected = ac.GetValue(item); if (buffer != NULL) - strcpy(buffer, selected.c_str()); + memcpy(buffer, selected.c_str(), selected.length()+1); return static_cast(selected.length()); } } @@ -417,16 +417,16 @@ void ScintillaBase::CallTipShow(Point pt, const char *defn) { // space PRectangle rcClient = GetClientRectangle(); 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. if (rc.bottom > rcClient.bottom) { rc.top -= 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. CreateCallTipWindow(rc); ct.wCallTip.SetPositionRelative(rc, wMain); @@ -463,9 +463,13 @@ void ScintillaBase::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(); - 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 @@ -482,7 +486,7 @@ class LexState : public LexInterface { public: int lexLanguage; - LexState(Document *pdoc_); + explicit LexState(Document *pdoc_); virtual ~LexState(); void SetLexer(uptr_t wParam); 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: return ct.posStartCallTip; + case SCI_CALLTIPSETPOSSTART: + ct.posStartCallTip = wParam; + break; + case SCI_CALLTIPSETHLT: ct.SetHighlight(wParam, lParam); break; diff --git a/scintilla/src/ScintillaBase.h b/scintilla/src/ScintillaBase.h index 6ec06d443..59ffea41e 100644 --- a/scintilla/src/ScintillaBase.h +++ b/scintilla/src/ScintillaBase.h @@ -83,6 +83,7 @@ protected: virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0; 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); void NotifyStyleToNeeded(int endStyleNeeded); diff --git a/scintilla/src/Selection.cxx b/scintilla/src/Selection.cxx index 385e2360e..ae4d8bfc7 100644 --- a/scintilla/src/Selection.cxx +++ b/scintilla/src/Selection.cxx @@ -166,7 +166,7 @@ void SelectionRange::MinimizeVirtualSpace() { } Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) { - AddSelection(SelectionPosition(0)); + AddSelection(SelectionRange(SelectionPosition(0))); } Selection::~Selection() { @@ -305,6 +305,21 @@ void Selection::AddSelectionWithoutTrim(SelectionRange range) { 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) { if (!tentativeMain) { rangesSaved = ranges; diff --git a/scintilla/src/Selection.h b/scintilla/src/Selection.h index d7c7d79ad..e84d3c32c 100644 --- a/scintilla/src/Selection.h +++ b/scintilla/src/Selection.h @@ -88,9 +88,9 @@ struct SelectionRange { 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_) { } @@ -167,6 +167,7 @@ public: void SetSelection(SelectionRange range); void AddSelection(SelectionRange range); void AddSelectionWithoutTrim(SelectionRange range); + void DropSelection(size_t r); void TentativeSelection(SelectionRange range); void CommitTentative(); int CharacterInSelection(int posCharacter) const; diff --git a/scintilla/src/SplitVector.h b/scintilla/src/SplitVector.h index 0c6e350cb..288c9e39f 100644 --- a/scintilla/src/SplitVector.h +++ b/scintilla/src/SplitVector.h @@ -272,7 +272,7 @@ public: GapTo(position); return body + position + gapLength; } else { - return body + position ; + return body + position; } } else { return body + position + gapLength; @@ -280,7 +280,7 @@ public: } int GapPosition() const { - return part1Length; + return part1Length; } }; diff --git a/scintilla/src/UniConversion.cxx b/scintilla/src/UniConversion.cxx index b769250c8..2286e047d 100644 --- a/scintilla/src/UniConversion.cxx +++ b/scintilla/src/UniConversion.cxx @@ -159,7 +159,7 @@ static int BytesFromLead(int leadByte) { void UTF8BytesOfLeadInitialise() { if (!initialisedBytesOfLead) { - for (int i=0;i<256;i++) { + for (int i=0; i<256; i++) { UTF8BytesOfLead[i] = BytesFromLead(i); } initialisedBytesOfLead = true; diff --git a/scintilla/src/ViewStyle.cxx b/scintilla/src/ViewStyle.cxx index daa5b1a99..b1c9dc10b 100644 --- a/scintilla/src/ViewStyle.cxx +++ b/scintilla/src/ViewStyle.cxx @@ -55,8 +55,9 @@ const char *FontNames::Save(const char *name) { return *it; } } - char *nameSave = new char[strlen(name) + 1]; - strcpy(nameSave, name); + const size_t lenName = strlen(name) + 1; + char *nameSave = new char[lenName]; + memcpy(nameSave, name, lenName); names.push_back(nameSave); return nameSave; } @@ -309,9 +310,9 @@ void ViewStyle::Refresh(Surface &surface, int tabInChars) { styles[i].extraFontFlag = extraFontFlag; } - CreateFont(styles[STYLE_DEFAULT]); + CreateAndAddFont(styles[STYLE_DEFAULT]); for (unsigned int j=0; j FontMap; -enum WrapMode { eWrapNone, eWrapWord, eWrapChar }; +enum WrapMode { eWrapNone, eWrapWord, eWrapChar, eWrapWhitespace }; class ColourOptional : public ColourDesired { public: @@ -178,7 +178,7 @@ public: private: void AllocStyles(size_t sizeNew); - void CreateFont(const FontSpecification &fs); + void CreateAndAddFont(const FontSpecification &fs); FontRealised *Find(const FontSpecification &fs); void FindMaxAscentDescent(); // Private so can only be copied through copy constructor which ensures font names initialised correctly diff --git a/scintilla/src/XPM.cxx b/scintilla/src/XPM.cxx index 915636de9..e1d91846d 100644 --- a/scintilla/src/XPM.cxx +++ b/scintilla/src/XPM.cxx @@ -61,11 +61,9 @@ XPM::XPM(const char *const *linesForm) { } XPM::~XPM() { - Clear(); } void XPM::Init(const char *textForm) { - Clear(); // 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 ((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) { - Clear(); height = 1; width = 1; nColours = 1; @@ -120,14 +117,11 @@ void XPM::Init(const char *const *linesForm) { for (int y=0; y(lform[x]); } } -void XPM::Clear() { -} - void XPM::Draw(Surface *surface, PRectangle &rc) { if (pixels.empty()) { return; @@ -244,7 +238,7 @@ void RGBAImage::SetPixel(int x, int y, ColourDesired colour, int alpha) { pixel[3] = static_cast(alpha); } -RGBAImageSet::RGBAImageSet() : height(-1), width(-1){ +RGBAImageSet::RGBAImageSet() : height(-1), width(-1) { } RGBAImageSet::~RGBAImageSet() { diff --git a/scintilla/src/XPM.h b/scintilla/src/XPM.h index c19025d1a..631fe1386 100644 --- a/scintilla/src/XPM.h +++ b/scintilla/src/XPM.h @@ -25,12 +25,11 @@ class XPM { ColourDesired ColourFromCode(int ch) const; void FillRun(Surface *surface, int code, int startX, int y, int x); public: - XPM(const char *textForm); - XPM(const char *const *linesForm); + explicit XPM(const char *textForm); + explicit XPM(const char *const *linesForm); ~XPM(); void Init(const char *textForm); void Init(const char *const *linesForm); - void Clear(); /// Decompose image into runs and use FillRectangle for each run void Draw(Surface *surface, PRectangle &rc); int GetHeight() const { return height; } @@ -53,7 +52,7 @@ class RGBAImage { std::vector pixelBytes; public: RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_); - RGBAImage(const XPM &xpm); + explicit RGBAImage(const XPM &xpm); virtual ~RGBAImage(); int GetHeight() const { return height; } int GetWidth() const { return width; } @@ -62,7 +61,7 @@ public: float GetScaledWidth() const { return width / scale; } int CountBytes() 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); }; /** diff --git a/scintilla/version.txt b/scintilla/version.txt index e64f24d55..947e93bc2 100644 --- a/scintilla/version.txt +++ b/scintilla/version.txt @@ -1 +1 @@ -336 +341