diff -r 5693714a8b0b src/Catalogue.cxx --- a/src/Catalogue.cxx Fri Dec 06 16:19:52 2013 +1100 +++ b/src/Catalogue.cxx Sun Dec 15 21:21:20 2013 -0500 @@ -74,6 +74,7 @@ // Shorten the code that declares a lexer and ensures it is linked in by calling a method. #define LINK_LEXER(lexer) extern LexerModule lexer; Catalogue::AddLexerModule(&lexer); +#if 0 //++Autogenerated -- run scripts/LexGen.py to regenerate //**\(\tLINK_LEXER(\*);\n\) LINK_LEXER(lmA68k); @@ -187,6 +188,8 @@ LINK_LEXER(lmYAML); //--Autogenerated -- end of automatically generated section +#endif + LINK_LEXER(lmLPeg); return 1; } diff -r eb69b2b4bb85 gtk/ScintillaGTK.cxx --- a/gtk/ScintillaGTK.cxx Mon Jan 18 09:02:53 2016 +1100 +++ b/gtk/ScintillaGTK.cxx Wed Jan 20 00:52:11 2016 -0500 @@ -3110,7 +3110,7 @@ // of the signal handlers here (those that currently attached to wDraw // in Initialise() may require coordinate translation?) - object_class->dispose = Dispose; + //object_class->dispose = Dispose; object_class->finalize = Destroy; #if GTK_CHECK_VERSION(3,0,0) widget_class->get_preferred_width = GetPreferredWidth; diff -r bfdfb44eb777 src/Document.cxx --- a/src/Document.cxx Sun May 22 08:57:20 2016 +1000 +++ b/src/Document.cxx Mon Jul 04 15:23:05 2016 -0400 @@ -2845,3 +2845,157 @@ #endif #endif + +#include "tre.h" + +class TreRegex : public RegexSearchBase { +public: + explicit TreRegex() : lastS(NULL), lastSLen(0), lastSFlags(0) {} + virtual ~TreRegex() { if (lastS) free(lastS), tre_regfree(&preg); } + virtual long FindText(Document *doc, int minPos, int maxPos, const char *s, + bool caseSensitive, bool word, bool wordStart, int flags, + int *length); + virtual const char *SubstituteByPosition(Document *doc, const char *text, + int *length); +private: + char *lastS; + int lastSLen, lastSFlags; + regex_t preg; + regmatch_t pmatch[10]; + std::string substituted; +}; + +long TreRegex::FindText(Document *doc, int minPos, int maxPos, const char *s, + bool caseSensitive, bool, bool, int, + int *length) { + // Determine the search range. (From Document.cxx::RESearchRange.) + int increment, startPos, endPos; + if (minPos <= maxPos) + increment = 1, startPos = minPos, endPos = maxPos; + else + increment = -1, startPos = maxPos, endPos = minPos; + // Range endpoints should not be inside DBCS characters, but just in case, + // move them. + startPos = doc->MovePositionOutsideChar(startPos, 1, false); + endPos = doc->MovePositionOutsideChar(endPos, 1, false); + int lineRangeStart = doc->LineFromPosition(startPos); + int lineRangeEnd = doc->LineFromPosition(endPos); + if (increment == 1 && startPos >= doc->LineEnd(lineRangeStart) && + lineRangeStart < lineRangeEnd) { + // The start position is at end of line or between line end characters. + lineRangeStart++; + startPos = doc->LineStart(lineRangeStart); + } else if (increment == -1 && startPos <= doc->LineStart(lineRangeStart) && + lineRangeStart > lineRangeEnd) { + // The start position is at beginning of line. + lineRangeStart--; + startPos = doc->LineEnd(lineRangeStart); + } + + // Compile the regex or used the cached one. + int cflags = REG_EXTENDED | (!caseSensitive ? REG_ICASE : 0) | REG_NEWLINE; + if (!lastS || lastSLen != *length || lastSFlags != cflags || strncmp(lastS, s, *length) != 0) { + if (tre_regncomp(&preg, s, *length, cflags) != REG_OK) return -1; + if (lastS) free(lastS); + lastS = static_cast(malloc(*length + 1)); + strncpy(lastS, s, *length); + lastS[*length] = '\0'; + lastSLen = *length, lastSFlags = cflags; + } + + // Perform the matching. + int pos = -1, lenRet = 0; + const char *string = doc->BufferPointer(); + size_t len = endPos - startPos; + int eflags = ((startPos != doc->LineStart(lineRangeStart)) ? REG_NOTBOL : 0) | + ((endPos != doc->LineEnd(lineRangeEnd)) ? REG_NOTEOL : 0); + int success = tre_regnexec(&preg, string + startPos, len, 10, pmatch, eflags) == REG_OK; + if (success) { + for (int i = 0; i < 10 && pmatch[i].rm_so != -1; i++) + pmatch[i].rm_so += startPos, pmatch[i].rm_eo += startPos; // adjust + pos = pmatch[0].rm_so, lenRet = pmatch[0].rm_eo - pmatch[0].rm_so; + if (increment == -1) { + // Check for the last match on this line. + int repetitions = 1000; // break out of infinite loop + while (success && pmatch[0].rm_eo <= endPos && repetitions--) { + success = tre_regnexec(&preg, string + pos + 1, len - (pos + 1), 10, + pmatch, eflags) == REG_OK; + if (success) { + for (int i = 0; i < 10 && pmatch[i].rm_so != -1; i++) + pmatch[i].rm_so += pos + 1, pmatch[i].rm_eo += pos + 1; // adjust + if (pmatch[0].rm_eo <= minPos) + pos = pmatch[0].rm_so, lenRet = pmatch[0].rm_eo - pmatch[0].rm_so; + else + success = 0; + } + } + } + } + *length = lenRet; + return pos; +} + +const char *TreRegex::SubstituteByPosition(Document *doc, const char *text, + int *length) { + substituted.clear(); + for (int j = 0; j < *length; j++) { + if (text[j] == '\\') { + if (text[j + 1] >= '0' && text[j + 1] <= '9') { + unsigned int patNum = text[j + 1] - '0'; + unsigned int len = pmatch[patNum].rm_eo - pmatch[patNum].rm_so; + if (len > 0) // will be -1 for a match that did not occur + substituted.append(doc->BufferPointer() + pmatch[patNum].rm_so, len); + j++; + } else { + j++; + switch (text[j]) { + case 'a': + substituted.push_back('\a'); + break; + case 'b': + substituted.push_back('\b'); + break; + case 'f': + substituted.push_back('\f'); + break; + case 'n': + substituted.push_back('\n'); + break; + case 'r': + substituted.push_back('\r'); + break; + case 't': + substituted.push_back('\t'); + break; + case 'v': + substituted.push_back('\v'); + break; + case '\\': + substituted.push_back('\\'); + break; + default: + substituted.push_back('\\'); + j--; + } + } + } else { + substituted.push_back(text[j]); + } + } + *length = static_cast(substituted.length()); + return substituted.c_str(); +} + +#ifdef SCI_NAMESPACE + +RegexSearchBase *Scintilla::CreateRegexSearch(CharClassify *charClassTable) { + return new TreRegex(); +} + +#else + +RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable) { + return new TreRegex(); +} + +#endif diff -r e99b1a2bfbf8 src/Editor.cxx --- a/src/Editor.cxx Thu Feb 16 08:37:09 2017 +1100 +++ b/src/Editor.cxx Wed Feb 22 11:37:10 2017 -0500 @@ -3111,6 +3111,9 @@ } void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) { + if ((selt == Selection::noSel) && sel.MoveExtends()) { + selt = Selection::selStream; + } SelectionPosition caretToUse = sel.Range(sel.Main()).caret; if (sel.IsRectangular()) { if (selt == Selection::noSel) {