From ad9559da432f1ea84f1f350f0edf42b94fe79d4c Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Wed, 3 Feb 2021 14:47:34 -0500 Subject: python syntax highlighting --- keywords.h | 48 +++++++++++++++++++++++++ keywords.py | 33 +++++++++++++++++- syntax.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- ted.cfg | 1 + ted.h | 9 ++++- 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 { -- cgit v1.2.3