diff options
-rw-r--r-- | doc/ScintillaHistory.html | 4 | ||||
-rw-r--r-- | include/SciLexer.h | 18 | ||||
-rw-r--r-- | include/Scintilla.iface | 18 | ||||
-rw-r--r-- | lexers/LexErrorList.cxx | 91 |
4 files changed, 124 insertions, 7 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index eb5a3958c..765e281d5 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -502,6 +502,10 @@ <a href="http://sourceforge.net/p/scintilla/bugs/1749/">Bug #1749</a>. </li> <li> + The errorlist lexer understands some ANSI escape sequences to change foreground colour and intensity. + This is sufficient to colour diagnotic output from gcc and clang when -fdiagnostics-color set. + </li> + <li> MySql lexer fixes empty comments /**/ so the comment state does not continue. </li> <li> diff --git a/include/SciLexer.h b/include/SciLexer.h index 57c15cb33..2103b47b9 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -498,6 +498,24 @@ #define SCE_ERR_JAVA_STACK 20 #define SCE_ERR_VALUE 21 #define SCE_ERR_GCC_INCLUDED_FROM 22 +#define SCE_ERR_ESCSEQ 23 +#define SCE_ERR_ESCSEQ_UNKNOWN 24 +#define SCE_ERR_ES_BLACK 40 +#define SCE_ERR_ES_RED 41 +#define SCE_ERR_ES_GREEN 42 +#define SCE_ERR_ES_BROWN 43 +#define SCE_ERR_ES_BLUE 44 +#define SCE_ERR_ES_MAGENTA 45 +#define SCE_ERR_ES_CYAN 46 +#define SCE_ERR_ES_GRAY 47 +#define SCE_ERR_ES_DARK_GRAY 48 +#define SCE_ERR_ES_BRIGHT_RED 49 +#define SCE_ERR_ES_BRIGHT_GREEN 50 +#define SCE_ERR_ES_YELLOW 51 +#define SCE_ERR_ES_BRIGHT_BLUE 52 +#define SCE_ERR_ES_BRIGHT_MAGENTA 53 +#define SCE_ERR_ES_BRIGHT_CYAN 54 +#define SCE_ERR_ES_WHITE 55 #define SCE_BAT_DEFAULT 0 #define SCE_BAT_COMMENT 1 #define SCE_BAT_WORD 2 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 99ac27597..d7a39e92d 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -3202,6 +3202,24 @@ val SCE_ERR_TIDY=19 val SCE_ERR_JAVA_STACK=20 val SCE_ERR_VALUE=21 val SCE_ERR_GCC_INCLUDED_FROM=22 +val SCE_ERR_ESCSEQ=23 +val SCE_ERR_ESCSEQ_UNKNOWN=24 +val SCE_ERR_ES_BLACK=40 +val SCE_ERR_ES_RED=41 +val SCE_ERR_ES_GREEN=42 +val SCE_ERR_ES_BROWN=43 +val SCE_ERR_ES_BLUE=44 +val SCE_ERR_ES_MAGENTA=45 +val SCE_ERR_ES_CYAN=46 +val SCE_ERR_ES_GRAY=47 +val SCE_ERR_ES_DARK_GRAY=48 +val SCE_ERR_ES_BRIGHT_RED=49 +val SCE_ERR_ES_BRIGHT_GREEN=50 +val SCE_ERR_ES_YELLOW=51 +val SCE_ERR_ES_BRIGHT_BLUE=52 +val SCE_ERR_ES_BRIGHT_MAGENTA=53 +val SCE_ERR_ES_BRIGHT_CYAN=54 +val SCE_ERR_ES_WHITE=55 # Lexical states for SCLEX_BATCH lex Batch=SCLEX_BATCH SCE_BAT_ val SCE_BAT_DEFAULT=0 diff --git a/lexers/LexErrorList.cxx b/lexers/LexErrorList.cxx index be85cdc8f..28348dfe2 100644 --- a/lexers/LexErrorList.cxx +++ b/lexers/LexErrorList.cxx @@ -259,19 +259,91 @@ static int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLi } } +#define CSI "\033[" + +namespace { + +bool SequenceEnd(int ch) { + return (ch == 0) || ((ch >= '@') && (ch <= '~')); +} + +int StyleFromSequence(const char *seq) { + int bold = 0; + int colour = 0; + while (!SequenceEnd(*seq)) { + if (Is0To9(*seq)) { + int base = *seq - '0'; + if (Is0To9(seq[1])) { + base = base * 10; + base += seq[1] - '0'; + seq++; + } + if (base == 0) { + colour = 0; + bold = 0; + } + else if (base == 1) { + bold = 1; + } + else if (base >= 30 && base <= 37) { + colour = base - 30; + } + } + seq++; + } + return SCE_ERR_ES_BLACK + bold * 8 + colour; +} + +} + static void ColouriseErrorListLine( char *lineBuffer, Sci_PositionU lengthLine, Sci_PositionU endPos, Accessor &styler, - bool valueSeparate) { + bool valueSeparate, + bool escapeSequences) { Sci_Position startValue = -1; int style = RecogniseErrorListLine(lineBuffer, lengthLine, startValue); - if (valueSeparate && (startValue >= 0)) { - styler.ColourTo(endPos - (lengthLine - startValue), style); - styler.ColourTo(endPos, SCE_ERR_VALUE); + if (escapeSequences && strstr(lineBuffer, CSI)) { + const int startPos = endPos - lengthLine; + const char *linePortion = lineBuffer; + int startPortion = startPos; + int portionStyle = style; + while (const char *startSeq = strstr(linePortion, CSI)) { + if (startSeq > linePortion) { + styler.ColourTo(startPortion + (startSeq - linePortion), portionStyle); + } + const char *endSeq = startSeq + 2; + while (!SequenceEnd(*endSeq)) + endSeq++; + const int endSeqPosition = startPortion + (endSeq - linePortion) + 1; + switch (*endSeq) { + case 0: + styler.ColourTo(endPos, SCE_ERR_ESCSEQ_UNKNOWN); + return; + case 'm': // Colour command + styler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ); + portionStyle = StyleFromSequence(startSeq+2); + break; + case 'K': // Erase to end of line -> ignore + styler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ); + break; + default: + styler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ_UNKNOWN); + portionStyle = style; + } + startPortion = endSeqPosition; + linePortion = endSeq + 1; + } + styler.ColourTo(endPos, portionStyle); } else { - styler.ColourTo(endPos, style); + if (valueSeparate && (startValue >= 0)) { + styler.ColourTo(endPos - (lengthLine - startValue), style); + styler.ColourTo(endPos, SCE_ERR_VALUE); + } else { + styler.ColourTo(endPos, style); + } } } @@ -287,17 +359,22 @@ static void ColouriseErrorListDoc(Sci_PositionU startPos, Sci_Position length, i // line with style 21 used for the rest of the line. // This allows matched text to be more easily distinguished from its location. bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0; + + // property lexer.errorlist.escape.sequences + // Set to 1 to interpret escape sequences. + const bool escapeSequences = styler.GetPropertyInt("lexer.errorlist.escape.sequences") != 0; + for (Sci_PositionU i = startPos; i < startPos + length; i++) { lineBuffer[linePos++] = styler[i]; if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it lineBuffer[linePos] = '\0'; - ColouriseErrorListLine(lineBuffer, linePos, i, styler, valueSeparate); + ColouriseErrorListLine(lineBuffer, linePos, i, styler, valueSeparate, escapeSequences); linePos = 0; } } if (linePos > 0) { // Last line does not have ending characters - ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler, valueSeparate); + ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler, valueSeparate, escapeSequences); } } |