Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: Colomban Wendling ban@herbesfolles.org Date: Mon, 18 Jan 2016 03:22:26 UTC Commit: 99938dd821efb4b920db029a509b1a42ef86ea3c https://github.com/geany/geany/commit/99938dd821efb4b920db029a509b1a42ef86ea...
Log Message: ----------- Update Scintilla to version 3.6.3
Includes improvements for Lua 5.3 and Perl 5.22.
Modified Paths: -------------- scintilla/gtk/PlatGTK.cxx scintilla/gtk/ScintillaGTK.cxx scintilla/include/Platform.h scintilla/include/Scintilla.h scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h scintilla/lexers/LexBash.cxx scintilla/lexers/LexCPP.cxx scintilla/lexers/LexCaml.cxx scintilla/lexers/LexCmake.cxx scintilla/lexers/LexLaTeX.cxx scintilla/lexers/LexLua.cxx scintilla/lexers/LexMatlab.cxx scintilla/lexers/LexPO.cxx scintilla/lexers/LexPerl.cxx scintilla/lexers/LexRust.cxx scintilla/lexers/LexSQL.cxx scintilla/scintilla_changes.patch scintilla/src/CellBuffer.cxx scintilla/src/CellBuffer.h scintilla/src/Document.cxx scintilla/src/Document.h scintilla/src/EditModel.h scintilla/src/EditView.cxx scintilla/src/Editor.cxx scintilla/src/Editor.h scintilla/src/Indicator.cxx scintilla/src/PerLine.cxx scintilla/src/ScintillaBase.cxx scintilla/src/UniConversion.cxx scintilla/src/UniConversion.h scintilla/version.txt
Modified: scintilla/gtk/PlatGTK.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -1608,7 +1608,7 @@ void ListBoxX::Create(Window &, int, Point, int, bool, int) { cssProvider = gtk_css_provider_new(); } #endif - + wid = widCached = gtk_window_new(GTK_WINDOW_POPUP);
frame = gtk_frame_new(NULL);
Modified: scintilla/gtk/ScintillaGTK.cxx 138 lines changed, 60 insertions(+), 78 deletions(-) =================================================================== @@ -296,8 +296,6 @@ class ScintillaGTK : public ScintillaBase { static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis); void MoveImeCarets(int pos); void DrawImeIndicator(int indicator, int len); - static void GetImeUnderlines(PangoAttrList *attrs, bool *normalInput); - static void GetImeBackgrounds(PangoAttrList *attrs, bool *targetInput); void SetCandidateWindowPos();
static void StyleSetText(GtkWidget *widget, GtkStyle *previous, void*); @@ -306,7 +304,7 @@ class ScintillaGTK : public ScintillaBase { static void Destroy(GObject *object); static void SelectionReceived(GtkWidget *widget, GtkSelectionData *selection_data, guint time); - static void ClipboardReceived(GtkClipboard *clipboard, GtkSelectionData *selection_data, + static void ClipboardReceived(GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data); static void SelectionGet(GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint time); @@ -1930,7 +1928,7 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget, GdkEventScroll *event) { // intensity of scrolling info in the native message, gtk doesn't // support this so we simulate similarly adaptive scrolling) // Note that this is disabled on OS X (Darwin) with the X11 backend - // where the X11 server already has an adaptive scrolling algorithm + // where the X11 server already has an adaptive scrolling algorithm // that fights with this one int cLineScroll; #if defined(__APPLE__) && !defined(GDK_WINDOWING_QUARTZ) @@ -2328,24 +2326,28 @@ void ScintillaGTK::DrawImeIndicator(int indicator, int len) { } }
-void ScintillaGTK::GetImeUnderlines(PangoAttrList *attrs, bool *normalInput) { - // Whether single underlines attribute is or not - // attr position is counted by the number of UTF-8 bytes +static std::vector<int> MapImeIndicators(PangoAttrList *attrs, const char *u8Str) { + // Map input style to scintilla ime indicator. + // Attrs position points between UTF-8 bytes. + // Indicator index to be returned is character based though. + glong charactersLen = g_utf8_strlen(u8Str, strlen(u8Str)); + std::vector<int> indicator(charactersLen, SC_INDICATOR_UNKNOWN); + PangoAttrIterator *iterunderline = pango_attr_list_get_iterator(attrs); if (iterunderline) { do { PangoAttribute *attrunderline = pango_attr_iterator_get(iterunderline, PANGO_ATTR_UNDERLINE); if (attrunderline) { - glong start = attrunderline->start_index; - glong end = attrunderline->end_index; + glong start = g_utf8_strlen(u8Str, attrunderline->start_index); + glong end = g_utf8_strlen(u8Str, attrunderline->end_index); PangoUnderline uline = (PangoUnderline)((PangoAttrInt *)attrunderline)->value; for (glong i=start; i < end; ++i) { switch (uline) { case PANGO_UNDERLINE_NONE: - normalInput[i] = false; + indicator[i] = SC_INDICATOR_UNKNOWN; break; case PANGO_UNDERLINE_SINGLE: // normal input - normalInput[i] = true; + indicator[i] = SC_INDICATOR_INPUT; break; case PANGO_UNDERLINE_DOUBLE: case PANGO_UNDERLINE_LOW: @@ -2357,25 +2359,22 @@ void ScintillaGTK::GetImeUnderlines(PangoAttrList *attrs, bool *normalInput) { } while (pango_attr_iterator_next(iterunderline)); pango_attr_iterator_destroy(iterunderline); } -}
-void ScintillaGTK::GetImeBackgrounds(PangoAttrList *attrs, bool *targetInput) { - // Whether background color attribue is or not - // attr position is measured in UTF-8 bytes PangoAttrIterator *itercolor = pango_attr_list_get_iterator(attrs); if (itercolor) { do { PangoAttribute *backcolor = pango_attr_iterator_get(itercolor, PANGO_ATTR_BACKGROUND); if (backcolor) { - glong start = backcolor->start_index; - glong end = backcolor->end_index; + glong start = g_utf8_strlen(u8Str, backcolor->start_index); + glong end = g_utf8_strlen(u8Str, backcolor->end_index); for (glong i=start; i < end; ++i) { - targetInput[i] = true; // target converted + indicator[i] = SC_INDICATOR_TARGET; // target converted } } } while (pango_attr_iterator_next(itercolor)); pango_attr_iterator_destroy(itercolor); } + return indicator; }
void ScintillaGTK::SetCandidateWindowPos() { @@ -2401,23 +2400,13 @@ void ScintillaGTK::CommitThis(char *commitStr) { glong uniStrLen = 0; gunichar *uniStr = g_utf8_to_ucs4_fast(commitStr, strlen(commitStr), &uniStrLen); for (glong i = 0; i < uniStrLen; i++) { + gchar u8Char[UTF8MaxBytes+2] = {0}; + gint u8CharLen = g_unichar_to_utf8(uniStr[i], u8Char); + std::string docChar = u8Char; + if (!IsUnicodeMode()) + docChar = ConvertText(u8Char, u8CharLen, charSetSource, "UTF-8", true);
- gunichar uniChar[1] = {0}; - uniChar[0] = uniStr[i]; - - glong oneCharLen = 0; - gchar *oneChar = g_ucs4_to_utf8(uniChar, 1, NULL, &oneCharLen, NULL); - - if (IsUnicodeMode()) { - // Do nothing ; - } else { - std::string oneCharSTD = ConvertText(oneChar, oneCharLen, charSetSource, "UTF-8", true); - oneCharLen = oneCharSTD.copy(oneChar,oneCharSTD.length(), 0); - oneChar[oneCharLen] = '\0'; - } - - AddCharUTF(oneChar, oneCharLen); - g_free(oneChar); + AddCharUTF(docChar.c_str(), docChar.size()); } g_free(uniStr); ShowCaretAtCurrentPosition(); @@ -2434,6 +2423,11 @@ void ScintillaGTK::PreeditChangedInlineThis() { // Copy & paste by johnsonj with a lot of helps of Neil // Great thanks for my foreruners, jiniya and BLUEnLIVE try { + if (pdoc->IsReadOnly() || SelectionContainsProtected()) { + gtk_im_context_reset(im_context); + return; + } + view.imeCaretBlockOverride = false; // If backspace.
if (pdoc->TentativeActive()) { @@ -2461,64 +2455,38 @@ void ScintillaGTK::PreeditChangedInlineThis() { pdoc->TentativeStart(); // TentativeActive() from now on
// Get preedit string attribues - bool normalInput[maxLenInputIME*3+1] = {false}; - bool targetInput[maxLenInputIME*3+1] = {false}; - GetImeUnderlines(preeditStr.attrs, normalInput); - GetImeBackgrounds(preeditStr.attrs, targetInput); + std::vector<int> indicator = MapImeIndicators(preeditStr.attrs, preeditStr.str);
// Display preedit characters, one by one glong imeCharPos[maxLenInputIME+1] = { 0 }; - glong attrPos = -1; // Start at -1 to designate the last byte of one character. glong charWidth = 0;
bool tmpRecordingMacro = recordingMacro; recordingMacro = false; for (glong i = 0; i < preeditStr.uniStrLen; i++) { + gchar u8Char[UTF8MaxBytes+2] = {0}; + gint u8CharLen = g_unichar_to_utf8(preeditStr.uniStr[i], u8Char); + std::string docChar = u8Char; + if (!IsUnicodeMode()) + docChar = ConvertText(u8Char, u8CharLen, charSetSource, "UTF-8", true);
- gunichar uniChar[1] = {0}; - uniChar[0] = preeditStr.uniStr[i]; - - glong oneCharLen = 0; - gchar *oneChar = g_ucs4_to_utf8(uniChar, 1, NULL, &oneCharLen, NULL); + AddCharUTF(docChar.c_str(), docChar.size());
- // Record attribute positions in UTF-8 bytes - attrPos += oneCharLen; - - if (IsUnicodeMode()) { - // Do nothing - } else { - std::string oneCharSTD = ConvertText(oneChar, oneCharLen, charSetSource, "UTF-8", true); - oneCharLen = oneCharSTD.copy(oneChar,oneCharSTD.length(), 0); - oneChar[oneCharLen] = '\0'; - } + // Draw an indicator on the character, + DrawImeIndicator(indicator[i], docChar.size());
// Record character positions in UTF-8 or DBCS bytes - - charWidth += oneCharLen; + charWidth += docChar.size(); imeCharPos[i+1] = charWidth; - - // Display one character - AddCharUTF(oneChar, oneCharLen); - - // Draw an indicator on the character, - // Overlapping allowed - if (normalInput[attrPos]) { - DrawImeIndicator(SC_INDICATOR_INPUT, oneCharLen); - } - if (targetInput[attrPos]) { - DrawImeIndicator(SC_INDICATOR_TARGET, oneCharLen); - } - g_free(oneChar); } recordingMacro = tmpRecordingMacro;
// Move caret to ime cursor position. + MoveImeCarets( - (imeCharPos[preeditStr.uniStrLen]) + imeCharPos[preeditStr.cursor_pos]); + if (KoreanIME()) { + MoveImeCarets( - imeCharPos[1]); // always 2 bytes for DBCS or 3 bytes for UTF8. view.imeCaretBlockOverride = true; - MoveImeCarets( - (imeCharPos[preeditStr.uniStrLen])); - - } else { - MoveImeCarets( - (imeCharPos[preeditStr.uniStrLen]) + imeCharPos[preeditStr.cursor_pos]); }
EnsureCaretVisible(); @@ -3077,28 +3045,34 @@ sptr_t ScintillaGTK::DirectFunction( return reinterpret_cast<ScintillaGTK *>(ptr)->WndProc(iMessage, wParam, lParam); }
+/* legacy name for scintilla_object_send_message */ GEANY_API_SYMBOL sptr_t scintilla_send_message(ScintillaObject *sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { ScintillaGTK *psci = static_cast<ScintillaGTK *>(sci->pscin); return psci->WndProc(iMessage, wParam, lParam); }
+sptr_t scintilla_object_send_message(ScintillaObject *sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { + return scintilla_send_message(sci, iMessage, wParam, lParam); +} + static void scintilla_class_init(ScintillaClass *klass); static void scintilla_init(ScintillaObject *sci);
extern void Platform_Initialise(); extern void Platform_Finalise();
+/* legacy name for scintilla_object_get_type */ GEANY_API_SYMBOL GType scintilla_get_type() { static GType scintilla_type = 0; try {
if (!scintilla_type) { - scintilla_type = g_type_from_name("Scintilla"); + scintilla_type = g_type_from_name("ScintillaObject"); if (!scintilla_type) { static GTypeInfo scintilla_info = { - (guint16) sizeof (ScintillaClass), + (guint16) sizeof (ScintillaObjectClass), NULL, //(GBaseInitFunc) NULL, //(GBaseFinalizeFunc) (GClassInitFunc) scintilla_class_init, @@ -3109,9 +3083,8 @@ GType scintilla_get_type() { (GInstanceInitFunc) scintilla_init, NULL //(GTypeValueTable*) }; - scintilla_type = g_type_register_static( - GTK_TYPE_CONTAINER, "Scintilla", &scintilla_info, (GTypeFlags) 0); + GTK_TYPE_CONTAINER, "ScintillaObject", &scintilla_info, (GTypeFlags) 0); } }
@@ -3120,6 +3093,10 @@ GType scintilla_get_type() { return scintilla_type; }
+GType scintilla_object_get_type() { + return scintilla_get_type(); +} + void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class) { Platform_Initialise(); #ifdef SCI_LEXER @@ -3135,8 +3112,8 @@ void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_ // of the signal handlers here (those that currently attached to wDraw // in Initialise() may require coordinate translation?)
- object_class->finalize = Destroy; object_class->dispose = Dispose; + object_class->finalize = Destroy; #if GTK_CHECK_VERSION(3,0,0) widget_class->get_preferred_width = GetPreferredWidth; widget_class->get_preferred_height = GetPreferredHeight; @@ -3224,6 +3201,7 @@ static void scintilla_init(ScintillaObject *sci) { } }
+/* legacy name for scintilla_object_new */ GEANY_API_SYMBOL GtkWidget* scintilla_new() { GtkWidget *widget = GTK_WIDGET(g_object_new(scintilla_get_type(), NULL)); @@ -3232,6 +3210,10 @@ GtkWidget* scintilla_new() { return widget; }
+GtkWidget *scintilla_object_new() { + return scintilla_new(); +} + void scintilla_set_id(ScintillaObject *sci, uptr_t id) { ScintillaGTK *psci = static_cast<ScintillaGTK *>(sci->pscin); psci->ctrlID = id;
Modified: scintilla/include/Platform.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -145,7 +145,7 @@ class PRectangle { (pt.y >= top) && (pt.y <= bottom); } bool ContainsWholePixel(Point pt) const { - // Does the rectangle contain all of the pixel to left/below the point + // Does the rectangle contain all of the pixel to left/below the point return (pt.x >= left) && ((pt.x+1) <= right) && (pt.y >= top) && ((pt.y+1) <= bottom); }
Modified: scintilla/include/Scintilla.h 6 lines changed, 6 insertions(+), 0 deletions(-) =================================================================== @@ -506,6 +506,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_WORDSTARTPOSITION 2266 #define SCI_WORDENDPOSITION 2267 #define SCI_ISRANGEWORD 2691 +#define SC_IDLESTYLING_NONE 0 +#define SC_IDLESTYLING_TOVISIBLE 1 +#define SC_IDLESTYLING_AFTERVISIBLE 2 +#define SC_IDLESTYLING_ALL 3 +#define SCI_SETIDLESTYLING 2692 +#define SCI_GETIDLESTYLING 2693 #define SC_WRAP_NONE 0 #define SC_WRAP_WORD 1 #define SC_WRAP_CHAR 2
Modified: scintilla/include/Scintilla.iface 20 lines changed, 16 insertions(+), 4 deletions(-) =================================================================== @@ -249,11 +249,11 @@ enu IMEInteraction=SC_IME_ val SC_IME_WINDOWED=0 val SC_IME_INLINE=1
-# Is the IME displayed in a winow or inline? +# Is the IME displayed in a window or inline? get int GetIMEInteraction=2678(,)
# Choose to display the the IME in a winow or inline. -set void SetIMEInteraction=2679(int imeInteraction,) +set void SetIMEInteraction=2679(int imeInteraction,)
enu MarkerSymbol=SC_MARK_ val MARKER_MAX=31 @@ -1260,6 +1260,18 @@ fun int WordEndPosition=2267(position pos, bool onlyWordCharacters) # Is the range start..end considered a word? fun bool IsRangeWord=2691(position start, position end)
+enu IdleStyling=SC_IDLESTYLING_ +val SC_IDLESTYLING_NONE=0 +val SC_IDLESTYLING_TOVISIBLE=1 +val SC_IDLESTYLING_AFTERVISIBLE=2 +val SC_IDLESTYLING_ALL=3 + +# Sets limits to idle styling. +set void SetIdleStyling=2692(int idleStyling,) + +# Retrieve the limits to idle styling. +get int GetIdleStyling=2693(,) + enu Wrap=SC_WRAP_ val SC_WRAP_NONE=0 val SC_WRAP_WORD=1 @@ -1408,7 +1420,7 @@ val SC_MULTIPASTE_EACH=1 # Change the effect of pasting when there are multiple selections. set void SetMultiPaste=2614(int multiPaste,)
-# Retrieve the effect of pasting when there are multiple selections.. +# Retrieve the effect of pasting when there are multiple selections. get int GetMultiPaste=2615(,)
# Retrieve the value of a tag from a regular expression search. @@ -1977,7 +1989,7 @@ val SC_MULTIAUTOC_EACH=1 # Change the effect of autocompleting when there are multiple selections. set void AutoCSetMulti=2636(int multi,)
-# Retrieve the effect of autocompleting when there are multiple selections.. +# Retrieve the effect of autocompleting when there are multiple selections. get int AutoCGetMulti=2637(,)
enu Ordering=SC_ORDER_
Modified: scintilla/include/ScintillaWidget.h 27 lines changed, 22 insertions(+), 5 deletions(-) =================================================================== @@ -1,8 +1,9 @@ /* Scintilla source code edit control */ -/** @file ScintillaWidget.h - ** Definition of Scintilla widget for GTK+. - ** Only needed by GTK+ code but is harmless on other platforms. - **/ +/* @file ScintillaWidget.h + * Definition of Scintilla widget for GTK+. + * Only needed by GTK+ code but is harmless on other platforms. + * This comment is not a doc-comment as that causes warnings from g-ir-scanner. + */ /* Copyright 1998-2001 by Neil Hodgson neilh@scintilla.org * The License.txt file describes the conditions under which this software may be distributed. */
@@ -19,8 +20,15 @@ extern "C" { #define SCINTILLA_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass) #define IS_SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, scintilla_get_type ())
+#define SCINTILLA_TYPE_OBJECT (scintilla_object_get_type()) +#define SCINTILLA_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SCINTILLA_TYPE_OBJECT, ScintillaObject)) +#define SCINTILLA_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCINTILLA_TYPE_OBJECT)) +#define SCINTILLA_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SCINTILLA_TYPE_OBJECT, ScintillaObjectClass)) +#define SCINTILLA_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SCINTILLA_TYPE_OBJECT)) +#define SCINTILLA_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SCINTILLA_TYPE_OBJECT, ScintillaObjectClass)) + typedef struct _ScintillaObject ScintillaObject; -typedef struct _ScintillaClass ScintillaClass; +typedef struct _ScintillaClass ScintillaObjectClass;
struct _ScintillaObject { GtkContainer cont; @@ -34,11 +42,20 @@ struct _ScintillaClass { void (* notify) (ScintillaObject *ttt); };
+GType scintilla_object_get_type (void); +GtkWidget* scintilla_object_new (void); +long scintilla_object_send_message (ScintillaObject *sci, unsigned int iMessage, guintptr wParam, gintptr lParam); + +#ifndef G_IR_SCANNING +/* The legacy names confuse the g-ir-scanner program */ +typedef struct _ScintillaClass ScintillaClass; + GType scintilla_get_type (void); GtkWidget* scintilla_new (void); void scintilla_set_id (ScintillaObject *sci, uptr_t id); sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam); void scintilla_release_resources(void); +#endif
#define SCINTILLA_NOTIFY "sci-notify"
Modified: scintilla/lexers/LexBash.cxx 82 lines changed, 59 insertions(+), 23 deletions(-) =================================================================== @@ -96,6 +96,19 @@ static int opposite(int ch) { return ch; }
+static int GlobScan(StyleContext &sc) { + // forward scan for a glob-like (...), no whitespace allowed + int c, sLen = 0; + while ((c = sc.GetRelativeCharacter(++sLen)) != 0) { + if (IsASpace(c)) { + return 0; + } else if (c == ')') { + return sLen; + } + } + return 0; +} + static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) {
@@ -113,9 +126,9 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in CharacterSet setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/<?!.~@"); CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn"); CharacterSet setParam(CharacterSet::setAlphaNum, "$_"); - CharacterSet setHereDoc(CharacterSet::setAlpha, "_\-+!"); - CharacterSet setHereDoc2(CharacterSet::setAlphaNum, "_-+!"); - CharacterSet setLeftShift(CharacterSet::setDigits, "=$"); + CharacterSet setHereDoc(CharacterSet::setAlpha, "_\-+!%*,./:?@[]^`{}~"); + CharacterSet setHereDoc2(CharacterSet::setAlphaNum, "_-+!%*,./:=?@[]^`{}~"); + CharacterSet setLeftShift(CharacterSet::setDigits, "$");
class HereDocCls { // Class to manage HERE document elements public: @@ -126,14 +139,13 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in bool Quoted; // true if Quote in (''','"','`') bool Indent; // indented delimiter (for <<-) int DelimiterLength; // strlen(Delimiter) - char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf + char Delimiter[HERE_DELIM_MAX]; // the Delimiter HereDocCls() { State = 0; Quote = 0; Quoted = false; Indent = 0; DelimiterLength = 0; - Delimiter = new char[HERE_DELIM_MAX]; Delimiter[0] = '\0'; } void Append(int ch) { @@ -141,7 +153,6 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in Delimiter[DelimiterLength] = '\0'; } ~HereDocCls() { - delete []Delimiter; } }; HereDocCls HereDoc; @@ -173,18 +184,15 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in int Up, Down; int Style; int Depth; // levels pushed - int *CountStack; - int *UpStack; - int *StyleStack; + int CountStack[BASH_DELIM_STACK_MAX]; + int UpStack [BASH_DELIM_STACK_MAX]; + int StyleStack[BASH_DELIM_STACK_MAX]; QuoteStackCls() { Count = 0; Up = '\0'; Down = '\0'; Style = 0; Depth = 0; - CountStack = new int[BASH_DELIM_STACK_MAX]; - UpStack = new int[BASH_DELIM_STACK_MAX]; - StyleStack = new int[BASH_DELIM_STACK_MAX]; } void Start(int u, int s) { Count = 1; @@ -214,9 +222,6 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in Down = opposite(Up); } ~QuoteStackCls() { - delete []CountStack; - delete []UpStack; - delete []StyleStack; } }; QuoteStackCls QuoteStack; @@ -345,6 +350,8 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in sc.ForwardSetState(SCE_SH_DEFAULT); } else if (!setWord.Contains(sc.ch)) { sc.SetState(SCE_SH_DEFAULT); + } else if (cmdState == BASH_CMD_ARITH && !setWordStart.Contains(sc.ch)) { + sc.SetState(SCE_SH_DEFAULT); } break; case SCE_SH_NUMBER: @@ -419,17 +426,18 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in sc.Forward(); HereDoc.Quoted = true; HereDoc.State = 1; - } else if (setHereDoc.Contains(sc.chNext)) { + } else if (setHereDoc.Contains(sc.chNext) || + (sc.chNext == '=' && cmdState != BASH_CMD_ARITH)) { // an unquoted here-doc delimiter, no special handling - // TODO check what exactly bash considers part of the delim HereDoc.State = 1; } else if (sc.chNext == '<') { // HERE string <<< sc.Forward(); sc.ForwardSetState(SCE_SH_DEFAULT); } else if (IsASpace(sc.chNext)) { // eat whitespace - } else if (setLeftShift.Contains(sc.chNext)) { - // left shift << or <<= operator cases + } else if (setLeftShift.Contains(sc.chNext) || + (sc.chNext == '=' && cmdState == BASH_CMD_ARITH)) { + // left shift <<$var or <<= cases sc.ChangeState(SCE_SH_OPERATOR); sc.ForwardSetState(SCE_SH_DEFAULT); } else { @@ -584,12 +592,14 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in HereDoc.State = 2; if (HereDoc.Quoted) { if (sc.state == SCE_SH_HERE_DELIM) { - // Missing quote at end of string! We are stricter than bash. - // Colour here-doc anyway while marking this bit as an error. + // Missing quote at end of string! Syntax error in bash 4.3 + // Mark this bit as an error, do not colour any here-doc sc.ChangeState(SCE_SH_ERROR); + sc.SetState(SCE_SH_DEFAULT); + } else { + // HereDoc.Quote always == ''' + sc.SetState(SCE_SH_HERE_Q); } - // HereDoc.Quote always == ''' - sc.SetState(SCE_SH_HERE_Q); } else if (HereDoc.DelimiterLength == 0) { // no delimiter, illegal (but '' and "" are legal) sc.ChangeState(SCE_SH_ERROR); @@ -634,6 +644,23 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in } else { sc.SetState(SCE_SH_WORD); } + // handle some zsh features within arithmetic expressions only + if (cmdState == BASH_CMD_ARITH) { + if (sc.chPrev == '[') { // [#8] [##8] output digit setting + sc.SetState(SCE_SH_WORD); + if (sc.chNext == '#') { + sc.Forward(); + } + } else if (sc.Match("##^") && IsUpperCase(sc.GetRelative(3))) { // ##^A + sc.SetState(SCE_SH_IDENTIFIER); + sc.Forward(3); + } else if (sc.chNext == '#' && !IsASpace(sc.GetRelative(2))) { // ##a + sc.SetState(SCE_SH_IDENTIFIER); + sc.Forward(2); + } else if (setWordStart.Contains(sc.chNext)) { // #name + sc.SetState(SCE_SH_IDENTIFIER); + } + } } else if (sc.ch == '"') { sc.SetState(SCE_SH_STRING); QuoteStack.Start(sc.ch, BASH_DELIM_STRING); @@ -687,6 +714,15 @@ static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int in char s[10]; bool isCmdDelim = false; sc.SetState(SCE_SH_OPERATOR); + // globs have no whitespace, do not appear in arithmetic expressions + if (cmdState != BASH_CMD_ARITH && sc.ch == '(' && sc.chNext != '(') { + int i = GlobScan(sc); + if (i > 1) { + sc.SetState(SCE_SH_IDENTIFIER); + sc.Forward(i); + continue; + } + } // handle opening delimiters for test/arithmetic expressions - ((,[[,[ if (cmdState == BASH_CMD_START || cmdState == BASH_CMD_BODY) {
Modified: scintilla/lexers/LexCPP.cxx 6 lines changed, 3 insertions(+), 3 deletions(-) =================================================================== @@ -374,7 +374,7 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
DefineProperty("lexer.cpp.verbatim.strings.allow.escapes", &OptionsCPP::verbatimStringsAllowEscapes, "Set to 1 to allow verbatim strings to contain escape sequences."); - + DefineProperty("lexer.cpp.triplequoted.strings", &OptionsCPP::triplequotedStrings, "Set to 1 to enable highlighting of triple-quoted strings.");
@@ -1467,7 +1467,7 @@ void LexerCPP::EvaluateTokens(std::vectorstd::string &tokens, const SymbolTabl } iMacro++; } - + // Insert results back into tokens tokens.insert(tokens.begin() + i, macroTokens.begin(), macroTokens.end());
@@ -1481,7 +1481,7 @@ void LexerCPP::EvaluateTokens(std::vectorstd::string &tokens, const SymbolTabl tokens.insert(tokens.begin() + i, macroTokens.begin(), macroTokens.end()); } } else { - // Identifier not found + // Identifier not found tokens.erase(tokens.begin() + i); } } else {
Modified: scintilla/lexers/LexCaml.cxx 6 lines changed, 3 insertions(+), 3 deletions(-) =================================================================== @@ -112,7 +112,7 @@ long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long void EXT_LEXER_DECL Fold(unsigned int lexer, Sci_PositionU startPos, Sci_Position length, int initStyle, char *words[], WindowID window, char *props) { - // below useless evaluation(s) to suppress "not used" warnings + // below useless evaluation(s) to supress "not used" warnings lexer; // build expected data structures and do the Fold InternalLexOrFold(1, startPos, length, initStyle, words, window, props); @@ -126,7 +126,7 @@ int EXT_LEXER_DECL GetLexerCount()
void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength) { - // below useless evaluation(s) to suppress "not used" warnings + // below useless evaluation(s) to supress "not used" warnings Index; // return as much of our lexer name as will fit (what's up with Index?) if (buflength > 0) { @@ -141,7 +141,7 @@ void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength) void EXT_LEXER_DECL Lex(unsigned int lexer, Sci_PositionU startPos, Sci_Position length, int initStyle, char *words[], WindowID window, char *props) { - // below useless evaluation(s) to suppress "not used" warnings + // below useless evaluation(s) to supress "not used" warnings lexer; // build expected data structures and do the Lex InternalLexOrFold(0, startPos, length, initStyle, words, window, props);
Modified: scintilla/lexers/LexCmake.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -54,7 +54,7 @@ static bool CmakeNextLineHasElse(Sci_PositionU start, Sci_PositionU end, Accesso } }
- if ( nNextLine == -1 ) // We never found the next line... + if ( nNextLine == -1 ) // We never foudn the next line... return false;
for ( Sci_PositionU firstChar = nNextLine; firstChar < end; firstChar++ ) {
Modified: scintilla/lexers/LexLaTeX.cxx 10 lines changed, 5 insertions(+), 5 deletions(-) =================================================================== @@ -60,7 +60,7 @@ class LexerLaTeX : public LexerBase { if (static_cast<Sci_Position>(modes.size()) > numLines * 2 + 256) modes.resize(numLines + 128); } - + vector<latexFoldSave> saves; void setSave(Sci_Position line, const latexFoldSave &save) { if (line >= static_cast<Sci_Position>(saves.size())) saves.resize(line + 1); @@ -192,7 +192,7 @@ void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int int state = initStyle; if (state == SCE_L_ERROR || state == SCE_L_SHORTCMD || state == SCE_L_SPECIAL) // should not happen latexStateReset(mode, state); - + char chNext = styler.SafeGetCharAt(startPos); char chVerbatimDelim = '\0'; styler.StartSegment(startPos); @@ -207,7 +207,7 @@ void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int chNext = styler.SafeGetCharAt(i + 1); continue; } - + if (ch == '\r' || ch == '\n') setMode(styler.GetLine(i), mode);
@@ -256,7 +256,7 @@ void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int state = SCE_L_COMMENT; break; } - break; + break; // These 3 will never be reached. case SCE_L_ERROR: case SCE_L_SPECIAL: @@ -400,7 +400,7 @@ void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int chNext = styler.SafeGetCharAt(i + 1); mode = 0; state = SCE_L_DEFAULT; - } else { // This may not be an error, e.g. \begin{equation}\text{$a$}\end{equation} + } else { // This may not be an error, e.g. \begin{equation}\text{$a$}\end{equation} styler.ColourTo(i, SCE_L_SHORTCMD); } break;
Modified: scintilla/lexers/LexLua.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -64,7 +64,7 @@ static void ColouriseLuaDoc( // but probably enough in most cases. [pP] is for hex floats. CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP"); CharacterSet setExponent(CharacterSet::setNone, "eEpP"); - CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#"); + CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#&|"); CharacterSet setEscapeSkip(CharacterSet::setNone, ""'\");
Sci_Position currentLine = styler.GetLine(startPos);
Modified: scintilla/lexers/LexMatlab.cxx 10 lines changed, 5 insertions(+), 5 deletions(-) =================================================================== @@ -67,7 +67,7 @@ static void ColouriseMatlabOctaveDoc(
styler.StartAt(startPos);
- // boolean for when the ' is allowed to be transpose vs the start/end + // boolean for when the ' is allowed to be transpose vs the start/end // of a string bool transpose = false;
@@ -86,13 +86,13 @@ static void ColouriseMatlabOctaveDoc( for (; sc.More(); sc.Forward(), column++) {
if(sc.atLineStart) { - // set the line state to the current commentDepth + // set the line state to the current commentDepth curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, commentDepth);
// reset the column to 0, nonSpace to -1 (not set) column = 0; - nonSpaceColumn = -1; + nonSpaceColumn = -1; }
// save the column position of first non space character in a line @@ -111,7 +111,7 @@ static void ColouriseMatlabOctaveDoc( sc.ForwardSetState(SCE_MATLAB_DEFAULT); transpose = true; } else if(sc.ch == '.' && sc.chNext == '.') { - // we werent an operator, but a '...' + // we werent an operator, but a '...' sc.ChangeState(SCE_MATLAB_COMMENT); transpose = false; } else { @@ -165,7 +165,7 @@ static void ColouriseMatlabOctaveDoc( // end or start of a nested a block comment? if( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column) { if(commentDepth > 0) commentDepth --; - + curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, commentDepth); sc.Forward();
Modified: scintilla/lexers/LexPO.cxx 32 lines changed, 16 insertions(+), 16 deletions(-) =================================================================== @@ -41,7 +41,7 @@ static void ColourisePODoc(Sci_PositionU startPos, Sci_Position length, int init Sci_Position curLine = styler.GetLine(startPos); // the line state holds the last state on or before the line that isn't the default style int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : SCE_PO_DEFAULT; - + for (; sc.More(); sc.Forward()) { // whether we should leave a state switch (sc.state) { @@ -57,19 +57,19 @@ static void ColourisePODoc(Sci_PositionU startPos, Sci_Position length, int init // on its own like a keyword rather than changing the whole flags style sc.ChangeState(SCE_PO_FUZZY); break; - + case SCE_PO_MSGCTXT: case SCE_PO_MSGID: case SCE_PO_MSGSTR: if (isspacechar(sc.ch)) sc.SetState(SCE_PO_DEFAULT); break; - + case SCE_PO_ERROR: if (sc.atLineEnd) sc.SetState(SCE_PO_DEFAULT); break; - + case SCE_PO_MSGCTXT_TEXT: case SCE_PO_MSGID_TEXT: case SCE_PO_MSGSTR_TEXT: @@ -92,7 +92,7 @@ static void ColourisePODoc(Sci_PositionU startPos, Sci_Position length, int init } break; } - + // whether we should enter a new state if (sc.state == SCE_PO_DEFAULT) { // forward to the first non-white character on the line @@ -103,11 +103,11 @@ static void ColourisePODoc(Sci_PositionU startPos, Sci_Position length, int init // and anyway the styling don't use line state for comments if (curLineState == SCE_PO_COMMENT) curLineState = SCE_PO_DEFAULT; - + while (sc.More() && ! sc.atLineEnd && isspacechar(sc.ch)) sc.Forward(); } - + if (atLineStart && sc.ch == '#') { if (sc.chNext == '.') sc.SetState(SCE_PO_PROGRAMMER_COMMENT); @@ -134,11 +134,11 @@ static void ColourisePODoc(Sci_PositionU startPos, Sci_Position length, int init sc.SetState(SCE_PO_ERROR); } else if (! isspacechar(sc.ch)) sc.SetState(SCE_PO_ERROR); - + if (sc.state != SCE_PO_DEFAULT) curLineState = sc.state; } - + if (sc.atLineEnd) { // Update the line state, so it can be seen by next line curLine = styler.GetLine(sc.currentPos); @@ -163,7 +163,7 @@ static void FoldPODoc(Sci_PositionU startPos, Sci_Position length, int, WordList return; bool foldCompact = styler.GetPropertyInt("fold.compact") != 0; bool foldComment = styler.GetPropertyInt("fold.comment") != 0; - + Sci_PositionU endPos = startPos + length; Sci_Position curLine = styler.GetLine(startPos); int lineState = styler.GetLineState(curLine); @@ -172,17 +172,17 @@ static void FoldPODoc(Sci_PositionU startPos, Sci_Position length, int, WordList int nextLevel; int visible = 0; int chNext = styler[startPos]; - + for (Sci_PositionU i = startPos; i < endPos; i++) { int ch = chNext; chNext = styler.SafeGetCharAt(i+1); - + if (! isspacechar(ch)) { visible++; } else if ((ch == '\r' && chNext != '\n') || ch == '\n' || i+1 >= endPos) { int lvl = level; Sci_Position nextLine = curLine + 1; - + nextLineState = styler.GetLineState(nextLine); if ((lineState != SCE_PO_COMMENT || foldComment) && nextLineState == lineState && @@ -190,14 +190,14 @@ static void FoldPODoc(Sci_PositionU startPos, Sci_Position length, int, WordList nextLevel = SC_FOLDLEVELBASE + 1; else nextLevel = SC_FOLDLEVELBASE; - + if (nextLevel > level) lvl |= SC_FOLDLEVELHEADERFLAG; if (visible == 0 && foldCompact) lvl |= SC_FOLDLEVELWHITEFLAG; - + styler.SetLevel(curLine, lvl); - + lineState = nextLineState; curLine = nextLine; level = nextLevel;
Modified: scintilla/lexers/LexPerl.cxx 134 lines changed, 107 insertions(+), 27 deletions(-) =================================================================== @@ -52,10 +52,10 @@ using namespace Scintilla;
#define HERE_DELIM_MAX 256 // maximum length of HERE doc delimiter
-#define PERLNUM_BINARY 1 // order is significant: 1-4 cannot have a dot -#define PERLNUM_HEX 2 -#define PERLNUM_OCTAL 3 -#define PERLNUM_FLOAT_EXP 4 // exponent part only +#define PERLNUM_BINARY 1 // order is significant: 1-3 cannot have a dot +#define PERLNUM_OCTAL 2 +#define PERLNUM_FLOAT_EXP 3 // exponent part only +#define PERLNUM_HEX 4 // may be a hex float #define PERLNUM_DECIMAL 5 // 1-5 are numbers; 6-7 are strings #define PERLNUM_VECTOR 6 #define PERLNUM_V_VECTOR 7 @@ -65,6 +65,12 @@ using namespace Scintilla; #define BACK_OPERATOR 1 // whitespace/comments are insignificant #define BACK_KEYWORD 2 // operators/keywords are needed for disambiguation
+#define SUB_BEGIN 0 // states for subroutine prototype scan: +#define SUB_HAS_PROTO 1 // only 'prototype' attribute allows prototypes +#define SUB_HAS_ATTRIB 2 // other attributes can exist leftward +#define SUB_HAS_MODULE 3 // sub name can have a ::identifier part +#define SUB_HAS_SUB 4 // 'sub' keyword + // all interpolated styles are different from their parent styles by a constant difference // we also assume SCE_PL_STRING_VAR is the interpolated style with the smallest value #define INTERPOLATE_SHIFT (SCE_PL_STRING_VAR - SCE_PL_STRING) @@ -105,9 +111,11 @@ static int disambiguateBareword(LexAccessor &styler, Sci_PositionU bk, Sci_Posit // &bareword: subroutine call || styler.Match(bk - 1, "->") // ->bareword: part of variable spec + || styler.Match(bk - 1, "::") + // ::bareword: part of module spec || styler.Match(bk - 2, "sub")) { - // sub bareword: subroutine declaration - // (implied BACK_KEYWORD, no keywords end in 'sub'!) + // sub bareword: subroutine declaration + // (implied BACK_KEYWORD, no keywords end in 'sub'!) result |= 1; } // next, scan forward after word past tab/spaces only; @@ -121,7 +129,7 @@ static int disambiguateBareword(LexAccessor &styler, Sci_PositionU bk, Sci_Posit if ((ch == '}' && brace) // {bareword}: variable spec || styler.Match(fw, "=>")) { - // [{(, bareword=>: hash literal + // [{(, bareword=>: hash literal result |= 2; } } @@ -136,6 +144,22 @@ static void skipWhitespaceComment(LexAccessor &styler, Sci_PositionU &p) { p--; }
+static int findPrevLexeme(LexAccessor &styler, Sci_PositionU &bk, int &style) { + // scan backward past whitespace and comments to find a lexeme + skipWhitespaceComment(styler, bk); + if (bk == 0) + return 0; + int sz = 1; + style = styler.StyleAt(bk); + while (bk > 0) { // find extent of lexeme + if (styler.StyleAt(bk - 1) == style) { + bk--; sz++; + } else + break; + } + return sz; +} + static int styleBeforeBracePair(LexAccessor &styler, Sci_PositionU bk) { // backtrack to find open '{' corresponding to a '}', balanced // return significant style to be tested for '/' disambiguation @@ -214,20 +238,59 @@ static int podLineScan(LexAccessor &styler, Sci_PositionU &pos, Sci_PositionU en
static bool styleCheckSubPrototype(LexAccessor &styler, Sci_PositionU bk) { // backtrack to identify if we're starting a subroutine prototype - // we also need to ignore whitespace/comments: - // 'sub' [whitespace|comment] <identifier> [whitespace|comment] + // we also need to ignore whitespace/comments, format is like: + // sub abc::pqr :const :prototype(...) + // lexemes are tested in pairs, e.g. '::'+'pqr', ':'+'const', etc. + // and a state machine generates legal subroutine syntax matches styler.Flush(); - skipWhitespaceComment(styler, bk); - if (bk == 0 || styler.StyleAt(bk) != SCE_PL_IDENTIFIER) // check identifier - return false; - while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_IDENTIFIER)) { - bk--; - } - skipWhitespaceComment(styler, bk); - if (bk < 2 || styler.StyleAt(bk) != SCE_PL_WORD // check "sub" keyword - || !styler.Match(bk - 2, "sub")) // assume suffix is unique! - return false; - return true; + int state = SUB_BEGIN; + do { + // find two lexemes, lexeme 2 follows lexeme 1 + int style2 = SCE_PL_DEFAULT; + Sci_PositionU pos2 = bk; + int len2 = findPrevLexeme(styler, pos2, style2); + int style1 = SCE_PL_DEFAULT; + Sci_PositionU pos1 = pos2; + if (pos1 > 0) pos1--; + int len1 = findPrevLexeme(styler, pos1, style1); + if (len1 == 0 || len2 == 0) // lexeme pair must exist + break; + + // match parts of syntax, if invalid subroutine syntax, break off + if (style1 == SCE_PL_OPERATOR && len1 == 1 && + styler.SafeGetCharAt(pos1) == ':') { // ':' + if (style2 == SCE_PL_IDENTIFIER || style2 == SCE_PL_WORD) { + if (len2 == 9 && styler.Match(pos2, "prototype")) { // ':' 'prototype' + if (state == SUB_BEGIN) { + state = SUB_HAS_PROTO; + } else + break; + } else { // ':' <attribute> + if (state == SUB_HAS_PROTO || state == SUB_HAS_ATTRIB) { + state = SUB_HAS_ATTRIB; + } else + break; + } + } else + break; + } else if (style1 == SCE_PL_OPERATOR && len1 == 2 && + styler.Match(pos1, "::")) { // '::' + if (style2 == SCE_PL_IDENTIFIER) { // '::' <identifier> + state = SUB_HAS_MODULE; + } else + break; + } else if (style1 == SCE_PL_WORD && len1 == 3 && + styler.Match(pos1, "sub")) { // 'sub' + if (style2 == SCE_PL_IDENTIFIER) { // 'sub' <identifier> + state = SUB_HAS_SUB; + } else + break; + } else + break; + bk = pos1; // set position for finding next lexeme pair + if (bk > 0) bk--; + } while (state != SUB_HAS_SUB); + return (state == SUB_HAS_SUB); }
static int actualNumStyle(int numberStyle) { @@ -537,7 +600,8 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int CharacterSet &setPOD = setModifiers; CharacterSet setNonHereDoc(CharacterSet::setDigits, "=$@"); CharacterSet setHereDocDelim(CharacterSet::setAlphaNum, "_"); - CharacterSet setSubPrototype(CharacterSet::setNone, "\[$@%&*+];"); + CharacterSet setSubPrototype(CharacterSet::setNone, "\[$@%&*+];_ \t"); + CharacterSet setRepetition(CharacterSet::setDigits, ")"'"); // for format identifiers CharacterSet setFormatStart(CharacterSet::setAlpha, "_="); CharacterSet &setFormat = setHereDocDelim; @@ -555,13 +619,12 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int int Quote; // the char after '<<' bool Quoted; // true if Quote in (''','"','`') int DelimiterLength; // strlen(Delimiter) - char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf + char Delimiter[HERE_DELIM_MAX]; // the Delimiter HereDocCls() { State = 0; Quote = 0; Quoted = false; DelimiterLength = 0; - Delimiter = new char[HERE_DELIM_MAX]; Delimiter[0] = '\0'; } void Append(int ch) { @@ -569,7 +632,6 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int Delimiter[DelimiterLength] = '\0'; } ~HereDocCls() { - delete []Delimiter; } }; HereDocCls HereDoc; // TODO: FIFO for stacked here-docs @@ -762,6 +824,14 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int break; } // number then dot (go through) + } else if (numState == PERLNUM_HEX) { + if (dotCount <= 1 && IsADigit(sc.chNext, 16)) { + break; // hex with one dot is a hex float + } else { + sc.SetState(SCE_PL_OPERATOR); + break; + } + // hex then dot (go through) } else if (IsADigit(sc.chNext)) // vectors break; // vector then dot (go through) @@ -780,8 +850,15 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int break; // number then word (go through) } else if (numState == PERLNUM_HEX) { - if (IsADigit(sc.ch, 16)) + if (sc.ch == 'P' || sc.ch == 'p') { // hex float exponent, sign + numState = PERLNUM_FLOAT_EXP; + if (sc.chNext == '+' || sc.chNext == '-') { + sc.Forward(); + } + break; + } else if (IsADigit(sc.ch, 16)) break; + // hex or hex float then word (go through) } else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) { if (IsADigit(sc.ch)) // vector break; @@ -1265,7 +1342,7 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int fw++; } else if (sc.ch == 'x' && (sc.chNext == '=' || // repetition !setWord.Contains(sc.chNext) || - (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) { + (setRepetition.Contains(sc.chPrev) && IsADigit(sc.chNext)))) { sc.ChangeState(SCE_PL_OPERATOR); } // if potentially a keyword, scan forward and grab word, then check @@ -1438,7 +1515,10 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int } backFlag = BACK_NONE; if (isHereDoc) { // handle '<<', HERE doc - if (preferRE) { + if (sc.Match("<<>>")) { // double-diamond operator (5.22) + sc.SetState(SCE_PL_OPERATOR); + sc.Forward(3); + } else if (preferRE) { sc.SetState(SCE_PL_HERE_DELIM); HereDoc.State = 0; } else { // << operator
Modified: scintilla/lexers/LexRust.cxx 6 lines changed, 3 insertions(+), 3 deletions(-) =================================================================== @@ -287,7 +287,7 @@ static void ScanNumber(Accessor& styler, Sci_Position& pos) { } else if (!error) { /* If there's a period, it's a floating point literal unless it's * followed by an identifier (meaning this is a method call, e.g. - * `1.foo()`) or another period, in which case it's a range (e.g. 1..2) + * `1.foo()`) or another period, in which case it's a range (e.g. 1..2) */ n = styler.SafeGetCharAt(pos + 1, '\0'); if (c == '.' && !(IsIdentifierStart(n) || n == '.')) { @@ -308,7 +308,7 @@ static void ScanNumber(Accessor& styler, Sci_Position& pos) { /* It is invalid to have no digits in the exponent. */ error |= !ScanDigits(styler, pos, 10); } - + /* Scan the floating point suffix. */ c = styler.SafeGetCharAt(pos, '\0'); if (c == 'f') { @@ -620,7 +620,7 @@ static void ResumeRawString(Accessor &styler, Sci_Position& pos, Sci_Position ma } else if (pos >= max) { break; } else { - if (ascii_only && !IsASCII((char)c)) + if (ascii_only && !IsASCII((char)c)) break; pos++; }
Modified: scintilla/lexers/LexSQL.cxx 10 lines changed, 5 insertions(+), 5 deletions(-) =================================================================== @@ -567,8 +567,8 @@ void SCI_METHOD LexerSQL::Lex(Sci_PositionU startPos, Sci_Position length, int i break; } } - - char qComplement = 0x00; + + char qComplement = 0x00;
if (qOperator == '<') { qComplement = '>'; @@ -580,8 +580,8 @@ void SCI_METHOD LexerSQL::Lex(Sci_PositionU startPos, Sci_Position length, int i qComplement = ']'; } else { qComplement = qOperator; - } - + } + if (sc.Match(qComplement, ''')) { sc.Forward(); sc.ForwardSetState(SCE_SQL_DEFAULT); @@ -592,7 +592,7 @@ void SCI_METHOD LexerSQL::Lex(Sci_PositionU startPos, Sci_Position length, int i // Determine if a new state should be entered. if (sc.state == SCE_SQL_DEFAULT) { if (sc.Match('q', ''') || sc.Match('Q', ''')) { - sc.SetState(SCE_SQL_QOPERATOR); + sc.SetState(SCE_SQL_QOPERATOR); sc.Forward(); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)) || ((sc.ch == '-' || sc.ch == '+') && IsADigit(sc.chNext) && !IsADigit(sc.chPrev))) {
Modified: scintilla/scintilla_changes.patch 16 lines changed, 8 insertions(+), 8 deletions(-) =================================================================== @@ -4,26 +4,26 @@ diff --git scintilla/gtk/ScintillaGTK.cxx scintilla/gtk/ScintillaGTK.cxx index 0871ca2..49dc278 100644 --- scintilla/gtk/ScintillaGTK.cxx +++ scintilla/gtk/ScintillaGTK.cxx -@@ -3104,6 +3104,7 @@ sptr_t ScintillaGTK::DirectFunction( - return reinterpret_cast<ScintillaGTK *>(ptr)->WndProc(iMessage, wParam, lParam); +@@ -3046,6 +3046,7 @@ sptr_t ScintillaGTK::DirectFunction( }
+ /* legacy name for scintilla_object_send_message */ +GEANY_API_SYMBOL sptr_t scintilla_send_message(ScintillaObject *sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { ScintillaGTK *psci = static_cast<ScintillaGTK *>(sci->pscin); return psci->WndProc(iMessage, wParam, lParam); -@@ -3115,6 +3116,7 @@ static void scintilla_init(ScintillaObject *sci); - extern void Platform_Initialise(); +@@ -3062,6 +3062,7 @@ extern void Platform_Initialise(); extern void Platform_Finalise();
+ /* legacy name for scintilla_object_get_type */ +GEANY_API_SYMBOL GType scintilla_get_type() { static GType scintilla_type = 0; try { -@@ -3252,6 +3254,7 @@ static void scintilla_init(ScintillaObject *sci) { - } +@@ -3200,6 +3200,7 @@ static void scintilla_init(ScintillaObject *sci) { }
+ /* legacy name for scintilla_object_new */ +GEANY_API_SYMBOL GtkWidget* scintilla_new() { GtkWidget *widget = GTK_WIDGET(g_object_new(scintilla_get_type(), NULL)); @@ -57,10 +57,10 @@ index be57b7c..cee3e73 100644 { typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1, diff --git scintilla/src/Catalogue.cxx scintilla/src/Catalogue.cxx -index b02a010..400d423 100644 +index ed47aa8..e58f1ab 100644 --- scintilla/src/Catalogue.cxx +++ scintilla/src/Catalogue.cxx -@@ -76,120 +76,50 @@ int Scintilla_LinkLexers() { +@@ -77,120 +77,50 @@ int Scintilla_LinkLexers() {
//++Autogenerated -- run scripts/LexGen.py to regenerate //**(\tLINK_LEXER(*);\n)
Modified: scintilla/src/CellBuffer.cxx 19 lines changed, 19 insertions(+), 0 deletions(-) =================================================================== @@ -496,6 +496,25 @@ void CellBuffer::SetLineEndTypes(int utf8LineEnds_) { } }
+bool CellBuffer::ContainsLineEnd(const char *s, int length) const { + unsigned char chBeforePrev = 0; + unsigned char chPrev = 0; + for (int i = 0; i < length; i++) { + const unsigned char ch = s[i]; + if ((ch == '\r') || (ch == '\n')) { + return true; + } else if (utf8LineEnds) { + unsigned char back3[3] = { chBeforePrev, chPrev, ch }; + if (UTF8IsSeparator(back3) || UTF8IsNEL(back3 + 1)) { + return true; + } + } + chBeforePrev = chPrev; + chPrev = ch; + } + return false; +} + void CellBuffer::SetPerLine(PerLine *pl) { lv.SetPerLine(pl); }
Modified: scintilla/src/CellBuffer.h 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -177,6 +177,7 @@ class CellBuffer { void Allocate(int newSize); int GetLineEndTypes() const { return utf8LineEnds; } void SetLineEndTypes(int utf8LineEnds_); + bool ContainsLineEnd(const char *s, int length) const; void SetPerLine(PerLine *pl); int Lines() const; int LineStart(int line) const;
Modified: scintilla/src/Document.cxx 42 lines changed, 35 insertions(+), 7 deletions(-) =================================================================== @@ -109,6 +109,7 @@ Document::Document() { useTabs = true; tabIndents = true; backspaceUnindents = false; + durationStyleOneLine = 0.00001;
matchesValid = false; regex = 0; @@ -270,7 +271,7 @@ void Document::TentativeUndo() { bool endSavePoint = cb.IsSavePoint(); if (startSavePoint != endSavePoint) NotifySavePoint(endSavePoint); - + cb.TentativeCommit(); } enteredModification--; @@ -1276,7 +1277,7 @@ int Document::SetLineIndentation(int line, int indent) { int indentPos = GetLineIndentPosition(line); UndoGroup ug(this); DeleteChars(thisLineStart, indentPos - thisLineStart); - return thisLineStart + InsertString(thisLineStart, linebuf.c_str(), + return thisLineStart + InsertString(thisLineStart, linebuf.c_str(), static_cast<int>(linebuf.length())); } else { return GetLineIndentPosition(line); @@ -1892,6 +1893,33 @@ void Document::EnsureStyledTo(int pos) { } }
+void Document::StyleToAdjustingLineDuration(int pos) { + // Place bounds on the duration used to avoid glitches spiking it + // and so causing slow styling or non-responsive scrolling + const double minDurationOneLine = 0.000001; + const double maxDurationOneLine = 0.0001; + + // Alpha value for exponential smoothing. + // Most recent value contributes 25% to smoothed value. + const double alpha = 0.25; + + const Sci_Position lineFirst = LineFromPosition(GetEndStyled()); + ElapsedTime etStyling; + EnsureStyledTo(pos); + const double durationStyling = etStyling.Duration(); + const Sci_Position lineLast = LineFromPosition(GetEndStyled()); + if (lineLast >= lineFirst + 8) { + // Only adjust for styling multiple lines to avoid instability + const double durationOneLine = durationStyling / (lineLast - lineFirst); + durationStyleOneLine = alpha * durationOneLine + (1.0 - alpha) * durationStyleOneLine; + if (durationStyleOneLine < minDurationOneLine) { + durationStyleOneLine = minDurationOneLine; + } else if (durationStyleOneLine > maxDurationOneLine) { + durationStyleOneLine = maxDurationOneLine; + } + } +} + void Document::LexerChanged() { // Tell the watchers the lexer has changed. for (std::vector<WatcherWithUserData>::iterator it = watchers.begin(); it != watchers.end(); ++it) { @@ -2187,7 +2215,7 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) { char chSeek = BraceOpposite(chBrace); if (chSeek == '\0') return - 1; - char styBrace = static_cast<char>(StyleAt(position)); + const int styBrace = StyleIndexAt(position); int direction = -1; if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<') direction = 1; @@ -2195,7 +2223,7 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) { position = NextPosition(position, direction); while ((position >= 0) && (position < Length())) { char chAtPos = CharAt(position); - char styAtPos = static_cast<char>(StyleAt(position)); + const int styAtPos = StyleIndexAt(position); if ((position > GetEndStyled()) || (styAtPos == styBrace)) { if (chAtPos == chBrace) depth++; @@ -2526,10 +2554,10 @@ class UTF8Iterator : public std::iterator<std::bidirectional_iterator_tag, wchar return doc != other.doc || position != other.position; } int Pos() const { - return position; + return position; } int PosRoundUp() const { - return position; + return position; } };
@@ -2626,7 +2654,7 @@ long Cxx11RegexFindText(Document *doc, int minPos, int maxPos, const char *s, std::wregex regexp; #if defined(__APPLE__) // Using a UTF-8 locale doesn't change to Unicode over a byte buffer so '.' - // is one byte not one character. + // is one byte not one character. // However, on OS X this makes wregex act as Unicode std::locale localeU("en_US.UTF-8"); regexp.imbue(localeU);
Modified: scintilla/src/Document.h 8 lines changed, 6 insertions(+), 2 deletions(-) =================================================================== @@ -246,6 +246,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { bool useTabs; bool tabIndents; bool backspaceUnindents; + double durationStyleOneLine;
DecorationList decorations;
@@ -272,6 +273,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader {
Sci_Position SCI_METHOD LineFromPosition(Sci_Position pos) const; int ClampPositionIntoDocument(int pos) const; + bool ContainsLineEnd(const char *s, int length) const { return cb.ContainsLineEnd(s, length); } bool IsCrLf(int pos) const; int LenChar(int pos); bool InGoodUTF8(int pos, int &start, int &end) const; @@ -339,6 +341,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { cb.GetCharRange(buffer, position, lengthRetrieve); } char SCI_METHOD StyleAt(Sci_Position position) const { return cb.StyleAt(position); } + int StyleIndexAt(Sci_Position position) const { return static_cast<unsigned char>(cb.StyleAt(position)); } void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const { cb.GetStyleRange(buffer, position, lengthRetrieve); } @@ -375,7 +378,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { struct CharacterExtracted { unsigned int character; unsigned int widthBytes; - CharacterExtracted(unsigned int character_, unsigned int widthBytes_) : + CharacterExtracted(unsigned int character_, unsigned int widthBytes_) : character(character_), widthBytes(widthBytes_) { } }; @@ -400,6 +403,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { bool SCI_METHOD SetStyles(Sci_Position length, const char *styles); int GetEndStyled() const { return endStyled; } void EnsureStyledTo(int pos); + void StyleToAdjustingLineDuration(int pos); void LexerChanged(); int GetStyleClock() const { return styleClock; } void IncrementStyleClock(); @@ -425,7 +429,7 @@ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { void AnnotationSetStyles(int line, const unsigned char *styles); int AnnotationLines(int line) const; void AnnotationClearAll(); - + bool AddWatcher(DocWatcher *watcher, void *userData); bool RemoveWatcher(DocWatcher *watcher, void *userData);
Modified: scintilla/src/EditModel.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -42,7 +42,7 @@ class EditModel { Selection sel; bool primarySelection;
- enum IMEInteraction { imeWindowed, imeInline } imeInteraction; + enum IMEInteraction { imeWindowed, imeInline } imeInteraction;
int foldFlags; ContractionState cs;
Modified: scintilla/src/EditView.cxx 21 lines changed, 10 insertions(+), 11 deletions(-) =================================================================== @@ -376,14 +376,14 @@ void EditView::LayoutLine(const EditModel &model, int line, Surface *surface, co // See if chars, styles, indicators, are all the same bool allSame = true; // Check base line layout - char styleByte = 0; + int styleByte = 0; int numCharsInLine = 0; while (numCharsInLine < lineLength) { int charInDoc = numCharsInLine + posLineStart; char chDoc = model.pdoc->CharAt(charInDoc); - styleByte = model.pdoc->StyleAt(charInDoc); + styleByte = model.pdoc->StyleIndexAt(charInDoc); allSame = allSame && - (ll->styles[numCharsInLine] == static_cast<unsigned char>(styleByte)); + (ll->styles[numCharsInLine] == styleByte); if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseMixed) allSame = allSame && (ll->chars[numCharsInLine] == chDoc); @@ -394,7 +394,7 @@ void EditView::LayoutLine(const EditModel &model, int line, Surface *surface, co allSame = allSame && (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc))); else { // Style::caseCamel - if ((model.pdoc->WordCharClass(ll->chars[numCharsInLine]) == CharClassify::ccWord) && + if ((model.pdoc->WordCharClass(ll->chars[numCharsInLine]) == CharClassify::ccWord) && ((numCharsInLine == 0) || (model.pdoc->WordCharClass(ll->chars[numCharsInLine - 1]) != CharClassify::ccWord))) { allSame = allSame && (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc))); } else { @@ -444,13 +444,13 @@ void EditView::LayoutLine(const EditModel &model, int line, Surface *surface, co else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseLower) ll->chars[charInLine] = static_cast<char>(tolower(chDoc)); else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseCamel) { - if ((model.pdoc->WordCharClass(ll->chars[charInLine]) == CharClassify::ccWord) && + if ((model.pdoc->WordCharClass(ll->chars[charInLine]) == CharClassify::ccWord) && ((charInLine == 0) || (model.pdoc->WordCharClass(ll->chars[charInLine - 1]) != CharClassify::ccWord))) { ll->chars[charInLine] = static_cast<char>(toupper(chDoc)); } else { ll->chars[charInLine] = static_cast<char>(tolower(chDoc)); } - } + } } } ll->xHighlightGuide = 0; @@ -986,11 +986,10 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS startPos = deco->rs.EndRun(startPos); } while ((startPos < posLineEnd) && (deco->rs.ValueAt(startPos))) { - int endPos = deco->rs.EndRun(startPos); - if (endPos > posLineEnd) - endPos = posLineEnd; + const Range rangeRun(deco->rs.StartRun(startPos), deco->rs.EndRun(startPos)); + const int endPos = std::min(rangeRun.end, posLineEnd); const bool hover = vsDraw.indicators[deco->indicator].IsDynamic() && - ((hoverIndicatorPos >= startPos) && (hoverIndicatorPos <= endPos)); + rangeRun.ContainsCharacter(hoverIndicatorPos); const int value = deco->rs.ValueAt(startPos); Indicator::DrawState drawState = hover ? Indicator::drawHover : Indicator::drawNormal; DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart, @@ -1476,7 +1475,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi if (indicatorValue) { const Indicator &indicator = vsDraw.indicators[deco->indicator]; const bool hover = indicator.IsDynamic() && - ((model.hoverIndicatorPos >= ts.start + posLineStart) && + ((model.hoverIndicatorPos >= ts.start + posLineStart) && (model.hoverIndicatorPos <= ts.end() + posLineStart)); if (hover) { if (indicator.sacHover.style == INDIC_TEXTFORE) {
Modified: scintilla/src/Editor.cxx 158 lines changed, 118 insertions(+), 40 deletions(-) =================================================================== @@ -173,6 +173,8 @@ Editor::Editor() { paintAbandonedByStyling = false; paintingAllText = false; willRedrawAll = false; + idleStyling = SC_IDLESTYLING_NONE; + needIdleStyling = false;
modEventMask = SC_MODEVENTMASKALL;
@@ -762,7 +764,7 @@ bool Editor::RangeContainsProtected(int start, int end) const { end = t; } for (int pos = start; pos < end; pos++) { - if (vs.styles[pdoc->StyleAt(pos)].IsProtected()) + if (vs.styles[pdoc->StyleIndexAt(pos)].IsProtected()) return true; } } @@ -792,15 +794,15 @@ SelectionPosition Editor::MovePositionOutsideChar(SelectionPosition pos, int mov pos.SetPosition(posMoved); if (vs.ProtectionActive()) { if (moveDir > 0) { - if ((pos.Position() > 0) && vs.styles[pdoc->StyleAt(pos.Position() - 1)].IsProtected()) { + if ((pos.Position() > 0) && vs.styles[pdoc->StyleIndexAt(pos.Position() - 1)].IsProtected()) { while ((pos.Position() < pdoc->Length()) && - (vs.styles[pdoc->StyleAt(pos.Position())].IsProtected())) + (vs.styles[pdoc->StyleIndexAt(pos.Position())].IsProtected())) pos.Add(1); } } else if (moveDir < 0) { - if (vs.styles[pdoc->StyleAt(pos.Position())].IsProtected()) { + if (vs.styles[pdoc->StyleIndexAt(pos.Position())].IsProtected()) { while ((pos.Position() > 0) && - (vs.styles[pdoc->StyleAt(pos.Position() - 1)].IsProtected())) + (vs.styles[pdoc->StyleIndexAt(pos.Position() - 1)].IsProtected())) pos.Add(-1); } } @@ -919,7 +921,7 @@ void Editor::ScrollTo(int line, bool moveThumb) { SetTopLine(topLineNew); // Optimize by styling the view as this will invalidate any needed area // which could abort the initial paint if discovered later. - StyleToPositionInView(PositionAfterArea(GetClientRectangle())); + StyleAreaBounded(GetClientRectangle(), true); #ifndef UNDER_CE // Perform redraw rather than scroll if many lines would be redrawn anyway. if (performBlit) { @@ -1692,7 +1694,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
paintAbandonedByStyling = false;
- StyleToPositionInView(PositionAfterArea(rcArea)); + StyleAreaBounded(rcArea, false);
PRectangle rcClient = GetClientRectangle(); //Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d) %d\n", @@ -1954,6 +1956,8 @@ void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) {
void Editor::ClearBeforeTentativeStart() { // Make positions for the first composition string. + FilterSelections(); + UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike); for (size_t r = 0; r<sel.Count(); r++) { if (!RangeContainsProtected(sel.Range(r).Start().Position(), sel.Range(r).End().Position())) { @@ -2575,21 +2579,24 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) { } if ((mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) && cs.HiddenLines()) { // Some lines are hidden so may need shown. - // TODO: check if the modified area is hidden. + const int lineOfPos = pdoc->LineFromPosition(mh.position); + int endNeedShown = mh.position; if (mh.modificationType & SC_MOD_BEFOREINSERT) { - int lineOfPos = pdoc->LineFromPosition(mh.position); - bool insertingNewLine = false; - for (int i=0; i < mh.length; i++) { - if ((mh.text[i] == '\n') || (mh.text[i] == '\r')) - insertingNewLine = true; - } - if (insertingNewLine && (mh.position != pdoc->LineStart(lineOfPos))) - NeedShown(mh.position, pdoc->LineStart(lineOfPos+1) - mh.position); - else - NeedShown(mh.position, 0); + if (pdoc->ContainsLineEnd(mh.text, mh.length) && (mh.position != pdoc->LineStart(lineOfPos))) + endNeedShown = pdoc->LineStart(lineOfPos+1); } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { - NeedShown(mh.position, mh.length); + // Extend the need shown area over any folded lines + endNeedShown = mh.position + mh.length; + int lineLast = pdoc->LineFromPosition(mh.position+mh.length); + for (int line = lineOfPos; line <= lineLast; line++) { + const int lineMaxSubord = pdoc->GetLastChild(line, -1, -1); + if (lineLast < lineMaxSubord) { + lineLast = lineMaxSubord; + endNeedShown = pdoc->LineEnd(lineLast); + } + } } + NeedShown(mh.position, endNeedShown - mh.position); } if (mh.linesAdded != 0) { // Update contraction state for inserted and removed lines @@ -3109,7 +3116,7 @@ void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) { const SelectionPosition spCaretNow = sel.Range(r).caret; const SelectionPosition posNew = MovePositionSoVisible( PositionUpOrDown(spCaretNow, direction, lastX), direction); - sel.Range(r) = selt == Selection::selStream ? + sel.Range(r) = selt == Selection::selStream ? SelectionRange(posNew, sel.Range(r).anchor) : SelectionRange(posNew); } sel.RemoveDuplicates(); @@ -3475,7 +3482,7 @@ int Editor::DelWordOrLine(unsigned int iMessage) { // which means 2 actions so wrap in an undo group.
// Rightwards and leftwards deletions differ in treatment of virtual space. - // Clear virtual space for leftwards, realise for rightwards. + // Clear virtual space for leftwards, realise for rightwards. const bool leftwards = (iMessage == SCI_DELWORDLEFT) || (iMessage == SCI_DELLINELEFT);
if (!additionalSelectionTyping) { @@ -3494,7 +3501,7 @@ int Editor::DelWordOrLine(unsigned int iMessage) { sel.Range(r) = SelectionRange( InsertSpace(sel.Range(r).caret.Position(), sel.Range(r).caret.VirtualSpace())); } - + Range rangeDelete; switch (iMessage) { case SCI_DELWORDLEFT: @@ -4556,7 +4563,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b }
bool Editor::PositionIsHotspot(int position) const { - return vs.styles[static_cast<unsigned char>(pdoc->StyleAt(position))].hotspot; + return vs.styles[pdoc->StyleIndexAt(position)].hotspot; }
bool Editor::PointIsHotspot(Point pt) { @@ -4581,10 +4588,7 @@ void Editor::SetHoverIndicatorPosition(int position) { } } if (hoverIndicatorPosPrev != hoverIndicatorPos) { - if (hoverIndicatorPosPrev != INVALID_POSITION) - InvalidateRange(hoverIndicatorPosPrev, hoverIndicatorPosPrev + 1); - if (hoverIndicatorPos != INVALID_POSITION) - InvalidateRange(hoverIndicatorPos, hoverIndicatorPos + 1); + Redraw(); } }
@@ -4882,17 +4886,15 @@ void Editor::Tick() { }
bool Editor::Idle() { + bool needWrap = Wrapping() && wrapPending.NeedsWrap();
- bool idleDone; - - bool wrappingDone = !Wrapping(); - - if (!wrappingDone) { + if (needWrap) { // Wrap lines during idle. WrapLines(wsIdle); // No more wrapping - if (!wrapPending.NeedsWrap()) - wrappingDone = true; + needWrap = wrapPending.NeedsWrap(); + } else if (needIdleStyling) { + IdleStyling(); }
// Add more idle things to do here, but make sure idleDone is @@ -4900,7 +4902,7 @@ bool Editor::Idle() { // false will stop calling this idle function until SetIdle() is // called again.
- idleDone = wrappingDone; // && thatDone && theOtherThingDone... + const bool idleDone = !needWrap && !needIdleStyling; // && thatDone && theOtherThingDone...
return !idleDone; } @@ -4991,9 +4993,9 @@ void Editor::StyleToPositionInView(Position pos) { int endWindow = PositionAfterArea(GetClientDrawingRectangle()); if (pos > endWindow) pos = endWindow; - int styleAtEnd = pdoc->StyleAt(pos-1); + const int styleAtEnd = pdoc->StyleIndexAt(pos-1); pdoc->EnsureStyledTo(pos); - if ((endWindow > pos) && (styleAtEnd != pdoc->StyleAt(pos-1))) { + if ((endWindow > pos) && (styleAtEnd != pdoc->StyleIndexAt(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 @@ -5003,12 +5005,71 @@ void Editor::StyleToPositionInView(Position pos) { } }
+int Editor::PositionAfterMaxStyling(int posMax, bool scrolling) const { + if ((idleStyling == SC_IDLESTYLING_NONE) || (idleStyling == SC_IDLESTYLING_AFTERVISIBLE)) { + // Both states do not limit styling + return posMax; + } + + // Try to keep time taken by styling reasonable so interaction remains smooth. + // When scrolling, allow less time to ensure responsive + const double secondsAllowed = scrolling ? 0.005 : 0.02; + + const int linesToStyle = Platform::Clamp(static_cast<int>(secondsAllowed / pdoc->durationStyleOneLine), + 10, 0x10000); + const int stylingMaxLine = std::min( + static_cast<int>(pdoc->LineFromPosition(pdoc->GetEndStyled()) + linesToStyle), + pdoc->LinesTotal()); + return std::min(static_cast<int>(pdoc->LineStart(stylingMaxLine)), posMax); +} + +void Editor::StartIdleStyling(bool truncatedLastStyling) { + if ((idleStyling == SC_IDLESTYLING_ALL) || (idleStyling == SC_IDLESTYLING_AFTERVISIBLE)) { + if (pdoc->GetEndStyled() < pdoc->Length()) { + // Style remainder of document in idle time + needIdleStyling = true; + } + } else if (truncatedLastStyling) { + needIdleStyling = true; + } + + if (needIdleStyling) { + SetIdle(true); + } +} + +// Style for an area but bound the amount of styling to remain responsive +void Editor::StyleAreaBounded(PRectangle rcArea, bool scrolling) { + const int posAfterArea = PositionAfterArea(rcArea); + const int posAfterMax = PositionAfterMaxStyling(posAfterArea, scrolling); + if (posAfterMax < posAfterArea) { + // Idle styling may be performed before current visible area + // Style a bit now then style further in idle time + pdoc->StyleToAdjustingLineDuration(posAfterMax); + } else { + // Can style all wanted now. + StyleToPositionInView(posAfterArea); + } + StartIdleStyling(posAfterMax < posAfterArea); +} + +void Editor::IdleStyling() { + const int posAfterArea = PositionAfterArea(GetClientRectangle()); + const int endGoal = (idleStyling >= SC_IDLESTYLING_AFTERVISIBLE) ? + pdoc->Length() : posAfterArea; + const int posAfterMax = PositionAfterMaxStyling(endGoal, false); + pdoc->StyleToAdjustingLineDuration(posAfterMax); + if (pdoc->GetEndStyled() >= endGoal) { + needIdleStyling = false; + } +} + void Editor::IdleWork() { // Style the line after the modification as this allows modifications that change just the // line of the modification to heal instead of propagating to the rest of the window. - if (workNeeded.items & WorkNeeded::workStyle) + if (workNeeded.items & WorkNeeded::workStyle) { StyleToPositionInView(pdoc->LineStart(pdoc->LineFromPosition(workNeeded.upTo) + 2)); - + } NotifyUpdateUI(); workNeeded.Reset(); } @@ -6401,6 +6462,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_ISRANGEWORD: return pdoc->IsWordAt(static_cast<int>(wParam), static_cast<int>(lParam));
+ case SCI_SETIDLESTYLING: + idleStyling = static_cast<int>(wParam); + break; + + case SCI_GETIDLESTYLING: + return idleStyling; + case SCI_SETWRAPMODE: if (vs.SetWrapState(static_cast<int>(wParam))) { xOffset = 0; @@ -6599,7 +6667,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_GETIMEINTERACTION: return imeInteraction; - + #ifdef INCLUDE_DEPRECATED_FEATURES case SCI_SETUSEPALETTE: InvalidateStyleRedraw(); @@ -7760,6 +7828,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_CLEARSELECTIONS: sel.Clear(); + ContainerNeedsUpdate(SC_UPDATE_SELECTION); Redraw(); break;
@@ -7770,16 +7839,19 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_ADDSELECTION: sel.AddSelection(SelectionRange(static_cast<int>(wParam), static_cast<int>(lParam))); + ContainerNeedsUpdate(SC_UPDATE_SELECTION); Redraw(); break;
case SCI_DROPSELECTIONN: sel.DropSelection(static_cast<int>(wParam)); + ContainerNeedsUpdate(SC_UPDATE_SELECTION); Redraw(); break;
case SCI_SETMAINSELECTION: sel.SetMain(static_cast<int>(wParam)); + ContainerNeedsUpdate(SC_UPDATE_SELECTION); Redraw(); break;
@@ -7788,6 +7860,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_SETSELECTIONNCARET: sel.Range(wParam).caret.SetPosition(static_cast<int>(lParam)); + ContainerNeedsUpdate(SC_UPDATE_SELECTION); Redraw(); break;
@@ -7796,6 +7869,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_SETSELECTIONNANCHOR: sel.Range(wParam).anchor.SetPosition(static_cast<int>(lParam)); + ContainerNeedsUpdate(SC_UPDATE_SELECTION); Redraw(); break; case SCI_GETSELECTIONNANCHOR: @@ -7803,6 +7877,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_SETSELECTIONNCARETVIRTUALSPACE: sel.Range(wParam).caret.SetVirtualSpace(static_cast<int>(lParam)); + ContainerNeedsUpdate(SC_UPDATE_SELECTION); Redraw(); break;
@@ -7811,6 +7886,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_SETSELECTIONNANCHORVIRTUALSPACE: sel.Range(wParam).anchor.SetVirtualSpace(static_cast<int>(lParam)); + ContainerNeedsUpdate(SC_UPDATE_SELECTION); Redraw(); break;
@@ -7819,6 +7895,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_SETSELECTIONNSTART: sel.Range(wParam).anchor.SetPosition(static_cast<int>(lParam)); + ContainerNeedsUpdate(SC_UPDATE_SELECTION); Redraw(); break;
@@ -7827,6 +7904,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_SETSELECTIONNEND: sel.Range(wParam).caret.SetPosition(static_cast<int>(lParam)); + ContainerNeedsUpdate(SC_UPDATE_SELECTION); Redraw(); break;
Modified: scintilla/src/Editor.h 8 lines changed, 7 insertions(+), 1 deletions(-) =================================================================== @@ -36,7 +36,7 @@ class Idler {
/** * When platform has a way to generate an event before painting, - * accumulate needed styling range and other work items in + * accumulate needed styling range and other work items in * WorkNeeded to avoid unnecessary work inside paint handler */ class WorkNeeded { @@ -234,6 +234,8 @@ class Editor : public EditModel, public DocWatcher { bool paintingAllText; bool willRedrawAll; WorkNeeded workNeeded; + int idleStyling; + bool needIdleStyling;
int modEventMask;
@@ -525,6 +527,10 @@ class Editor : public EditModel, public DocWatcher {
int PositionAfterArea(PRectangle rcArea) const; void StyleToPositionInView(Position pos); + int PositionAfterMaxStyling(int posMax, bool scrolling) const; + void StartIdleStyling(bool truncatedLastStyling); + void StyleAreaBounded(PRectangle rcArea, bool scrolling); + void IdleStyling(); virtual void IdleWork(); virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo=0);
Modified: scintilla/src/Indicator.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -128,7 +128,7 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r rcBox.top = rcLine.top + 1; rcBox.left = rc.left; rcBox.right = rc.right; - surface->AlphaRectangle(rcBox, (sacDraw.style == INDIC_ROUNDBOX) ? 1 : 0, + surface->AlphaRectangle(rcBox, (sacDraw.style == INDIC_ROUNDBOX) ? 1 : 0, sacDraw.fore, fillAlpha, sacDraw.fore, outlineAlpha, 0); } else if (sacDraw.style == INDIC_DOTBOX) { PRectangle rcBox = PixelGridAlign(rc);
Modified: scintilla/src/PerLine.cxx 3 lines changed, 1 insertions(+), 2 deletions(-) =================================================================== @@ -410,8 +410,7 @@ const unsigned char *LineAnnotation::Styles(int line) const {
static char *AllocateAnnotation(int length, int style) { size_t len = sizeof(AnnotationHeader) + length + ((style == IndividualStyles) ? length : 0); - char *ret = new char[len]; - memset(ret, 0, len); + char *ret = new char[len](); return ret; }
Modified: scintilla/src/ScintillaBase.cxx 4 lines changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -276,7 +276,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { } PRectangle rcac; rcac.left = pt.x - ac.lb->CaretFromEdge(); - if (pt.y >= rcPopupBounds.bottom - heightLB && // Wont fit below. + if (pt.y >= rcPopupBounds.bottom - heightLB && // Won't fit below. pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above. rcac.top = pt.y - heightLB; if (rcac.top < rcPopupBounds.top) { @@ -305,7 +305,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { // Make an allowance for large strings in list rcList.left = pt.x - ac.lb->CaretFromEdge(); rcList.right = rcList.left + widthLB; - if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Wont fit below. + if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Won't fit below. ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above. rcList.top = pt.y - heightAlloced; } else {
Modified: scintilla/src/UniConversion.cxx 4 lines changed, 0 insertions(+), 4 deletions(-) =================================================================== @@ -19,10 +19,6 @@ using namespace Scintilla; namespace Scintilla { #endif
-enum { SURROGATE_TRAIL_FIRST = 0xDC00 }; -enum { SURROGATE_TRAIL_LAST = 0xDFFF }; -enum { SUPPLEMENTAL_PLANE_FIRST = 0x10000 }; - unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen) { unsigned int len = 0; for (unsigned int i = 0; i < tlen && uptr[i];) {
Modified: scintilla/src/UniConversion.h 4 lines changed, 4 insertions(+), 0 deletions(-) =================================================================== @@ -57,6 +57,10 @@ inline bool UTF8IsNEL(const unsigned char *us) {
enum { SURROGATE_LEAD_FIRST = 0xD800 }; enum { SURROGATE_LEAD_LAST = 0xDBFF }; +enum { SURROGATE_TRAIL_FIRST = 0xDC00 }; +enum { SURROGATE_TRAIL_LAST = 0xDFFF }; +enum { SUPPLEMENTAL_PLANE_FIRST = 0x10000 }; + inline unsigned int UTF16CharLength(wchar_t uch) { return ((uch >= SURROGATE_LEAD_FIRST) && (uch <= SURROGATE_LEAD_LAST)) ? 2 : 1; }
Modified: scintilla/version.txt 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -1 +1 @@ -362 +363
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).