summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2021-02-03 14:47:34 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2021-02-03 14:47:34 -0500
commitad9559da432f1ea84f1f350f0edf42b94fe79d4c (patch)
tree1b0720afcd3c5032aed56c109fcc4cfa65fcce9f
parent986040bc48a271b693ac81814b3c4607da6db1a3 (diff)
python syntax highlighting
-rw-r--r--keywords.h48
-rw-r--r--keywords.py33
-rw-r--r--syntax.c114
-rw-r--r--ted.cfg1
-rw-r--r--ted.h9
5 files changed, 202 insertions, 3 deletions
diff --git a/keywords.h b/keywords.h
index b9d80f1..77291bd 100644
--- a/keywords.h
+++ b/keywords.h
@@ -129,3 +129,51 @@ static Keyword const *const syntax_all_keywords_rust[] = {
['A'] = syntax_keywords_rust_A, ['B'] = syntax_keywords_rust_B, ['C'] = syntax_keywords_rust_C, ['D'] = syntax_keywords_rust_D, ['E'] = syntax_keywords_rust_E, ['F'] = syntax_keywords_rust_F, ['I'] = syntax_keywords_rust_I, ['N'] = syntax_keywords_rust_N, ['O'] = syntax_keywords_rust_O, ['P'] = syntax_keywords_rust_P, ['R'] = syntax_keywords_rust_R, ['S'] = syntax_keywords_rust_S, ['T'] = syntax_keywords_rust_T, ['U'] = syntax_keywords_rust_U, ['V'] = syntax_keywords_rust_V, ['a'] = syntax_keywords_rust_a, ['b'] = syntax_keywords_rust_b, ['c'] = syntax_keywords_rust_c, ['d'] = syntax_keywords_rust_d, ['e'] = syntax_keywords_rust_e, ['f'] = syntax_keywords_rust_f, ['g'] = syntax_keywords_rust_g, ['i'] = syntax_keywords_rust_i, ['l'] = syntax_keywords_rust_l, ['m'] = syntax_keywords_rust_m, ['o'] = syntax_keywords_rust_o, ['p'] = syntax_keywords_rust_p, ['r'] = syntax_keywords_rust_r, ['s'] = syntax_keywords_rust_s, ['t'] = syntax_keywords_rust_t, ['u'] = syntax_keywords_rust_u, ['v'] = syntax_keywords_rust_v, ['w'] = syntax_keywords_rust_w, ['y'] = syntax_keywords_rust_y
};
+static Keyword const syntax_keywords_python_A[4] = {{"ArithmeticError", SYNTAX_BUILTIN},{"AssertionError", SYNTAX_BUILTIN},{"AttributeError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_B[6] = {{"BaseException", SYNTAX_BUILTIN},{"BlockingIOError", SYNTAX_BUILTIN},{"BrokenPipeError", SYNTAX_BUILTIN},{"BufferError", SYNTAX_BUILTIN},{"BytesWarning", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_C[6] = {{"ChildProcessError", SYNTAX_BUILTIN},{"ConnectionAbortedError", SYNTAX_BUILTIN},{"ConnectionError", SYNTAX_BUILTIN},{"ConnectionRefusedError", SYNTAX_BUILTIN},{"ConnectionResetError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_D[2] = {{"DeprecationWarning", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_E[5] = {{"EOFError", SYNTAX_BUILTIN},{"Ellipsis", SYNTAX_BUILTIN},{"EnvironmentError", SYNTAX_BUILTIN},{"Exception", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_F[7] = {{"False", SYNTAX_CONSTANT},{"False", SYNTAX_BUILTIN},{"FileExistsError", SYNTAX_BUILTIN},{"FileNotFoundError", SYNTAX_BUILTIN},{"FloatingPointError", SYNTAX_BUILTIN},{"FutureWarning", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_G[2] = {{"GeneratorExit", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_I[8] = {{"IOError", SYNTAX_BUILTIN},{"ImportError", SYNTAX_BUILTIN},{"ImportWarning", SYNTAX_BUILTIN},{"IndentationError", SYNTAX_BUILTIN},{"IndexError", SYNTAX_BUILTIN},{"InterruptedError", SYNTAX_BUILTIN},{"IsADirectoryError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_K[3] = {{"KeyError", SYNTAX_BUILTIN},{"KeyboardInterrupt", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_L[2] = {{"LookupError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_M[3] = {{"MemoryError", SYNTAX_BUILTIN},{"ModuleNotFoundError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_N[7] = {{"None", SYNTAX_CONSTANT},{"NameError", SYNTAX_BUILTIN},{"None", SYNTAX_BUILTIN},{"NotADirectoryError", SYNTAX_BUILTIN},{"NotImplemented", SYNTAX_BUILTIN},{"NotImplementedError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_O[3] = {{"OSError", SYNTAX_BUILTIN},{"OverflowError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_P[4] = {{"PendingDeprecationWarning", SYNTAX_BUILTIN},{"PermissionError", SYNTAX_BUILTIN},{"ProcessLookupError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_R[6] = {{"RecursionError", SYNTAX_BUILTIN},{"ReferenceError", SYNTAX_BUILTIN},{"ResourceWarning", SYNTAX_BUILTIN},{"RuntimeError", SYNTAX_BUILTIN},{"RuntimeWarning", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_S[7] = {{"StopAsyncIteration", SYNTAX_BUILTIN},{"StopIteration", SYNTAX_BUILTIN},{"SyntaxError", SYNTAX_BUILTIN},{"SyntaxWarning", SYNTAX_BUILTIN},{"SystemError", SYNTAX_BUILTIN},{"SystemExit", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_T[6] = {{"True", SYNTAX_CONSTANT},{"TabError", SYNTAX_BUILTIN},{"TimeoutError", SYNTAX_BUILTIN},{"True", SYNTAX_BUILTIN},{"TypeError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_U[8] = {{"UnboundLocalError", SYNTAX_BUILTIN},{"UnicodeDecodeError", SYNTAX_BUILTIN},{"UnicodeEncodeError", SYNTAX_BUILTIN},{"UnicodeError", SYNTAX_BUILTIN},{"UnicodeTranslateError", SYNTAX_BUILTIN},{"UnicodeWarning", SYNTAX_BUILTIN},{"UserWarning", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_V[2] = {{"ValueError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_W[3] = {{"Warning", SYNTAX_BUILTIN},{"WindowsError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_Z[2] = {{"ZeroDivisionError", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python__[9] = {{"__build_class__", SYNTAX_BUILTIN},{"__debug__", SYNTAX_BUILTIN},{"__doc__", SYNTAX_BUILTIN},{"__import__", SYNTAX_BUILTIN},{"__loader__", SYNTAX_BUILTIN},{"__name__", SYNTAX_BUILTIN},{"__package__", SYNTAX_BUILTIN},{"__spec__", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_a[10] = {{"and", SYNTAX_KEYWORD},{"as", SYNTAX_KEYWORD},{"assert", SYNTAX_KEYWORD},{"async", SYNTAX_KEYWORD},{"await", SYNTAX_KEYWORD},{"abs", SYNTAX_BUILTIN},{"all", SYNTAX_BUILTIN},{"any", SYNTAX_BUILTIN},{"ascii", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_b[7] = {{"break", SYNTAX_KEYWORD},{"bin", SYNTAX_BUILTIN},{"bool", SYNTAX_BUILTIN},{"breakpoint", SYNTAX_BUILTIN},{"bytearray", SYNTAX_BUILTIN},{"bytes", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_c[10] = {{"class", SYNTAX_KEYWORD},{"continue", SYNTAX_KEYWORD},{"callable", SYNTAX_BUILTIN},{"chr", SYNTAX_BUILTIN},{"classmethod", SYNTAX_BUILTIN},{"compile", SYNTAX_BUILTIN},{"complex", SYNTAX_BUILTIN},{"copyright", SYNTAX_BUILTIN},{"credits", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_d[7] = {{"def", SYNTAX_KEYWORD},{"del", SYNTAX_KEYWORD},{"delattr", SYNTAX_BUILTIN},{"dict", SYNTAX_BUILTIN},{"dir", SYNTAX_BUILTIN},{"divmod", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_e[8] = {{"elif", SYNTAX_KEYWORD},{"else", SYNTAX_KEYWORD},{"except", SYNTAX_KEYWORD},{"enumerate", SYNTAX_BUILTIN},{"eval", SYNTAX_BUILTIN},{"exec", SYNTAX_BUILTIN},{"exit", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_f[8] = {{"finally", SYNTAX_KEYWORD},{"for", SYNTAX_KEYWORD},{"from", SYNTAX_KEYWORD},{"filter", SYNTAX_BUILTIN},{"float", SYNTAX_BUILTIN},{"format", SYNTAX_BUILTIN},{"frozenset", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_g[4] = {{"global", SYNTAX_KEYWORD},{"getattr", SYNTAX_BUILTIN},{"globals", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_h[5] = {{"hasattr", SYNTAX_BUILTIN},{"hash", SYNTAX_BUILTIN},{"help", SYNTAX_BUILTIN},{"hex", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_i[11] = {{"if", SYNTAX_KEYWORD},{"import", SYNTAX_KEYWORD},{"in", SYNTAX_KEYWORD},{"is", SYNTAX_KEYWORD},{"id", SYNTAX_BUILTIN},{"input", SYNTAX_BUILTIN},{"int", SYNTAX_BUILTIN},{"isinstance", SYNTAX_BUILTIN},{"issubclass", SYNTAX_BUILTIN},{"iter", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_l[6] = {{"lambda", SYNTAX_KEYWORD},{"len", SYNTAX_BUILTIN},{"license", SYNTAX_BUILTIN},{"list", SYNTAX_BUILTIN},{"locals", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_m[5] = {{"map", SYNTAX_BUILTIN},{"max", SYNTAX_BUILTIN},{"memoryview", SYNTAX_BUILTIN},{"min", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_n[4] = {{"nonlocal", SYNTAX_KEYWORD},{"not", SYNTAX_KEYWORD},{"next", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_o[6] = {{"or", SYNTAX_KEYWORD},{"object", SYNTAX_BUILTIN},{"oct", SYNTAX_BUILTIN},{"open", SYNTAX_BUILTIN},{"ord", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_p[5] = {{"pass", SYNTAX_KEYWORD},{"pow", SYNTAX_BUILTIN},{"print", SYNTAX_BUILTIN},{"property", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_q[2] = {{"quit", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_r[7] = {{"raise", SYNTAX_KEYWORD},{"return", SYNTAX_KEYWORD},{"range", SYNTAX_BUILTIN},{"repr", SYNTAX_BUILTIN},{"reversed", SYNTAX_BUILTIN},{"round", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_s[9] = {{"set", SYNTAX_BUILTIN},{"setattr", SYNTAX_BUILTIN},{"slice", SYNTAX_BUILTIN},{"sorted", SYNTAX_BUILTIN},{"staticmethod", SYNTAX_BUILTIN},{"str", SYNTAX_BUILTIN},{"sum", SYNTAX_BUILTIN},{"super", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_t[4] = {{"try", SYNTAX_KEYWORD},{"tuple", SYNTAX_BUILTIN},{"type", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_v[2] = {{"vars", SYNTAX_BUILTIN}};
+static Keyword const syntax_keywords_python_w[3] = {{"while", SYNTAX_KEYWORD},{"with", SYNTAX_KEYWORD}};
+static Keyword const syntax_keywords_python_y[2] = {{"yield", SYNTAX_KEYWORD}};
+static Keyword const syntax_keywords_python_z[2] = {{"zip", SYNTAX_BUILTIN}};
+static Keyword const *const syntax_all_keywords_python[] = {
+ ['A'] = syntax_keywords_python_A, ['B'] = syntax_keywords_python_B, ['C'] = syntax_keywords_python_C, ['D'] = syntax_keywords_python_D, ['E'] = syntax_keywords_python_E, ['F'] = syntax_keywords_python_F, ['G'] = syntax_keywords_python_G, ['I'] = syntax_keywords_python_I, ['K'] = syntax_keywords_python_K, ['L'] = syntax_keywords_python_L, ['M'] = syntax_keywords_python_M, ['N'] = syntax_keywords_python_N, ['O'] = syntax_keywords_python_O, ['P'] = syntax_keywords_python_P, ['R'] = syntax_keywords_python_R, ['S'] = syntax_keywords_python_S, ['T'] = syntax_keywords_python_T, ['U'] = syntax_keywords_python_U, ['V'] = syntax_keywords_python_V, ['W'] = syntax_keywords_python_W, ['Z'] = syntax_keywords_python_Z, ['_'] = syntax_keywords_python__, ['a'] = syntax_keywords_python_a, ['b'] = syntax_keywords_python_b, ['c'] = syntax_keywords_python_c, ['d'] = syntax_keywords_python_d, ['e'] = syntax_keywords_python_e, ['f'] = syntax_keywords_python_f, ['g'] = syntax_keywords_python_g, ['h'] = syntax_keywords_python_h, ['i'] = syntax_keywords_python_i, ['l'] = syntax_keywords_python_l, ['m'] = syntax_keywords_python_m, ['n'] = syntax_keywords_python_n, ['o'] = syntax_keywords_python_o, ['p'] = syntax_keywords_python_p, ['q'] = syntax_keywords_python_q, ['r'] = syntax_keywords_python_r, ['s'] = syntax_keywords_python_s, ['t'] = syntax_keywords_python_t, ['v'] = syntax_keywords_python_v, ['w'] = syntax_keywords_python_w, ['y'] = syntax_keywords_python_y, ['z'] = syntax_keywords_python_z
+};
+
diff --git a/keywords.py b/keywords.py
index b4645cb..199912f 100644
--- a/keywords.py
+++ b/keywords.py
@@ -183,7 +183,37 @@ builtins_rust = [
'f32', 'f64', 'bool', 'char', 'str',
]
constants_rust = ['false', 'true']
-
+
+
+
+constants_python = ['False', 'None', 'True']
+keywords_python = ['await', 'else', 'import', 'pass', 'break', 'except', 'in', 'raise', 'class', 'finally',
+ 'is', 'return', 'and', 'continue', 'for', 'lambda', 'try', 'as', 'def', 'from', 'nonlocal',
+ 'while', 'assert', 'del', 'global', 'not', 'with', 'async', 'elif', 'if', 'or', 'yield',
+]
+builtins_python = ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError',
+ 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError',
+ 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
+ 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError',
+ 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning',
+ 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt',
+ 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError',
+ 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning',
+ 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning',
+ 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning',
+ 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError',
+ 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning',
+ 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__build_class__', '__debug__',
+ '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii',
+ 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex',
+ 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter',
+ 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int',
+ 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min',
+ 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed',
+ 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type',
+ 'vars', 'zip',
+]
+
file = open('keywords.h', 'w')
file.write('''typedef struct {
char const *str;
@@ -202,4 +232,5 @@ cpp_things.remove((SYNTAX_BUILTIN, 'bool'))
cpp_things.remove((SYNTAX_BUILTIN, 'wchar_t'))
output_keywords(file, cpp_things, 'cpp')
output_keywords(file, label(keywords_rust, SYNTAX_KEYWORD) + label(builtins_rust, SYNTAX_BUILTIN) + label(constants_rust, SYNTAX_CONSTANT), 'rust')
+output_keywords(file, label(keywords_python, SYNTAX_KEYWORD) + label(builtins_python, SYNTAX_BUILTIN) + label(constants_python, SYNTAX_CONSTANT), 'python')
file.close()
diff --git a/syntax.c b/syntax.c
index ae8ee0a..635beea 100644
--- a/syntax.c
+++ b/syntax.c
@@ -188,7 +188,7 @@ static void syntax_highlight_c_cpp(SyntaxState *state_ptr, bool cpp, char32_t *l
}
// keywords don't matter for advancing the state
- if (char_types && !in_single_line_comment && !in_multi_line_comment && !in_string && !in_preprocessor && !in_char) {
+ if (char_types && !in_single_line_comment && !in_multi_line_comment && !in_number && !in_string && !in_preprocessor && !in_char) {
u32 keyword_len = syntax_keyword_len(cpp ? LANG_CPP : LANG_C, line, i, line_len);
Keyword const *keyword = NULL;
if (cpp)
@@ -393,6 +393,115 @@ static void syntax_highlight_rust(SyntaxState *state, char32_t *line, u32 line_l
);
}
+static void syntax_highlight_python(SyntaxState *state, char32_t *line, u32 line_len, SyntaxCharType *char_types) {
+ (void)state;
+ bool in_string = (*state & SYNTAX_STATE_PYTHON_STRING) != 0;
+ bool string_is_dbl_quoted = (*state & SYNTAX_STATE_PYTHON_STRING_DBL_QUOTED) != 0;
+ bool string_is_multiline = true;
+ bool in_number = false;
+ uint backslashes = 0;
+
+ for (u32 i = 0; i < line_len; ++i) {
+ char32_t c = line[i];
+ bool dealt_with = false;
+ switch (c) {
+ case '#':
+ if (!in_string) {
+ // comment
+ if (char_types) {
+ for (u32 j = i; j < line_len; ++j)
+ char_types[j] = SYNTAX_COMMENT;
+ dealt_with = true;
+ }
+ i = line_len - 1;
+ }
+ break;
+ case '\'':
+ case '"': {
+ // @TODO: multi-line strings
+ bool dbl_quoted = c == '"';
+ bool is_triple = i < line_len - 2 &&
+ line[i+1] == c && line[i+2] == c;
+ if (in_string) {
+ if (!string_is_multiline || is_triple) {
+ // end of string
+ if (string_is_dbl_quoted == dbl_quoted && backslashes % 2 == 0) {
+ in_string = false;
+ if (char_types) {
+ char_types[i] = SYNTAX_STRING;
+ if (string_is_multiline) {
+ // highlight all three ending quotes
+ char_types[++i] = SYNTAX_STRING;
+ char_types[++i] = SYNTAX_STRING;
+ }
+ dealt_with = true;
+ }
+ }
+ }
+ } else {
+ // start of string
+ string_is_dbl_quoted = dbl_quoted;
+ in_string = true;
+ string_is_multiline = is_triple;
+ }
+ } break;
+ case ANY_DIGIT:
+ if (char_types && !in_string && !in_number) {
+ in_number = true;
+ if (i) {
+ if (line[i - 1] == '.') {
+ // support .6, for example
+ char_types[i - 1] = SYNTAX_CONSTANT;
+ } else if (is32_ident(line[i - 1])) {
+ // actually, this isn't a number. it's something like a*6* or u3*2*.
+ in_number = false;
+ }
+ }
+ }
+ break;
+ case '\\':
+ ++backslashes;
+ break;
+ default:
+ if ((i && is32_ident(line[i - 1])) || !is32_ident(c))
+ break; // can't be a keyword on its own.
+
+ if (char_types && !in_string && !in_number) {
+ u32 keyword_len = syntax_keyword_len(LANG_PYTHON, line, i, line_len);
+ Keyword const *keyword = syntax_keyword_lookup(syntax_all_keywords_python, arr_count(syntax_all_keywords_python),
+ &line[i], keyword_len);
+ if (keyword) {
+ SyntaxCharType type = keyword->type;
+ for (size_t j = 0; j < keyword_len; ++j) {
+ char_types[i++] = type;
+ }
+ --i; // we'll increment i from the for loop
+ dealt_with = true;
+ break;
+ }
+ }
+ break;
+ }
+ if (c != '\\') backslashes = 0;
+ if (in_number && !syntax_number_continues(line, line_len, i))
+ in_number = false;
+
+ if (char_types && !dealt_with) {
+ SyntaxCharType type = SYNTAX_NORMAL;
+ if (in_string)
+ type = SYNTAX_STRING;
+ else if (in_number)
+ type = SYNTAX_CONSTANT;
+ char_types[i] = type;
+ }
+ }
+ *state = 0;
+ if (in_string && string_is_multiline) {
+ *state |= SYNTAX_STATE_PYTHON_STRING
+ | (SYNTAX_STATE_PYTHON_STRING_DBL_QUOTED * string_is_dbl_quoted);
+ }
+}
+
// This is the main syntax highlighting function. It will determine which colors to use for each character.
// Rather than returning colors, it returns a character type (e.g. comment) which can be converted to a color.
// To highlight multiple lines, start out with a zeroed SyntaxState, and pass a pointer to it each time.
@@ -412,6 +521,9 @@ void syntax_highlight(SyntaxState *state, Language lang, char32_t *line, u32 lin
case LANG_RUST:
syntax_highlight_rust(state, line, line_len, char_types);
break;
+ case LANG_PYTHON:
+ syntax_highlight_python(state, line, line_len, char_types);
+ break;
case LANG_COUNT: assert(0); break;
}
}
diff --git a/ted.cfg b/ted.cfg
index 9c8ac90..6091a47 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -144,3 +144,4 @@ constant = #8ff
C = .c, .h
C++ = .cpp, .hpp, .C, .H, .cxx, .hxx, .cc, .hh
Rust = .rs
+Python = .py \ No newline at end of file
diff --git a/ted.h b/ted.h
index 6664e78..646da6d 100644
--- a/ted.h
+++ b/ted.h
@@ -14,13 +14,18 @@ enum {
};
enum {
- SYNTAX_STATE_RUST_COMMENT_DEPTH_MASK = 0x7u, // in rust, /* */ comments can nest.
+ SYNTAX_STATE_RUST_COMMENT_DEPTH_MASK = 0xfu, // in rust, /* */ comments can nest.
SYNTAX_STATE_RUST_COMMENT_DEPTH_MUL = 0x1u,
SYNTAX_STATE_RUST_COMMENT_DEPTH_BITS = 4, // number of bits we allocate for the comment depth.
SYNTAX_STATE_RUST_STRING = 0x10u,
SYNTAX_STATE_RUST_STRING_IS_RAW = 0x20u,
};
+enum {
+ SYNTAX_STATE_PYTHON_STRING = 0x01u, // multiline strings (''' and """)
+ SYNTAX_STATE_PYTHON_STRING_DBL_QUOTED = 0x02u, // is this a """ string, as opposed to a ''' string?
+};
+
typedef u8 SyntaxState;
ENUM_U16 {
@@ -28,6 +33,7 @@ ENUM_U16 {
LANG_C,
LANG_CPP,
LANG_RUST,
+ LANG_PYTHON,
LANG_COUNT
} ENUM_U16_END(Language);
@@ -41,6 +47,7 @@ static LanguageName const language_names[] = {
{LANG_C, "C"},
{LANG_CPP, "C++"},
{LANG_RUST, "Rust"},
+ {LANG_PYTHON, "Python"},
};
ENUM_U8 {