color.ha (2901B)
1 // SPDX-License-Identifier: GPL-3.0-only 2 // (c) Hare authors <https://harelang.org> 3 4 use fmt; 5 use hare::unparse; 6 use io; 7 use os; 8 use regex; 9 use strings; 10 11 // Colors/Renditions with defaults; SGR parameters for ANSI escape sequences. 12 const default_colors = [ 13 "_", // ident 14 "1", // comment 15 "_", // constant 16 "_", // function 17 "_", // global 18 "_", // typedef 19 "_", // import_alias 20 "_", // secondary 21 "94", // keyword 22 "96", // type 23 "33", // attribute 24 "1", // operator 25 "_", // punctuation 26 "91", // rune_string 27 "95", // number 28 "_", // label 29 ]; 30 31 let colors: [len(default_colors)]str = [""...]; 32 let normal_color = ""; 33 let primary_color = ""; 34 35 fn init_colors() (void | error) = { 36 const env_colors = os::tryenv("HAREDOC_COLORS", ""); 37 38 const expr = regex::compile(`([a-z_]+)=(_|[0-9;]*)`)!; 39 defer regex::finish(&expr); 40 41 const matches = regex::findall(&expr, env_colors); 42 defer regex::result_freeall(matches); 43 44 for (let m .. matches) { 45 let (k, v) = (m[1].content, m[2].content); 46 47 let idx = 0z; 48 let out: *str = switch (k) { 49 case "ident" => 50 yield &colors[unparse::synkind::IDENT]; 51 case "comment" => 52 yield &colors[unparse::synkind::COMMENT]; 53 case "constant" => 54 yield &colors[unparse::synkind::CONSTANT]; 55 case "function" => 56 yield &colors[unparse::synkind::FUNCTION]; 57 case "global" => 58 yield &colors[unparse::synkind::GLOBAL]; 59 case "typedef" => 60 yield &colors[unparse::synkind::TYPEDEF]; 61 case "import_alias" => 62 yield &colors[unparse::synkind::IMPORT_ALIAS]; 63 case "secondary" => 64 yield &colors[unparse::synkind::SECONDARY]; 65 case "keyword" => 66 yield &colors[unparse::synkind::KEYWORD]; 67 case "type" => 68 yield &colors[unparse::synkind::TYPE]; 69 case "attribute" => 70 yield &colors[unparse::synkind::ATTRIBUTE]; 71 case "operator" => 72 yield &colors[unparse::synkind::OPERATOR]; 73 case "punctuation" => 74 yield &colors[unparse::synkind::PUNCTUATION]; 75 case "rune_string" => 76 yield &colors[unparse::synkind::RUNE_STRING]; 77 case "number" => 78 yield &colors[unparse::synkind::NUMBER]; 79 case "label" => 80 yield &colors[unparse::synkind::LABEL]; 81 case "normal" => 82 yield &normal_color; 83 case "primary" => 84 yield &primary_color; 85 case => 86 static let err: [64]u8 = [0...]; 87 if (len(k) > len(err)) { 88 return "": haredoc_colors_error; 89 }; 90 return fmt::bsprint(err, k): haredoc_colors_error; 91 }; 92 93 *out = if (v == "_" && k == "normal") "0" else v; 94 }; 95 }; 96 97 fn color(kind: unparse::synkind) str = { 98 const color = if (colors[kind] != "") colors[kind] 99 else default_colors[kind]; 100 if (color != "_") { 101 return color; 102 }; 103 104 if (primary_color != "" && primary_color != "_") { 105 switch (kind) { 106 case unparse::synkind::CONSTANT, 107 unparse::synkind::FUNCTION, 108 unparse::synkind::GLOBAL, 109 unparse::synkind::TYPEDEF => 110 return primary_color; 111 case => void; 112 }; 113 }; 114 115 return if (normal_color == "") "0" else normal_color; 116 };