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.

add private method colors

+130 -27
+5
include/highlight.h
··· 31 31 HL_TYPE_BOOLEAN, 32 32 HL_LITERAL_NULL, 33 33 HL_STRING, 34 + HL_STRING_DELIMITER, 35 + HL_STRING_ESCAPE, 36 + HL_STRING_KEY, 37 + HL_STRING_KEYWORD, 38 + HL_STRING_TEMPLATE, 34 39 HL_REGEX, 35 40 HL_REGEX_ESCAPE, 36 41 HL_REGEX_DELIMITER,
+125 -27
src/highlight.c
··· 502 502 } 503 503 } 504 504 505 + if (c == '#' && i + 1 < input_len && is_ident_begin((unsigned char)input[i + 1])) { 506 + size_t start = i; 507 + i += 2; 508 + while (i < input_len && is_ident_continue((unsigned char)input[i])) i++; 509 + it->ctx = HL_CTX_NONE; 510 + *out = (hl_span){ start, i - start, HL_PROPERTY }; 511 + it->pos = i; 512 + return true; 513 + } 514 + 505 515 if (is_ident_begin(c)) { 506 516 size_t start = i; 507 517 i++; ··· 644 654 for (size_t i = 0; i < n; i++) ob_put_escaped(o, s[i]); 645 655 } 646 656 657 + static bool span_is_template_string(const char *s, size_t n) { 658 + for (size_t i = 0; i < n; i++) { 659 + if (s[i] == '`') return true; 660 + if (s[i] == '$' && i + 1 < n && s[i + 1] == '{') return true; 661 + } 662 + return false; 663 + } 664 + 665 + static bool is_string_key_context(const char *input, size_t input_len, size_t off, size_t len) { 666 + size_t i = off + len; 667 + while (i < input_len && (input[i] == ' ' || input[i] == '\t')) i++; 668 + return (i < input_len && input[i] == ':' && (i + 1 >= input_len || input[i + 1] != ':')); 669 + } 670 + 671 + static bool is_string_keyword_literal(const char *s, size_t n) { 672 + if (n < 2) return false; 673 + if (!((s[0] == '"' && s[n - 1] == '"') || (s[0] == '\'' && s[n - 1] == '\''))) return false; 674 + 675 + const char *inner = s + 1; 676 + size_t len = n - 2; 677 + 678 + #define SKW(w) (len == sizeof(w) - 1 && memcmp(inner, w, sizeof(w) - 1) == 0) 679 + return SKW("true") || SKW("false") || SKW("null") || SKW("undefined") || 680 + SKW("NaN") || SKW("Infinity"); 681 + #undef SKW 682 + } 683 + 647 684 static const char *class_to_crvar(hl_token_class cls) { 648 685 switch (cls) { 649 - case HL_STRING: return "green"; 650 686 case HL_NUMBER: return "yellow"; 651 687 case HL_BOOLEAN: return "magenta"; 652 688 653 - case HL_REGEX: return "#FFB265"; 654 - case HL_REGEX_ESCAPE: return "#FFCC99"; 655 - case HL_REGEX_DELIMITER: return "#FF9932"; 656 - case HL_REGEX_CDATA: return "#65B2FF"; 689 + case HL_STRING: return "#FF8A7F"; 690 + case HL_STRING_DELIMITER: return "#FF7265"; 691 + case HL_STRING_ESCAPE: return "#F4AAA3"; 692 + case HL_STRING_KEY: return "#CCA3F4"; 693 + case HL_STRING_KEYWORD: return "#FFE5CC"; 694 + case HL_STRING_TEMPLATE: return "#FFB265"; 695 + 696 + case HL_REGEX: return "#FFB265"; 697 + case HL_REGEX_ESCAPE: return "#FFCC99"; 698 + case HL_REGEX_DELIMITER: return "#FF9932"; 699 + case HL_REGEX_CDATA: return "#65B2FF"; 657 700 658 - case HL_KEYWORD: return "#65B2FF"; 659 - case HL_KEYWORD_DELETE: return "#F43D3D"; 660 - case HL_TYPE: return "#59D8F1"; 661 - case HL_TYPE_STRING: return "#30E8AA"; 662 - case HL_TYPE_BOOLEAN: return "#30E8AA"; 663 - case HL_LITERAL_NULL: return "#242628"; 664 - case HL_COMMENT: return "#758CA3"; 665 - case HL_FUNCTION_NAME: return "#30E8AA"; 666 - case HL_FUNCTION: return "#30E8AA"; 667 - case HL_ARGUMENT: return "#CCA3F4"; 668 - case HL_PROPERTY: return "#CCA3F4"; 669 - case HL_OPERATOR: return "#8CB2D8"; 670 - case HL_OPTIONAL_CHAIN: return "#8CB2D8"; 671 - case HL_BRACKET: return "#8CB2D8"; 672 - case HL_SEMICOLON: return "#B2CCE5"; 701 + case HL_KEYWORD: return "#65B2FF"; 702 + case HL_KEYWORD_DELETE: return "#F43D3D"; 703 + case HL_TYPE: return "#59D8F1"; 704 + case HL_TYPE_STRING: return "#30E8AA"; 705 + case HL_TYPE_BOOLEAN: return "#30E8AA"; 706 + case HL_LITERAL_NULL: return "#242628"; 707 + case HL_COMMENT: return "#758CA3"; 708 + case HL_FUNCTION_NAME: return "#30E8AA"; 709 + case HL_FUNCTION: return "#30E8AA"; 710 + case HL_ARGUMENT: return "#CCA3F4"; 711 + case HL_PROPERTY: return "#CCA3F4"; 712 + case HL_OPERATOR: return "#8CB2D8"; 713 + case HL_OPTIONAL_CHAIN: return "#8CB2D8"; 714 + case HL_BRACKET: return "#8CB2D8"; 715 + case HL_SEMICOLON: return "#B2CCE5"; 673 716 674 - case HL_KEYWORD_ITALIC: return "italic+#65B2FF"; 675 - case HL_CLASS_NAME: return "bold+#F7B76D"; 676 - case HL_PARENT_CLASS: return "bold+#59D8F1"; 677 - case HL_KEYWORD_EXTENDS: return "italic+#59D8F1"; 717 + case HL_KEYWORD_ITALIC: return "italic+#65B2FF"; 718 + case HL_CLASS_NAME: return "bold+#F7B76D"; 719 + case HL_PARENT_CLASS: return "bold+#59D8F1"; 720 + case HL_KEYWORD_EXTENDS: return "italic+#59D8F1"; 678 721 679 - default: return NULL; 722 + default: return NULL; 680 723 }} 681 724 682 725 static inline void ob_write_with_class(outbuf_t *o, hl_token_class cls, const char *s, size_t n) { ··· 692 735 } else ob_write_escaped(o, s, n); 693 736 } 694 737 738 + static void ob_write_string_literal(outbuf_t *o, const char *s, size_t n, hl_token_class body_cls) { 739 + if (n == 0) return; 740 + 741 + size_t i = 0; 742 + size_t seg_start = 0; 743 + 744 + while (i < n) { 745 + unsigned char ch = (unsigned char)s[i]; 746 + 747 + if (ch == '\\') { 748 + ob_write_with_class(o, body_cls, s + seg_start, i - seg_start); 749 + size_t esc_len = (i + 1 < n) ? 2 : 1; 750 + ob_write_with_class(o, HL_STRING_ESCAPE, s + i, esc_len); 751 + i += esc_len; 752 + seg_start = i; 753 + continue; 754 + } 755 + 756 + if (ch == '"' || ch == '\'' || ch == '`') { 757 + ob_write_with_class(o, body_cls, s + seg_start, i - seg_start); 758 + ob_write_with_class(o, HL_STRING_DELIMITER, s + i, 1); 759 + i++; 760 + seg_start = i; 761 + continue; 762 + } 763 + 764 + if (ch == '$' && i + 1 < n && s[i + 1] == '{') { 765 + ob_write_with_class(o, body_cls, s + seg_start, i - seg_start); 766 + ob_write_with_class(o, HL_BRACKET, s + i, 1); 767 + ob_write_with_class(o, HL_BRACKET, s + i + 1, 1); 768 + i += 2; 769 + seg_start = i; 770 + continue; 771 + } 772 + 773 + i++; 774 + } 775 + 776 + ob_write_with_class(o, body_cls, s + seg_start, n - seg_start); 777 + } 778 + 695 779 static void ob_write_regex_literal(outbuf_t *o, const char *s, size_t n) { 696 780 if (n == 0) return; 697 781 ··· 755 839 756 840 hl_span span; 757 841 while (hl_iter_next(&it, &span) && !o.overflow) { 758 - if (span.cls == HL_REGEX) ob_write_regex_literal(&o, input + span.off, span.len); 842 + if (span.cls == HL_STRING) { 843 + const char *piece = input + span.off; 844 + hl_token_class body_cls = HL_STRING; 845 + 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 + ob_write_string_literal(&o, piece, span.len, body_cls); 849 + } else if (span.cls == HL_REGEX) ob_write_regex_literal(&o, input + span.off, span.len); 759 850 else ob_write_with_class(&o, span.cls, input + span.off, span.len); 760 851 } 761 852 ··· 804 895 size_t emit_len = span.len < span_remaining ? span.len : span_remaining; 805 896 806 897 if (!o.overflow) { 807 - if (span.cls == HL_REGEX) ob_write_regex_literal(&o, line + span.off, emit_len); 898 + if (span.cls == HL_STRING) { 899 + const char *piece = line + span.off; 900 + hl_token_class body_cls = HL_STRING; 901 + 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 + ob_write_string_literal(&o, piece, emit_len, body_cls); 905 + } else if (span.cls == HL_REGEX) ob_write_regex_literal(&o, line + span.off, emit_len); 808 906 else ob_write_with_class(&o, span.cls, line + span.off, emit_len); 809 907 } 810 908