NeoMutt  2022-04-29-178-g3b62e6
Teaching an old dog new tricks
DOXYGEN
regex.c File Reference

Regex Colour. More...

#include "config.h"
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "index/lib.h"
#include "pattern/lib.h"
#include "attr.h"
#include "color.h"
#include "command2.h"
#include "curses2.h"
#include "debug.h"
#include "notify2.h"
#include "regex4.h"
+ Include dependency graph for regex.c:

Go to the source code of this file.

Functions

void regex_colors_init (void)
 Initialise the Regex colours. More...
 
void regex_colors_clear (void)
 Clear the Regex colours. More...
 
void regex_color_clear (struct RegexColor *rcol)
 Free the contents of a Regex colour. More...
 
void regex_color_free (struct RegexColorList *list, struct RegexColor **ptr)
 Free a Regex colour. More...
 
struct RegexColorregex_color_new (void)
 Create a new RegexColor. More...
 
void regex_color_list_clear (struct RegexColorList *rcl)
 Free the contents of a RegexColorList. More...
 
struct RegexColorList * regex_colors_get_list (enum ColorId cid)
 Return the RegexColorList for a colour id. More...
 
static enum CommandResult add_pattern (struct RegexColorList *rcl, const char *s, bool sensitive, uint32_t fg, uint32_t bg, int attrs, struct Buffer *err, bool is_index, int match)
 Associate a colour to a pattern. More...
 
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. More...
 
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. More...
 
bool regex_colors_parse_uncolor (enum ColorId cid, const char *pat, bool uncolor)
 Parse a Regex 'uncolor' command. More...
 

Variables

struct RegexColorList AttachList
 List of colours applied to the attachment headers. More...
 
struct RegexColorList BodyList
 List of colours applied to the email body. More...
 
struct RegexColorList HeaderList
 List of colours applied to the email headers. More...
 
struct RegexColorList IndexAuthorList
 List of colours applied to the author in the index. More...
 
struct RegexColorList IndexFlagsList
 List of colours applied to the flags in the index. More...
 
struct RegexColorList IndexList
 List of default colours applied to the index. More...
 
struct RegexColorList IndexSubjectList
 List of colours applied to the subject in the index. More...
 
struct RegexColorList IndexTagList
 List of colours applied to tags in the index. More...
 
struct RegexColorList StatusList
 List of colours applied to the status bar. More...
 

Detailed Description

Regex Colour.

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 regex.c.

Function Documentation

◆ regex_colors_init()

void regex_colors_init ( void  )

Initialise the Regex colours.

Definition at line 62 of file regex.c.

63{
64 color_debug(LL_DEBUG5, "init AttachList, BodyList, etc\n");
74}
struct RegexColorList IndexFlagsList
List of colours applied to the flags in the index.
Definition: regex.c:52
struct RegexColorList IndexAuthorList
List of colours applied to the author in the index.
Definition: regex.c:51
struct RegexColorList IndexSubjectList
List of colours applied to the subject in the index.
Definition: regex.c:54
struct RegexColorList StatusList
List of colours applied to the status bar.
Definition: regex.c:56
struct RegexColorList IndexList
List of default colours applied to the index.
Definition: regex.c:53
struct RegexColorList IndexTagList
List of colours applied to tags in the index.
Definition: regex.c:55
struct RegexColorList BodyList
List of colours applied to the email body.
Definition: regex.c:49
struct RegexColorList HeaderList
List of colours applied to the email headers.
Definition: regex.c:50
struct RegexColorList AttachList
List of colours applied to the attachment headers.
Definition: regex.c:48
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
#define STAILQ_INIT(head)
Definition: queue.h:372
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ regex_colors_clear()

void regex_colors_clear ( void  )

Clear the Regex colours.

Definition at line 79 of file regex.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ regex_color_clear()

void regex_color_clear ( struct RegexColor rcol)

Free the contents of a Regex colour.

