NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
quoted.h File Reference

Quoted-Email colours. More...

#include "config.h"
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "core/lib.h"
#include "attr.h"
#include "color.h"
+ Include dependency graph for quoted.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  QuoteStyle
 Style of quoted text. More...
 

Macros

#define COLOR_QUOTES_MAX   10
 Ten colours, quoted0..quoted9 (quoted and quoted0 are equivalent)
 

Functions

void quoted_colors_cleanup (void)
 Reset the quoted-email colours.
 
struct AttrColorquoted_colors_get (int q)
 Return the color of a quote, cycling through the used quotes.
 
int quoted_colors_num_used (void)
 Return the number of used quotes.
 
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.
 
enum CommandResult quoted_colors_parse_uncolor (enum ColorId cid, int q_level, struct Buffer *err)
 Parse the 'uncolor quoted' command.
 
struct QuoteStyleqstyle_classify (struct QuoteStyle **quote_list, const char *qptr, size_t length, bool *force_redraw, int *q_level)
 Find a style for a string.
 
void qstyle_free_tree (struct QuoteStyle **quote_list)
 Free an entire tree of QuoteStyle.
 
void qstyle_recolour (struct QuoteStyle *quote_list)
 Recolour quotes after colour changes.
 

Variables

struct AttrColor QuotedColors []
 Array of colours for quoted email text.
 
int NumQuotedColors
 Number of colours for quoted email text.
 

Detailed Description

Quoted-Email colours.

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 quoted.h.

Macro Definition Documentation

◆ COLOR_QUOTES_MAX

#define COLOR_QUOTES_MAX   10

Ten colours, quoted0..quoted9 (quoted and quoted0 are equivalent)

Definition at line 37 of file quoted.h.

Function Documentation

◆ quoted_colors_cleanup()

void quoted_colors_cleanup ( void  )

Reset the quoted-email colours.

Definition at line 64 of file quoted.c.

65{
66 color_debug(LL_DEBUG5, "QuotedColors: clean up\n");
67 for (size_t i = 0; i < COLOR_QUOTES_MAX; i++)
68 {
70 }
72}
void attr_color_clear(struct AttrColor *ac)
Free the contents of an AttrColor.
Definition: attr.c:44
int color_debug(enum LogLevel level, const char *format,...)
Write to the log file.
Definition: debug.c:51
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
int NumQuotedColors
Number of colours for quoted email text.
Definition: quoted.c:45
struct AttrColor QuotedColors[COLOR_QUOTES_MAX]
Array of colours for quoted email text.
Definition: quoted.c:44
#define COLOR_QUOTES_MAX
Ten colours, quoted0..quoted9 (quoted and quoted0 are equivalent)
Definition: quoted.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quoted_colors_get()

struct AttrColor * quoted_colors_get ( int  q)

Return the color of a quote, cycling through the used quotes.

Parameters
qQuote level
Return values
enumColorId, e.g. MT_COLOR_QUOTED

Definition at line 79 of file quoted.c.

80{
81 if (NumQuotedColors == 0)
82 return NULL;
83 return &QuotedColors[q % NumQuotedColors];
84}
+ Here is the caller graph for this function:

◆ quoted_colors_num_used()

int quoted_colors_num_used ( void  )

Return the number of used quotes.

Return values
numNumber of used quotes

Definition at line 90 of file quoted.c.

91{
92 return NumQuotedColors;
93}
+ Here is the caller graph for this function:

◆ quoted_colors_parse_color()

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.

Parameters
cidColour Id, should be MT_COLOR_QUOTED
fgForeground colour
bgBackground colour
attrsAttributes, e.g. A_UNDERLINE
q_levelQuoting depth level
rcReturn code, e.g. MUTT_CMD_SUCCESS
errBuffer for error messages
Return values
trueColour was parsed

Definition at line 106 of file quoted.c.

