hare

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

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 };