From 8ef7a72c55e66c097c0130ab17e2062ef75e4723 Mon Sep 17 00:00:00 2001 From: pommicket Date: Wed, 28 Dec 2022 17:53:22 -0500 Subject: syntax highlighting for JSON, and XML as a separate language --- README.md | 16 ++++++++++++++ keywords.h | 35 ++++++++++++++++++------------- keywords.py | 19 ++++++++++++----- lsp-write.c | 4 ++++ main.c | 3 ++- signature-help.c | 38 ++++++++++++++++++++++------------ syntax.c | 63 ++++++++++++++++++++++++++++++++------------------------ ted.cfg | 6 +++++- ted.h | 4 ++++ 9 files changed, 127 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index aa2d9e2..e90467b 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,22 @@ the current directory or one of its parents, depending on where `Makefile` is. O If a `Cargo.toml` file exists in this directory or one of its parents, F4 will run `cargo build`. You can set the default build command in the `[core]` section of the config file. +### ctags vs LSP + +`ted` has support for two separate systems for IDE features. `ctags` +is very lightweight (a ctags installation is just 1.6 MB), and allows +for go-to-definition and limited autocompletion. This has very low CPU usage, +and will work just fine on very large projects (for large projects I would +recommend increasing `tags-max-depth` and turning `regenerate-tags-if-not-found` off). + +LSP servers have lots of features but use lots of CPU and memory, +and may take longer to come up with completions/find definitions, especially +for large projects. However the LSP server runs in a separate thread, so it will not slow down +the ordinary text editing features of `ted` (unless the server starts +using 100% of all CPU cores, which is unlikely). + +I would recommend trying out an LSP server if you're unsure about which one to use. + ## LSP support ted has support for [LSPs](https://microsoft.github.io/language-server-protocol/)! diff --git a/keywords.h b/keywords.h index f27f629..cb0e438 100644 --- a/keywords.h +++ b/keywords.h @@ -49,7 +49,7 @@ static const Keyword syntax_keywords_c_u[16] = {{"uint16_t", SYNTAX_BUILTIN},{"u static const Keyword syntax_keywords_c_v[3] = {{"va_list", SYNTAX_BUILTIN},{"void", SYNTAX_KEYWORD},{"volatile", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_c_w[5] = {{"wchar_t", SYNTAX_BUILTIN},{"wctrans_t", SYNTAX_BUILTIN},{"wctype_t", SYNTAX_BUILTIN},{"while", SYNTAX_KEYWORD},{"wint_t", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_c_x[1] = {{"xtime", SYNTAX_BUILTIN}}; -static const KeywordList syntax_all_keywords_c[] = { +static const KeywordList syntax_all_keywords_c[128] = { ['A'] = {syntax_keywords_c_A, arr_count(syntax_keywords_c_A)}, ['B'] = {syntax_keywords_c_B, arr_count(syntax_keywords_c_B)}, ['C'] = {syntax_keywords_c_C, arr_count(syntax_keywords_c_C)}, ['D'] = {syntax_keywords_c_D, arr_count(syntax_keywords_c_D)}, ['E'] = {syntax_keywords_c_E, arr_count(syntax_keywords_c_E)}, ['F'] = {syntax_keywords_c_F, arr_count(syntax_keywords_c_F)}, ['H'] = {syntax_keywords_c_H, arr_count(syntax_keywords_c_H)}, ['I'] = {syntax_keywords_c_I, arr_count(syntax_keywords_c_I)}, ['L'] = {syntax_keywords_c_L, arr_count(syntax_keywords_c_L)}, ['M'] = {syntax_keywords_c_M, arr_count(syntax_keywords_c_M)}, ['N'] = {syntax_keywords_c_N, arr_count(syntax_keywords_c_N)}, ['O'] = {syntax_keywords_c_O, arr_count(syntax_keywords_c_O)}, ['P'] = {syntax_keywords_c_P, arr_count(syntax_keywords_c_P)}, ['R'] = {syntax_keywords_c_R, arr_count(syntax_keywords_c_R)}, ['S'] = {syntax_keywords_c_S, arr_count(syntax_keywords_c_S)}, ['T'] = {syntax_keywords_c_T, arr_count(syntax_keywords_c_T)}, ['U'] = {syntax_keywords_c_U, arr_count(syntax_keywords_c_U)}, ['W'] = {syntax_keywords_c_W, arr_count(syntax_keywords_c_W)}, ['_'] = {syntax_keywords_c__, arr_count(syntax_keywords_c__)}, ['a'] = {syntax_keywords_c_a, arr_count(syntax_keywords_c_a)}, ['b'] = {syntax_keywords_c_b, arr_count(syntax_keywords_c_b)}, ['c'] = {syntax_keywords_c_c, arr_count(syntax_keywords_c_c)}, ['d'] = {syntax_keywords_c_d, arr_count(syntax_keywords_c_d)}, ['e'] = {syntax_keywords_c_e, arr_count(syntax_keywords_c_e)}, ['f'] = {syntax_keywords_c_f, arr_count(syntax_keywords_c_f)}, ['g'] = {syntax_keywords_c_g, arr_count(syntax_keywords_c_g)}, ['i'] = {syntax_keywords_c_i, arr_count(syntax_keywords_c_i)}, ['j'] = {syntax_keywords_c_j, arr_count(syntax_keywords_c_j)}, ['l'] = {syntax_keywords_c_l, arr_count(syntax_keywords_c_l)}, ['m'] = {syntax_keywords_c_m, arr_count(syntax_keywords_c_m)}, ['n'] = {syntax_keywords_c_n, arr_count(syntax_keywords_c_n)}, ['o'] = {syntax_keywords_c_o, arr_count(syntax_keywords_c_o)}, ['p'] = {syntax_keywords_c_p, arr_count(syntax_keywords_c_p)}, ['r'] = {syntax_keywords_c_r, arr_count(syntax_keywords_c_r)}, ['s'] = {syntax_keywords_c_s, arr_count(syntax_keywords_c_s)}, ['t'] = {syntax_keywords_c_t, arr_count(syntax_keywords_c_t)}, ['u'] = {syntax_keywords_c_u, arr_count(syntax_keywords_c_u)}, ['v'] = {syntax_keywords_c_v, arr_count(syntax_keywords_c_v)}, ['w'] = {syntax_keywords_c_w, arr_count(syntax_keywords_c_w)}, ['x'] = {syntax_keywords_c_x, arr_count(syntax_keywords_c_x)} }; @@ -93,7 +93,7 @@ static const Keyword syntax_keywords_cpp_u[17] = {{"uint16_t", SYNTAX_BUILTIN},{ static const Keyword syntax_keywords_cpp_v[4] = {{"va_list", SYNTAX_BUILTIN},{"virtual", SYNTAX_KEYWORD},{"void", SYNTAX_KEYWORD},{"volatile", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_cpp_w[5] = {{"wchar_t", SYNTAX_KEYWORD},{"wctrans_t", SYNTAX_BUILTIN},{"wctype_t", SYNTAX_BUILTIN},{"while", SYNTAX_KEYWORD},{"wint_t", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_cpp_x[3] = {{"xor", SYNTAX_KEYWORD},{"xor_eq", SYNTAX_KEYWORD},{"xtime", SYNTAX_BUILTIN}}; -static const KeywordList syntax_all_keywords_cpp[] = { +static const KeywordList syntax_all_keywords_cpp[128] = { ['A'] = {syntax_keywords_cpp_A, arr_count(syntax_keywords_cpp_A)}, ['B'] = {syntax_keywords_cpp_B, arr_count(syntax_keywords_cpp_B)}, ['C'] = {syntax_keywords_cpp_C, arr_count(syntax_keywords_cpp_C)}, ['D'] = {syntax_keywords_cpp_D, arr_count(syntax_keywords_cpp_D)}, ['E'] = {syntax_keywords_cpp_E, arr_count(syntax_keywords_cpp_E)}, ['F'] = {syntax_keywords_cpp_F, arr_count(syntax_keywords_cpp_F)}, ['H'] = {syntax_keywords_cpp_H, arr_count(syntax_keywords_cpp_H)}, ['I'] = {syntax_keywords_cpp_I, arr_count(syntax_keywords_cpp_I)}, ['L'] = {syntax_keywords_cpp_L, arr_count(syntax_keywords_cpp_L)}, ['M'] = {syntax_keywords_cpp_M, arr_count(syntax_keywords_cpp_M)}, ['N'] = {syntax_keywords_cpp_N, arr_count(syntax_keywords_cpp_N)}, ['O'] = {syntax_keywords_cpp_O, arr_count(syntax_keywords_cpp_O)}, ['P'] = {syntax_keywords_cpp_P, arr_count(syntax_keywords_cpp_P)}, ['R'] = {syntax_keywords_cpp_R, arr_count(syntax_keywords_cpp_R)}, ['S'] = {syntax_keywords_cpp_S, arr_count(syntax_keywords_cpp_S)}, ['T'] = {syntax_keywords_cpp_T, arr_count(syntax_keywords_cpp_T)}, ['U'] = {syntax_keywords_cpp_U, arr_count(syntax_keywords_cpp_U)}, ['W'] = {syntax_keywords_cpp_W, arr_count(syntax_keywords_cpp_W)}, ['_'] = {syntax_keywords_cpp__, arr_count(syntax_keywords_cpp__)}, ['a'] = {syntax_keywords_cpp_a, arr_count(syntax_keywords_cpp_a)}, ['b'] = {syntax_keywords_cpp_b, arr_count(syntax_keywords_cpp_b)}, ['c'] = {syntax_keywords_cpp_c, arr_count(syntax_keywords_cpp_c)}, ['d'] = {syntax_keywords_cpp_d, arr_count(syntax_keywords_cpp_d)}, ['e'] = {syntax_keywords_cpp_e, arr_count(syntax_keywords_cpp_e)}, ['f'] = {syntax_keywords_cpp_f, arr_count(syntax_keywords_cpp_f)}, ['g'] = {syntax_keywords_cpp_g, arr_count(syntax_keywords_cpp_g)}, ['i'] = {syntax_keywords_cpp_i, arr_count(syntax_keywords_cpp_i)}, ['j'] = {syntax_keywords_cpp_j, arr_count(syntax_keywords_cpp_j)}, ['l'] = {syntax_keywords_cpp_l, arr_count(syntax_keywords_cpp_l)}, ['m'] = {syntax_keywords_cpp_m, arr_count(syntax_keywords_cpp_m)}, ['n'] = {syntax_keywords_cpp_n, arr_count(syntax_keywords_cpp_n)}, ['o'] = {syntax_keywords_cpp_o, arr_count(syntax_keywords_cpp_o)}, ['p'] = {syntax_keywords_cpp_p, arr_count(syntax_keywords_cpp_p)}, ['r'] = {syntax_keywords_cpp_r, arr_count(syntax_keywords_cpp_r)}, ['s'] = {syntax_keywords_cpp_s, arr_count(syntax_keywords_cpp_s)}, ['t'] = {syntax_keywords_cpp_t, arr_count(syntax_keywords_cpp_t)}, ['u'] = {syntax_keywords_cpp_u, arr_count(syntax_keywords_cpp_u)}, ['v'] = {syntax_keywords_cpp_v, arr_count(syntax_keywords_cpp_v)}, ['w'] = {syntax_keywords_cpp_w, arr_count(syntax_keywords_cpp_w)}, ['x'] = {syntax_keywords_cpp_x, arr_count(syntax_keywords_cpp_x)} }; @@ -131,7 +131,7 @@ static const Keyword syntax_keywords_rust_u[12] = {{"u128", SYNTAX_BUILTIN},{"u1 static const Keyword syntax_keywords_rust_v[2] = {{"vec!", SYNTAX_BUILTIN},{"virtual", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_rust_w[4] = {{"where", SYNTAX_KEYWORD},{"while", SYNTAX_KEYWORD},{"write!", SYNTAX_BUILTIN},{"writeln!", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_rust_y[1] = {{"yield", SYNTAX_KEYWORD}}; -static const KeywordList syntax_all_keywords_rust[] = { +static const KeywordList syntax_all_keywords_rust[128] = { ['A'] = {syntax_keywords_rust_A, arr_count(syntax_keywords_rust_A)}, ['B'] = {syntax_keywords_rust_B, arr_count(syntax_keywords_rust_B)}, ['C'] = {syntax_keywords_rust_C, arr_count(syntax_keywords_rust_C)}, ['D'] = {syntax_keywords_rust_D, arr_count(syntax_keywords_rust_D)}, ['E'] = {syntax_keywords_rust_E, arr_count(syntax_keywords_rust_E)}, ['F'] = {syntax_keywords_rust_F, arr_count(syntax_keywords_rust_F)}, ['I'] = {syntax_keywords_rust_I, arr_count(syntax_keywords_rust_I)}, ['N'] = {syntax_keywords_rust_N, arr_count(syntax_keywords_rust_N)}, ['O'] = {syntax_keywords_rust_O, arr_count(syntax_keywords_rust_O)}, ['P'] = {syntax_keywords_rust_P, arr_count(syntax_keywords_rust_P)}, ['R'] = {syntax_keywords_rust_R, arr_count(syntax_keywords_rust_R)}, ['S'] = {syntax_keywords_rust_S, arr_count(syntax_keywords_rust_S)}, ['T'] = {syntax_keywords_rust_T, arr_count(syntax_keywords_rust_T)}, ['U'] = {syntax_keywords_rust_U, arr_count(syntax_keywords_rust_U)}, ['V'] = {syntax_keywords_rust_V, arr_count(syntax_keywords_rust_V)}, ['a'] = {syntax_keywords_rust_a, arr_count(syntax_keywords_rust_a)}, ['b'] = {syntax_keywords_rust_b, arr_count(syntax_keywords_rust_b)}, ['c'] = {syntax_keywords_rust_c, arr_count(syntax_keywords_rust_c)}, ['d'] = {syntax_keywords_rust_d, arr_count(syntax_keywords_rust_d)}, ['e'] = {syntax_keywords_rust_e, arr_count(syntax_keywords_rust_e)}, ['f'] = {syntax_keywords_rust_f, arr_count(syntax_keywords_rust_f)}, ['g'] = {syntax_keywords_rust_g, arr_count(syntax_keywords_rust_g)}, ['i'] = {syntax_keywords_rust_i, arr_count(syntax_keywords_rust_i)}, ['l'] = {syntax_keywords_rust_l, arr_count(syntax_keywords_rust_l)}, ['m'] = {syntax_keywords_rust_m, arr_count(syntax_keywords_rust_m)}, ['o'] = {syntax_keywords_rust_o, arr_count(syntax_keywords_rust_o)}, ['p'] = {syntax_keywords_rust_p, arr_count(syntax_keywords_rust_p)}, ['r'] = {syntax_keywords_rust_r, arr_count(syntax_keywords_rust_r)}, ['s'] = {syntax_keywords_rust_s, arr_count(syntax_keywords_rust_s)}, ['t'] = {syntax_keywords_rust_t, arr_count(syntax_keywords_rust_t)}, ['u'] = {syntax_keywords_rust_u, arr_count(syntax_keywords_rust_u)}, ['v'] = {syntax_keywords_rust_v, arr_count(syntax_keywords_rust_v)}, ['w'] = {syntax_keywords_rust_w, arr_count(syntax_keywords_rust_w)}, ['y'] = {syntax_keywords_rust_y, arr_count(syntax_keywords_rust_y)} }; @@ -161,19 +161,26 @@ static const Keyword syntax_keywords_javascript_f[4] = {{"false", SYNTAX_CONSTAN static const Keyword syntax_keywords_javascript_g[1] = {{"globalThis", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_javascript_i[6] = {{"if", SYNTAX_KEYWORD},{"import", SYNTAX_KEYWORD},{"in", SYNTAX_KEYWORD},{"instanceof", SYNTAX_KEYWORD},{"isFinite", SYNTAX_BUILTIN},{"isNaN", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_javascript_l[1] = {{"let", SYNTAX_KEYWORD}}; -static const Keyword syntax_keywords_javascript_n[2] = {{"new", SYNTAX_KEYWORD},{"null", SYNTAX_BUILTIN}}; +static const Keyword syntax_keywords_javascript_n[2] = {{"new", SYNTAX_KEYWORD},{"null", SYNTAX_CONSTANT}}; static const Keyword syntax_keywords_javascript_p[2] = {{"parseFloat", SYNTAX_BUILTIN},{"parseInt", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_javascript_r[1] = {{"return", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_javascript_s[2] = {{"super", SYNTAX_KEYWORD},{"switch", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_javascript_t[5] = {{"this", SYNTAX_KEYWORD},{"throw", SYNTAX_KEYWORD},{"true", SYNTAX_CONSTANT},{"try", SYNTAX_KEYWORD},{"typeof", SYNTAX_KEYWORD}}; -static const Keyword syntax_keywords_javascript_u[1] = {{"undefined", SYNTAX_BUILTIN}}; +static const Keyword syntax_keywords_javascript_u[1] = {{"undefined", SYNTAX_CONSTANT}}; static const Keyword syntax_keywords_javascript_v[2] = {{"var", SYNTAX_KEYWORD},{"void", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_javascript_w[2] = {{"while", SYNTAX_KEYWORD},{"with", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_javascript_y[1] = {{"yield", SYNTAX_KEYWORD}}; -static const KeywordList syntax_all_keywords_javascript[] = { +static const KeywordList syntax_all_keywords_javascript[128] = { ['A'] = {syntax_keywords_javascript_A, arr_count(syntax_keywords_javascript_A)}, ['B'] = {syntax_keywords_javascript_B, arr_count(syntax_keywords_javascript_B)}, ['D'] = {syntax_keywords_javascript_D, arr_count(syntax_keywords_javascript_D)}, ['E'] = {syntax_keywords_javascript_E, arr_count(syntax_keywords_javascript_E)}, ['F'] = {syntax_keywords_javascript_F, arr_count(syntax_keywords_javascript_F)}, ['G'] = {syntax_keywords_javascript_G, arr_count(syntax_keywords_javascript_G)}, ['I'] = {syntax_keywords_javascript_I, arr_count(syntax_keywords_javascript_I)}, ['J'] = {syntax_keywords_javascript_J, arr_count(syntax_keywords_javascript_J)}, ['M'] = {syntax_keywords_javascript_M, arr_count(syntax_keywords_javascript_M)}, ['N'] = {syntax_keywords_javascript_N, arr_count(syntax_keywords_javascript_N)}, ['O'] = {syntax_keywords_javascript_O, arr_count(syntax_keywords_javascript_O)}, ['P'] = {syntax_keywords_javascript_P, arr_count(syntax_keywords_javascript_P)}, ['R'] = {syntax_keywords_javascript_R, arr_count(syntax_keywords_javascript_R)}, ['S'] = {syntax_keywords_javascript_S, arr_count(syntax_keywords_javascript_S)}, ['T'] = {syntax_keywords_javascript_T, arr_count(syntax_keywords_javascript_T)}, ['U'] = {syntax_keywords_javascript_U, arr_count(syntax_keywords_javascript_U)}, ['W'] = {syntax_keywords_javascript_W, arr_count(syntax_keywords_javascript_W)}, ['a'] = {syntax_keywords_javascript_a, arr_count(syntax_keywords_javascript_a)}, ['b'] = {syntax_keywords_javascript_b, arr_count(syntax_keywords_javascript_b)}, ['c'] = {syntax_keywords_javascript_c, arr_count(syntax_keywords_javascript_c)}, ['d'] = {syntax_keywords_javascript_d, arr_count(syntax_keywords_javascript_d)}, ['e'] = {syntax_keywords_javascript_e, arr_count(syntax_keywords_javascript_e)}, ['f'] = {syntax_keywords_javascript_f, arr_count(syntax_keywords_javascript_f)}, ['g'] = {syntax_keywords_javascript_g, arr_count(syntax_keywords_javascript_g)}, ['i'] = {syntax_keywords_javascript_i, arr_count(syntax_keywords_javascript_i)}, ['l'] = {syntax_keywords_javascript_l, arr_count(syntax_keywords_javascript_l)}, ['n'] = {syntax_keywords_javascript_n, arr_count(syntax_keywords_javascript_n)}, ['p'] = {syntax_keywords_javascript_p, arr_count(syntax_keywords_javascript_p)}, ['r'] = {syntax_keywords_javascript_r, arr_count(syntax_keywords_javascript_r)}, ['s'] = {syntax_keywords_javascript_s, arr_count(syntax_keywords_javascript_s)}, ['t'] = {syntax_keywords_javascript_t, arr_count(syntax_keywords_javascript_t)}, ['u'] = {syntax_keywords_javascript_u, arr_count(syntax_keywords_javascript_u)}, ['v'] = {syntax_keywords_javascript_v, arr_count(syntax_keywords_javascript_v)}, ['w'] = {syntax_keywords_javascript_w, arr_count(syntax_keywords_javascript_w)}, ['y'] = {syntax_keywords_javascript_y, arr_count(syntax_keywords_javascript_y)} }; +static const Keyword syntax_keywords_json_f[1] = {{"false", SYNTAX_CONSTANT}}; +static const Keyword syntax_keywords_json_n[1] = {{"null", SYNTAX_CONSTANT}}; +static const Keyword syntax_keywords_json_t[1] = {{"true", SYNTAX_CONSTANT}}; +static const KeywordList syntax_all_keywords_json[128] = { + ['f'] = {syntax_keywords_json_f, arr_count(syntax_keywords_json_f)}, ['n'] = {syntax_keywords_json_n, arr_count(syntax_keywords_json_n)}, ['t'] = {syntax_keywords_json_t, arr_count(syntax_keywords_json_t)} +}; + static const Keyword syntax_keywords_typescript_A[7] = {{"AggregateError", SYNTAX_BUILTIN},{"Array", SYNTAX_BUILTIN},{"ArrayBuffer", SYNTAX_BUILTIN},{"AsyncFunction", SYNTAX_BUILTIN},{"AsyncGenerator", SYNTAX_BUILTIN},{"AsyncGeneratorFunction", SYNTAX_BUILTIN},{"Atomics", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_typescript_B[4] = {{"BigInt", SYNTAX_BUILTIN},{"BigInt64Array", SYNTAX_BUILTIN},{"BigUint64Array", SYNTAX_BUILTIN},{"Boolean", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_typescript_D[2] = {{"DataView", SYNTAX_BUILTIN},{"Date", SYNTAX_BUILTIN}}; @@ -201,16 +208,16 @@ static const Keyword syntax_keywords_typescript_g[2] = {{"get", SYNTAX_BUILTIN}, static const Keyword syntax_keywords_typescript_i[8] = {{"if", SYNTAX_KEYWORD},{"implements", SYNTAX_KEYWORD},{"import", SYNTAX_KEYWORD},{"in", SYNTAX_KEYWORD},{"instanceof", SYNTAX_KEYWORD},{"interface", SYNTAX_KEYWORD},{"isFinite", SYNTAX_BUILTIN},{"isNaN", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_typescript_l[1] = {{"let", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_typescript_m[1] = {{"module", SYNTAX_KEYWORD}}; -static const Keyword syntax_keywords_typescript_n[3] = {{"new", SYNTAX_KEYWORD},{"null", SYNTAX_BUILTIN},{"number", SYNTAX_BUILTIN}}; +static const Keyword syntax_keywords_typescript_n[3] = {{"new", SYNTAX_KEYWORD},{"null", SYNTAX_CONSTANT},{"number", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_typescript_p[5] = {{"package", SYNTAX_KEYWORD},{"parseFloat", SYNTAX_BUILTIN},{"parseInt", SYNTAX_BUILTIN},{"private", SYNTAX_KEYWORD},{"public", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_typescript_r[1] = {{"return", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_typescript_s[5] = {{"set", SYNTAX_BUILTIN},{"static", SYNTAX_KEYWORD},{"string", SYNTAX_BUILTIN},{"super", SYNTAX_KEYWORD},{"switch", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_typescript_t[6] = {{"this", SYNTAX_KEYWORD},{"throw", SYNTAX_KEYWORD},{"true", SYNTAX_CONSTANT},{"try", SYNTAX_KEYWORD},{"type", SYNTAX_KEYWORD},{"typeof", SYNTAX_KEYWORD}}; -static const Keyword syntax_keywords_typescript_u[1] = {{"undefined", SYNTAX_BUILTIN}}; +static const Keyword syntax_keywords_typescript_u[1] = {{"undefined", SYNTAX_CONSTANT}}; static const Keyword syntax_keywords_typescript_v[2] = {{"var", SYNTAX_KEYWORD},{"void", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_typescript_w[2] = {{"while", SYNTAX_KEYWORD},{"with", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_typescript_y[1] = {{"yield", SYNTAX_KEYWORD}}; -static const KeywordList syntax_all_keywords_typescript[] = { +static const KeywordList syntax_all_keywords_typescript[128] = { ['A'] = {syntax_keywords_typescript_A, arr_count(syntax_keywords_typescript_A)}, ['B'] = {syntax_keywords_typescript_B, arr_count(syntax_keywords_typescript_B)}, ['D'] = {syntax_keywords_typescript_D, arr_count(syntax_keywords_typescript_D)}, ['E'] = {syntax_keywords_typescript_E, arr_count(syntax_keywords_typescript_E)}, ['F'] = {syntax_keywords_typescript_F, arr_count(syntax_keywords_typescript_F)}, ['G'] = {syntax_keywords_typescript_G, arr_count(syntax_keywords_typescript_G)}, ['I'] = {syntax_keywords_typescript_I, arr_count(syntax_keywords_typescript_I)}, ['J'] = {syntax_keywords_typescript_J, arr_count(syntax_keywords_typescript_J)}, ['M'] = {syntax_keywords_typescript_M, arr_count(syntax_keywords_typescript_M)}, ['N'] = {syntax_keywords_typescript_N, arr_count(syntax_keywords_typescript_N)}, ['O'] = {syntax_keywords_typescript_O, arr_count(syntax_keywords_typescript_O)}, ['P'] = {syntax_keywords_typescript_P, arr_count(syntax_keywords_typescript_P)}, ['R'] = {syntax_keywords_typescript_R, arr_count(syntax_keywords_typescript_R)}, ['S'] = {syntax_keywords_typescript_S, arr_count(syntax_keywords_typescript_S)}, ['T'] = {syntax_keywords_typescript_T, arr_count(syntax_keywords_typescript_T)}, ['U'] = {syntax_keywords_typescript_U, arr_count(syntax_keywords_typescript_U)}, ['W'] = {syntax_keywords_typescript_W, arr_count(syntax_keywords_typescript_W)}, ['a'] = {syntax_keywords_typescript_a, arr_count(syntax_keywords_typescript_a)}, ['b'] = {syntax_keywords_typescript_b, arr_count(syntax_keywords_typescript_b)}, ['c'] = {syntax_keywords_typescript_c, arr_count(syntax_keywords_typescript_c)}, ['d'] = {syntax_keywords_typescript_d, arr_count(syntax_keywords_typescript_d)}, ['e'] = {syntax_keywords_typescript_e, arr_count(syntax_keywords_typescript_e)}, ['f'] = {syntax_keywords_typescript_f, arr_count(syntax_keywords_typescript_f)}, ['g'] = {syntax_keywords_typescript_g, arr_count(syntax_keywords_typescript_g)}, ['i'] = {syntax_keywords_typescript_i, arr_count(syntax_keywords_typescript_i)}, ['l'] = {syntax_keywords_typescript_l, arr_count(syntax_keywords_typescript_l)}, ['m'] = {syntax_keywords_typescript_m, arr_count(syntax_keywords_typescript_m)}, ['n'] = {syntax_keywords_typescript_n, arr_count(syntax_keywords_typescript_n)}, ['p'] = {syntax_keywords_typescript_p, arr_count(syntax_keywords_typescript_p)}, ['r'] = {syntax_keywords_typescript_r, arr_count(syntax_keywords_typescript_r)}, ['s'] = {syntax_keywords_typescript_s, arr_count(syntax_keywords_typescript_s)}, ['t'] = {syntax_keywords_typescript_t, arr_count(syntax_keywords_typescript_t)}, ['u'] = {syntax_keywords_typescript_u, arr_count(syntax_keywords_typescript_u)}, ['v'] = {syntax_keywords_typescript_v, arr_count(syntax_keywords_typescript_v)}, ['w'] = {syntax_keywords_typescript_w, arr_count(syntax_keywords_typescript_w)}, ['y'] = {syntax_keywords_typescript_y, arr_count(syntax_keywords_typescript_y)} }; @@ -231,7 +238,7 @@ static const Keyword syntax_keywords_go_s[4] = {{"select", SYNTAX_KEYWORD},{"str static const Keyword syntax_keywords_go_t[2] = {{"true", SYNTAX_CONSTANT},{"type", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_go_u[6] = {{"uint", SYNTAX_BUILTIN},{"uint16", SYNTAX_BUILTIN},{"uint32", SYNTAX_BUILTIN},{"uint64", SYNTAX_BUILTIN},{"uint8", SYNTAX_BUILTIN},{"uintptr", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_go_v[1] = {{"var", SYNTAX_KEYWORD}}; -static const KeywordList syntax_all_keywords_go[] = { +static const KeywordList syntax_all_keywords_go[128] = { ['a'] = {syntax_keywords_go_a, arr_count(syntax_keywords_go_a)}, ['b'] = {syntax_keywords_go_b, arr_count(syntax_keywords_go_b)}, ['c'] = {syntax_keywords_go_c, arr_count(syntax_keywords_go_c)}, ['d'] = {syntax_keywords_go_d, arr_count(syntax_keywords_go_d)}, ['e'] = {syntax_keywords_go_e, arr_count(syntax_keywords_go_e)}, ['f'] = {syntax_keywords_go_f, arr_count(syntax_keywords_go_f)}, ['g'] = {syntax_keywords_go_g, arr_count(syntax_keywords_go_g)}, ['i'] = {syntax_keywords_go_i, arr_count(syntax_keywords_go_i)}, ['l'] = {syntax_keywords_go_l, arr_count(syntax_keywords_go_l)}, ['m'] = {syntax_keywords_go_m, arr_count(syntax_keywords_go_m)}, ['n'] = {syntax_keywords_go_n, arr_count(syntax_keywords_go_n)}, ['p'] = {syntax_keywords_go_p, arr_count(syntax_keywords_go_p)}, ['r'] = {syntax_keywords_go_r, arr_count(syntax_keywords_go_r)}, ['s'] = {syntax_keywords_go_s, arr_count(syntax_keywords_go_s)}, ['t'] = {syntax_keywords_go_t, arr_count(syntax_keywords_go_t)}, ['u'] = {syntax_keywords_go_u, arr_count(syntax_keywords_go_u)}, ['v'] = {syntax_keywords_go_v, arr_count(syntax_keywords_go_v)} }; @@ -251,7 +258,7 @@ static const Keyword syntax_keywords_java_s[6] = {{"short", SYNTAX_KEYWORD},{"st static const Keyword syntax_keywords_java_t[6] = {{"this", SYNTAX_KEYWORD},{"throw", SYNTAX_KEYWORD},{"throws", SYNTAX_KEYWORD},{"transient", SYNTAX_KEYWORD},{"true", SYNTAX_CONSTANT},{"try", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_java_v[3] = {{"var", SYNTAX_KEYWORD},{"void", SYNTAX_KEYWORD},{"volatile", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_java_w[1] = {{"while", SYNTAX_KEYWORD}}; -static const KeywordList syntax_all_keywords_java[] = { +static const KeywordList syntax_all_keywords_java[128] = { ['a'] = {syntax_keywords_java_a, arr_count(syntax_keywords_java_a)}, ['b'] = {syntax_keywords_java_b, arr_count(syntax_keywords_java_b)}, ['c'] = {syntax_keywords_java_c, arr_count(syntax_keywords_java_c)}, ['d'] = {syntax_keywords_java_d, arr_count(syntax_keywords_java_d)}, ['e'] = {syntax_keywords_java_e, arr_count(syntax_keywords_java_e)}, ['f'] = {syntax_keywords_java_f, arr_count(syntax_keywords_java_f)}, ['g'] = {syntax_keywords_java_g, arr_count(syntax_keywords_java_g)}, ['i'] = {syntax_keywords_java_i, arr_count(syntax_keywords_java_i)}, ['l'] = {syntax_keywords_java_l, arr_count(syntax_keywords_java_l)}, ['n'] = {syntax_keywords_java_n, arr_count(syntax_keywords_java_n)}, ['p'] = {syntax_keywords_java_p, arr_count(syntax_keywords_java_p)}, ['r'] = {syntax_keywords_java_r, arr_count(syntax_keywords_java_r)}, ['s'] = {syntax_keywords_java_s, arr_count(syntax_keywords_java_s)}, ['t'] = {syntax_keywords_java_t, arr_count(syntax_keywords_java_t)}, ['v'] = {syntax_keywords_java_v, arr_count(syntax_keywords_java_v)}, ['w'] = {syntax_keywords_java_w, arr_count(syntax_keywords_java_w)} }; @@ -299,7 +306,7 @@ static const Keyword syntax_keywords_python_v[1] = {{"vars", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_python_w[2] = {{"while", SYNTAX_KEYWORD},{"with", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_python_y[1] = {{"yield", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_python_z[1] = {{"zip", SYNTAX_BUILTIN}}; -static const KeywordList syntax_all_keywords_python[] = { +static const KeywordList syntax_all_keywords_python[128] = { ['A'] = {syntax_keywords_python_A, arr_count(syntax_keywords_python_A)}, ['B'] = {syntax_keywords_python_B, arr_count(syntax_keywords_python_B)}, ['C'] = {syntax_keywords_python_C, arr_count(syntax_keywords_python_C)}, ['D'] = {syntax_keywords_python_D, arr_count(syntax_keywords_python_D)}, ['E'] = {syntax_keywords_python_E, arr_count(syntax_keywords_python_E)}, ['F'] = {syntax_keywords_python_F, arr_count(syntax_keywords_python_F)}, ['G'] = {syntax_keywords_python_G, arr_count(syntax_keywords_python_G)}, ['I'] = {syntax_keywords_python_I, arr_count(syntax_keywords_python_I)}, ['K'] = {syntax_keywords_python_K, arr_count(syntax_keywords_python_K)}, ['L'] = {syntax_keywords_python_L, arr_count(syntax_keywords_python_L)}, ['M'] = {syntax_keywords_python_M, arr_count(syntax_keywords_python_M)}, ['N'] = {syntax_keywords_python_N, arr_count(syntax_keywords_python_N)}, ['O'] = {syntax_keywords_python_O, arr_count(syntax_keywords_python_O)}, ['P'] = {syntax_keywords_python_P, arr_count(syntax_keywords_python_P)}, ['R'] = {syntax_keywords_python_R, arr_count(syntax_keywords_python_R)}, ['S'] = {syntax_keywords_python_S, arr_count(syntax_keywords_python_S)}, ['T'] = {syntax_keywords_python_T, arr_count(syntax_keywords_python_T)}, ['U'] = {syntax_keywords_python_U, arr_count(syntax_keywords_python_U)}, ['V'] = {syntax_keywords_python_V, arr_count(syntax_keywords_python_V)}, ['W'] = {syntax_keywords_python_W, arr_count(syntax_keywords_python_W)}, ['Z'] = {syntax_keywords_python_Z, arr_count(syntax_keywords_python_Z)}, ['_'] = {syntax_keywords_python__, arr_count(syntax_keywords_python__)}, ['a'] = {syntax_keywords_python_a, arr_count(syntax_keywords_python_a)}, ['b'] = {syntax_keywords_python_b, arr_count(syntax_keywords_python_b)}, ['c'] = {syntax_keywords_python_c, arr_count(syntax_keywords_python_c)}, ['d'] = {syntax_keywords_python_d, arr_count(syntax_keywords_python_d)}, ['e'] = {syntax_keywords_python_e, arr_count(syntax_keywords_python_e)}, ['f'] = {syntax_keywords_python_f, arr_count(syntax_keywords_python_f)}, ['g'] = {syntax_keywords_python_g, arr_count(syntax_keywords_python_g)}, ['h'] = {syntax_keywords_python_h, arr_count(syntax_keywords_python_h)}, ['i'] = {syntax_keywords_python_i, arr_count(syntax_keywords_python_i)}, ['l'] = {syntax_keywords_python_l, arr_count(syntax_keywords_python_l)}, ['m'] = {syntax_keywords_python_m, arr_count(syntax_keywords_python_m)}, ['n'] = {syntax_keywords_python_n, arr_count(syntax_keywords_python_n)}, ['o'] = {syntax_keywords_python_o, arr_count(syntax_keywords_python_o)}, ['p'] = {syntax_keywords_python_p, arr_count(syntax_keywords_python_p)}, ['q'] = {syntax_keywords_python_q, arr_count(syntax_keywords_python_q)}, ['r'] = {syntax_keywords_python_r, arr_count(syntax_keywords_python_r)}, ['s'] = {syntax_keywords_python_s, arr_count(syntax_keywords_python_s)}, ['t'] = {syntax_keywords_python_t, arr_count(syntax_keywords_python_t)}, ['v'] = {syntax_keywords_python_v, arr_count(syntax_keywords_python_v)}, ['w'] = {syntax_keywords_python_w, arr_count(syntax_keywords_python_w)}, ['y'] = {syntax_keywords_python_y, arr_count(syntax_keywords_python_y)}, ['z'] = {syntax_keywords_python_z, arr_count(syntax_keywords_python_z)} }; @@ -323,7 +330,7 @@ static const Keyword syntax_keywords_html_t[5] = {{"tabindex=", SYNTAX_BUILTIN}, static const Keyword syntax_keywords_html_u[1] = {{"usemap=", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_html_v[1] = {{"value=", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_html_w[2] = {{"width=", SYNTAX_BUILTIN},{"wrap=", SYNTAX_BUILTIN}}; -static const KeywordList syntax_all_keywords_html[] = { +static const KeywordList syntax_all_keywords_html[128] = { ['a'] = {syntax_keywords_html_a, arr_count(syntax_keywords_html_a)}, ['b'] = {syntax_keywords_html_b, arr_count(syntax_keywords_html_b)}, ['c'] = {syntax_keywords_html_c, arr_count(syntax_keywords_html_c)}, ['d'] = {syntax_keywords_html_d, arr_count(syntax_keywords_html_d)}, ['e'] = {syntax_keywords_html_e, arr_count(syntax_keywords_html_e)}, ['f'] = {syntax_keywords_html_f, arr_count(syntax_keywords_html_f)}, ['h'] = {syntax_keywords_html_h, arr_count(syntax_keywords_html_h)}, ['i'] = {syntax_keywords_html_i, arr_count(syntax_keywords_html_i)}, ['k'] = {syntax_keywords_html_k, arr_count(syntax_keywords_html_k)}, ['l'] = {syntax_keywords_html_l, arr_count(syntax_keywords_html_l)}, ['m'] = {syntax_keywords_html_m, arr_count(syntax_keywords_html_m)}, ['n'] = {syntax_keywords_html_n, arr_count(syntax_keywords_html_n)}, ['o'] = {syntax_keywords_html_o, arr_count(syntax_keywords_html_o)}, ['p'] = {syntax_keywords_html_p, arr_count(syntax_keywords_html_p)}, ['r'] = {syntax_keywords_html_r, arr_count(syntax_keywords_html_r)}, ['s'] = {syntax_keywords_html_s, arr_count(syntax_keywords_html_s)}, ['t'] = {syntax_keywords_html_t, arr_count(syntax_keywords_html_t)}, ['u'] = {syntax_keywords_html_u, arr_count(syntax_keywords_html_u)}, ['v'] = {syntax_keywords_html_v, arr_count(syntax_keywords_html_v)}, ['w'] = {syntax_keywords_html_w, arr_count(syntax_keywords_html_w)} }; @@ -332,7 +339,7 @@ static const Keyword syntax_keywords_config_n[1] = {{"no", SYNTAX_CONSTANT}}; static const Keyword syntax_keywords_config_o[2] = {{"off", SYNTAX_CONSTANT},{"on", SYNTAX_CONSTANT}}; static const Keyword syntax_keywords_config_t[1] = {{"true", SYNTAX_CONSTANT}}; static const Keyword syntax_keywords_config_y[1] = {{"yes", SYNTAX_CONSTANT}}; -static const KeywordList syntax_all_keywords_config[] = { +static const KeywordList syntax_all_keywords_config[128] = { ['f'] = {syntax_keywords_config_f, arr_count(syntax_keywords_config_f)}, ['n'] = {syntax_keywords_config_n, arr_count(syntax_keywords_config_n)}, ['o'] = {syntax_keywords_config_o, arr_count(syntax_keywords_config_o)}, ['t'] = {syntax_keywords_config_t, arr_count(syntax_keywords_config_t)}, ['y'] = {syntax_keywords_config_y, arr_count(syntax_keywords_config_y)} }; diff --git a/keywords.py b/keywords.py index 6a29b25..1779811 100755 --- a/keywords.py +++ b/keywords.py @@ -1,4 +1,10 @@ #!/usr/bin/python3 + +# creates lists of keywords for all languages +# to make keyword lookup more efficient, the lists are split up by their first letter +# (or by their first codepoint, modulo 128, although no language I know of has non-ASCII keywords) +# (probably APL but i hope no one is using APL) + import ast types = [ @@ -23,7 +29,7 @@ def output_keywords(file, keywords, language): kwds = list(sorted(kwds)) file.write('static const Keyword syntax_keywords_{}_{}[{}] = {{'.format(language, c, len(kwds))) file.write(','.join(map(lambda kwd: '{"'+kwd[0]+'", ' + types[kwd[1]] + '}', kwds)) + '};\n') - file.write('static const KeywordList syntax_all_keywords_{}[] = {{\n'.format(language)) + file.write('static const KeywordList syntax_all_keywords_{}[128] = {{\n'.format(language)) file.write('\t'+', '.join(["['{}'] = {{syntax_keywords_{}_{}, arr_count(syntax_keywords_{}_{})}}".format( c, language, c, language, c) for c in sorted(keywords.keys())]) + '\n') file.write('};\n\n') @@ -268,9 +274,10 @@ keywords_javascript = [ 'let', 'await' ] -constants_javascript = [ - 'true', 'false' +constants_json = [ + 'true', 'false', 'null' ] +constants_javascript = constants_json + ['undefined'] builtins_javascript = [ 'AggregateError','Array','ArrayBuffer','AsyncFunction','AsyncGenerator','AsyncGeneratorFunction', @@ -280,8 +287,8 @@ builtins_javascript = [ 'Int16Array','Int32Array','Int8Array','InternalError','Intl','isFinite','isNaN','JSON','Map','Math', 'NaN','Number','Object','parseFloat','parseInt','Promise','Proxy','RangeError','ReferenceError', 'Reflect','RegExp','Set','SharedArrayBuffer','String','Symbol','SyntaxError','TypedArray', - 'TypeError','Uint16Array','Uint32Array','Uint8Array','Uint8ClampedArray','undefined', - 'URIError','WeakMap','WeakRef','WeakSet','WebAssembly', 'null' + 'TypeError','Uint16Array','Uint32Array','Uint8Array','Uint8ClampedArray', + 'URIError','WeakMap','WeakRef','WeakSet','WebAssembly' ] keywords_java = [ @@ -297,6 +304,7 @@ keywords_java = [ 'const', 'float', 'native', 'super', 'volatile', 'while' ] + keywords_typescript = keywords_javascript + [ 'public', 'any', 'as', 'module', 'static', 'interface', 'enum', 'type', @@ -364,6 +372,7 @@ 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_javascript, SYNTAX_KEYWORD) + label(builtins_javascript, SYNTAX_BUILTIN) + label(constants_javascript, SYNTAX_CONSTANT), 'javascript') +output_keywords(file, label(constants_json, SYNTAX_CONSTANT), 'json') output_keywords(file, label(keywords_typescript, SYNTAX_KEYWORD) + label(builtins_typescript, SYNTAX_BUILTIN) + label(constants_typescript, SYNTAX_CONSTANT), 'typescript') output_keywords(file, label(keywords_go, SYNTAX_KEYWORD) + label(builtins_go, SYNTAX_BUILTIN) + diff --git a/lsp-write.c b/lsp-write.c index edd4934..128b61b 100644 --- a/lsp-write.c +++ b/lsp-write.c @@ -12,6 +12,8 @@ static const char *lsp_language_id(Language lang) { return "java"; case LANG_JAVASCRIPT: return "javascript"; + case LANG_JSON: + return "json"; case LANG_TYPESCRIPT: return "typescript"; case LANG_MARKDOWN: @@ -26,6 +28,8 @@ static const char *lsp_language_id(Language lang) { return "html"; case LANG_TEX: return "latex"; + case LANG_XML: + return "xml"; case LANG_COUNT: break; } assert(0); diff --git a/main.c b/main.c index b73122f..7f2ccbc 100644 --- a/main.c +++ b/main.c @@ -1,10 +1,11 @@ /* @TODO: +- separate GLSL language +- don't highlight HTML stuff for XML - more LSP stuff: - hover - go to definition using LSP - find usages -- JSON syntax highlighting - check if there are any other non-optional/nice-to-have-support-for server-to-client requests - better non-error window/showMessage(Request) - document lsp.h and lsp.c. diff --git a/signature-help.c b/signature-help.c index 3951c29..1db8104 100644 --- a/signature-help.c +++ b/signature-help.c @@ -1,17 +1,38 @@ // deals with textDocument/signatureHelp LSP requests +static void signature_help_clear(SignatureHelp *help) { + for (int i = 0; i < help->signature_count; ++i) { + Signature sig = help->signatures[i]; + free(sig.label_pre); + free(sig.label_active); + free(sig.label_post); + } + memset(help->signatures, 0, sizeof help->signatures); + help->signature_count = 0; +} + void signature_help_send_request(Ted *ted) { + SignatureHelp *help = &ted->signature_help; Settings *settings = ted_active_settings(ted); - if (!settings->signature_help) return; + if (!settings->signature_help) { + signature_help_clear(help); + return; + } TextBuffer *buffer = ted->active_buffer; - if (!buffer) return; + if (!buffer) { + signature_help_clear(help); + return; + } LSP *lsp = buffer_lsp(buffer); - if (!lsp) return; + if (!lsp) { + signature_help_clear(help); + return; + } LSPRequest request = {.type = LSP_REQUEST_SIGNATURE_HELP}; LSPRequestSignatureHelp *s = &request.data.signature_help; s->position = buffer_cursor_pos_as_lsp_document_position(buffer); lsp_send_request(lsp, &request); - ted->signature_help.retrigger = false; + help->retrigger = false; } void signature_help_retrigger(Ted *ted) { @@ -29,15 +50,6 @@ bool signature_help_is_open(Ted *ted) { return ted->signature_help.signature_count > 0; } -static void signature_help_clear(SignatureHelp *help) { - for (int i = 0; i < help->signature_count; ++i) { - Signature sig = help->signatures[i]; - free(sig.label_pre); - free(sig.label_active); - free(sig.label_post); - } - memset(help->signatures, 0, sizeof help->signatures); -} void signature_help_close(Ted *ted) { signature_help_clear(&ted->signature_help); diff --git a/syntax.c b/syntax.c index a8ce4d4..f21999b 100644 --- a/syntax.c +++ b/syntax.c @@ -30,6 +30,7 @@ char const *language_comment_start(Language l) { case LANG_CPP: case LANG_JAVASCRIPT: case LANG_TYPESCRIPT: + case LANG_JSON: // JSON technically doesn't have comments but apparently some parsers support this so might as well have this here case LANG_JAVA: case LANG_GO: return "// "; @@ -40,6 +41,7 @@ char const *language_comment_start(Language l) { case LANG_TEX: return "% "; case LANG_HTML: + case LANG_XML: return "