NeoMutt  2022-04-29-247-gc6aae8
Teaching an old dog new tricks
DOXYGEN
command.c File Reference

Parse colour commands. More...

#include "config.h"
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "mutt/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "lib.h"
#include "init.h"
#include "options.h"
+ Include dependency graph for command.c:

Go to the source code of this file.

Functions

static enum CommandResult parse_color_name (const char *s, uint32_t *col, int *attrs, bool is_fg, struct Buffer *err)
 Parse a colour name. More...
 
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 -. More...
 
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 -. More...
 
void get_colorid_name (unsigned int cid, struct Buffer *buf)
 Get the name of a color id. More...
 
static enum CommandResult parse_object (struct Buffer *buf, struct Buffer *s, enum ColorId *cid, int *ql, struct Buffer *err)
 Identify a colour object. More...
 
static enum CommandResult parse_uncolor (struct Buffer *buf, struct Buffer *s, struct Buffer *err, bool uncolor)
 Parse an 'uncolor' command. More...
 
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. More...
 
enum CommandResult mutt_parse_uncolor (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'uncolor' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_unmono (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unmono' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_color (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'color' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_mono (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'mono' command - Implements Command::parse() -. More...
 

Variables

const struct Mapping ColorFields []
 Mapping of colour names to their IDs. More...
 
const struct Mapping ComposeColorFields []
 Mapping of compose colour names to their IDs. More...
 

Detailed Description

Parse colour commands.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file command.c.

Function Documentation

◆ parse_color_name()

static enum CommandResult parse_color_name ( const char *  s,
uint32_t *  col,
int *  attrs,
bool  is_fg,
struct Buffer err 
)
static

Parse a colour name.

Parameters
[in]sString to parse
[out]colNumber for 'colorNNN' colours
[out]attrsAttributes, e.g. A_UNDERLINE
[in]is_fgtrue if this is a foreground colour
[out]errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Parse a colour name, such as "red", "brightgreen", "color123".

Definition at line 121 of file command.c.

123{
124 char *eptr = NULL;
125 bool is_alert = false, is_bright = false, is_light = false;
126 int clen;
127
128 if ((clen = mutt_istr_startswith(s, "bright")))
129 {
130 color_debug(LL_DEBUG5, "bright\n");
131 is_bright = true;
132 s += clen;
133 }
134 else if ((clen = mutt_istr_startswith(s, "alert")))
135 {
136 color_debug(LL_DEBUG5, "alert\n");
137 is_alert = true;
138 is_bright = true;
139 s += clen;
140 }
141 else if ((clen = mutt_istr_startswith(s, "light")))
142 {
143 color_debug(LL_DEBUG5, "light\n");
144 is_light = true;
145 s += clen;
146 }
147
148 /* allow aliases for xterm color resources */
149 if ((clen = mutt_istr_startswith(s, "color")))
150 {
151 s += clen;
152 *col = strtoul(s, &eptr, 10);
153 if ((*s == '\0') || (*eptr != '\0') || ((*col >= COLORS) && !OptNoCurses))
154 {
155 mutt_buffer_printf(err, _("%s: color not supported by term"), s);
156 return MUTT_CMD_ERROR;
157 }
158 color_debug(LL_DEBUG5, "colorNNN %d\n", *col);
159 }
160 else if ((*col = mutt_map_get_value(s, ColorNames)) == -1)
161 {
162 mutt_buffer_printf(err, _("%s: no such color"), s);
163 return MUTT_CMD_WARNING;
164 }
165 const char *name = mutt_map_get_name(*col, ColorNames);
166 if (name)
167 color_debug(LL_DEBUG5, "color: %s\n", name);
168
169 if (is_bright || is_light)
170 {
171 if (is_alert)
172 {
173 *attrs |= A_BOLD;
174 *attrs |= A_BLINK;
175 }
176 else if (is_fg)
177 {
178 if ((COLORS >= 16) && is_light)
179 {
180 if (*col <= 7)
181 {
182 /* Advance the color 0-7 by 8 to get the light version */
183 *col += 8;
184 }
185 }
186 else
187 {
188 *attrs |= A_BOLD;
189 }
190 }
191 else
192 {
193 if (COLORS >= 16)
194 {
195 if (*col <= 7)
196 {
197 /* Advance the color 0-7 by 8 to get the light version */
198 *col += 8;
199 }
200 }
201 }
202 }
203
204 return MUTT_CMD_SUCCESS;
205}
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:168
const struct Mapping ColorNames[]
Definition: color.c:37
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:37
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:35
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: command.h:36
int color_debug(enum LogLevel level, const char *format,...)
Write to the log file.
Definition: debug.c:44
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
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
#define _(a)
Definition: message.h:28
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
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_colorid_name()

void get_colorid_name ( unsigned int  cid,
struct Buffer buf 
)

Get the name of a color id.

Parameters
cidColour, e.g. MT_COLOR_HEADER
bufBuffer for result

Definition at line 329 of file command.c.

330{
331 const char *name = NULL;
332
334 {
336 if (name)
337 {
338 mutt_buffer_printf(buf, "compose %s", name);
339 return;
340 }
341 }
342
343 name = mutt_map_get_name(cid, ColorFields);
344 if (name)
345 mutt_buffer_printf(buf, "%s", name);
346 else
347 mutt_buffer_printf(buf, "UNKNOWN %d", cid);
348}
const struct Mapping ComposeColorFields[]
Mapping of compose colour names to their IDs.
Definition: command.c:99
const struct Mapping ColorFields[]
Mapping of colour names to their IDs.
Definition: command.c:45
@ MT_COLOR_COMPOSE_SECURITY_SIGN
Mail will be signed.
Definition: color.h:45
@ MT_COLOR_COMPOSE_HEADER
Header labels, e.g. From:
Definition: color.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_object()

static enum CommandResult parse_object ( struct Buffer buf,
struct Buffer s,
enum ColorId cid,
int *  ql,
struct Buffer err 
)
static

Identify a colour object.

Parameters
[in]bufTemporary Buffer space
[in]sBuffer containing string to be parsed
[out]cidObject type, e.g. MT_COLOR_TILDE
[out]qlQuote level, if type MT_COLOR_QUOTED
[out]errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Identify a colour object, e.g. "quoted", "compose header"

Definition at line 361 of file command.c.

363{
364 int rc;
365
366 if (mutt_str_startswith(buf->data, "quoted") != 0)
367 {
368 int val = 0;
369 if (buf->data[6] != '\0')
370 {
371 if (!mutt_str_atoi_full(buf->data + 6, &val) || (val > COLOR_QUOTES_MAX))
372 {
373 mutt_buffer_printf(err, _("%s: no such object"), buf->data);
374 return MUTT_CMD_WARNING;
375 }
376 }
377
378 *ql = val;
379 *cid = MT_COLOR_QUOTED;
380 return MUTT_CMD_SUCCESS;
381 }
382
383 if (mutt_istr_equal(buf->data, "compose"))
384 {
385 if (!MoreArgs(s))
386 {
387 mutt_buffer_printf(err, _("%s: too few arguments"), "color");
388 return MUTT_CMD_WARNING;
389 }
390
392
394 if (rc == -1)
395 {
396 mutt_buffer_printf(err, _("%s: no such object"), buf->data);
397 return MUTT_CMD_WARNING;
398 }
399
400 *cid = rc;
401 return MUTT_CMD_SUCCESS;
402 }
403
405 if (rc == -1)
406 {
407 mutt_buffer_printf(err, _("%s: no such object"), buf->data);
408 return MUTT_CMD_WARNING;
409 }
410 else
411 {
412 color_debug(LL_DEBUG5, "object: %s\n", mutt_map_get_name(rc, ColorFields));
413 }
414
415 *cid = rc;
416 return MUTT_CMD_SUCCESS;
417}
#define MoreArgs(buf)
Definition: buffer.h:40
@ MT_COLOR_QUOTED
Pager: quoted text.
Definition: color.h:58
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:273
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:819
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:227
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:67
#define COLOR_QUOTES_MAX
Ten colours, quoted0..quoted9 (quoted and quoted0 are equivalent)
Definition: quoted.h:37
char * data
Pointer to data.
Definition: buffer.h:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_uncolor()

static enum CommandResult parse_uncolor ( struct Buffer buf,
struct Buffer s,
struct Buffer err,
bool  uncolor 
)
static

Parse an 'uncolor' command.

Parameters
bufTemporary Buffer space
sBuffer containing string to be parsed
errBuffer for error messages
uncolorIf true, 'uncolor', else 'unmono'
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Usage:

  • uncolor index pattern [pattern...]
  • unmono index pattern [pattern...]

Definition at line 431 of file command.c.

433{
435
436 if (mutt_str_equal(buf->data, "*"))
437 {
438 colors_clear();
439 return MUTT_CMD_SUCCESS;
440 }
441
442 unsigned int cid = MT_COLOR_NONE;
443 int ql = 0;
444 color_debug(LL_DEBUG5, "uncolor: %s\n", mutt_buffer_string(buf));
445 enum CommandResult rc = parse_object(buf, s, &cid, &ql, err);
446 if (rc != MUTT_CMD_SUCCESS)
447 return rc;
448
449 if (cid == -1)
450 {
451 mutt_buffer_printf(err, _("%s: no such object"), buf->data);
452 return MUTT_CMD_ERROR;
453 }
454
455 if (cid == MT_COLOR_QUOTED)
456 {
457 color_debug(LL_DEBUG5, "quoted\n");
458 return quoted_colors_parse_uncolor(cid, ql, err);
459 }
460
461 if ((cid == MT_COLOR_STATUS) && !MoreArgs(s))
462 {
463 color_debug(LL_DEBUG5, "simple\n");
464 simple_color_reset(cid); // default colour for the status bar
465 return MUTT_CMD_SUCCESS;
466 }
467
468 if (!mutt_color_has_pattern(cid))
469 {
470 color_debug(LL_DEBUG5, "simple\n");
472 return MUTT_CMD_SUCCESS;
473 }
474
475 if (OptNoCurses)
476 {
477 do
478 {
479 color_debug(LL_DEBUG5, "do nothing\n");
480 /* just eat the command, but don't do anything real about it */
482 } while (MoreArgs(s));
483
484 return MUTT_CMD_SUCCESS;
485 }
486
487 bool changes = false;
488 if (!MoreArgs(s))
489 {
490 if (regex_colors_parse_uncolor(cid, NULL, uncolor))
491 return MUTT_CMD_SUCCESS;
492 else
493 return MUTT_CMD_ERROR;
494 }
495
496 do
497 {
499 if (mutt_str_equal("*", buf->data))
500 {
501 if (regex_colors_parse_uncolor(cid, NULL, uncolor))
502 return MUTT_CMD_SUCCESS;
503 else
504 return MUTT_CMD_ERROR;
505 }
506
507 changes |= regex_colors_parse_uncolor(cid, buf->data, uncolor);
508
509 } while (MoreArgs(s));
510
511 if (changes)
513
514 return MUTT_CMD_SUCCESS;
515}
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
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:361
bool regex_colors_parse_uncolor(enum ColorId cid, const char *pat, bool uncolor)
Parse a Regex 'uncolor' command.
Definition: regex.c:439
void simple_color_reset(enum ColorId cid)
Clear the colour of a simple object.
Definition: simple.c:144
bool mutt_color_has_pattern(enum ColorId cid)
Check if a color object supports a regex pattern.
Definition: color.c:102
void colors_clear(void)
Reset all the simple, quoted and regex colours.
Definition: color.c:55
@ MT_COLOR_STATUS
Status bar (takes a pattern)
Definition: color.h:71
@ MT_COLOR_NONE
Definition: color.h:36
CommandResult
Error codes for command_t parse functions.
Definition: command.h:34
void regex_colors_dump_all(void)
Dump all the Regex colours to the log.
Definition: debug.c:380
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
enum CommandResult quoted_colors_parse_uncolor(enum ColorId cid, int q_level, struct Buffer *err)
Parse the 'uncolor quoted' command.
Definition: quoted.c:163
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_color()

static enum CommandResult parse_color ( struct Buffer buf,
struct Buffer s,
struct Buffer err,
parser_callback_t  callback,
bool  dry_run,
bool  color 
)
static

Parse a 'color' command.

Parameters
bufTemporary Buffer space
sBuffer containing string to be parsed
errBuffer for error messages
callbackFunction to handle command - Implements parser_callback_t
dry_runIf true, test the command, but don't apply it
colorIf true "color", else "mono"
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Usage:

  • color OBJECT [ ATTRS ] FG BG [ REGEX ]
  • mono OBJECT ATTRS [ REGEX ]

Definition at line 531 of file command.c.

534{
535 int attrs = 0, q_level = 0;
536 uint32_t fg = 0, bg = 0, match = 0;
537 enum ColorId cid = MT_COLOR_NONE;
538 enum CommandResult rc;
539
540 if (!MoreArgs(s))
541 {
542 mutt_buffer_printf(err, _("%s: too few arguments"), "color");
543 return MUTT_CMD_WARNING;
544 }
545
547 color_debug(LL_DEBUG5, "color: %s\n", mutt_buffer_string(buf));
548
549 rc = parse_object(buf, s, &cid, &q_level, err);
550 if (rc != MUTT_CMD_SUCCESS)
551 return rc;
552
553 rc = callback(buf, s, &fg, &bg, &attrs, err);
554 if (rc != MUTT_CMD_SUCCESS)
555 return rc;
556
557 /* extract a regular expression if needed */
558
559 if (mutt_color_has_pattern(cid) && cid != MT_COLOR_STATUS)
560 {
561 color_debug(LL_DEBUG5, "regex needed\n");
562 if (MoreArgs(s))
563 {
565 }
566 else
567 {
568 mutt_buffer_strcpy(buf, ".*");
569 }
570 }
571
572 if (MoreArgs(s) && (cid != MT_COLOR_STATUS))
573 {
574 mutt_buffer_printf(err, _("%s: too many arguments"), color ? "color" : "mono");
575 return MUTT_CMD_WARNING;
576 }
577
578 if (dry_run)
579 {
580 color_debug(LL_DEBUG5, "dry_run bailout\n");
581 *s->dptr = '\0'; /* fake that we're done parsing */
582 return MUTT_CMD_SUCCESS;
583 }
584
585 /* The case of the tree object is special, because a non-default fg color of
586 * the tree element may be combined dynamically with the default bg color of
587 * an index line, not necessarily defined in a rc file. */
588 if (!OptNoCurses &&
589 ((fg == COLOR_DEFAULT) || (bg == COLOR_DEFAULT) || (cid == MT_COLOR_TREE)) &&
590 (use_default_colors() != OK))
591 {
592 mutt_buffer_strcpy(err, _("default colors not supported"));
593 return MUTT_CMD_ERROR;
594 }
595
596 if (regex_colors_parse_color_list(cid, buf->data, fg, bg, attrs, &rc, err))
597 {
598 color_debug(LL_DEBUG5, "regex_colors_parse_color_list done\n");
599 return rc;
600 // do nothing
601 }
602 else if (quoted_colors_parse_color(cid, fg, bg, attrs, q_level, &rc, err))
603 {
604 color_debug(LL_DEBUG5, "quoted_colors_parse_color done\n");
605 return rc;
606 // do nothing
607 }
608 else if ((cid == MT_COLOR_STATUS) && MoreArgs(s))
609 {
610 color_debug(LL_DEBUG5, "status\n");
611 /* 'color status fg bg' can have up to 2 arguments:
612 * 0 arguments: sets the default status color (handled below by else part)
613 * 1 argument : colorize pattern on match
614 * 2 arguments: colorize nth submatch of pattern */
616
617 if (MoreArgs(s))
618 {
619 struct Buffer tmp = mutt_buffer_make(0);
621 if (!mutt_str_atoui_full(tmp.data, &match))
622 {
623 mutt_buffer_printf(err, _("%s: invalid number: %s"),
624 color ? "color" : "mono", tmp.data);
626 return MUTT_CMD_WARNING;
627 }
629 }
630
631 if (MoreArgs(s))
632 {
633 mutt_buffer_printf(err, _("%s: too many arguments"), color ? "color" : "mono");
634 return MUTT_CMD_WARNING;
635 }
636
637 rc = regex_colors_parse_status_list(cid, buf->data, fg, bg, attrs, match, err);
638 return rc;
639 }
640 else // Remaining simple colours
641 {
642 color_debug(LL_DEBUG5, "simple\n");
643 if (simple_color_set(cid, fg, bg, attrs))
644 rc = MUTT_CMD_SUCCESS;
645 else
646 rc = MUTT_CMD_ERROR;
647 }
648
649 if (rc == MUTT_CMD_SUCCESS)
650 {
651 get_colorid_name(cid, buf);
652 color_debug(LL_DEBUG5, "NT_COLOR_SET: %s\n", buf->data);
653 struct EventColor ev_c = { cid, NULL };
655 }
656
657 return rc;
658}
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:327
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:309
void get_colorid_name(unsigned int cid, struct Buffer *buf)
Get the name of a color id.
Definition: command.c:329
struct Notify * ColorsNotify
Notifications: ColorId, EventColor.
Definition: notify.c:34
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
#define COLOR_DEFAULT
Definition: color.h:99
ColorId
List of all colored objects.
Definition: color.h:35
@ MT_COLOR_TREE
Index: tree-drawing characters.
Definition: color.h:73
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
@ NT_COLOR_SET
Color has been set.
Definition: notify2.h:41
@ NT_COLOR
Colour has changed, NotifyColor, EventColor.
Definition: notify_type.h:41
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
String manipulation buffer.
Definition: buffer.h:34
char * dptr
Current read/write position.
Definition: buffer.h:36
An Event that happened to a Colour.
Definition: notify2.h:53
enum ColorId cid
Colour ID that has changed.
Definition: notify2.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ ColorFields

const struct Mapping ColorFields[]

Mapping of colour names to their IDs.

Definition at line 45 of file command.c.

◆ ComposeColorFields

const struct Mapping ComposeColorFields[]
Initial value:
= {
{ "header", MT_COLOR_COMPOSE_HEADER },
{ "security_encrypt", MT_COLOR_COMPOSE_SECURITY_ENCRYPT },
{ "security_sign", MT_COLOR_COMPOSE_SECURITY_SIGN },
{ "security_both", MT_COLOR_COMPOSE_SECURITY_BOTH },
{ "security_none", MT_COLOR_COMPOSE_SECURITY_NONE },
{ NULL, 0 }
}
@ MT_COLOR_COMPOSE_SECURITY_ENCRYPT
Mail will be encrypted.
Definition: color.h:43
@ MT_COLOR_COMPOSE_SECURITY_NONE
Mail will not be encrypted or signed.
Definition: color.h:44
@ MT_COLOR_COMPOSE_SECURITY_BOTH
Mail will be encrypted and signed.
Definition: color.h:42

Mapping of compose colour names to their IDs.

Definition at line 99 of file command.c.