[geany/geany] 99938d: Update Scintilla to version 3.6.3

Colomban Wendling git-noreply at xxxxx
Mon Jan 18 03:22:26 UTC 2016


Branch:      refs/heads/master
Author:      Colomban Wendling <ban at herbesfolles.org>
Committer:   Colomban Wendling <ban at herbesfolles.org>
Date:        Mon, 18 Jan 2016 03:22:26 UTC
Commit:      99938dd821efb4b920db029a509b1a42ef86ea3c
             https://github.com/geany/geany/commit/99938dd821efb4b920db029a509b1a42ef86ea3c

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 at 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::vector<std::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::vector<std::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).


More information about the Commits mailing list