From e52c5c62824e378bc9a25fff1f41b0254eb85a8a Mon Sep 17 00:00:00 2001 From: pommicket Date: Sun, 21 May 2023 22:52:19 -0400 Subject: highlight TODOs in comments --- CMakeLists.txt | 3 ++- colors.c | 1 + colors.h | 1 + keywords.h | 9 +++++++ keywords.py | 7 +++++- main.c | 9 ++----- syntax.c | 57 ++++++++++++++++++++++++++++++++++++++------ ted.h | 3 ++- themes/classic-light.ted.cfg | 1 + themes/classic.ted.cfg | 1 + themes/extradark.ted.cfg | 1 + 11 files changed, 76 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 994f286..e808041 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,8 @@ if(MSVC) target_link_libraries(ted ${SDL2_LIB_DIR}/SDL2.lib) target_link_libraries(ted ${CMAKE_SOURCE_DIR}/pcre2-32-static.lib) else() - set(CMAKE_C_FLAGS "-Wall -Wextra -Wshadow -Wconversion -Wpedantic -pedantic -std=gnu11 -Wno-unused-function -Wno-fixed-enum-extension -Wimplicit-fallthrough -Wno-format-truncation -Wno-unknown-warning-option") + # NOTE: -gdwarf-4 is needed for valgrind to work + set(CMAKE_C_FLAGS "-Wall -Wextra -Wshadow -Wconversion -Wpedantic -pedantic -std=gnu11 -gdwarf-4 -Wno-unused-function -Wno-fixed-enum-extension -Wimplicit-fallthrough -Wno-format-truncation -Wno-unknown-warning-option") target_link_libraries(ted m SDL2) target_link_libraries(ted ${CMAKE_SOURCE_DIR}/libpcre2-32.a) endif() diff --git a/colors.c b/colors.c index 1a3f649..7157dae 100644 --- a/colors.c +++ b/colors.c @@ -41,6 +41,7 @@ static ColorName color_names[] = { {COLOR_STRING, "string"}, {COLOR_CHARACTER, "character"}, {COLOR_CONSTANT, "constant"}, + {COLOR_TODO, "todo"}, {COLOR_AUTOCOMPLETE_BG, "autocomplete-bg"}, {COLOR_AUTOCOMPLETE_HL, "autocomplete-hl"}, {COLOR_AUTOCOMPLETE_BORDER, "autocomplete-border"}, diff --git a/colors.h b/colors.h index eda97af..d026619 100644 --- a/colors.h +++ b/colors.h @@ -55,6 +55,7 @@ typedef enum { COLOR_KEYWORD, COLOR_BUILTIN, + COLOR_TODO, COLOR_COMMENT, COLOR_PREPROCESSOR, COLOR_STRING, diff --git a/keywords.h b/keywords.h index ea05647..fae4a16 100644 --- a/keywords.h +++ b/keywords.h @@ -403,3 +403,12 @@ static const KeywordList syntax_all_keywords_css[128] = { ['!'] = {syntax_keywords_css_x21, arr_count(syntax_keywords_css_x21)}, ['-'] = {syntax_keywords_css_x2d, arr_count(syntax_keywords_css_x2d)}, ['@'] = {syntax_keywords_css_x40, arr_count(syntax_keywords_css_x40)}, ['a'] = {syntax_keywords_css_a, arr_count(syntax_keywords_css_a)}, ['b'] = {syntax_keywords_css_b, arr_count(syntax_keywords_css_b)}, ['c'] = {syntax_keywords_css_c, arr_count(syntax_keywords_css_c)}, ['d'] = {syntax_keywords_css_d, arr_count(syntax_keywords_css_d)}, ['e'] = {syntax_keywords_css_e, arr_count(syntax_keywords_css_e)}, ['f'] = {syntax_keywords_css_f, arr_count(syntax_keywords_css_f)}, ['g'] = {syntax_keywords_css_g, arr_count(syntax_keywords_css_g)}, ['h'] = {syntax_keywords_css_h, arr_count(syntax_keywords_css_h)}, ['i'] = {syntax_keywords_css_i, arr_count(syntax_keywords_css_i)}, ['j'] = {syntax_keywords_css_j, arr_count(syntax_keywords_css_j)}, ['k'] = {syntax_keywords_css_k, arr_count(syntax_keywords_css_k)}, ['l'] = {syntax_keywords_css_l, arr_count(syntax_keywords_css_l)}, ['m'] = {syntax_keywords_css_m, arr_count(syntax_keywords_css_m)}, ['n'] = {syntax_keywords_css_n, arr_count(syntax_keywords_css_n)}, ['o'] = {syntax_keywords_css_o, arr_count(syntax_keywords_css_o)}, ['p'] = {syntax_keywords_css_p, arr_count(syntax_keywords_css_p)}, ['q'] = {syntax_keywords_css_q, arr_count(syntax_keywords_css_q)}, ['r'] = {syntax_keywords_css_r, arr_count(syntax_keywords_css_r)}, ['s'] = {syntax_keywords_css_s, arr_count(syntax_keywords_css_s)}, ['t'] = {syntax_keywords_css_t, arr_count(syntax_keywords_css_t)}, ['u'] = {syntax_keywords_css_u, arr_count(syntax_keywords_css_u)}, ['v'] = {syntax_keywords_css_v, arr_count(syntax_keywords_css_v)}, ['w'] = {syntax_keywords_css_w, arr_count(syntax_keywords_css_w)}, ['x'] = {syntax_keywords_css_x, arr_count(syntax_keywords_css_x)}, ['y'] = {syntax_keywords_css_y, arr_count(syntax_keywords_css_y)}, ['z'] = {syntax_keywords_css_z, arr_count(syntax_keywords_css_z)} }; +static const Keyword syntax_keywords_comment_B[1] = {{"BUG", SYNTAX_TODO}}; +static const Keyword syntax_keywords_comment_F[1] = {{"FIXME", SYNTAX_TODO}}; +static const Keyword syntax_keywords_comment_O[1] = {{"OPTIMIZE", SYNTAX_TODO}}; +static const Keyword syntax_keywords_comment_T[2] = {{"TEMP", SYNTAX_TODO},{"TODO", SYNTAX_TODO}}; +static const Keyword syntax_keywords_comment_X[1] = {{"XXX", SYNTAX_TODO}}; +static const KeywordList syntax_all_keywords_comment[128] = { + ['B'] = {syntax_keywords_comment_B, arr_count(syntax_keywords_comment_B)}, ['F'] = {syntax_keywords_comment_F, arr_count(syntax_keywords_comment_F)}, ['O'] = {syntax_keywords_comment_O, arr_count(syntax_keywords_comment_O)}, ['T'] = {syntax_keywords_comment_T, arr_count(syntax_keywords_comment_T)}, ['X'] = {syntax_keywords_comment_X, arr_count(syntax_keywords_comment_X)} +}; + diff --git a/keywords.py b/keywords.py index 9a74b85..75d02dc 100755 --- a/keywords.py +++ b/keywords.py @@ -8,7 +8,8 @@ import ast types = [ - 'SYNTAX_KEYWORD', 'SYNTAX_CONSTANT', 'SYNTAX_BUILTIN' + 'SYNTAX_KEYWORD', 'SYNTAX_CONSTANT', 'SYNTAX_BUILTIN', + 'SYNTAX_TODO' ] exec('\n'.join(['{} = {}'.format(type, i) for (i, type) in enumerate(types)])) @@ -599,6 +600,9 @@ keywords_css = [ 'xmp', 'svg' ] +keywords_comment = [ + 'TODO', 'FIXME', 'XXX', 'BUG', 'TEMP', 'OPTIMIZE', +] file = open('keywords.h', 'w') @@ -638,4 +642,5 @@ output_keywords(file, label(constants_config, SYNTAX_CONSTANT), 'config') output_keywords(file, label(keywords_glsl, SYNTAX_KEYWORD) + label(constants_glsl, SYNTAX_CONSTANT) + label(builtins_glsl, SYNTAX_BUILTIN), 'glsl') output_keywords(file, label(builtins_css, SYNTAX_BUILTIN) + label(constants_css, SYNTAX_CONSTANT) + label(keywords_css, SYNTAX_KEYWORD), 'css') +output_keywords(file, label(keywords_comment, SYNTAX_TODO), 'comment') file.close() diff --git a/main.c b/main.c index 49d9663..eb883a1 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,7 @@ /* +TODO: +- select sole completion if all completions' textEdits are identical (e.g. SyntaxCharT___ in ted) FUTURE FEATURES: -- highlight TODO, FIXME, XXX, others(?) in comments - autodetect indentation (tabs vs spaces) - font setting & support for multiple fonts to cover more characters - support for variable-width fonts @@ -23,12 +24,6 @@ FUTURE FEATURES: - with macros we can really test performance of buffer_insert_text_at_pos, etc. (which should ideally be fast) - manual.md - LSP request timeout -BUG REPORTS IM TO LAZY TO FILE (RIGHT NOW) -- rust-analyzer: - - bad json can give "Unexpected error: client exited without proper shutdown sequence" - - containerName not always given in workspace/symbols -- texlab: - - textDocument/definition gives LocationLink regardless of client capabilities */ #include "ted.h" diff --git a/syntax.c b/syntax.c index 258ff20..e7ee69d 100644 --- a/syntax.c +++ b/syntax.c @@ -109,6 +109,7 @@ ColorSetting syntax_char_type_to_color_setting(SyntaxCharType t) { case SYNTAX_CHARACTER: return COLOR_CHARACTER; case SYNTAX_CONSTANT: return COLOR_CONSTANT; case SYNTAX_BUILTIN: return COLOR_BUILTIN; + case SYNTAX_TODO: return COLOR_TODO; } return COLOR_TEXT; } @@ -168,7 +169,7 @@ bool syntax_is_opening_bracket(Language lang, char32_t c) { } // lookup the given string in the keywords table -static Keyword const *syntax_keyword_lookup(const KeywordList *all_keywords, const char32_t *str, size_t len) { +static const Keyword *syntax_keyword_lookup(const KeywordList *all_keywords, const char32_t *str, size_t len) { if (!len) return NULL; const KeywordList *list = &all_keywords[str[0] % 128]; @@ -184,6 +185,48 @@ static Keyword const *syntax_keyword_lookup(const KeywordList *all_keywords, con return NULL; } +// fast function to figure out if something can be in a comment keyword (like _TODO_) +static bool can_be_comment_keyword(char32_t c) { + return c < 128 && c >= 'A' && c <= 'Z';//fuck you ebcdic +} + +// this is used to highlight comments across languages, for stuff like TODOs +static SyntaxCharType syntax_highlight_comment(const char32_t *line, u32 i, u32 line_len) { + assert(i < line_len); + if (!can_be_comment_keyword(line[i])) + return SYNTAX_COMMENT; // cannot be a keyword + + u32 max_len = 10; // maximum length of any comment keyword + + // find end of keyword + u32 end = i + 1; + while (end < line_len && i + max_len > end && is32_alpha(line[end])) { + if (!can_be_comment_keyword(line[end])) + return SYNTAX_COMMENT; + ++end; + } + if (end < line_len && (line[end] == '_' || is32_digit(line[end]))) + return SYNTAX_COMMENT; + + // find start of keyword + u32 start = i; + while (start > 0 && start + max_len > i && is32_alpha(line[start])) { + if (!can_be_comment_keyword(line[start])) + return SYNTAX_COMMENT; + --start; + } + if (!is32_alpha(line[start])) + ++start; + if (start > 0 && (line[start - 1] == '_' || is32_digit(line[start - 1]))) + return SYNTAX_COMMENT; + + // look it up + const Keyword *kwd = syntax_keyword_lookup(syntax_all_keywords_comment, &line[start], end - start); + if (kwd) + return kwd->type; + return SYNTAX_COMMENT; +} + // does i continue the number literal from i-1 static bool syntax_number_continues(Language lang, const char32_t *line, u32 line_len, u32 i) { if (line[i] == '.') { @@ -423,7 +466,7 @@ static void syntax_highlight_c_cpp(SyntaxState *state_ptr, const char32_t *line, if (char_types && !dealt_with) { SyntaxCharType type = SYNTAX_NORMAL; if (in_single_line_comment || in_multi_line_comment) - type = SYNTAX_COMMENT; + type = syntax_highlight_comment(line, i, line_len); else if (in_string) type = SYNTAX_STRING; else if (in_char) @@ -648,7 +691,7 @@ static void syntax_highlight_rust(SyntaxState *state, const char32_t *line, u32 if (char_types && !dealt_with) { SyntaxCharType type = SYNTAX_NORMAL; if (comment_depth) { - type = SYNTAX_COMMENT; + type = syntax_highlight_comment(line, i, line_len); } else if (in_string) { type = SYNTAX_STRING; } else if (in_number) { @@ -1451,7 +1494,7 @@ static void syntax_highlight_javascript_like( if (char_types && !dealt_with) { SyntaxCharType type = SYNTAX_NORMAL; if (in_multiline_comment) - type = SYNTAX_COMMENT; + type = syntax_highlight_comment(line, i, line_len); else if (in_string) type = SYNTAX_STRING; else if (in_number) @@ -1574,7 +1617,7 @@ static void syntax_highlight_java(SyntaxState *state_ptr, const char32_t *line, if (char_types && !dealt_with) { SyntaxCharType type = SYNTAX_NORMAL; if (in_multiline_comment) - type = SYNTAX_COMMENT; + type = syntax_highlight_comment(line, i, line_len); else if (in_string) type = SYNTAX_STRING; else if (in_char) @@ -1714,7 +1757,7 @@ static void syntax_highlight_go(SyntaxState *state_ptr, const char32_t *line, u3 if (char_types && !dealt_with) { SyntaxCharType type = SYNTAX_NORMAL; if (in_multiline_comment) - type = SYNTAX_COMMENT; + type = syntax_highlight_comment(line, i, line_len); else if (in_string) type = SYNTAX_STRING; else if (in_char) @@ -1935,7 +1978,7 @@ static void syntax_highlight_css(SyntaxState *state_ptr, const char32_t *line, u if (char_types && !dealt_with && i < line_len) { SyntaxCharType type = SYNTAX_NORMAL; if (in_comment) - type = SYNTAX_COMMENT; + type = syntax_highlight_comment(line, i, line_len); char_types[i] = type; } } diff --git a/ted.h b/ted.h index 5b79599..abfe991 100644 --- a/ted.h +++ b/ted.h @@ -101,7 +101,7 @@ typedef u32 SyntaxState; /// types of syntax highlighting enum SyntaxCharType { - // do not change these numbers as it will break backwards compatibility + // do not change these numbers as it will break backwards compatibility with plugins SYNTAX_NORMAL = 0, SYNTAX_KEYWORD = 1, SYNTAX_BUILTIN = 2, @@ -110,6 +110,7 @@ enum SyntaxCharType { SYNTAX_STRING = 5, SYNTAX_CHARACTER = 6, SYNTAX_CONSTANT = 7, + SYNTAX_TODO = 8, }; /// Type of syntax highlighting. typedef u8 SyntaxCharType; diff --git a/themes/classic-light.ted.cfg b/themes/classic-light.ted.cfg index c154020..a7458ab 100644 --- a/themes/classic-light.ted.cfg +++ b/themes/classic-light.ted.cfg @@ -42,6 +42,7 @@ keyword = #062 preprocessor = #11a string = #b33 character = #960 +todo = #a00 builtin = #70a comment = #555 constant = #077 diff --git a/themes/classic.ted.cfg b/themes/classic.ted.cfg index b7a9025..0202a81 100644 --- a/themes/classic.ted.cfg +++ b/themes/classic.ted.cfg @@ -67,6 +67,7 @@ character = #fa7 builtin = #a7f comment = #999 constant = #8ff +todo = #f44 line-numbers = #779 cursor-line-number = #ddf diff --git a/themes/extradark.ted.cfg b/themes/extradark.ted.cfg index 0b3603e..808d975 100644 --- a/themes/extradark.ted.cfg +++ b/themes/extradark.ted.cfg @@ -43,6 +43,7 @@ string = #f40 character = #fa0 builtin = #c0f comment = #999 +todo = #f00 constant = #0ff line-numbers = #8a8 cursor-line-number = #dfd -- cgit v1.2.3