108{
109 if (cid != MT_COLOR_QUOTED)
110 return false;
111
112 color_debug(LL_DEBUG5, "quoted %d\n", q_level);
113 if (q_level >= COLOR_QUOTES_MAX)
114 {
115 buf_printf(err, _("Maximum quoting level is %d"), COLOR_QUOTES_MAX - 1);
116 return false;
117 }
118
119 if (q_level >= NumQuotedColors)
120 NumQuotedColors = q_level + 1;
121
122 struct AttrColor *ac = &QuotedColors[q_level];
123 const bool was_set = ((ac->attrs != 0) || ac->curses_color);
124 ac->attrs = attrs;
125
126 struct CursesColor *cc = curses_color_new(fg, bg);
128 ac->curses_color = cc;
129
130 if (!cc)
132
133 if (was_set)
134 quoted_color_dump(ac, q_level, "QuotedColors changed: ");
135 else
136 quoted_color_dump(ac, q_level, "QuotedColors new: ");
137
138 struct Buffer *buf = buf_pool_get();
139 get_colorid_name(cid, buf);
140 color_debug(LL_DEBUG5, "NT_COLOR_SET: %s\n", buf->data);
141 buf_pool_release(&buf);
142
143 if (q_level == 0)
144 {
145 // Copy the colour into the SimpleColors
146 struct AttrColor *ac_quoted = simple_color_get(MT_COLOR_QUOTED);
147 *ac_quoted = *ac;
148 ac_quoted->ref_count = 1;
149 if (ac_quoted->curses_color)
150 ac_quoted->curses_color->ref_count++;
151 }
152
153 struct EventColor ev_c = { cid, ac };
155
158
159 *rc = MUTT_CMD_SUCCESS;
160 return true;
161}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:173
void get_colorid_name(unsigned int cid, struct Buffer *buf)
Get the name of a color id.
Definition: command.c:677
struct Notify * ColorsNotify
Notifications: ColorId, EventColor.
Definition: notify.c:35
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
Definition: simple.c:81
@ MT_COLOR_QUOTED
Pager: quoted text.
Definition: color.h:61
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:39
void curses_color_free(struct CursesColor **ptr)
Free a CursesColor.
Definition: curses.c:121
struct CursesColor * curses_color_new(int fg, int bg)
Create a new CursesColor.
Definition: curses.c:151
void quoted_color_list_dump(void)
Log all the Quoted colours.
Definition: debug.c:319
void quoted_color_dump(struct AttrColor *ac, int q_level, const char *prefix)
Log a Quoted colour.
Definition: debug.c:295
void curses_colors_dump(void)
Log all the Curses colours.
Definition: debug.c:274
#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:173
@ NT_COLOR_SET
Color has been set.
Definition: notify2.h:41
@ NT_COLOR
Colour has changed, NotifyColor, EventColor.
Definition: notify_type.h:41
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
static int find_highest_used(void)
Find the highest-numbered quotedN in use.
Definition: quoted.c:51
A curses colour and its attributes.
Definition: attr.h:35
short ref_count
Number of users.
Definition: attr.h:38
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 * 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
short ref_count
Number of users.
Definition: curses2.h:44
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:

◆ quoted_colors_parse_uncolor()

enum CommandResult quoted_colors_parse_uncolor ( enum ColorId  cid,
int  q_level,
struct Buffer err 
)

Parse the 'uncolor quoted' command.

Parameters
cidColour Id, should be MT_COLOR_QUOTED
q_levelQuoting depth level
errBuffer for error messages
Return values
enumCommandResult, e.g. MUTT_CMD_SUCCESS

Definition at line 170 of file quoted.c.

172{
173 color_debug(LL_DEBUG5, "unquoted %d\n", q_level);
174
175 struct AttrColor *ac = &QuotedColors[q_level];
177 quoted_color_dump(ac, q_level, "QuotedColors clear: ");
178
181
183
184 struct EventColor ev_c = { cid, ac };
186
187 return MUTT_CMD_SUCCESS;
188}
@ NT_COLOR_RESET
Color has been reset/removed.
Definition: notify2.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ qstyle_classify()

