NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
dlgpattern.c
Go to the documentation of this file.
1 
71 #include "config.h"
72 #include <stddef.h>
73 #include <stdbool.h>
74 #include <stdint.h>
75 #include <stdio.h>
76 #include "private.h"
77 #include "mutt/lib.h"
78 #include "config/lib.h"
79 #include "core/lib.h"
80 #include "gui/lib.h"
81 #include "lib.h"
82 #include "menu/lib.h"
83 #include "format_flags.h"
84 #include "muttlib.h"
85 #include "opcodes.h"
86 
91 {
92  int num;
93  const char *tag;
94  const char *expr;
95  const char *desc;
96 };
97 
99 static const struct Mapping PatternHelp[] = {
100  // clang-format off
101  { N_("Exit"), OP_EXIT },
102  { N_("Select"), OP_GENERIC_SELECT_ENTRY },
103  { N_("Help"), OP_HELP },
104  { NULL, 0 },
105  // clang-format on
106 };
107 
117 static const char *pattern_format_str(char *buf, size_t buflen, size_t col, int cols,
118  char op, const char *src, const char *prec,
119  const char *if_str, const char *else_str,
120  intptr_t data, MuttFormatFlags flags)
121 {
122  struct PatternEntry *entry = (struct PatternEntry *) data;
123 
124  switch (op)
125  {
126  case 'd':
127  mutt_format_s(buf, buflen, prec, NONULL(entry->desc));
128  break;
129  case 'e':
130  mutt_format_s(buf, buflen, prec, NONULL(entry->expr));
131  break;
132  case 'n':
133  {
134  char tmp[32];
135  snprintf(tmp, sizeof(tmp), "%%%sd", prec);
136  snprintf(buf, buflen, tmp, entry->num);
137  break;
138  }
139  }
140 
141  return src;
142 }
143 
147 static void make_pattern_entry(struct Menu *menu, char *buf, size_t buflen, int num)
148 {
149  struct PatternEntry *entry = &((struct PatternEntry *) menu->mdata)[num];
150 
151  const char *const c_pattern_format =
152  cs_subset_string(NeoMutt->sub, "pattern_format");
153  mutt_expando_format(buf, buflen, 0, menu->win->state.cols, NONULL(c_pattern_format),
154  pattern_format_str, (intptr_t) entry, MUTT_FORMAT_ARROWCURSOR);
155 }
156 
160 static void free_pattern_menu(struct Menu *menu, void **ptr)
161 {
162  struct PatternEntry *entries = *ptr;
163 
164  for (size_t i = 0; i < menu->max; i++)
165  {
166  FREE(&entries[i].tag);
167  FREE(&entries[i].expr);
168  FREE(&entries[i].desc);
169  }
170 
171  FREE(ptr);
172 }
173 
179 static struct Menu *create_pattern_menu(struct MuttWindow *dlg)
180 {
181  int num_entries = 0, i = 0;
182  struct Buffer *entrybuf = NULL;
183 
184  while (Flags[num_entries].tag)
185  num_entries++;
186  /* Add three more hard-coded entries */
187  num_entries += 3;
188  struct PatternEntry *entries =
189  mutt_mem_calloc(num_entries, sizeof(struct PatternEntry));
190 
191  struct Menu *menu = dlg->wdata;
193  menu->mdata = entries;
195  menu->max = num_entries;
196 
197  struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
198  // L10N: Pattern completion menu title
199  sbar_set_title(sbar, _("Patterns"));
200 
201  entrybuf = mutt_buffer_pool_get();
202  while (Flags[i].tag)
203  {
204  entries[i].num = i + 1;
205 
206  mutt_buffer_printf(entrybuf, "~%c", (char) Flags[i].tag);
207  entries[i].tag = mutt_str_dup(mutt_buffer_string(entrybuf));
208 
209  switch (Flags[i].eat_arg)
210  {
211  case EAT_REGEX:
212  /* L10N:
213  Pattern Completion Menu argument type: a regular expression
214  */
215  mutt_buffer_add_printf(entrybuf, " %s", _("EXPR"));
216  break;
217  case EAT_RANGE:
218  case EAT_MESSAGE_RANGE:
219  /* L10N:
220  Pattern Completion Menu argument type: a numeric range.
221  Used by ~m, ~n, ~X, ~z.
222  */
223  mutt_buffer_add_printf(entrybuf, " %s", _("RANGE"));
224  break;
225  case EAT_DATE:
226  /* L10N:
227  Pattern Completion Menu argument type: a date range
228  Used by ~d, ~r.
229  */
230  mutt_buffer_add_printf(entrybuf, " %s", _("DATERANGE"));
231  break;
232  case EAT_QUERY:
233  /* L10N:
234  Pattern Completion Menu argument type: a query
235  Used by ~I.
236  */
237  mutt_buffer_add_printf(entrybuf, " %s", _("QUERY"));
238  break;
239  default:
240  break;
241  }
242  entries[i].expr = mutt_str_dup(mutt_buffer_string(entrybuf));
243  entries[i].desc = mutt_str_dup(_(Flags[i].desc));
244 
245  i++;
246  }
247 
248  /* Add struct MuttThread patterns manually.
249  * Note we allocated 3 extra slots for these above. */
250 
251  /* L10N:
252  Pattern Completion Menu argument type: a nested pattern.
253  Used by ~(), ~<(), ~>().
254  */
255  const char *patternstr = _("PATTERN");
256 
257  entries[i].num = i + 1;
258  entries[i].tag = mutt_str_dup("~()");
259  mutt_buffer_printf(entrybuf, "~(%s)", patternstr);
260  entries[i].expr = mutt_str_dup(mutt_buffer_string(entrybuf));
261  // L10N: Pattern Completion Menu description for ~()
262  entries[i].desc = mutt_str_dup(
263  _("messages in threads containing messages matching PATTERN"));
264  i++;
265 
266  entries[i].num = i + 1;
267  entries[i].tag = mutt_str_dup("~<()");
268  mutt_buffer_printf(entrybuf, "~<(%s)", patternstr);
269  entries[i].expr = mutt_str_dup(mutt_buffer_string(entrybuf));
270  // L10N: Pattern Completion Menu description for ~<()
271  entries[i].desc =
272  mutt_str_dup(_("messages whose immediate parent matches PATTERN"));
273  i++;
274 
275  entries[i].num = i + 1;
276  entries[i].tag = mutt_str_dup("~>()");
277  mutt_buffer_printf(entrybuf, "~>(%s)", patternstr);
278  entries[i].expr = mutt_str_dup(mutt_buffer_string(entrybuf));
279  // L10N: Pattern Completion Menu description for ~>()
280  entries[i].desc =
281  mutt_str_dup(_("messages having an immediate child matching PATTERN"));
282 
283  mutt_buffer_pool_release(&entrybuf);
284 
285  return menu;
286 }
287 
294 {
295  if ((nc->event_type != NT_CONFIG) || !nc->global_data || !nc->event_data)
296  return -1;
297 
298  struct EventConfig *ev_c = nc->event_data;
299 
300  if (!mutt_str_equal(ev_c->name, "pattern_format"))
301  return 0;
302 
303  struct Menu *menu = nc->global_data;
305  mutt_debug(LL_DEBUG5, "config done, request WA_RECALC, MENU_REDRAW_FULL\n");
306 
307  return 0;
308 }
309 
318 {
319  if ((nc->event_type != NT_WINDOW) || !nc->global_data || !nc->event_data)
320  return -1;
321 
322  if (nc->event_subtype != NT_WINDOW_DELETE)
323  return 0;
324 
325  struct MuttWindow *win_menu = nc->global_data;
326  struct EventWindow *ev_w = nc->event_data;
327  if (ev_w->win != win_menu)
328  return 0;
329 
330  struct Menu *menu = win_menu->wdata;
331 
334 
335  mutt_debug(LL_DEBUG5, "window delete done\n");
336  return 0;
337 }
338 
345 bool dlg_select_pattern(char *buf, size_t buflen)
346 {
347  struct MuttWindow *dlg = simple_dialog_new(MENU_GENERIC, WT_DLG_PATTERN, PatternHelp);
348  struct Menu *menu = create_pattern_menu(dlg);
349 
350  struct MuttWindow *win_menu = menu->win;
351 
352  // NT_COLOR is handled by the SimpleDialog
355 
356  bool rc = false;
357  bool done = false;
358  while (!done)
359  {
360  switch (menu_loop(menu))
361  {
362  case OP_GENERIC_SELECT_ENTRY:
363  {
364  const int index = menu_get_index(menu);
365  struct PatternEntry *entry = ((struct PatternEntry *) menu->mdata) + index;
366  mutt_str_copy(buf, entry->tag, buflen);
367  rc = true;
368  done = true;
369  break;
370  }
371 
372  case OP_EXIT:
373  done = true;
374  break;
375  }
376  }
377 
378  simple_dialog_free(&dlg);
379  return rc;
380 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
Convenience wrapper for the gui headers.
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:550
static void free_pattern_menu(struct Menu *menu, void **ptr)
Free the Pattern Completion menu - Implements Menu::mdata_free() -.
Definition: dlgpattern.c:160
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string -.
Definition: muttlib.c:780
uint8_t MuttFormatFlags
Flags for mutt_expando_format(), e.g. MUTT_FORMAT_FORCESUBJ.
Definition: format_flags.h:29
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:165
Process a number (range)
Definition: private.h:41
Definition: lib.h:67
Data passed to a notification function.
Definition: observer.h:39
struct MuttWindow * win
Window that changed.
Definition: mutt_window.h:217
An Event that happened to a Window.
Definition: mutt_window.h:215
Generic selection list.
Definition: type.h:45
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
A config-change event.
Definition: subset.h:69
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
Window is about to be deleted.
Definition: mutt_window.h:206
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Process a regex.
Definition: private.h:39
Flags to control mutt_expando_format()
All user-callable functions.
Container for Accounts, Notifications.
Definition: neomutt.h:36
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:53
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
Convenience wrapper for the config headers.
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:105
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
int event_subtype
Send: Event subtype, e.g. NT_ACCOUNT_ADD.
Definition: observer.h:43
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
Some miscellaneous functions.
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
const struct PatternFlags Flags[]
Lookup table for all patterns.
Definition: flags.c:41
Convenience wrapper for the core headers.
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:189
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
static const char * pattern_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the pattern completion menu - Implements format_t -Expando Description %d Patter...
Definition: dlgpattern.c:117
bool dlg_select_pattern(char *buf, size_t buflen)
Show menu to select a Pattern.
Definition: dlgpattern.c:345
Process a message number (range)
Definition: private.h:42
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
void * mdata
Private data.
Definition: lib.h:155
const char * expr
Displayed in the menu.
Definition: dlgpattern.c:94
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:221
const char * tag
Copied to buffer if selected.
Definition: dlgpattern.c:93
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void * event_data
Data from notify_send()
Definition: observer.h:44
int max
Number of entries in the menu.
Definition: lib.h:71
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:42
static int pattern_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t.
Definition: dlgpattern.c:293
void(* mdata_free)(struct Menu *menu, void **ptr)
Definition: lib.h:170
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:867
Shared constants/structs that are private to libpattern.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
Pattern Dialog, create_pattern_menu()
Definition: mutt_window.h:87
static void make_pattern_entry(struct Menu *menu, char *buf, size_t buflen, int num)
Create a line for the Pattern Completion menu - Implements Menu::make_entry() -.
Definition: dlgpattern.c:147
int num
Index number.
Definition: dlgpattern.c:92
#define FREE(x)
Definition: memory.h:40
Mapping between user-readable string and a constant.
Definition: mapping.h:31
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:228
struct MuttWindow * simple_dialog_new(enum MenuType mtype, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition: simple.c:128
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
const char * desc
Description of pattern.
Definition: dlgpattern.c:95
Log at debug level 5.
Definition: logging.h:44
Convenience wrapper for the library headers.
Process a date (range)
Definition: private.h:40
void * wdata
Private data.
Definition: mutt_window.h:145
#define N_(a)
Definition: message.h:32
const char * name
Name of config item that changed.
Definition: subset.h:72
A line in the Pattern Completion menu.
Definition: dlgpattern.c:90
Process a query string.
Definition: private.h:43
static int pattern_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t.
Definition: dlgpattern.c:317
static struct Menu * create_pattern_menu(struct MuttWindow *dlg)
Create the Pattern Completion menu.
Definition: dlgpattern.c:179