Text Editor: update syntax highlighting for different Python strings

Python has several different string types [0], each using a prefix to
indicate the type. Presently Blender's Text Editor / syntax highlighting
does not include the prefix as part of the string, which makes the
prefix appear as a syntax error. This patch looks for these prefixes,
and includes them with the string highlighting.

Note: prefixes can appear in either case (ex: f and F mean the same
thing), and some prefixes can be combined (ex: fr is a raw f-string).

[0]: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals

Ref D14739
This commit is contained in:
Jon Denning
2023-04-06 13:59:36 +10:00
committed by Campbell Barton
parent 68092297ca
commit bbf756ddf1

View File

@@ -425,6 +425,49 @@ static void txtfmt_py_format_line(SpaceText *st, TextLine *line, const bool do_n
}
*fmt = FMT_TYPE_STRING;
}
else if (ELEM(*str, 'f', 'F', 'r', 'R', 'u', 'U') && ELEM(*(str + 1), '"', '\'')) {
/* Strings with single letter prefixes (f-strings, raw strings, and unicode strings).
* Format the prefix as part of the string. */
*fmt = FMT_TYPE_STRING;
fmt++;
str++;
find = *str;
cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE;
if (*(str + 1) == find && *(str + 2) == find) {
*fmt = FMT_TYPE_STRING;
fmt++;
str++;
*fmt = FMT_TYPE_STRING;
fmt++;
str++;
cont |= FMT_CONT_TRIPLE;
}
*fmt = FMT_TYPE_STRING;
}
else if (((ELEM(*str, 'f', 'F') && ELEM(*(str + 1), 'r', 'R')) ||
(ELEM(*str, 'r', 'R') && ELEM(*(str + 1), 'f', 'F'))) &&
ELEM(*(str + 2), '"', '\'')) {
/* Strings with two letter prefixes (raw f-strings).
* Format the prefix as part of the string. */
*fmt = FMT_TYPE_STRING;
fmt++;
str++;
*fmt = FMT_TYPE_STRING;
fmt++;
str++;
find = *str;
cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE;
if (*(str + 1) == find && *(str + 2) == find) {
*fmt = FMT_TYPE_STRING;
fmt++;
str++;
*fmt = FMT_TYPE_STRING;
fmt++;
str++;
cont |= FMT_CONT_TRIPLE;
}
*fmt = FMT_TYPE_STRING;
}
/* White-space (all white-space has been converted to spaces). */
else if (*str == ' ') {
*fmt = FMT_TYPE_WHITESPACE;