Parameters
rcolRegexColor to empty
Note
The RegexColor object isn't freed

Definition at line 99 of file regex.c.

100{
101 if (!rcol)
102 return;
103
104 rcol->match = 0;
105 rcol->stop_matching = false;
106
108 FREE(&rcol->pattern);
109 regfree(&rcol->regex);
111}
void attr_color_clear(struct AttrColor *ac)
Free the contents of an AttrColor.
Definition: attr.c:44
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
#define FREE(x)
Definition: memory.h:43
regex_t regex
Compiled regex.
Definition: regex4.h:40
struct PatternList * color_pattern
Compiled pattern to speed up index color calculation.
Definition: regex4.h:42
struct AttrColor attr_color
Colour and attributes to apply.
Definition: regex4.h:38
char * pattern
Pattern to match.
Definition: regex4.h:39
bool stop_matching
Used by the pager for body patterns, to prevent the color from being retried once it fails.
Definition: regex4.h:44
int match
Substring to match, 0 for old behaviour.
Definition: regex4.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ regex_color_free()

void regex_color_free ( struct RegexColorList *  list,
struct RegexColor **  ptr 
)

Free a Regex colour.

Parameters
listRegexColorList holding the colour
ptrRegexColor to free

Definition at line 118 of file regex.c.

119{
120 if (!ptr || !*ptr)
121 return;
122
123 struct RegexColor *rcol = *ptr;
124 regex_color_clear(rcol);
125
126 FREE(ptr);
127}
void regex_color_clear(struct RegexColor *rcol)
Free the contents of a Regex colour.
Definition: regex.c:99
A regular expression and a color to highlight a line.
Definition: regex4.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ regex_color_new()

struct RegexColor * regex_color_new ( void  )

Create a new RegexColor.

Return values
ptrNew RegexColor

Definition at line 133 of file regex.c.

134{
135 struct RegexColor *rcol = mutt_mem_calloc(1, sizeof(*rcol));
136
137 return rcol;
138}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ regex_color_list_clear()

void regex_color_list_clear ( struct RegexColorList *  rcl)

Free the contents of a RegexColorList.

Parameters
rclList to clear

Free each of the RegexColorList in a list.

Note
The list object isn't freed, only emptied

Definition at line 148 of file regex.c.

149{
150 if (!rcl)
151 return;
152
153 struct RegexColor *np = NULL, *tmp = NULL;
154 STAILQ_FOREACH_SAFE(np, rcl, entries, tmp)
155 {
156 STAILQ_REMOVE(rcl, np, RegexColor, entries);
157 regex_color_free(rcl, &np);
158 }
159}
void regex_color_free(struct RegexColorList *list, struct RegexColor **ptr)
Free a Regex colour.
Definition: regex.c:118
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ regex_colors_get_list()

struct RegexColorList * regex_colors_get_list ( enum ColorId  cid)

Return the RegexColorList for a colour id.

Parameters
cidColour Id, e.g. MT_COLOR_BODY
Return values
ptrRegexColorList

Definition at line 166 of file regex.c.

167{
168 switch (cid)
169 {
171 return &AttachList;
172 case MT_COLOR_BODY:
173 return &BodyList;
174 case MT_COLOR_HEADER:
175 return &HeaderList;
176 case MT_COLOR_INDEX:
177 return &IndexList;
179 return &IndexAuthorList;
181 return &IndexFlagsList;
183 return &IndexSubjectList;
185 return &IndexTagList;
186 case MT_COLOR_STATUS:
187 return &StatusList;
188 default:
189 return NULL;
190 }
191}
@ MT_COLOR_INDEX_AUTHOR
Index: author field (takes a pattern)
Definition: color.h:78
@ MT_COLOR_HEADER
Message headers (takes a pattern)
Definition: color.h:48
@ MT_COLOR_STATUS
Status bar (takes a pattern)
Definition: color.h:71
@ MT_COLOR_INDEX_SUBJECT
Index: subject field (takes a pattern)
Definition: color.h:80
@ MT_COLOR_BODY
Pager: highlight body of message (takes a pattern)
Definition: color.h:39
@ MT_COLOR_INDEX_TAG
Index: tag field (g, takes a pattern)
Definition: color.h:81
@ MT_COLOR_ATTACH_HEADERS
MIME attachment test (takes a pattern)
Definition: color.h:38
@ MT_COLOR_INDEX
Index: default colour (takes a pattern)
Definition: color.h:77
@ MT_COLOR_INDEX_FLAGS
Index: flags field (takes a pattern)
Definition: color.h:79
+ Here is the caller graph for this function:

