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 .bg = -1,
122 .fg = -1,
123 .attr = A_REVERSE,
124 };
126 struct minibuffer_face minibuffer_face = {
127 .bg = -1,
128 .fg = -1,
129 .attr = A_NORMAL,
130 };
132 struct mapping {
133 const char *label;
134 int linetype;
135 } mappings[] = {
136 {"text", LINE_TEXT},
137 {"link", LINE_LINK},
138 {"title1", LINE_TITLE_1},
139 {"title2", LINE_TITLE_2},
140 {"title3", LINE_TITLE_3},
141 {"item", LINE_ITEM},
142 {"quote", LINE_QUOTE},
143 {"pre.start", LINE_PRE_START},
144 {"pre", LINE_PRE_CONTENT},
145 {"pre.end", LINE_PRE_END},
146 };
148 static struct mapping *
149 mapping_by_name(const char *name)
151 size_t i;
153 for (i = 0; i < sizeof(mappings)/sizeof(mappings[0]); ++i) {
154 if (!strcmp(name, mappings[i].label))
155 return &mappings[i];
158 return NULL;
161 void
162 config_init(void)
164 struct line_face *f;
165 size_t i, len;
167 len = sizeof(line_faces)/sizeof(line_faces[0]);
168 for (i = 0; i < len; ++i) {
169 f = &line_faces[i];
171 f->prfx_bg = f->bg = f->trail_bg = -1;
172 f->prfx_fg = f->fg = f->trail_fg = -1;
175 line_faces[LINE_LINK].fg = COLOR_BLUE;
178 int
179 config_setprfx(const char *name, const char *prfx, const char *cont)
181 struct lineprefix *p;
182 struct mapping *m;
184 if (!has_prefix(name, "line."))
185 return 0;
186 name += 5;
188 if ((m = mapping_by_name(name)) == NULL)
189 return 0;
191 p = &line_prefixes[m->linetype];
192 p->prfx1 = prfx;
193 p->prfx2 = cont;
195 return 1;
198 int
199 config_setvari(const char *var, int val)
201 if (!strcmp(var, "fill-column")) {
202 if ((fill_column = val) <= 0)
203 fill_column = INT_MAX;
204 } else if (!strcmp(var, "olivetti-mode")) {
205 olivetti_mode = !!val;
206 } else if (!strcmp(var, "enable-colors")) {
207 enable_colors = !!val;
208 } else {
209 return 0;
212 return 1;
215 int
216 config_setvars(const char *var, char *val)
218 if (!strcmp(var, "new-tab-url")) {
219 if (new_tab_url != NULL)
220 free(new_tab_url);
221 new_tab_url = val;
222 } else
223 return 0;
224 return 1;
227 int
228 config_setcolor(int bg, const char *name, int prfx, int line, int trail)
230 struct mapping *m;
231 struct line_face *f;
233 if (!strcmp(name, "tabline")) {
234 if (bg)
235 tab_face.bg_bg = prfx;
236 else
237 tab_face.bg_fg = prfx;
238 } else if (has_prefix(name, "tabline.")) {
239 name += 8;
241 if (!strcmp(name, "tab")) {
242 if (bg)
243 tab_face.t_bg = prfx;
244 else
245 tab_face.t_fg = prfx;
246 } else if (!strcmp(name, "current")) {
247 if (bg)
248 tab_face.c_bg = prfx;
249 else
250 tab_face.c_fg = prfx;
251 } else
252 return 0;
253 } else if (has_prefix(name, "line.")) {
254 name += 5;
256 if ((m = mapping_by_name(name)) == NULL)
257 return 0;
259 f = &line_faces[m->linetype];
261 if (bg) {
262 f->prfx_bg = prfx;
263 f->bg = line;
264 f->trail_bg = trail;
265 } else {
266 f->prfx_fg = prfx;
267 f->fg = line;
268 f->trail_fg = trail;
270 } else if (!strcmp(name, "line")) {
271 if (bg) {
272 body_face.lbg = prfx;
273 body_face.bg = line;
274 body_face.rbg = trail;
275 } else {
276 body_face.lfg = prfx;
277 body_face.fg = line;
278 body_face.rfg = trail;
280 } else if (!strcmp(name, "minibuffer")) {
281 if (bg)
282 minibuffer_face.bg = prfx;
283 else
284 minibuffer_face.fg = prfx;
285 } else if (!strcmp(name, "modeline")) {
286 if (bg)
287 modeline_face.bg = prfx;
288 else
289 modeline_face.fg = prfx;
290 } else {
291 return 0;
294 return 1;
297 int
298 config_setattr(const char *name, int prfx, int line, int trail)
300 struct mapping *m;
301 struct line_face *f;
303 if (!strcmp(name, "tabline")) {
304 tab_face.bg_attr = prfx;
305 } else if (has_prefix(name, "tabline.")) {
306 name += 8;
308 if (!strcmp(name, "tab"))
309 tab_face.t_attr = prfx;
310 else if (!strcmp(name, "current"))
311 tab_face.c_attr = prfx;
312 else
313 return 0;
314 } else if (has_prefix(name, "line.")) {
315 name += 5;
317 if ((m = mapping_by_name(name)) == NULL)
318 return 0;
320 f = &line_faces[m->linetype];
322 f->prfx_attr = prfx;
323 f->attr = line;
324 f->trail_attr = trail;
325 } else if (!strcmp(name, "minibuffer")) {
326 minibuffer_face.attr = prfx;
327 } else if (!strcmp(name, "modeline")) {
328 modeline_face.attr = prfx;
329 } else {
330 return 0;
333 return 1;
336 static inline void
337 tl_init_pair(int colors, int pair, int f, int b)
339 if (f >= colors || !enable_colors)
340 f = -1;
341 if (b >= colors || !enable_colors)
342 b = -1;
343 init_pair(pair, f, b);
346 void
347 config_apply_style(void)
349 size_t i, colors, len;
350 struct line_face *f;
352 colors = COLORS;
354 len = sizeof(line_faces)/sizeof(line_faces[0]);
355 for (i = 0; i < len; ++i) {
356 f = &line_faces[i];
358 tl_init_pair(colors, f->prfx_pair, f->prfx_fg, f->prfx_bg);
359 f->prefix = COLOR_PAIR(f->prfx_pair) | f->prfx_attr;
361 tl_init_pair(colors, f->pair, f->fg, f->bg);
362 f->text = COLOR_PAIR(f->pair) | f->attr;
364 tl_init_pair(colors, f->trail_pair, f->trail_fg, f->trail_bg);
365 f->trail = COLOR_PAIR(f->trail_pair) | f->trail_attr;
368 /* tab line */
369 tl_init_pair(colors, PTL_BG, tab_face.bg_fg, tab_face.bg_bg);
370 tab_face.background = COLOR_PAIR(PTL_BG) | tab_face.bg_attr;
372 tl_init_pair(colors, PTL_TAB, tab_face.t_fg, tab_face.t_bg);
373 tab_face.tab = COLOR_PAIR(PTL_TAB) | tab_face.t_attr;
375 tl_init_pair(colors, PTL_CURR, tab_face.c_fg, tab_face.c_bg);
376 tab_face.current = COLOR_PAIR(PTL_CURR) | tab_face.c_attr;
378 /* body */
379 tl_init_pair(colors, PBODY, body_face.fg, body_face.bg);
380 body_face.body = COLOR_PAIR(PBODY);
382 tl_init_pair(colors, PBLEFT, body_face.lfg, body_face.lbg);
383 body_face.left = COLOR_PAIR(PBLEFT);
385 tl_init_pair(colors, PBRIGHT, body_face.rfg, body_face.rbg);
386 body_face.right = COLOR_PAIR(PBRIGHT);
388 /* modeline */
389 tl_init_pair(colors, PMODELINE, modeline_face.fg, modeline_face.bg);
390 modeline_face.background = COLOR_PAIR(PMODELINE) | modeline_face.attr;
392 /* minibuffer */
393 tl_init_pair(colors, PMINIBUF, minibuffer_face.fg, minibuffer_face.bg);
394 minibuffer_face.background = COLOR_PAIR(PMINIBUF) | minibuffer_face.attr;