MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

improve string highlighting

+43 -21
-1
include/highlight.h
··· 34 34 HL_STRING_DELIMITER, 35 35 HL_STRING_ESCAPE, 36 36 HL_STRING_KEY, 37 - HL_STRING_KEYWORD, 38 37 HL_STRING_TEMPLATE, 39 38 HL_REGEX, 40 39 HL_REGEX_ESCAPE,
+43 -20
src/highlight.c
··· 29 29 30 30 static hl_token_class lookup_extra_keyword(const char *word, size_t len) { 31 31 switch (word[0]) { 32 - case 'a': K("abstract", HL_TYPE); break; 32 + case 'a': 33 + K("abstract", HL_TYPE); 34 + K("async", HL_KEYWORD_ITALIC); 35 + break; 33 36 case 'b': K("boolean", HL_TYPE_BOOLEAN); break; 34 37 case 'd': K("declare", HL_TYPE); break; 35 - case 'e': K("enum", HL_TYPE); break; 38 + case 'e': 39 + K("enum", HL_TYPE); 40 + K("export", HL_KEYWORD_ITALIC); 41 + break; 36 42 case 'g': K("global", HL_KEYWORD_ITALIC); break; 37 43 case 'i': 38 44 K("interface", HL_TYPE); ··· 208 214 } 209 215 210 216 static size_t skip_inline_ws_forward(const char *input, size_t input_len, size_t i) { 211 - while (i < input_len && (input[i] == ' ' || input[i] == '\t')) i++; 217 + while (i < input_len && (input[i] == ' ' || input[i] == '\t' || input[i] == '\n' || input[i] == '\r')) i++; 212 218 return i; 213 219 } 214 220 215 221 static size_t skip_inline_ws_backward(const char *input, size_t i) { 216 - while (i > 0 && (input[i - 1] == ' ' || input[i - 1] == '\t')) i--; 222 + while (i > 0 && (input[i - 1] == ' ' || input[i - 1] == '\t' || input[i - 1] == '\n' || input[i - 1] == '\r')) i--; 217 223 return i; 218 224 } 219 225 ··· 229 235 return true; 230 236 } 231 237 238 + static bool is_arrow_after(const char *input, size_t input_len, size_t pos) { 239 + size_t i = skip_inline_ws_forward(input, input_len, pos); 240 + return (i + 1 < input_len && input[i] == '=' && input[i + 1] == '>'); 241 + } 242 + 232 243 static bool has_function_keyword_before_paren(const char *input, size_t open_paren) { 233 244 size_t word_start = 0; 234 245 size_t word_len = 0; ··· 240 251 return (word_len == 8 && memcmp(input + word_start, "function", 8) == 0); 241 252 } 242 253 254 + static bool is_control_paren_prefix(const char *input, size_t open_paren) { 255 + size_t word_start = 0; 256 + size_t word_len = 0; 257 + if (!read_prev_word(input, open_paren, &word_start, &word_len)) return false; 258 + 259 + #define C(s) (word_len == sizeof(s) - 1 && memcmp(input + word_start, s, sizeof(s) - 1) == 0) 260 + return C("if") || C("for") || C("while") || C("switch") || C("catch") || C("with"); 261 + #undef C 262 + } 263 + 264 + static bool is_likely_function_param_paren( 265 + const char *input, size_t input_len, 266 + size_t open_paren, size_t close_paren 267 + ) { 268 + if (is_arrow_after(input, input_len, close_paren + 1)) return true; 269 + if (has_function_keyword_before_paren(input, open_paren)) return true; 270 + 271 + size_t after = skip_inline_ws_forward(input, input_len, close_paren + 1); 272 + if (after < input_len && input[after] == '{' && !is_control_paren_prefix(input, open_paren)) 273 + return true; 274 + 275 + return false; 276 + } 277 + 243 278 static bool find_enclosing_open_paren(const char *input, size_t pos, size_t *open_paren) { 244 279 size_t depth = 0; 245 280 size_t i = pos; ··· 281 316 return false; 282 317 } 283 318 284 - static bool is_arrow_after(const char *input, size_t input_len, size_t pos) { 285 - size_t i = skip_inline_ws_forward(input, input_len, pos); 286 - return (i + 1 < input_len && input[i] == '=' && input[i + 1] == '>'); 287 - } 288 - 289 319 static bool is_function_argument_identifier(const char *input, size_t input_len, size_t start, size_t end) { 290 320 if (is_arrow_after(input, input_len, end)) { 291 321 size_t left = skip_inline_ws_backward(input, start); ··· 296 326 size_t prev = skip_inline_ws_backward(input, start); 297 327 if (prev == 0) return false; 298 328 unsigned char prev_ch = (unsigned char)input[prev - 1]; 299 - if (!(prev_ch == '(' || prev_ch == ',')) return false; 329 + if (!(prev_ch == '(' || prev_ch == ',' || prev_ch == '{' || prev_ch == '[' || prev_ch == ':')) 330 + return false; 300 331 301 332 size_t open_paren = 0; 302 333 if (!find_enclosing_open_paren(input, start, &open_paren)) return false; 303 334 304 335 size_t close_paren = 0; 305 - if (find_matching_close_paren(input, input_len, open_paren, &close_paren) && 306 - is_arrow_after(input, input_len, close_paren + 1)) 307 - return true; 308 - 309 - return has_function_keyword_before_paren(input, open_paren); 336 + if (!find_matching_close_paren(input, input_len, open_paren, &close_paren)) return false; 337 + return is_likely_function_param_paren(input, input_len, open_paren, close_paren); 310 338 } 311 339 312 340 bool hl_iter_next(hl_iter *it, hl_span *out) { ··· 691 719 case HL_STRING_DELIMITER: return "#FF7265"; 692 720 case HL_STRING_ESCAPE: return "#F4AAA3"; 693 721 case HL_STRING_KEY: return "#CCA3F4"; 694 - case HL_STRING_KEYWORD: return "#FFE5CC"; 695 722 case HL_STRING_TEMPLATE: return "#FFB265"; 696 723 697 724 case HL_REGEX: return "#FFB265"; ··· 843 870 const char *piece = input + span.off; 844 871 hl_token_class body_cls = HL_STRING; 845 872 if (span_is_template_string(piece, span.len)) body_cls = HL_STRING_TEMPLATE; 846 - else if (is_string_key_context(input, input_len, span.off, span.len)) body_cls = HL_STRING_KEY; 847 - else if (is_string_keyword_literal(piece, span.len)) body_cls = HL_STRING_KEYWORD; 848 873 ob_write_string_literal(&o, piece, span.len, body_cls); 849 874 } else if (span.cls == HL_REGEX) ob_write_regex_literal(&o, input + span.off, span.len); 850 875 else ob_write_with_class(&o, span.cls, input + span.off, span.len); ··· 899 924 const char *piece = line + span.off; 900 925 hl_token_class body_cls = HL_STRING; 901 926 if (span_is_template_string(piece, emit_len)) body_cls = HL_STRING_TEMPLATE; 902 - else if (is_string_key_context(line, line_len, span.off, emit_len)) body_cls = HL_STRING_KEY; 903 - else if (is_string_keyword_literal(piece, emit_len)) body_cls = HL_STRING_KEYWORD; 904 927 ob_write_string_literal(&o, piece, emit_len, body_cls); 905 928 } else if (span.cls == HL_REGEX) ob_write_regex_literal(&o, line + span.off, emit_len); 906 929 else ob_write_with_class(&o, span.cls, line + span.off, emit_len);