struct QuoteStyle * qstyle_classify ( struct QuoteStyle **  quote_list,
const char *  qptr,
size_t  length,
bool *  force_redraw,
int *  q_level 
)

Find a style for a string.

Parameters
[out]quote_listList of quote colours
[in]qptrString to classify
[in]lengthLength of string
[out]force_redrawSet to true if a screen redraw is needed
[out]q_levelQuoting level
Return values
ptrQuoting style

Definition at line 291 of file quoted.c.

293{
294 struct QuoteStyle *q_list = *quote_list;
295 struct QuoteStyle *qc = NULL, *tmp = NULL, *ptr = NULL, *save = NULL;
296 const char *tail_qptr = NULL;
297 size_t offset, tail_lng;
298 int index = -1;
299
300 /* classify quoting prefix */
301 while (q_list)
302 {
303 if (length <= q_list->prefix_len)
304 {
305 /* case 1: check the top level nodes */
306
307 if (mutt_strn_equal(qptr, q_list->prefix, length))
308 {
309 if (length == q_list->prefix_len)
310 return q_list; /* same prefix: return the current class */
311
312 /* found shorter prefix */
313 if (tmp)
314 {
315 /* found another branch for which tmp is a shorter prefix */
316
317 /* save the next sibling for later */
318 save = q_list->next;
319
320 /* unlink q_list from the top level list */
321 if (q_list->next)
322 q_list->next->prev = q_list->prev;
323 if (q_list->prev)
324 q_list->prev->next = q_list->next;
325
326 /* at this point, we have a tmp->down; link q_list to it */
327 ptr = tmp->down;
328 /* sibling order is important here, q_list should be linked last */
329 while (ptr->next)
330 ptr = ptr->next;
331 ptr->next = q_list;
332 q_list->next = NULL;
333 q_list->prev = ptr;
334 q_list->up = tmp;
335
336 index = q_list->quote_n;
337
338 /* next class to test; as above, we shouldn't go down */
339 q_list = save;
340 }
341 else
342 {
343 /* add a node above q_list */
344 tmp = qstyle_new();
345 tmp->prefix = mutt_strn_dup(qptr, length);
346 tmp->prefix_len = length;
347
348 /* replace q_list by tmp in the top level list */
349 if (q_list->next)
350 {
351 tmp->next = q_list->next;
352 q_list->next->prev = tmp;
353 }
354 if (q_list->prev)
355 {
356 tmp->prev = q_list->prev;
357 q_list->prev->next = tmp;
358 }
359
360 /* make q_list a child of tmp */
361 tmp->down = q_list;
362 q_list->up = tmp;
363
364 /* q_list has no siblings for now */
365 q_list->next = NULL;
366 q_list->prev = NULL;
367
368 /* update the root if necessary */
369 if (q_list == *quote_list)
370 *quote_list = tmp;
371
372 index = q_list->quote_n;
373
374 /* tmp should be the return class too */
375 qc = tmp;
376
377 /* next class to test; if tmp is a shorter prefix for another
378 * node, that node can only be in the top level list, so don't
379 * go down after this point */
380 q_list = tmp->next;
381 }
382
383 /* we found a shorter prefix, so certain quotes have changed classes */
384 *force_redraw = true;
385 continue;
386 }
387 else
388 {
389 /* shorter, but not a substring of the current class: try next */
390 q_list = q_list->next;
391 continue;
392 }
393 }
394 else
395 {
396 /* case 2: try subclassing the current top level node */
397
398 /* tmp != NULL means we already found a shorter prefix at case 1 */
399 if (!tmp && mutt_strn_equal(qptr, q_list->prefix, q_list->prefix_len))
400 {
401 /* ok, it's a subclass somewhere on this branch */
402
403 ptr = q_list;
404 offset = q_list->prefix_len;
405
406 q_list = q_list->down;
407 tail_lng = length - offset;
408 tail_qptr = qptr + offset;
409
410 while (q_list)
411 {
412 if (length <= q_list->prefix_len)
413 {
414 if (mutt_strn_equal(tail_qptr, (q_list->prefix) + offset, tail_lng))
415 {
416 /* same prefix: return the current class */
417 if (length == q_list->prefix_len)
418 return q_list;
419
420 /* found shorter common prefix */
421 if (!tmp)
422 {
423 /* add a node above q_list */
424 tmp = qstyle_new();
425 tmp->prefix = mutt_strn_dup(qptr, length);
426 tmp->prefix_len = length;
427
428 /* replace q_list by tmp */
429 if (q_list->next)
430 {
431 tmp->next = q_list->next;
432 q_list->next->prev = tmp;
433 }
434 if (q_list->prev)
435 {
436 tmp->prev = q_list->prev;
437 q_list->prev->next = tmp;
438 }
439
440 /* make q_list a child of tmp */
441 tmp->down = q_list;
442 tmp->up = q_list->up;
443 q_list->up = tmp;
444 if (tmp->up->down == q_list)
445 tmp->up->down = tmp;
446
447 /* q_list has no siblings */
448 q_list->next = NULL;
449 q_list->prev = NULL;
450
451 index = q_list->quote_n;
452
453 /* tmp should be the return class too */
454 qc = tmp;
455
456 /* next class to test */
457 q_list = tmp->next;
458 }
459 else
460 {
461 /* found another branch for which tmp is a shorter prefix */
462
463 /* save the next sibling for later */
464 save = q_list->next;
465
466 /* unlink q_list from the top level list */
467 if (q_list->next)
468 q_list->next->prev = q_list->prev;
469 if (q_list->prev)
470 q_list->prev->next = q_list->next;
471
472 /* at this point, we have a tmp->down; link q_list to it */
473 ptr = tmp->down;
474 while (ptr->next)
475 ptr = ptr->next;
476 ptr->next = q_list;
477 q_list->next = NULL;
478 q_list->prev = ptr;
479 q_list->up = tmp;
480
481 index = q_list->quote_n;
482
483 /* next class to test */
484 q_list = save;
485 }
486
487 /* we found a shorter prefix, so we need a redraw */
488 *force_redraw = true;
489 continue;
490 }
491 else
492 {
493 q_list = q_list->next;
494 continue;
495 }
496 }
497 else
498 {
499 /* longer than the current prefix: try subclassing it */
500 if (!tmp && mutt_strn_equal(tail_qptr, (q_list->prefix) + offset,
501 q_list->prefix_len - offset))
502 {
503 /* still a subclass: go down one level */
504 ptr = q_list;
505 offset = q_list->prefix_len;
506
507 q_list = q_list->down;
508 tail_lng = length - offset;
509 tail_qptr = qptr + offset;
510
511 continue;
512 }
513 else
514 {
515 /* nope, try the next prefix */
516 q_list = q_list->next;
517 continue;
518 }
519 }
520 }
521
522 /* still not found so far: add it as a sibling to the current node */
523 if (!qc)
524 {
525 tmp = qstyle_new();
526 tmp->prefix = mutt_strn_dup(qptr, length);
527 tmp->prefix_len = length;
528
529 if (ptr->down)
530 {
531 tmp->next = ptr->down;
532 ptr->down->prev = tmp;
533 }
534 ptr->down = tmp;
535 tmp->up = ptr;
536
537 tmp->quote_n = (*q_level)++;
538 tmp->attr_color = quoted_colors_get(tmp->quote_n);
539
540 return tmp;
541 }
542 else
543 {
544 if (index != -1)
545 qstyle_insert(*quote_list, tmp, index, q_level);
546
547 return qc;
548 }
549 }
550 else
551 {
552 /* nope, try the next prefix */
553 q_list = q_list->next;
554 continue;
555 }
556 }
557 }
558
559 if (!qc)
560 {
561 /* not found so far: add it as a top level class */
562 qc = qstyle_new();
563 qc->prefix = mutt_strn_dup(qptr, length);
564 qc->prefix_len = length;
565 qc->quote_n = (*q_level)++;
567
568 if (*quote_list)
569 {
570 if ((*quote_list)->next)
571 {
572 qc->next = (*quote_list)->next;
573 qc->next->prev = qc;
574 }
575 (*quote_list)->next = qc;
576 qc->prev = *quote_list;
577 }
578 else
579 {
580 *quote_list = qc;
581 }
582 }
583
584 if (index != -1)
585 qstyle_insert(*quote_list, tmp, index, q_level);
586
587 return qc;
588}
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:452
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:497
struct AttrColor * quoted_colors_get(int q)
Return the color of a quote, cycling through the used quotes.
Definition: quoted.c:79
static void qstyle_insert(struct QuoteStyle *quote_list, struct QuoteStyle *new_class, int index, int *q_level)
Insert a new quote colour class into a list.
Definition: quoted.c:243
static struct QuoteStyle * qstyle_new(void)
Create a new QuoteStyle.
Definition: quoted.c:231
Style of quoted text.
Definition: quoted.h:68
struct AttrColor * attr_color
Colour and attribute of the text.
Definition: quoted.h:70
struct QuoteStyle * next
Different quoting styles at the same level.
Definition: quoted.h:73
struct QuoteStyle * up
Definition: quoted.h:74
size_t prefix_len
Length of the prefix string.
Definition: quoted.h:72
struct QuoteStyle * prev
Definition: quoted.h:73
char * prefix
Prefix string, e.g. "> ".
Definition: quoted.h:71
struct QuoteStyle * down
Parent (less quoted) and child (more quoted) levels.
Definition: quoted.h:74
int quote_n
The quoteN colour index for this level.
Definition: quoted.h:69
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ qstyle_free_tree()