◆ add_pattern()

static enum CommandResult add_pattern ( struct RegexColorList *  rcl,
const char *  s,
bool  sensitive,
uint32_t  fg,
uint32_t  bg,
int  attrs,
struct Buffer err,
bool  is_index,
int  match 
)
static

Associate a colour to a pattern.

Parameters
rclList of existing colours
sString to match
sensitivetrue if the pattern case-sensitive
fgForeground colour
bgBackground colour
attrsAttributes, e.g. A_UNDERLINE
errBuffer for error messages
is_indextrue of this is for the index
matchNumber of regex subexpression to match (0 for entire pattern)
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

is_index used to store compiled pattern only for 'index' color object when called from mutt_parse_color()

Definition at line 209 of file regex.c.

212{
213 struct RegexColor *rcol = NULL;
214
215 STAILQ_FOREACH(rcol, rcl, entries)
216 {
217 if ((sensitive && mutt_str_equal(s, rcol->pattern)) ||
218 (!sensitive && mutt_istr_equal(s, rcol->pattern)))
219 {
220 break;
221 }
222 }
223
224 if (rcol) // found a matching regex
225 {
226 struct AttrColor *ac = &rcol->attr_color;
227 struct CursesColor *cc = ac->curses_color;
228
229 // different colours
230 if (!cc || (cc && ((cc->fg != fg) || (cc->bg != bg))))
231 {
232 cc = curses_color_new(fg, bg);
233 if (cc)
234 {
236 cc->fg = fg;
237 cc->bg = bg;
238 }
239 ac->curses_color = cc;
240 }
241 ac->attrs = attrs;
242 }
243 else
244 {
245 rcol = regex_color_new();
246 if (is_index)
247 {
248 struct Buffer *buf = mutt_buffer_pool_get();
249 mutt_buffer_strcpy(buf, s);
250 const char *const c_simple_search = cs_subset_string(NeoMutt->sub, "simple_search");
251 mutt_check_simple(buf, NONULL(c_simple_search));
252 struct Mailbox *m_cur = get_current_mailbox();
253 struct Menu *menu = get_current_menu();
254 rcol->color_pattern = mutt_pattern_comp(m_cur, menu, buf->data, MUTT_PC_FULL_MSG, err);
256 if (!rcol->color_pattern)
257 {
258 regex_color_free(rcl, &rcol);
259 return MUTT_CMD_ERROR;
260 }
261 }
262 else
263 {
264 uint16_t flags = 0;
265 if (sensitive)
266 flags = mutt_mb_is_lower(s) ? REG_ICASE : 0;
267 else
268 flags = REG_ICASE;
269
270 const int r = REG_COMP(&rcol->regex, s, flags);
271 if (r != 0)
272 {
273 regerror(r, &rcol->regex, err->data, err->dsize);
274 regex_color_free(rcl, &rcol);
275 return MUTT_CMD_ERROR;
276 }
277 }
278 rcol->pattern = mutt_str_dup(s);
279 rcol->match = match;
280 struct CursesColor *cc = curses_color_new(fg, bg);
281 struct AttrColor *ac = &rcol->attr_color;
282 ac->curses_color = cc;
283 ac->attrs = attrs;
284 STAILQ_INSERT_TAIL(rcl, rcol, entries);
285 }
286
287 if (is_index)
288 {
289 /* force re-caching of index colors */
290 struct EventColor ev_c = { MT_COLOR_INDEX, NULL };
292 }
293
294 return MUTT_CMD_SUCCESS;
295}
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:310
struct Notify * ColorsNotify
Notifications: ColorId, EventColor.
Definition: notify.c:34
struct RegexColor * regex_color_new(void)
Create a new RegexColor.
Definition: regex.c:133
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:37
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:35
struct PatternList * mutt_pattern_comp(struct Mailbox *m, struct Menu *menu, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:1160
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
struct CursesColor * curses_color_new(int fg, int bg)
Create a new CursesColor.
Definition: curses.c:148
struct Mailbox * get_current_mailbox(void)
Get the current Mailbox.
Definition: index.c:624
struct Menu * get_current_menu(void)
Get the current Menu.
Definition: index.c:650
bool mutt_mb_is_lower(const char *s)
Does a multi-byte string contain only lowercase characters?
Definition: mbyte.c:355
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:796
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:784
@ NT_COLOR_SET
Color has been set.
Definition: notify2.h:41
@ NT_COLOR
Colour has changed, NotifyColor, EventColor.
Definition: notify_type.h:41
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: lib.h:62
void mutt_check_simple(struct Buffer *s, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:116
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:389
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:53
#define NONULL(x)
Definition: string2.h:37
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
size_t dsize
Length of data.
Definition: buffer.h:37
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
A mailbox.
Definition: mailbox.h:79
Definition: lib.h:69
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ regex_colors_parse_color_list()

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.

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

Parse a Regex 'color' command, e.g. "color index green default pattern"

Definition at line 310 of file regex.c.

313{
314 if (cid == MT_COLOR_STATUS)
315 return false;
316
317 struct RegexColorList *rcl = regex_colors_get_list(cid);
318 if (!rcl)
319 return false;
320
321 bool sensitive = false;
322 bool is_index = false;
323 switch (cid)
324 {
326 case MT_COLOR_BODY:
327 sensitive = true;
328 is_index = false;
329 break;
330 case MT_COLOR_HEADER:
331 sensitive = false;
332 is_index = false;
333 break;
334 case MT_COLOR_INDEX:
339 sensitive = true;
340 is_index = true;
341 break;
342 default:
343 return false;
344 }
345
346 *rc = add_pattern(rcl, pat, sensitive, fg, bg, attrs, err, is_index, 0);
347
348 struct Buffer *buf = mutt_buffer_pool_get();
349 get_colorid_name(cid, buf);
350 color_debug(LL_DEBUG5, "NT_COLOR_SET: %s\n", buf->data);
352
353 if (!is_index) // else it will be logged in add_pattern()
354 {
355 struct EventColor ev_c = { cid, NULL };
357 }
358
360 return true;
361}
void get_colorid_name(unsigned int cid, struct Buffer *buf)
Get the name of a color id.
Definition: command.c:329
struct RegexColorList * regex_colors_get_list(enum ColorId cid)
Return the RegexColorList for a colour id.
Definition: regex.c:166
static enum CommandResult add_pattern(struct RegexColorList *rcl, const char *s, bool sensitive, uint32_t fg, uint32_t bg, int attrs, struct Buffer *err, bool is_index, int match)
Associate a colour to a pattern.
Definition: regex.c:209
void regex_colors_dump_all(void)
Dump all the Regex colours to the log.
Definition: debug.c:380
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:

◆ regex_colors_parse_status_list()

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.

Parameters
cidColour ID, should be MT_COLOR_QUOTED
patRegex pattern
fgForeground colour
bgBackground colour
attrsAttributes, e.g. A_UNDERLINE
matchUse the nth regex submatch
errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Definition at line 374 of file regex.c.

376{
377 if (cid != MT_COLOR_STATUS)
378 return MUTT_CMD_ERROR;
379
380 int rc = add_pattern(&StatusList, pat, true, fg, bg, attrs, err, false, match);
381 if (rc != MUTT_CMD_SUCCESS)
382 return rc;
383
384 struct Buffer *buf = mutt_buffer_pool_get();
385 get_colorid_name(cid, buf);
386 color_debug(LL_DEBUG5, "NT_COLOR_SET: %s\n", buf->data);
388
389 struct EventColor ev_c = { cid, NULL };
391
393 return rc;
394}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ regex_colors_parse_uncolor()

bool regex_colors_parse_uncolor ( enum ColorId  cid,
const char *  pat,
bool  uncolor 
)

Parse a Regex 'uncolor' command.

Parameters
cidColour Id, e.g. MT_COLOR_STATUS
patPattern to remove (NULL to remove all)
uncolortrue if 'uncolor', false if 'unmono'
Return values
trueIf colours were unset

Definition at line 403 of file regex.c.

404{
405 struct RegexColorList *cl = regex_colors_get_list(cid);
406 if (!cl)
407 return false;
408
409 if (!pat) // Reset all patterns
410 {
411 if (STAILQ_EMPTY(cl))
412 return true;
413
414 mutt_debug(LL_NOTIFY, "NT_COLOR_RESET: [ALL]\n");
415 struct EventColor ev_c = { cid, NULL };
417
419 return true;
420 }
421
422 bool rc = false;
423 struct RegexColor *np = NULL, *prev = NULL;
424 prev = NULL;
425 STAILQ_FOREACH(np, cl, entries)
426 {
427 if (mutt_str_equal(pat, np->pattern))
428 {
429 rc = true;
430
431 mutt_debug(LL_DEBUG1, "Freeing pattern \"%s\" from XXX\n", pat);
432 if (prev)
433 STAILQ_REMOVE_AFTER(cl, prev, entries);
434 else
435 STAILQ_REMOVE_HEAD(cl, entries);
436
437 mutt_debug(LL_NOTIFY, "NT_COLOR_RESET: XXX\n");
438 struct EventColor ev_c = { cid, &np->attr_color };
440
441 regex_color_free(cl, &np);
442 break;
443 }
444 prev = np;
445 }
446
447 return rc;
448}
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
@ LL_NOTIFY
Log of notifications.
Definition: logging.h:45
@ NT_COLOR_RESET
Color has been reset/removed.
Definition: notify2.h:42
#define STAILQ_REMOVE_HEAD(head, field)
Definition: queue.h:422
#define STAILQ_REMOVE_AFTER(head, elm, field)
Definition: queue.h:416
#define STAILQ_EMPTY(head)
Definition: queue.h:348
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ AttachList

struct RegexColorList AttachList

List of colours applied to the attachment headers.

Definition at line 48 of file regex.c.

◆ BodyList

struct RegexColorList BodyList

List of colours applied to the email body.

Definition at line 49 of file regex.c.

◆ HeaderList

struct RegexColorList HeaderList

List of colours applied to the email headers.

Definition at line 50 of file regex.c.

◆ IndexAuthorList

struct RegexColorList IndexAuthorList

List of colours applied to the author in the index.

Definition at line 51 of file regex.c.

◆ IndexFlagsList

struct RegexColorList IndexFlagsList

List of colours applied to the flags in the index.

Definition at line 52 of file regex.c.

◆ IndexList

struct RegexColorList IndexList

List of default colours applied to the index.

Definition at line 53 of file regex.c.

◆ IndexSubjectList

struct RegexColorList IndexSubjectList

List of colours applied to the subject in the index.

Definition at line 54 of file regex.c.

◆ IndexTagList

struct RegexColorList IndexTagList

List of colours applied to tags in the index.

Definition at line 55 of file regex.c.

◆ StatusList

struct RegexColorList StatusList

List of colours applied to the status bar.

Definition at line 56 of file regex.c.