Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <stdlib.h> | ||
2 | #include <string.h> | ||
3 | #include "color.h" | ||
4 | #include "command/serialize.h" | ||
5 | #include "util/array.h" | ||
6 | #include "util/bsearch.h" | ||
7 | #include "util/debug.h" | ||
8 | #include "util/xmalloc.h" | ||
9 | |||
10 | static const char builtin_style_names[NR_BSE][16] = { | ||
11 | [BSE_ACTIVETAB] = "activetab", | ||
12 | [BSE_COMMANDLINE] = "commandline", | ||
13 | [BSE_CURRENTLINE] = "currentline", | ||
14 | [BSE_DEFAULT] = "default", | ||
15 | [BSE_DIALOG] = "dialog", | ||
16 | [BSE_ERRORMSG] = "errormsg", | ||
17 | [BSE_INACTIVETAB] = "inactivetab", | ||
18 | [BSE_INFOMSG] = "infomsg", | ||
19 | [BSE_LINENUMBER] = "linenumber", | ||
20 | [BSE_NOLINE] = "noline", | ||
21 | [BSE_NONTEXT] = "nontext", | ||
22 | [BSE_SELECTION] = "selection", | ||
23 | [BSE_STATUSLINE] = "statusline", | ||
24 | [BSE_TABBAR] = "tabbar", | ||
25 | [BSE_WSERROR] = "wserror", | ||
26 | }; | ||
27 | |||
28 | 18 | UNITTEST { | |
29 | 18 | CHECK_BSEARCH_STR_ARRAY(builtin_style_names, strcmp); | |
30 | 18 | } | |
31 | |||
32 | 9282 | static TermStyle *find_real_style(StyleMap *styles, const char *name) | |
33 | { | ||
34 | 9282 | ssize_t idx = BSEARCH_IDX(name, builtin_style_names, vstrcmp); | |
35 |
2/2✓ Branch 0 (3→4) taken 209 times.
✓ Branch 1 (3→7) taken 9073 times.
|
9282 | if (idx >= 0) { |
36 | 209 | BUG_ON(idx >= ARRAYLEN(builtin_style_names)); | |
37 | 209 | return &styles->builtin[idx]; | |
38 | } | ||
39 | 9073 | return hashmap_get(&styles->other, name); | |
40 | } | ||
41 | |||
42 | 8858 | static const TermStyle *find_real_style_const(const StyleMap *styles, const char *name) | |
43 | { | ||
44 | 8858 | return find_real_style((StyleMap*)styles, name); | |
45 | } | ||
46 | |||
47 | 424 | void set_highlight_style(StyleMap *styles, const char *name, const TermStyle *style) | |
48 | { | ||
49 | 424 | TermStyle *existing = find_real_style(styles, name); | |
50 |
2/2✓ Branch 0 (3→4) taken 208 times.
✓ Branch 1 (3→5) taken 216 times.
|
424 | if (existing) { |
51 | 208 | *existing = *style; | |
52 | } else { | ||
53 | 216 | hashmap_insert(&styles->other, xstrdup(name), XMEMDUP(style)); | |
54 | } | ||
55 | 424 | } | |
56 | |||
57 | 4475 | const TermStyle *find_style(const StyleMap *styles, const char *name) | |
58 | { | ||
59 | 4475 | const TermStyle *style = find_real_style_const(styles, name); | |
60 |
2/2✓ Branch 0 (3→4) taken 4383 times.
✓ Branch 1 (3→6) taken 92 times.
|
4475 | if (style) { |
61 | return style; | ||
62 | } | ||
63 | |||
64 | 4383 | const char *dot = strchr(name, '.'); | |
65 |
1/2✓ Branch 0 (4→5) taken 4383 times.
✗ Branch 1 (4→6) not taken.
|
4383 | return dot ? find_real_style_const(styles, dot + 1) : NULL; |
66 | } | ||
67 | |||
68 | 12 | void clear_hl_styles(StyleMap *styles) | |
69 | { | ||
70 | 12 | hashmap_clear(&styles->other, free); | |
71 | 12 | } | |
72 | |||
73 | 1 | void collect_builtin_styles(PointerArray *a, const char *prefix) | |
74 | { | ||
75 | 1 | COLLECT_STRINGS(builtin_style_names, a, prefix); | |
76 | 1 | } | |
77 | |||
78 | typedef struct { | ||
79 | const char *name; | ||
80 | TermStyle style; | ||
81 | } HlStyle; | ||
82 | |||
83 | 146 | static int hlstyle_cmp(const void *ap, const void *bp) | |
84 | { | ||
85 | 146 | const HlStyle *a = ap; | |
86 | 146 | const HlStyle *b = bp; | |
87 | 146 | return strcmp(a->name, b->name); | |
88 | } | ||
89 | |||
90 | 51 | void string_append_hl_style(String *s, const char *name, const TermStyle *style) | |
91 | { | ||
92 | 51 | string_append_literal(s, "hi "); | |
93 | 51 | string_append_escaped_arg(s, name, true); | |
94 | 51 | string_append_byte(s, ' '); | |
95 |
1/2✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 51 times.
|
51 | if (unlikely(name[0] == '-')) { |
96 | ✗ | string_append_literal(s, "-- "); | |
97 | } | ||
98 | 51 | char buf[TERM_STYLE_BUFSIZE]; | |
99 | 51 | string_append_cstring(s, term_style_to_string(buf, style)); | |
100 | 51 | } | |
101 | |||
102 | 1 | String dump_hl_styles(const StyleMap *styles) | |
103 | { | ||
104 | 1 | String buf = string_new(4096); | |
105 | 1 | string_append_literal(&buf, "# UI colors:\n"); | |
106 |
2/2✓ Branch 0 (8→5) taken 15 times.
✓ Branch 1 (8→9) taken 1 times.
|
16 | for (size_t i = 0; i < NR_BSE; i++) { |
107 | 15 | string_append_hl_style(&buf, builtin_style_names[i], &styles->builtin[i]); | |
108 | 15 | string_append_byte(&buf, '\n'); | |
109 | } | ||
110 | |||
111 | 1 | const HashMap *hl_styles = &styles->other; | |
112 | 1 | const size_t count = hl_styles->count; | |
113 |
1/2✗ Branch 0 (9→10) not taken.
✓ Branch 1 (9→11) taken 1 times.
|
1 | if (unlikely(count == 0)) { |
114 | ✗ | return buf; | |
115 | } | ||
116 | |||
117 | // Copy the HashMap entries into an array | ||
118 | 1 | HlStyle *array = xnew(HlStyle, count); | |
119 | 1 | size_t n = 0; | |
120 |
2/2✓ Branch 0 (15→13) taken 36 times.
✓ Branch 1 (15→16) taken 1 times.
|
37 | for (HashMapIter it = hashmap_iter(hl_styles); hashmap_next(&it); ) { |
121 | 36 | const TermStyle *style = it.entry->value; | |
122 | 36 | array[n++] = (HlStyle) { | |
123 | 36 | .name = it.entry->key, | |
124 | 36 | .style = *style, | |
125 | }; | ||
126 | } | ||
127 | |||
128 | // Sort the array | ||
129 | 1 | BUG_ON(n != count); | |
130 | 1 | qsort(array, count, sizeof(array[0]), hlstyle_cmp); | |
131 | |||
132 | 1 | string_append_literal(&buf, "\n# Syntax colors:\n"); | |
133 |
2/2✓ Branch 0 (24→21) taken 36 times.
✓ Branch 1 (24→25) taken 1 times.
|
37 | for (size_t i = 0; i < count; i++) { |
134 | 36 | string_append_hl_style(&buf, array[i].name, &array[i].style); | |
135 | 36 | string_append_byte(&buf, '\n'); | |
136 | } | ||
137 | |||
138 | 1 | free(array); | |
139 | 1 | return buf; | |
140 | } | ||
141 |