void qstyle_free_tree ( struct QuoteStyle **  quote_list)

Free an entire tree of QuoteStyle.

Parameters
[out]quote_listQuote list to free
Note
Use qstyle_free() to free a single object

Definition at line 213 of file quoted.c.

214{
215 struct QuoteStyle *next = NULL;
216
217 while (*quote_list)
218 {
219 if ((*quote_list)->down)
220 qstyle_free_tree(&((*quote_list)->down));
221 next = (*quote_list)->next;
222 qstyle_free(quote_list);
223 *quote_list = next;
224 }
225}
void qstyle_free_tree(struct QuoteStyle **quote_list)
Free an entire tree of QuoteStyle.
Definition: quoted.c:213
static void qstyle_free(struct QuoteStyle **ptr)
Free a single QuoteStyle object.
Definition: quoted.c:196
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ qstyle_recolour()

void qstyle_recolour ( struct QuoteStyle quote_list)

Recolour quotes after colour changes.

Parameters
quote_listList of quote colours

Definition at line 619 of file quoted.c.

620{
621 if (!quote_list)
622 return;
623
624 int num = quoted_colors_num_used();
625 int cur = 0;
626
628 qstyle_recurse(quote_list, num, &cur);
630}
int quoted_colors_num_used(void)
Return the number of used quotes.
Definition: quoted.c:90
static void qstyle_recurse(struct QuoteStyle *quote_list, int num_qlevel, int *cur_qlevel)
Update the quoting styles after colour changes.
Definition: quoted.c:596
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ QuotedColors

struct AttrColor QuotedColors[]
extern

Array of colours for quoted email text.

Definition at line 44 of file quoted.c.

◆ NumQuotedColors

int NumQuotedColors
extern

Number of colours for quoted email text.

Definition at line 45 of file quoted.c.