Regular expression matching in errorlist lexer

Neil <[email protected]> Wed, 12 Nov 2025 16:05:42 -0800 (PST)
Newsgroups gmane.comp.lib.scintilla.devel
Message-ID <[email protected]>
Users and app developers may encounter new diagnostic patterns that are not 
recognized by the errorlist lexer. A new setting and style would allow 
styling these diagnostics using a regular expression. Attached are a rough 
patch that implements lexer.errorlist.regex and an image showing the result 
of lexer.errorlist.regex=Error +\d+

Neil
[image: ErrorListRegEx.png]

-- 
You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/scintilla-interest/ecb6deb7-1175-4872-91dd-3d2e01f66392n%40googlegroups.com.
regex.patch (text/plain, 2.8 KB)
diff --git a/lexers/LexErrorList.cxx b/lexers/LexErrorList.cxx
index 2198a142..2269ebe4 100644
--- a/lexers/LexErrorList.cxx
+++ b/lexers/LexErrorList.cxx
@@ -14,11 +14,13 @@
 #include <string>
 #include <string_view>
 #include <initializer_list>
+#include <regex>
 
 #include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "PropSetSimple.h"
 #include "InList.h"
 #include "WordList.h"
 #include "LexAccessor.h"
@@ -351,12 +353,15 @@ int StyleFromSequence(const char *seq) noexcept {
 	return style;
 }
 
+#define SCE_ERR_REGEX 27
+
 void ColouriseErrorListLine(
     const std::string &lineBuffer,
     Sci_PositionU endPos,
     Accessor &styler,
 	bool valueSeparate,
-	bool escapeSequences) {
+	bool escapeSequences,
+	const std::string &regexUser) {
 	Sci_Position startValue = -1;
 	const Sci_PositionU lengthLine = lineBuffer.length();
 	const int style = RecogniseErrorListLine(lineBuffer.c_str(), lengthLine, startValue);
@@ -393,6 +398,19 @@ void ColouriseErrorListLine(
 		}
 		styler.ColourTo(endPos, portionStyle);
 	} else {
+		if (!regexUser.empty()) {
+			std::regex regex(regexUser, std::regex_constants::ECMAScript);
+			std::smatch match;
+			if (std::regex_search(lineBuffer, match, regex)) {
+				const size_t lineStart = endPos - lengthLine;
+				const size_t startRegularExpression = match.position();
+				const size_t endRegularExpression = match.position() + match.length();
+				styler.ColourTo(lineStart + startRegularExpression, style);
+				styler.ColourTo(lineStart + endRegularExpression, SCE_ERR_REGEX);
+				styler.ColourTo(endPos, style);
+				return;
+			}
+		}
 		if (valueSeparate && (startValue >= 0)) {
 			styler.ColourTo(endPos - (lengthLine - startValue), style);
 			styler.ColourTo(endPos, SCE_ERR_VALUE);
@@ -418,16 +436,20 @@ void ColouriseErrorListDoc(Sci_PositionU startPos, Sci_Position length, int, Wor
 	//	Set to 1 to interpret escape sequences.
 	const bool escapeSequences = styler.GetPropertyInt("lexer.errorlist.escape.sequences") != 0;
 
+	// property lexer.errorlist.regex
+	//	Set to non empty to highlight a regular expression.
+	const std::string regexUser = styler.pprops->Get("lexer.errorlist.regex");
+
 	for (Sci_PositionU i = startPos; i < startPos + length; i++) {
 		lineBuffer.push_back(styler[i]);
 		if (AtEOL(styler, i)) {
 			// End of line met, colourise it
-			ColouriseErrorListLine(lineBuffer, i, styler, valueSeparate, escapeSequences);
+			ColouriseErrorListLine(lineBuffer, i, styler, valueSeparate, escapeSequences, regexUser);
 			lineBuffer.clear();
 		}
 	}
 	if (!lineBuffer.empty()) {	// Last line does not have ending characters
-		ColouriseErrorListLine(lineBuffer, startPos + length - 1, styler, valueSeparate, escapeSequences);
+		ColouriseErrorListLine(lineBuffer, startPos + length - 1, styler, valueSeparate, escapeSequences, regexUser);
 	}
 }
ErrorListRegEx.png (image/png, 25 KB) - not displayed