Blob


1 /*
2 * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #include "telescope.h"
19 #include <curses.h>
20 #include <limits.h>
21 #include <stdlib.h>
22 #include <string.h>
24 char *new_tab_url = NULL;
25 int fill_column = 80;
26 int olivetti_mode = 1;
27 int enable_colors = 1;
29 struct lineprefix line_prefixes[] = {
30 [LINE_TEXT] = { "", "" },
31 [LINE_LINK] = { "=> ", " " },
32 [LINE_TITLE_1] = { "# ", " " },
33 [LINE_TITLE_2] = { "## ", " " },
34 [LINE_TITLE_3] = { "### ", " " },
35 [LINE_ITEM] = { "* ", " " },
36 [LINE_QUOTE] = { "> ", " " },
37 [LINE_PRE_START] = { "```", " " },
38 [LINE_PRE_CONTENT] = { "", "" },
39 [LINE_PRE_END] = { "```", "```" },
40 };
42 struct line_face line_faces[] = {
43 [LINE_TEXT] = {
44 .prfx_pair = PT_PRFX,
45 .pair = PT,
46 .trail_pair = PT_TRAIL,
47 },
48 [LINE_LINK] = {
49 .prfx_pair = PL_PRFX,
50 .pair = PL,
51 .trail_pair = PL_TRAIL,
52 .attr = A_UNDERLINE,
53 },
54 [LINE_TITLE_1] = {
55 .prfx_pair = PT1_PRFX,
56 .pair = PT1,
57 .trail_pair = PT1_TRAIL,
58 .attr = A_BOLD,
59 },
60 [LINE_TITLE_2] = {
61 .prfx_pair = PT2_PRFX,
62 .pair = PT2,
63 .trail_pair = PT2_TRAIL,
64 .attr = A_BOLD,
65 },
66 [LINE_TITLE_3] = {
67 .prfx_pair = PT3_PRFX,
68 .pair = PT3,
69 .trail_pair = PT3_TRAIL,
70 .attr = A_BOLD,
71 },
72 [LINE_ITEM] = {
73 .prfx_pair = PI_PRFX,
74 .pair = PI,
75 .trail_pair = PI_TRAIL,
76 },
77 [LINE_QUOTE] = {
78 .prfx_pair = PQ_PRFX,
79 .pair = PQ,
80 .trail_pair = PQ_TRAIL,
81 .attr = A_DIM,
82 },
83 [LINE_PRE_START] = {
84 .prfx_pair = PPSTART_PRFX,
85 .pair = PPSTART,
86 .trail_pair = PPSTART_TRAIL,
87 },
88 [LINE_PRE_CONTENT] = {
89 .prfx_pair = PP_PRFX,
90 .pair = PP,
91 .trail_pair = PP_TRAIL,
92 },
93 [LINE_PRE_END] = {
94 .prfx_pair = PPEND_PRFX,
95 .pair = PPEND,
96 .trail_pair = PPEND_TRAIL,
97 },
98 };
100 struct tab_face tab_face = {
101 .bg_attr = A_REVERSE, .bg_bg = -1, .bg_fg = -1,
102 .t_attr = A_REVERSE, .t_bg = -1, .t_fg = -1,
103 .c_attr = A_NORMAL, .c_bg = -1, .c_fg = -1,
105 /*
106 * set these so that even when enable-color=0 the bar has some
107 * sane defaults.
108 */
109 .background = A_REVERSE,
110 .tab = A_REVERSE,
111 .current = A_NORMAL,
112 };
114 struct body_face body_face = {
115 .lbg = -1, .lfg = -1,
116 .bg = -1, .fg = -1,
117 .rbg = -1, .rfg = -1,
118 };
120 struct modeline_face modeline_face = {
121 .background = A_REVERSE,
122 };
124 struct minibuffer_face minibuffer_face = {
125 .background = A_NORMAL,
126 };
128 struct mapping {
129 const char *label;
130 int linetype;
131 } mappings[] = {
132 {"text", LINE_TEXT},
133 {"link", LINE_LINK},
134 {"title1", LINE_TITLE_1},
135 {"title2", LINE_TITLE_2},
136 {"title3", LINE_TITLE_3},
137 {"item", LINE_ITEM},
138 {"quote", LINE_QUOTE},
139 {"pre.start", LINE_PRE_START},
140 {"pre", LINE_PRE_CONTENT},
141 {"pre.end", LINE_PRE_END},
142 };
144 static struct mapping *
145 mapping_by_name(const char *name)
147 size_t i;
149 for (i = 0; i < sizeof(mappings)/sizeof(mappings[0]); ++i) {
150 if (!strcmp(name, mappings[i].label))
151 return &mappings[i];
154 return NULL;
157 void
158 config_init(void)
160 struct line_face *f;
161 size_t i, len;
163 len = sizeof(line_faces)/sizeof(line_faces[0]);
164 for (i = 0; i < len; ++i) {
165 f = &line_faces[i];
167 f->prfx_bg = f->bg = f->trail_bg = -1;
168 f->prfx_fg = f->fg = f->trail_fg = -1;
171 line_faces[LINE_LINK].fg = COLOR_BLUE;
174 int
175 config_setprfx(const char *name, const char *prfx, const char *cont)
177 struct lineprefix *p;
178 struct mapping *m;
180 if (!has_prefix(name, "line."))
181 return 0;
182 name += 5;
184 if ((m = mapping_by_name(name)) == NULL)
185 return 0;
187 p = &line_prefixes[m->linetype];
188 p->prfx1 = prfx;
189 p->prfx2 = cont;
191 return 1;
194 int
195 config_setvari(const char *var, int val)
197 if (!strcmp(var, "fill-column")) {
198 if ((fill_column = val) <= 0)
199 fill_column = INT_MAX;
200 } else if (!strcmp(var, "olivetti-mode")) {
201 olivetti_mode = !!val;
202 } else if (!strcmp(var, "enable-colors")) {
203 enable_colors = !!val;
204 } else {
205 return 0;
208 return 1;
211 int
212 config_setvars(const char *var, char *val)
214 if (!strcmp(var, "new-tab-url")) {
215 if (new_tab_url != NULL)
216 free(new_tab_url);
217 new_tab_url = val;
218 } else
219 return 0;
220 return 1;
223 int
224 config_setcolor(int bg, const char *name, int prfx, int line, int trail)
226 struct mapping *m;
227 struct line_face *f;
229 if (!strcmp(name, "tabline")) {
230 if (bg)
231 tab_face.bg_bg = prfx;
232 else
233 tab_face.bg_fg = prfx;
234 } else if (has_prefix(name, "tabline.")) {
235 name += 8;
237 if (!strcmp(name, "tab")) {
238 if (bg)
239 tab_face.t_bg = prfx;
240 else
241 tab_face.t_fg = prfx;
242 } else if (!strcmp(name, "current")) {
243 if (bg)
244 tab_face.c_bg = prfx;
245 else
246 tab_face.c_fg = prfx;
247 } else
248 return 0;
249 } else if (has_prefix(name, "line.")) {
250 name += 5;
252 if ((m = mapping_by_name(name)) == NULL)
253 return 0;
255 f = &line_faces[m->linetype];
257 if (bg) {
258 f->prfx_bg = prfx;
259 f->bg = line;
260 f->trail_bg = trail;
261 } else {
262 f->prfx_fg = prfx;
263 f->fg = line;
264 f->trail_fg = trail;
266 } else if (!strcmp(name, "line")) {
267 if (bg) {
268 body_face.lbg = prfx;
269 body_face.bg = line;
270 body_face.rbg = trail;
271 } else {
272 body_face.fg = prfx;
273 body_face.fg = line;
274 body_face.fg = trail;
276 } else {
277 return 0;
280 return 1;
283 int
284 config_setattr(const char *name, int prfx, int line, int trail)
286 struct mapping *m;
287 struct line_face *f;
289 if (!strcmp(name, "tabline")) {
290 tab_face.bg_attr = prfx;
291 } else if (has_prefix(name, "tabline.")) {
292 name += 8;
294 if (!strcmp(name, "tab"))
295 tab_face.t_attr = prfx;
296 else if (!strcmp(name, "current"))
297 tab_face.c_attr = prfx;
298 else
299 return 0;
300 } else if (has_prefix(name, "line.")) {
301 name += 5;
303 if ((m = mapping_by_name(name)) == NULL)
304 return 0;
306 f = &line_faces[m->linetype];
308 f->prfx_attr = prfx;
309 f->attr = line;
310 f->trail_attr = trail;
311 } else {
312 return 0;
315 return 1;
318 static inline void
319 tl_init_pair(int colors, int pair, int f, int b)
321 if (f >= colors || !enable_colors)
322 f = -1;
323 if (b >= colors || !enable_colors)
324 b = -1;
325 init_pair(pair, f, b);
328 void
329 config_apply_style(void)
331 size_t i, colors, len;
332 struct line_face *f;
334 colors = COLORS;
336 len = sizeof(line_faces)/sizeof(line_faces[0]);
337 for (i = 0; i < len; ++i) {
338 f = &line_faces[i];
340 tl_init_pair(colors, f->prfx_pair, f->prfx_fg, f->prfx_bg);
341 f->prefix = COLOR_PAIR(f->prfx_pair) | f->prfx_attr;
343 tl_init_pair(colors, f->pair, f->fg, f->bg);
344 f->text = COLOR_PAIR(f->pair) | f->attr;
346 tl_init_pair(colors, f->trail_pair, f->trail_fg, f->trail_bg);
347 f->trail = COLOR_PAIR(f->trail_pair) | f->trail_attr;
350 /* tab line */
351 tl_init_pair(colors, PTL_BG, tab_face.bg_fg, tab_face.bg_bg);
352 tab_face.background = COLOR_PAIR(PTL_BG) | tab_face.bg_attr;
354 tl_init_pair(colors, PTL_TAB, tab_face.t_fg, tab_face.t_bg);
355 tab_face.tab = COLOR_PAIR(PTL_TAB) | tab_face.t_attr;
357 tl_init_pair(colors, PTL_CURR, tab_face.c_fg, tab_face.c_bg);
358 tab_face.current = COLOR_PAIR(PTL_CURR) | tab_face.c_attr;
360 /* body */
361 tl_init_pair(colors, PBODY, body_face.fg, body_face.bg);
362 body_face.body = COLOR_PAIR(PBODY);
364 tl_init_pair(colors, PBLEFT, body_face.lfg, body_face.lbg);
365 body_face.left = COLOR_PAIR(PBLEFT);
367 tl_init_pair(colors, PBRIGHT, body_face.rfg, body_face.rbg);
368 body_face.right = COLOR_PAIR(PBRIGHT);