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;
172 int
173 config_setprfx(const char *name, const char *prfx, const char *cont)
175 struct lineprefix *p;
176 struct mapping *m;
178 if (!has_prefix(name, "line."))
179 return 0;
180 name += 5;
182 if ((m = mapping_by_name(name)) == NULL)
183 return 0;
185 p = &line_prefixes[m->linetype];
186 p->prfx1 = prfx;
187 p->prfx2 = cont;
189 return 1;
192 int
193 config_setvari(const char *var, int val)
195 if (!strcmp(var, "fill-column")) {
196 if ((fill_column = val) <= 0)
197 fill_column = INT_MAX;
198 } else if (!strcmp(var, "olivetti-mode")) {
199 olivetti_mode = !!val;
200 } else if (!strcmp(var, "enable-colors")) {
201 enable_colors = !!val;
202 } else {
203 return 0;
206 return 1;
209 int
210 config_setvars(const char *var, char *val)
212 if (!strcmp(var, "new-tab-url")) {
213 if (new_tab_url != NULL)
214 free(new_tab_url);
215 new_tab_url = val;
216 } else
217 return 0;
218 return 1;
221 int
222 config_setcolor(int bg, const char *name, int prfx, int line, int trail)
224 struct mapping *m;
225 struct line_face *f;
227 if (!strcmp(name, "tabline")) {
228 if (bg)
229 tab_face.bg_bg = prfx;
230 else
231 tab_face.bg_fg = prfx;
232 } else if (has_prefix(name, "tabline.")) {
233 name += 8;
235 if (!strcmp(name, "tab")) {
236 if (bg)
237 tab_face.t_bg = prfx;
238 else
239 tab_face.t_fg = prfx;
240 } else if (!strcmp(name, "current")) {
241 if (bg)
242 tab_face.c_bg = prfx;
243 else
244 tab_face.c_fg = prfx;
245 } else
246 return 0;
247 } else if (has_prefix(name, "line.")) {
248 name += 5;
250 if ((m = mapping_by_name(name)) == NULL)
251 return 0;
253 f = &line_faces[m->linetype];
255 if (bg) {
256 f->prfx_bg = prfx;
257 f->bg = line;
258 f->trail_bg = trail;
259 } else {
260 f->prfx_fg = prfx;
261 f->fg = line;
262 f->trail_fg = trail;
264 } else if (!strcmp(name, "line")) {
265 if (bg) {
266 body_face.lbg = prfx;
267 body_face.bg = line;
268 body_face.rbg = trail;
269 } else {
270 body_face.fg = prfx;
271 body_face.fg = line;
272 body_face.fg = trail;
274 } else {
275 return 0;
278 return 1;
281 int
282 config_setattr(const char *name, int prfx, int line, int trail)
284 struct mapping *m;
285 struct line_face *f;
287 if (!strcmp(name, "tabline")) {
288 tab_face.bg_attr = prfx;
289 } else if (has_prefix(name, "tabline.")) {
290 name += 8;
292 if (!strcmp(name, "tab"))
293 tab_face.t_attr = prfx;
294 else if (!strcmp(name, "current"))
295 tab_face.c_attr = prfx;
296 else
297 return 0;
298 } else if (has_prefix(name, "line.")) {
299 name += 5;
301 if ((m = mapping_by_name(name)) == NULL)
302 return 0;
304 f = &line_faces[m->linetype];
306 f->prfx_attr = prfx;
307 f->attr = line;
308 f->trail_attr = trail;
309 } else {
310 return 0;
313 return 1;
316 static inline void
317 tl_init_pair(int colors, int pair, int f, int b)
319 if (f >= colors || !enable_colors)
320 f = -1;
321 if (b >= colors || !enable_colors)
322 b = -1;
323 init_pair(pair, f, b);
326 void
327 config_apply_style(void)
329 size_t i, colors, len;
330 struct line_face *f;
332 colors = COLORS;
334 len = sizeof(line_faces)/sizeof(line_faces[0]);
335 for (i = 0; i < len; ++i) {
336 f = &line_faces[i];
338 tl_init_pair(colors, f->prfx_pair, f->prfx_fg, f->prfx_bg);
339 f->prefix = COLOR_PAIR(f->prfx_pair) | f->prfx_attr;
341 tl_init_pair(colors, f->pair, f->fg, f->bg);
342 f->text = COLOR_PAIR(f->pair) | f->attr;
344 tl_init_pair(colors, f->trail_pair, f->trail_fg, f->trail_bg);
345 f->trail = COLOR_PAIR(f->trail_pair) | f->trail_attr;
348 /* tab line */
349 tl_init_pair(colors, PTL_BG, tab_face.bg_fg, tab_face.bg_bg);
350 tab_face.background = COLOR_PAIR(PTL_BG) | tab_face.bg_attr;
352 tl_init_pair(colors, PTL_TAB, tab_face.t_fg, tab_face.t_bg);
353 tab_face.tab = COLOR_PAIR(PTL_TAB) | tab_face.t_attr;
355 tl_init_pair(colors, PTL_CURR, tab_face.c_fg, tab_face.c_bg);
356 tab_face.current = COLOR_PAIR(PTL_CURR) | tab_face.c_attr;
358 /* body */
359 tl_init_pair(colors, PBODY, body_face.fg, body_face.bg);
360 body_face.body = COLOR_PAIR(PBODY);
362 tl_init_pair(colors, PBLEFT, body_face.lfg, body_face.lbg);
363 body_face.left = COLOR_PAIR(PBLEFT);
365 tl_init_pair(colors, PBRIGHT, body_face.rfg, body_face.rbg);
366 body_face.right = COLOR_PAIR(PBRIGHT);