hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

color.ha (2880B)


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