NeoMutt  2023-03-22-27-g3cb248
Teaching an old dog new tricks
DOXYGEN
command.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <stddef.h>
31#include <limits.h>
32#include <stdbool.h>
33#include <stdint.h>
34#include <stdlib.h>
35#include "mutt/lib.h"
36#include "core/lib.h"
37#include "gui/lib.h"
38#include "lib.h"
39#include "pager/lib.h"
40#include "parse/lib.h"
41#include "globals.h"
42#ifdef USE_DEBUG_COLOR
43#include <stdio.h>
44#include "mutt.h"
45#include "pager/private_data.h"
46#endif
47
51const struct Mapping ColorFields[] = {
52 // clang-format off
53 { "attachment", MT_COLOR_ATTACHMENT },
54 { "attach_headers", MT_COLOR_ATTACH_HEADERS },
55 { "body", MT_COLOR_BODY },
56 { "bold", MT_COLOR_BOLD },
57 { "error", MT_COLOR_ERROR },
58 { "hdrdefault", MT_COLOR_HDRDEFAULT },
59 { "header", MT_COLOR_HEADER },
60 { "index", MT_COLOR_INDEX },
61 { "index_author", MT_COLOR_INDEX_AUTHOR },
62 { "index_collapsed", MT_COLOR_INDEX_COLLAPSED },
63 { "index_date", MT_COLOR_INDEX_DATE },
64 { "index_flags", MT_COLOR_INDEX_FLAGS },
65 { "index_label", MT_COLOR_INDEX_LABEL },
66 { "index_number", MT_COLOR_INDEX_NUMBER },
67 { "index_size", MT_COLOR_INDEX_SIZE },
68 { "index_subject", MT_COLOR_INDEX_SUBJECT },
69 { "index_tag", MT_COLOR_INDEX_TAG },
70 { "index_tags", MT_COLOR_INDEX_TAGS },
71 { "indicator", MT_COLOR_INDICATOR },
72 { "italic", MT_COLOR_ITALIC },
73 { "markers", MT_COLOR_MARKERS },
74 { "message", MT_COLOR_MESSAGE },
75 { "normal", MT_COLOR_NORMAL },
76 { "options", MT_COLOR_OPTIONS },
77 { "progress", MT_COLOR_PROGRESS },
78 { "prompt", MT_COLOR_PROMPT },
79 { "quoted", MT_COLOR_QUOTED },
80 { "search", MT_COLOR_SEARCH },
81#ifdef USE_SIDEBAR
82 { "sidebar_background", MT_COLOR_SIDEBAR_BACKGROUND },
83 { "sidebar_divider", MT_COLOR_SIDEBAR_DIVIDER },
84 { "sidebar_flagged", MT_COLOR_SIDEBAR_FLAGGED },
85 { "sidebar_highlight", MT_COLOR_SIDEBAR_HIGHLIGHT },
86 { "sidebar_indicator", MT_COLOR_SIDEBAR_INDICATOR },
87 { "sidebar_new", MT_COLOR_SIDEBAR_NEW },
88 { "sidebar_ordinary", MT_COLOR_SIDEBAR_ORDINARY },
89 { "sidebar_spool_file", MT_COLOR_SIDEBAR_SPOOLFILE },
90 { "sidebar_spoolfile", MT_COLOR_SIDEBAR_SPOOLFILE }, // This will be deprecated
91 { "sidebar_unread", MT_COLOR_SIDEBAR_UNREAD },
92#endif
93 { "signature", MT_COLOR_SIGNATURE },
94 { "status", MT_COLOR_STATUS },
95 { "tilde", MT_COLOR_TILDE },
96 { "tree", MT_COLOR_TREE },
97 { "underline", MT_COLOR_UNDERLINE },
98 { "warning", MT_COLOR_WARNING },
99 { NULL, 0 },
100 // clang-format on
101};
102
106const struct Mapping ComposeColorFields[] = {
107 // clang-format off
108 { "header", MT_COLOR_COMPOSE_HEADER },
109 { "security_encrypt", MT_COLOR_COMPOSE_SECURITY_ENCRYPT },
110 { "security_sign", MT_COLOR_COMPOSE_SECURITY_SIGN },
111 { "security_both", MT_COLOR_COMPOSE_SECURITY_BOTH },
112 { "security_none", MT_COLOR_COMPOSE_SECURITY_NONE },
113 { NULL, 0 }
114 // clang-format on
115};
116
128static enum CommandResult parse_color_name(const char *s, uint32_t *col, int *attrs,
129 bool is_fg, struct Buffer *err)
130{
131 char *eptr = NULL;
132 bool is_alert = false, is_bright = false, is_light = false;
133 int clen;
134
135 if ((clen = mutt_istr_startswith(s, "bright")))
136 {
137 color_debug(LL_DEBUG5, "bright\n");
138 is_bright = true;
139 s += clen;
140 }
141 else if ((clen = mutt_istr_startswith(s, "alert")))
142 {
143 color_debug(LL_DEBUG5, "alert\n");
144 is_alert = true;
145 is_bright = true;
146 s += clen;
147 }
148 else if ((clen = mutt_istr_startswith(s, "light")))
149 {
150 color_debug(LL_DEBUG5, "light\n");
151 is_light = true;
152 s += clen;
153 }
154
155 /* allow aliases for xterm color resources */
156 if ((clen = mutt_istr_startswith(s, "color")))
157 {
158 s += clen;
159 *col = strtoul(s, &eptr, 10);
160 if ((*s == '\0') || (*eptr != '\0') || ((*col >= COLORS) && !OptNoCurses))
161 {
162 mutt_buffer_printf(err, _("%s: color not supported by term"), s);
163 return MUTT_CMD_ERROR;
164 }
165 color_debug(LL_DEBUG5, "colorNNN %d\n", *col);
166 }
167 else if ((*col = mutt_map_get_value(s, ColorNames)) == -1)
168 {
169 mutt_buffer_printf(err, _("%s: no such color"), s);
170 return MUTT_CMD_WARNING;
171 }
172 const char *name = mutt_map_get_name(*col, ColorNames);
173 if (name)
174 color_debug(LL_DEBUG5, "color: %s\n", name);
175
176 if (is_bright || is_light)
177 {
178 if (is_alert)
179 {
180 *attrs |= A_BOLD;
181 *attrs |= A_BLINK;
182 }
183 else if (is_fg)
184 {
185 if ((COLORS >= 16) && is_light)
186 {
187 if (*col <= 7)
188 {
189 /* Advance the color 0-7 by 8 to get the light version */
190 *col += 8;
191 }
192 }
193 else
194 {
195 *attrs |= A_BOLD;
196 }
197 }
198 else
199 {
200 if (COLORS >= 16)
201 {
202 if (*col <= 7)
203 {
204 /* Advance the color 0-7 by 8 to get the light version */
205 *col += 8;
206 }
207 }
208 }
209 }
210
211 return MUTT_CMD_SUCCESS;
212}
213
217static enum CommandResult parse_attr_spec(struct Buffer *buf, struct Buffer *s,
218 uint32_t *fg, uint32_t *bg,
219 int *attrs, struct Buffer *err)
220{
221 if (fg)
222 *fg = COLOR_UNSET;
223 if (bg)
224 *bg = COLOR_UNSET;
225
226 if (!MoreArgs(s))
227 {
228 mutt_buffer_printf(err, _("%s: too few arguments"), "mono");
229 return MUTT_CMD_WARNING;
230 }
231
233
234 if (mutt_istr_equal("bold", buf->data))
235 *attrs |= A_BOLD;
236 else if (mutt_istr_equal("italic", buf->data))
237 *attrs |= A_ITALIC;
238 else if (mutt_istr_equal("none", buf->data))
239 *attrs = A_NORMAL; // Use '=' to clear other bits
240 else if (mutt_istr_equal("normal", buf->data))
241 *attrs = A_NORMAL; // Use '=' to clear other bits
242 else if (mutt_istr_equal("reverse", buf->data))
243 *attrs |= A_REVERSE;
244 else if (mutt_istr_equal("standout", buf->data))
245 *attrs |= A_STANDOUT;
246 else if (mutt_istr_equal("underline", buf->data))
247 *attrs |= A_UNDERLINE;
248 else
249 {
250 mutt_buffer_printf(err, _("%s: no such attribute"), buf->data);
251 return MUTT_CMD_WARNING;
252 }
253
254 return MUTT_CMD_SUCCESS;
255}
256
262static enum CommandResult parse_color_pair(struct Buffer *buf, struct Buffer *s,
263 uint32_t *fg, uint32_t *bg,
264 int *attrs, struct Buffer *err)
265{
266 while (true)
267 {
268 if (!MoreArgs(s))
269 {
270 mutt_buffer_printf(err, _("%s: too few arguments"), "color");
271 return MUTT_CMD_WARNING;
272 }
273
275
276 if (mutt_istr_equal("bold", buf->data))
277 {
278 *attrs |= A_BOLD;
279 color_debug(LL_DEBUG5, "bold\n");
280 }
281 else if (mutt_istr_equal("italic", buf->data))
282 {
283 *attrs |= A_ITALIC;
284 color_debug(LL_DEBUG5, "italic\n");
285 }
286 else if (mutt_istr_equal("none", buf->data))
287 {
288 *attrs = A_NORMAL; // Use '=' to clear other bits
289 color_debug(LL_DEBUG5, "none\n");
290 }
291 else if (mutt_istr_equal("normal", buf->data))
292 {
293 *attrs = A_NORMAL; // Use '=' to clear other bits
294 color_debug(LL_DEBUG5, "normal\n");
295 }
296 else if (mutt_istr_equal("reverse", buf->data))
297 {
298 *attrs |= A_REVERSE;
299 color_debug(LL_DEBUG5, "reverse\n");
300 }
301 else if (mutt_istr_equal("standout", buf->data))
302 {
303 *attrs |= A_STANDOUT;
304 color_debug(LL_DEBUG5, "standout\n");
305 }
306 else if (mutt_istr_equal("underline", buf->data))
307 {
308 *attrs |= A_UNDERLINE;
309 color_debug(LL_DEBUG5, "underline\n");
310 }
311 else
312 {
313 enum CommandResult rc = parse_color_name(buf->data, fg, attrs, true, err);
314 if (rc != MUTT_CMD_SUCCESS)
315 return rc;
316 break;
317 }
318 }
319
320 if (!MoreArgs(s))
321 {
322 mutt_buffer_printf(err, _("%s: too few arguments"), "color");
323 return MUTT_CMD_WARNING;
324 }
325
327
328 return parse_color_name(buf->data, bg, attrs, false, err);
329}
330
336void get_colorid_name(unsigned int cid, struct Buffer *buf)
337{
338 const char *name = NULL;
339
341 {
343 if (name)
344 {
345 mutt_buffer_printf(buf, "compose %s", name);
346 return;
347 }
348 }
349
351 if (name)
352 mutt_buffer_printf(buf, "%s", name);
353 else
354 mutt_buffer_printf(buf, "UNKNOWN %d", cid);
355}
356
368static enum CommandResult parse_object(struct Buffer *buf, struct Buffer *s,
369 enum ColorId *cid, int *ql, struct Buffer *err)
370{
371 int rc;
372
373 if (mutt_str_startswith(buf->data, "quoted") != 0)
374 {
375 int val = 0;
376 if (buf->data[6] != '\0')
377 {
378 if (!mutt_str_atoi_full(buf->data + 6, &val) || (val > COLOR_QUOTES_MAX))
379 {
380 mutt_buffer_printf(err, _("%s: no such object"), buf->data);
381 return MUTT_CMD_WARNING;
382 }
383 }
384
385 *ql = val;
386 *cid = MT_COLOR_QUOTED;
387 return MUTT_CMD_SUCCESS;
388 }
389
390 if (mutt_istr_equal(buf->data, "compose"))
391 {
392 if (!MoreArgs(s))
393 {
394 mutt_buffer_printf(err, _("%s: too few arguments"), "color");
395 return MUTT_CMD_WARNING;
396 }
397
399
401 if (rc == -1)
402 {
403 mutt_buffer_printf(err, _("%s: no such object"), buf->data);
404 return MUTT_CMD_WARNING;
405 }
406
407 *cid = rc;
408 return MUTT_CMD_SUCCESS;
409 }
410
412 if (rc == -1)
413 {
414 mutt_buffer_printf(err, _("%s: no such object"), buf->data);
415 return MUTT_CMD_WARNING;
416 }
417 else
418 {
419 color_debug(LL_DEBUG5, "object: %s\n", mutt_map_get_name(rc, ColorFields));
420 }
421
422 *cid = rc;
423 return MUTT_CMD_SUCCESS;
424}
425
438static enum CommandResult parse_uncolor(struct Buffer *buf, struct Buffer *s,
439 struct Buffer *err, bool uncolor)
440{
442
443 if (mutt_str_equal(buf->data, "*"))
444 {
445 colors_clear();
446 return MUTT_CMD_SUCCESS;
447 }
448
449 unsigned int cid = MT_COLOR_NONE;
450 int ql = 0;
451 color_debug(LL_DEBUG5, "uncolor: %s\n", mutt_buffer_string(buf));
452 enum CommandResult rc = parse_object(buf, s, &cid, &ql, err);
453 if (rc != MUTT_CMD_SUCCESS)
454 return rc;
455
456 if (cid == -1)
457 {
458 mutt_buffer_printf(err, _("%s: no such object"), buf->data);
459 return MUTT_CMD_ERROR;
460 }
461
462 if (cid == MT_COLOR_QUOTED)
463 {
464 color_debug(LL_DEBUG5, "quoted\n");
465 return quoted_colors_parse_uncolor(cid, ql, err);
466 }
467
468 if ((cid == MT_COLOR_STATUS) && !MoreArgs(s))
469 {
470 color_debug(LL_DEBUG5, "simple\n");
471 simple_color_reset(cid); // default colour for the status bar
472 return MUTT_CMD_SUCCESS;
473 }
474
475 if (!mutt_color_has_pattern(cid))
476 {
477 color_debug(LL_DEBUG5, "simple\n");
479 return MUTT_CMD_SUCCESS;
480 }
481
482 if (OptNoCurses)
483 {
484 do
485 {
486 color_debug(LL_DEBUG5, "do nothing\n");
487 /* just eat the command, but don't do anything real about it */
489 } while (MoreArgs(s));
490
491 return MUTT_CMD_SUCCESS;
492 }
493
494 bool changes = false;
495 if (!MoreArgs(s))
496 {
497 if (regex_colors_parse_uncolor(cid, NULL, uncolor))
498 return MUTT_CMD_SUCCESS;
499 else
500 return MUTT_CMD_ERROR;
501 }
502
503 do
504 {
506 if (mutt_str_equal("*", buf->data))
507 {
508 if (regex_colors_parse_uncolor(cid, NULL, uncolor))
509 return MUTT_CMD_SUCCESS;
510 else
511 return MUTT_CMD_ERROR;
512 }
513
514 changes |= regex_colors_parse_uncolor(cid, buf->data, uncolor);
515
516 } while (MoreArgs(s));
517
518 if (changes)
520
521 return MUTT_CMD_SUCCESS;
522}
523
524#ifdef USE_DEBUG_COLOR
528static enum CommandResult color_dump(struct Buffer *buf, struct Buffer *s,
529 intptr_t data, struct Buffer *err)
530{
531 if (MoreArgs(s))
532 return MUTT_CMD_ERROR;
533
534 FILE *fp_out = NULL;
535 char tempfile[PATH_MAX] = { 0 };
536 struct Buffer filebuf = mutt_buffer_make(4096);
537 char color_fg[32] = { 0 };
538 char color_bg[32] = { 0 };
539
540 mutt_mktemp(tempfile, sizeof(tempfile));
541 fp_out = mutt_file_fopen(tempfile, "w");
542 if (!fp_out)
543 {
544 // L10N: '%s' is the file name of the temporary file
545 mutt_buffer_printf(err, _("Could not create temporary file %s"), tempfile);
546 mutt_buffer_dealloc(&filebuf);
547 return MUTT_CMD_ERROR;
548 }
549
550 mutt_buffer_addstr(&filebuf, "# All Colours\n\n");
551 mutt_buffer_addstr(&filebuf, "# Simple Colours\n");
552 for (enum ColorId cid = MT_COLOR_NONE + 1; cid < MT_COLOR_MAX; cid++)
553 {
554 struct AttrColor *ac = simple_color_get(cid);
555 if (!ac)
556 continue;
557
558 struct CursesColor *cc = ac->curses_color;
559 if (!cc)
560 continue;
561
562 const char *name = mutt_map_get_name(cid, ColorFields);
563 if (!name)
564 continue;
565
566 const char *swatch = color_debug_log_color_attrs(cc->fg, cc->bg, ac->attrs);
567 mutt_buffer_add_printf(&filebuf, "color %-18s %-30s %-8s %-8s # %s\n", name,
569 color_debug_log_name(color_fg, sizeof(color_fg), cc->fg),
570 color_debug_log_name(color_bg, sizeof(color_bg), cc->bg), swatch);
571 }
572
573 if (NumQuotedColors > 0)
574 {
575 mutt_buffer_addstr(&filebuf, "\n# Quoted Colours\n");
576 for (int i = 0; i < NumQuotedColors; i++)
577 {
578 struct AttrColor *ac = quoted_colors_get(i);
579 if (!ac)
580 continue;
581
582 struct CursesColor *cc = ac->curses_color;
583 if (!cc)
584 continue;
585
586 const char *swatch = color_debug_log_color_attrs(cc->fg, cc->bg, ac->attrs);
587 mutt_buffer_add_printf(&filebuf, "color quoted%d %-30s %-8s %-8s # %s\n",
589 color_debug_log_name(color_fg, sizeof(color_fg), cc->fg),
590 color_debug_log_name(color_bg, sizeof(color_bg), cc->bg),
591 swatch);
592 }
593 }
594
595 int rl_count = 0;
596 for (enum ColorId id = MT_COLOR_NONE; id != MT_COLOR_MAX; ++id)
597 {
598 if (!mutt_color_has_pattern(id))
599 {
600 continue;
601 }
602
603 struct RegexColorList *rcl = regex_colors_get_list(id);
604 if (!STAILQ_EMPTY(rcl))
605 rl_count++;
606 }
607
608 if (rl_count > 0)
609 {
610 for (enum ColorId id = MT_COLOR_NONE; id != MT_COLOR_MAX; ++id)
611 {
612 if (!mutt_color_has_pattern(id))
613 {
614 continue;
615 }
616
617 struct RegexColorList *rcl = regex_colors_get_list(id);
618 if (STAILQ_EMPTY(rcl))
619 continue;
620
621 const char *name = mutt_map_get_name(id, ColorFields);
622 if (!name)
623 continue;
624
625 mutt_buffer_add_printf(&filebuf, "\n# Regex Colour %s\n", name);
626
627 struct RegexColor *rc = NULL;
628 STAILQ_FOREACH(rc, rcl, entries)
629 {
630 struct AttrColor *ac = &rc->attr_color;
631 struct CursesColor *cc = ac->curses_color;
632 if (!cc)
633 continue;
634
635 const char *swatch = color_debug_log_color_attrs(cc->fg, cc->bg, ac->attrs);
636 mutt_buffer_add_printf(&filebuf, "color %-14s %-30s %-8s %-8s %-30s # %s\n",
638 color_debug_log_name(color_fg, sizeof(color_fg), cc->fg),
639 color_debug_log_name(color_bg, sizeof(color_bg), cc->bg),
640 rc->pattern, swatch);
641 }
642 }
643 }
644
645#ifdef USE_DEBUG_COLOR
647 {
648 mutt_buffer_addstr(&filebuf, "\n# Merged Colours\n");
649 struct AttrColor *ac = NULL;
650 TAILQ_FOREACH(ac, &MergedColors, entries)
651 {
652 struct CursesColor *cc = ac->curses_color;
653 if (!cc)
654 continue;
655
656 const char *swatch = color_debug_log_color_attrs(cc->fg, cc->bg, ac->attrs);
657 mutt_buffer_add_printf(&filebuf, "# %-30s %-8s %-8s # %s\n",
659 color_debug_log_name(color_fg, sizeof(color_fg), cc->fg),
660 color_debug_log_name(color_bg, sizeof(color_bg), cc->bg),
661 swatch);
662 }
663 }
664
665 struct MuttWindow *win = window_get_focus();
666 if (win && (win->type == WT_CUSTOM) && win->parent && (win->parent->type == WT_PAGER))
667 {
668 struct PagerPrivateData *priv = win->parent->wdata;
669 if (priv && !TAILQ_EMPTY(&priv->ansi_list))
670 {
671 mutt_buffer_addstr(&filebuf, "\n# Ansi Colours\n");
672 struct AttrColor *ac = NULL;
673 TAILQ_FOREACH(ac, &priv->ansi_list, entries)
674 {
675 struct CursesColor *cc = ac->curses_color;
676 if (!cc)
677 continue;
678
679 const char *swatch = color_debug_log_color_attrs(cc->fg, cc->bg, ac->attrs);
680 mutt_buffer_add_printf(&filebuf, "# %-30s %-8s %-8s # %s\n",
682 color_debug_log_name(color_fg, sizeof(color_fg), cc->fg),
683 color_debug_log_name(color_bg, sizeof(color_bg), cc->bg),
684 swatch);
685 }
686 }
687 }
688#endif
689
690 fputs(filebuf.data, fp_out);
691
692 mutt_file_fclose(&fp_out);
693 mutt_buffer_dealloc(&filebuf);
694
695 struct PagerData pdata = { 0 };
696 struct PagerView pview = { &pdata };
697
698 pdata.fname = tempfile;
699
700 pview.banner = "color";
701 pview.flags = MUTT_SHOWCOLOR;
702 pview.mode = PAGER_MODE_OTHER;
703
704 mutt_do_pager(&pview, NULL);
705 return MUTT_CMD_SUCCESS;
706}
707#endif
708
723static enum CommandResult parse_color(struct Buffer *buf, struct Buffer *s,
724 struct Buffer *err, parser_callback_t callback,
725 bool dry_run, bool color)
726{
727 int attrs = 0, q_level = 0;
728 uint32_t fg = 0, bg = 0, match = 0;
729 enum ColorId cid = MT_COLOR_NONE;
730 enum CommandResult rc;
731
732 if (!MoreArgs(s))
733 {
734#ifdef USE_DEBUG_COLOR
735 if (StartupComplete)
736 return color_dump(buf, s, 0, err);
737#endif
738
739 mutt_buffer_printf(err, _("%s: too few arguments"), "color");
740 return MUTT_CMD_WARNING;
741 }
742
744 color_debug(LL_DEBUG5, "color: %s\n", mutt_buffer_string(buf));
745
746 rc = parse_object(buf, s, &cid, &q_level, err);
747 if (rc != MUTT_CMD_SUCCESS)
748 return rc;
749
750 rc = callback(buf, s, &fg, &bg, &attrs, err);
751 if (rc != MUTT_CMD_SUCCESS)
752 return rc;
753
754 /* extract a regular expression if needed */
755
756 if (mutt_color_has_pattern(cid) && cid != MT_COLOR_STATUS)
757 {
758 color_debug(LL_DEBUG5, "regex needed\n");
759 if (MoreArgs(s))
760 {
762 }
763 else
764 {
765 mutt_buffer_strcpy(buf, ".*");
766 }
767 }
768
769 if (MoreArgs(s) && (cid != MT_COLOR_STATUS))
770 {
771 mutt_buffer_printf(err, _("%s: too many arguments"), color ? "color" : "mono");
772 return MUTT_CMD_WARNING;
773 }
774
775 if (dry_run)
776 {
777 color_debug(LL_DEBUG5, "dry_run bailout\n");
778 *s->dptr = '\0'; /* fake that we're done parsing */
779 return MUTT_CMD_SUCCESS;
780 }
781
782 /* The case of the tree object is special, because a non-default fg color of
783 * the tree element may be combined dynamically with the default bg color of
784 * an index line, not necessarily defined in a rc file. */
785 if (!OptNoCurses &&
786 ((fg == COLOR_DEFAULT) || (bg == COLOR_DEFAULT) || (cid == MT_COLOR_TREE)) &&
787 (use_default_colors() != OK))
788 {
789 mutt_buffer_strcpy(err, _("default colors not supported"));
790 return MUTT_CMD_ERROR;
791 }
792
793 if (regex_colors_parse_color_list(cid, buf->data, fg, bg, attrs, &rc, err))
794 {
795 color_debug(LL_DEBUG5, "regex_colors_parse_color_list done\n");
796 return rc;
797 // do nothing
798 }
799 else if (quoted_colors_parse_color(cid, fg, bg, attrs, q_level, &rc, err))
800 {
801 color_debug(LL_DEBUG5, "quoted_colors_parse_color done\n");
802 return rc;
803 // do nothing
804 }
805 else if ((cid == MT_COLOR_STATUS) && MoreArgs(s))
806 {
807 color_debug(LL_DEBUG5, "status\n");
808 /* 'color status fg bg' can have up to 2 arguments:
809 * 0 arguments: sets the default status color (handled below by else part)
810 * 1 argument : colorize pattern on match
811 * 2 arguments: colorize nth submatch of pattern */
813
814 if (MoreArgs(s))
815 {
816 struct Buffer tmp = mutt_buffer_make(0);
818 if (!mutt_str_atoui_full(tmp.data, &match))
819 {
820 mutt_buffer_printf(err, _("%s: invalid number: %s"),
821 color ? "color" : "mono", tmp.data);
823 return MUTT_CMD_WARNING;
824 }
826 }
827
828 if (MoreArgs(s))
829 {
830 mutt_buffer_printf(err, _("%s: too many arguments"), color ? "color" : "mono");
831 return MUTT_CMD_WARNING;
832 }
833
834 rc = regex_colors_parse_status_list(cid, buf->data, fg, bg, attrs, match, err);
835 return rc;
836 }
837 else // Remaining simple colours
838 {
839 color_debug(LL_DEBUG5, "simple\n");
840 if (simple_color_set(cid, fg, bg, attrs))
841 rc = MUTT_CMD_SUCCESS;
842 else
843 rc = MUTT_CMD_ERROR;
844 }
845
846 if (rc == MUTT_CMD_SUCCESS)
847 {
848 get_colorid_name(cid, buf);
849 color_debug(LL_DEBUG5, "NT_COLOR_SET: %s\n", buf->data);
850 struct EventColor ev_c = { cid, NULL };
852 }
853
854 return rc;
855}
856
860enum CommandResult mutt_parse_uncolor(struct Buffer *buf, struct Buffer *s,
861 intptr_t data, struct Buffer *err)
862{
863 if (OptNoCurses)
864 {
865 *s->dptr = '\0'; /* fake that we're done parsing */
866 return MUTT_CMD_SUCCESS;
867 }
868 color_debug(LL_DEBUG5, "parse: %s\n", mutt_buffer_string(buf));
869 enum CommandResult rc = parse_uncolor(buf, s, err, true);
870 // simple_colors_dump(false);
872 return rc;
873}
874
878enum CommandResult mutt_parse_unmono(struct Buffer *buf, struct Buffer *s,
879 intptr_t data, struct Buffer *err)
880{
881 *s->dptr = '\0'; /* fake that we're done parsing */
882 return MUTT_CMD_SUCCESS;
883}
884
888enum CommandResult mutt_parse_color(struct Buffer *buf, struct Buffer *s,
889 intptr_t data, struct Buffer *err)
890{
891 bool dry_run = OptNoCurses;
892
893 color_debug(LL_DEBUG5, "parse: %s\n", mutt_buffer_string(buf));
894 enum CommandResult rc = parse_color(buf, s, err, parse_color_pair, dry_run, true);
895 // simple_colors_dump(false);
897 return rc;
898}
899
903enum CommandResult mutt_parse_mono(struct Buffer *buf, struct Buffer *s,
904 intptr_t data, struct Buffer *err)
905{
906 return parse_color(buf, s, err, parse_attr_spec, true, false);
907}
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:67
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:365
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:347
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:233
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:211
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:168
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:78
const struct Mapping ComposeColorFields[]
Mapping of compose colour names to their IDs.
Definition: command.c:106
void get_colorid_name(unsigned int cid, struct Buffer *buf)
Get the name of a color id.
Definition: command.c:336
const struct Mapping ColorFields[]
Mapping of colour names to their IDs.
Definition: command.c:51
static enum CommandResult parse_color(struct Buffer *buf, struct Buffer *s, struct Buffer *err, parser_callback_t callback, bool dry_run, bool color)
Parse a 'color' command.
Definition: command.c:723
static enum CommandResult parse_color_name(const char *s, uint32_t *col, int *attrs, bool is_fg, struct Buffer *err)
Parse a colour name.
Definition: command.c:128
static enum CommandResult parse_object(struct Buffer *buf, struct Buffer *s, enum ColorId *cid, int *ql, struct Buffer *err)
Identify a colour object.
Definition: command.c:368
static enum CommandResult parse_uncolor(struct Buffer *buf, struct Buffer *s, struct Buffer *err, bool uncolor)
Parse an 'uncolor' command.
Definition: command.c:438
struct Notify * ColorsNotify
Notifications: ColorId, EventColor.
Definition: notify.c:34
struct RegexColorList * regex_colors_get_list(enum ColorId cid)
Return the RegexColorList for a colour id.
Definition: regex.c:184
bool regex_colors_parse_uncolor(enum ColorId cid, const char *pat, bool uncolor)
Parse a Regex 'uncolor' command.
Definition: regex.c:439
bool regex_colors_parse_color_list(enum ColorId cid, const char *pat, uint32_t fg, uint32_t bg, int attrs, int *rc, struct Buffer *err)
Parse a Regex 'color' command.
Definition: regex.c:340
int regex_colors_parse_status_list(enum ColorId cid, const char *pat, uint32_t fg, uint32_t bg, int attrs, int match, struct Buffer *err)
Parse a Regex 'color status' command.
Definition: regex.c:410
struct AttrColor * simple_color_set(enum ColorId cid, int fg, int bg, int attrs)
Set the colour of a simple object.
Definition: simple.c:118
void simple_color_reset(enum ColorId cid)
Clear the colour of a simple object.
Definition: simple.c:144
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
Definition: simple.c:74
const struct Mapping ColorNames[]
Definition: color.c:38
bool mutt_color_has_pattern(enum ColorId cid)
Check if a color object supports a regex pattern.
Definition: color.c:103
void colors_clear(void)
Reset all the simple, quoted and regex colours.
Definition: color.c:56
#define COLOR_DEFAULT
Definition: color.h:102
#define COLOR_UNSET
Definition: color.h:103
ColorId
List of all colored objects.
Definition: color.h:38
@ MT_COLOR_SIDEBAR_DIVIDER
Line dividing sidebar from the index/pager.
Definition: color.h:65
@ MT_COLOR_MARKERS
Pager: markers, line continuation.
Definition: color.h:54
@ MT_COLOR_COMPOSE_SECURITY_ENCRYPT
Mail will be encrypted.
Definition: color.h:46
@ MT_COLOR_MESSAGE
Informational message.
Definition: color.h:55
@ MT_COLOR_QUOTED
Pager: quoted text.
Definition: color.h:61
@ MT_COLOR_INDEX_AUTHOR
Index: author field.
Definition: color.h:82
@ MT_COLOR_MAX
Definition: color.h:92
@ MT_COLOR_SIDEBAR_NEW
Mailbox with new mail.
Definition: color.h:69
@ MT_COLOR_HEADER
Message headers (takes a pattern)
Definition: color.h:51
@ MT_COLOR_STATUS
Status bar (takes a pattern)
Definition: color.h:75
@ MT_COLOR_SIDEBAR_UNREAD
Mailbox with unread mail.
Definition: color.h:72
@ MT_COLOR_INDEX_SIZE
Index: size field.
Definition: color.h:88
@ MT_COLOR_INDICATOR
Selected item in list.
Definition: color.h:52
@ MT_COLOR_SIDEBAR_SPOOLFILE
$spool_file (Spool mailbox)
Definition: color.h:71
@ MT_COLOR_ERROR
Error message.
Definition: color.h:49
@ MT_COLOR_NONE
Definition: color.h:39
@ MT_COLOR_COMPOSE_SECURITY_NONE
Mail will not be encrypted or signed.
Definition: color.h:47
@ MT_COLOR_SIDEBAR_ORDINARY
Mailbox with no new or flagged messages.
Definition: color.h:70
@ MT_COLOR_INDEX_TAGS
Index: tags field (g, J)
Definition: color.h:91
@ MT_COLOR_BOLD
Bold text.
Definition: color.h:43
@ MT_COLOR_INDEX_SUBJECT
Index: subject field.
Definition: color.h:89
@ MT_COLOR_BODY
Pager: highlight body of message (takes a pattern)
Definition: color.h:42
@ MT_COLOR_INDEX_DATE
Index: date field.
Definition: color.h:84
@ MT_COLOR_PROGRESS
Progress bar.
Definition: color.h:59
@ MT_COLOR_COMPOSE_SECURITY_BOTH
Mail will be encrypted and signed.
Definition: color.h:45
@ MT_COLOR_SIDEBAR_BACKGROUND
Background colour for the Sidebar.
Definition: color.h:64
@ MT_COLOR_INDEX_TAG
Index: tag field (G)
Definition: color.h:90
@ MT_COLOR_HDRDEFAULT
Header default colour.
Definition: color.h:50
@ MT_COLOR_OPTIONS
Options in prompt.
Definition: color.h:58
@ MT_COLOR_TREE
Index: tree-drawing characters.
Definition: color.h:77
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:57
@ MT_COLOR_ATTACH_HEADERS
MIME attachment test (takes a pattern)
Definition: color.h:41
@ MT_COLOR_SEARCH
Pager: search matches.
Definition: color.h:62
@ MT_COLOR_COMPOSE_SECURITY_SIGN
Mail will be signed.
Definition: color.h:48
@ MT_COLOR_INDEX_LABEL
Index: label field.
Definition: color.h:86
@ MT_COLOR_ITALIC
Italic text.
Definition: color.h:53
@ MT_COLOR_PROMPT
Question/user input.
Definition: color.h:60
@ MT_COLOR_COMPOSE_HEADER
Header labels, e.g. From:
Definition: color.h:44
@ MT_COLOR_INDEX
Index: default colour.
Definition: color.h:81
@ MT_COLOR_ATTACHMENT
MIME attachments text (entire line)
Definition: color.h:40
@ MT_COLOR_SIDEBAR_INDICATOR
Current open mailbox.
Definition: color.h:68
@ MT_COLOR_SIDEBAR_HIGHLIGHT
Select cursor.
Definition: color.h:67
@ MT_COLOR_WARNING
Warning messages.
Definition: color.h:79
@ MT_COLOR_UNDERLINE
Underlined text.
Definition: color.h:78
@ MT_COLOR_INDEX_NUMBER
Index: index number.
Definition: color.h:87
@ MT_COLOR_SIGNATURE
Pager: signature lines.
Definition: color.h:74
@ MT_COLOR_INDEX_FLAGS
Index: flags field.
Definition: color.h:85
@ MT_COLOR_SIDEBAR_FLAGGED
Mailbox with flagged messages.
Definition: color.h:66
@ MT_COLOR_TILDE
Pager: empty lines after message.
Definition: color.h:76
@ MT_COLOR_INDEX_COLLAPSED
Index: number of messages in collapsed thread.
Definition: color.h:83
int(* parser_callback_t)(struct Buffer *buf, struct Buffer *s, uint32_t *fg, uint32_t *bg, int *attrs, struct Buffer *err)
Definition: command2.h:46
CommandResult
Error codes for command_t parse functions.
Definition: command.h:36
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:39
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:37
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: command.h:38
Convenience wrapper for the core headers.
void regex_colors_dump_all(void)
Dump all the Regex colours to the log.
Definition: debug.c:380
int color_debug(enum LogLevel level, const char *format,...)
Write to the log file.
Definition: debug.c:44
const char * color_debug_log_attrs_list(int attrs)
Get a string to represent some attributes in the log.
Definition: debug.c:150
const char * color_debug_log_name(char *buf, int buflen, int color)
Get a string to represent a colour name.
Definition: debug.c:181
const char * color_debug_log_color_attrs(int fg, int bg, int attrs)
Get a colourful string to represent a colour in the log.
Definition: debug.c:67
void curses_colors_dump(void)
Log all the Curses colours.
Definition: debug.c:267
int mutt_do_pager(struct PagerView *pview, struct Email *e)
Display some page-able text to the user (help or attachment)
Definition: do_pager.c:123
int parse_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: extract.c:48
#define MoreArgs(buf)
Definition: extract.h:30
#define TOKEN_NO_FLAGS
No flags are set.
Definition: extract.h:33
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:634
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: globals.c:81
enum CommandResult mutt_parse_unmono(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unmono' command - Implements Command::parse() -.
Definition: command.c:878
enum CommandResult mutt_parse_mono(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'mono' command - Implements Command::parse() -.
Definition: command.c:903
enum CommandResult mutt_parse_color(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'color' command - Implements Command::parse() -.
Definition: command.c:888
enum CommandResult mutt_parse_uncolor(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'uncolor' command - Implements Command::parse() -.
Definition: command.c:860
static enum CommandResult parse_color_pair(struct Buffer *buf, struct Buffer *s, uint32_t *fg, uint32_t *bg, int *attrs, struct Buffer *err)
Parse a pair of colours - Implements parser_callback_t -.
Definition: command.c:262
static enum CommandResult parse_attr_spec(struct Buffer *buf, struct Buffer *s, uint32_t *fg, uint32_t *bg, int *attrs, struct Buffer *err)
Parse an attribute description - Implements parser_callback_t -.
Definition: command.c:217
Convenience wrapper for the gui headers.
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
bool StartupComplete
When the config has been read.
Definition: main.c:201
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition: mapping.c:85
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
struct AttrColorList MergedColors
Array of user colours.
Definition: merged.c:41
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:171
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:819
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:227
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:239
Many unsorted constants and some structs.
#define PATH_MAX
Definition: mutt.h:41
struct MuttWindow * window_get_focus(void)
Get the currently focused Window.
Definition: mutt_window.c:644
@ WT_CUSTOM
Window with a custom drawing function.
Definition: mutt_window.h:95
@ WT_PAGER
A panel containing the Pager Window.
Definition: mutt_window.h:100
@ NT_COLOR_SET
Color has been set.
Definition: notify2.h:41
@ NT_COLOR
Colour has changed, NotifyColor, EventColor.
Definition: notify_type.h:41
GUI display a file/email/help in a viewport with paging.
#define MUTT_SHOWCOLOR
Show characters in color otherwise don't show characters.
Definition: lib.h:60
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition: lib.h:139
Private state data for the Pager.
Text parsing functions.
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_EMPTY(head)
Definition: queue.h:348
#define TAILQ_EMPTY(head)
Definition: queue.h:721
enum CommandResult quoted_colors_parse_uncolor(enum ColorId cid, int q_level, struct Buffer *err)
Parse the 'uncolor quoted' command.
Definition: quoted.c:163
struct AttrColor * quoted_colors_get(int q)
Return the color of a quote, cycling through the used quotes.
Definition: quoted.c:72
int NumQuotedColors
Number of colours for quoted email text.
Definition: quoted.c:38
bool quoted_colors_parse_color(enum ColorId cid, uint32_t fg, uint32_t bg, int attrs, int q_level, int *rc, struct Buffer *err)
Parse the 'color quoted' command.
Definition: quoted.c:99
#define COLOR_QUOTES_MAX
Ten colours, quoted0..quoted9 (quoted and quoted0 are equivalent)
Definition: quoted.h:37
Key value store.
A curses colour and its attributes.
Definition: attr.h:35
int attrs
Text attributes, e.g. A_BOLD.
Definition: attr.h:37
struct CursesColor * curses_color
Underlying Curses colour.
Definition: attr.h:36
String manipulation buffer.
Definition: buffer.h:34
char * dptr
Current read/write position.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:35
Colour in the ncurses palette.
Definition: curses2.h:38
uint32_t fg
Foreground colour.
Definition: curses2.h:41
uint32_t bg
Background colour.
Definition: curses2.h:42
An Event that happened to a Colour.
Definition: notify2.h:53
enum ColorId cid
Colour ID that has changed.
Definition: notify2.h:54
Mapping between user-readable string and a constant.
Definition: mapping.h:32
const char * name
String value.
Definition: mapping.h:33
void * wdata
Private data.
Definition: mutt_window.h:145
struct MuttWindow * parent
Parent Window.
Definition: mutt_window.h:135
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:144
Data to be displayed by PagerView.
Definition: lib.h:158
const char * fname
Name of the file to read.
Definition: lib.h:162
Private state data for the Pager.
Definition: private_data.h:41
struct AttrColorList ansi_list
List of ANSI colours used in the Pager.
Definition: private_data.h:70
Paged view into some data.
Definition: lib.h:169
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:170
enum PagerMode mode
Pager mode.
Definition: lib.h:171
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:172
const char * banner
Title to display in status bar.
Definition: lib.h:173
A regular expression and a color to highlight a line.
Definition: regex4.h:37
struct AttrColor attr_color
Colour and attributes to apply.
Definition: regex4.h:38
char * pattern
Pattern to match.
Definition: regex4.h:39
#define mutt_mktemp(buf, buflen)
Definition: tmp.h:34