• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

neomutt / neomutt / 13362243721

16 Feb 2025 04:04PM UTC coverage: 49.522% (+0.06%) from 49.467%
13362243721

push

github

flatcap
main: drop -B (batch mode) option

Drop the -B (batch mode) command line option.
It didn't do anything.

8915 of 18002 relevant lines covered (49.52%)

245.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pattern/dlg_pattern.c
1
/**
2
 * @file
3
 * Pattern Selection Dialog
4
 *
5
 * @authors
6
 * Copyright (C) 2019 Pietro Cerutti <gahr@gahr.ch>
7
 * Copyright (C) 2020-2024 Richard Russon <rich@flatcap.org>
8
 * Copyright (C) 2023-2024 Tóth János <gomba007@gmail.com>
9
 *
10
 * @copyright
11
 * This program is free software: you can redistribute it and/or modify it under
12
 * the terms of the GNU General Public License as published by the Free Software
13
 * Foundation, either version 2 of the License, or (at your option) any later
14
 * version.
15
 *
16
 * This program is distributed in the hope that it will be useful, but WITHOUT
17
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
19
 * details.
20
 *
21
 * You should have received a copy of the GNU General Public License along with
22
 * this program.  If not, see <http://www.gnu.org/licenses/>.
23
 */
24

25
/**
26
 * @page pattern_dlg_pattern Pattern Selection Dialog
27
 *
28
 * The Pattern Selection Dialog lets the user select a pattern.
29
 *
30
 * This is a @ref gui_simple
31
 *
32
 * ## Windows
33
 *
34
 * | Name                     | Type           | See Also      |
35
 * | :----------------------- | :------------- | :------------ |
36
 * | Pattern Selection Dialog | WT_DLG_PATTERN | dlg_pattern() |
37
 *
38
 * **Parent**
39
 * - @ref gui_dialog
40
 *
41
 * **Children**
42
 * - See: @ref gui_simple
43
 *
44
 * ## Data
45
 * - #Menu
46
 * - #Menu::mdata
47
 * - #PatternEntry
48
 *
49
 * The @ref gui_simple holds a Menu.  The Pattern Selection Dialog stores its
50
 * data (#PatternEntry) in Menu::mdata.
51
 *
52
 * ## Events
53
 *
54
 * Once constructed, it is controlled by the following events:
55
 *
56
 * | Event Type  | Handler                   |
57
 * | :---------- | :------------------------ |
58
 * | #NT_CONFIG  | pattern_config_observer() |
59
 * | #NT_WINDOW  | pattern_window_observer() |
60
 *
61
 * The Pattern Selection Dialog doesn't have any specific colours, so it
62
 * doesn't need to support #NT_COLOR.
63
 *
64
 * The Pattern Selection Dialog does not implement MuttWindow::recalc() or
65
 * MuttWindow::repaint().
66
 *
67
 * Some other events are handled by the @ref gui_simple.
68
 */
69

70
#include "config.h"
71
#include <stdbool.h>
72
#include <stddef.h>
73
#include "private.h"
74
#include "mutt/lib.h"
75
#include "config/lib.h"
76
#include "core/lib.h"
77
#include "gui/lib.h"
78
#include "lib.h"
79
#include "expando/lib.h"
80
#include "key/lib.h"
81
#include "menu/lib.h"
82
#include "expando.h"
83
#include "functions.h"
84
#include "mutt_logging.h"
85
#include "pattern_data.h"
86

87
/// Help Bar for the Pattern selection dialog
88
static const struct Mapping PatternHelp[] = {
89
  // clang-format off
90
  { N_("Exit"),   OP_EXIT },
91
  { N_("Select"), OP_GENERIC_SELECT_ENTRY },
92
  { N_("Help"),   OP_HELP },
93
  { NULL, 0 },
94
  // clang-format on
95
};
96

97
/**
98
 * pattern_make_entry - Create a Pattern for the Menu - Implements Menu::make_entry() - @ingroup menu_make_entry
99
 *
100
 * @sa $pattern_format
101
 */
102
static int pattern_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
×
103
{
104
  struct PatternData *pd = menu->mdata;
×
105

106
  struct PatternEntry *entry = ARRAY_GET(&pd->entries, line);
×
107

108
  const bool c_arrow_cursor = cs_subset_bool(menu->sub, "arrow_cursor");
×
109
  if (c_arrow_cursor)
×
110
  {
111
    const char *const c_arrow_string = cs_subset_string(menu->sub, "arrow_string");
×
112
    if (max_cols > 0)
×
113
      max_cols -= (mutt_strwidth(c_arrow_string) + 1);
×
114
  }
115

116
  const struct Expando *c_pattern_format = cs_subset_expando(NeoMutt->sub, "pattern_format");
×
117
  return expando_filter(c_pattern_format, PatternRenderCallbacks, entry,
×
118
                        MUTT_FORMAT_ARROWCURSOR, max_cols, NeoMutt->env, buf);
×
119
}
120

121
/**
122
 * create_pattern_entries - Create the Pattern Entries
123
 * @param pea Pattern Entry Array to fill
124
 */
125
static void create_pattern_entries(struct PatternEntryArray *pea)
×
126
{
127
  int num_entries = 0;
128
  while (Flags[num_entries].tag != 0)
×
129
    num_entries++;
×
130

131
  /* Add three more hard-coded entries */
132
  ARRAY_RESERVE(pea, num_entries + 3);
×
133

134
  struct Buffer *buf = buf_pool_get();
×
135

136
  struct PatternEntry entry = { 0 };
137
  for (int i = 0; Flags[i].tag != '\0'; i++)
×
138
  {
139
    entry.num = i + 1;
×
140

141
    buf_printf(buf, "~%c", Flags[i].tag);
×
142
    entry.tag = buf_strdup(buf);
×
143

144
    switch (Flags[i].eat_arg)
×
145
    {
146
      case EAT_REGEX:
×
147
        /* L10N:
148
           Pattern Completion Menu argument type: a regular expression
149
        */
150
        buf_add_printf(buf, " %s", _("EXPR"));
×
151
        break;
×
152
      case EAT_RANGE:
×
153
      case EAT_MESSAGE_RANGE:
154
        /* L10N:
155
           Pattern Completion Menu argument type: a numeric range.
156
           Used by ~m, ~n, ~X, ~z.
157
        */
158
        buf_add_printf(buf, " %s", _("RANGE"));
×
159
        break;
×
160
      case EAT_DATE:
×
161
        /* L10N:
162
           Pattern Completion Menu argument type: a date range
163
           Used by ~d, ~r.
164
        */
165
        buf_add_printf(buf, " %s", _("DATERANGE"));
×
166
        break;
×
167
      case EAT_QUERY:
×
168
        /* L10N:
169
           Pattern Completion Menu argument type: a query
170
           Used by ~I.
171
        */
172
        buf_add_printf(buf, " %s", _("QUERY"));
×
173
        break;
×
174
      default:
175
        break;
176
    }
177

178
    entry.expr = buf_strdup(buf);
×
179
    entry.desc = mutt_str_dup(_(Flags[i].desc));
×
180

181
    ARRAY_ADD(pea, entry);
×
182
  }
183

184
  /* Add struct MuttThread patterns manually.
185
   * Note we allocated 3 extra slots for these above. */
186

187
  /* L10N:
188
     Pattern Completion Menu argument type: a nested pattern.
189
     Used by ~(), ~<(), ~>().
190
  */
191
  const char *patternstr = _("PATTERN");
×
192

193
  entry.num = ARRAY_SIZE(pea) + 1;
×
194
  entry.tag = mutt_str_dup("~()");
×
195
  buf_printf(buf, "~(%s)", patternstr);
×
196
  entry.expr = buf_strdup(buf);
×
197
  // L10N: Pattern Completion Menu description for ~()
198
  entry.desc = mutt_str_dup(_("messages in threads containing messages matching PATTERN"));
×
199
  ARRAY_ADD(pea, entry);
×
200

201
  entry.num = ARRAY_SIZE(pea) + 1;
×
202
  entry.tag = mutt_str_dup("~<()");
×
203
  buf_printf(buf, "~<(%s)", patternstr);
×
204
  entry.expr = buf_strdup(buf);
×
205
  // L10N: Pattern Completion Menu description for ~<()
206
  entry.desc = mutt_str_dup(_("messages whose immediate parent matches PATTERN"));
×
207
  ARRAY_ADD(pea, entry);
×
208

209
  entry.num = ARRAY_SIZE(pea) + 1;
×
210
  entry.tag = mutt_str_dup("~>()");
×
211
  buf_printf(buf, "~>(%s)", patternstr);
×
212
  entry.expr = buf_strdup(buf);
×
213
  // L10N: Pattern Completion Menu description for ~>()
214
  entry.desc = mutt_str_dup(_("messages having an immediate child matching PATTERN"));
×
215
  ARRAY_ADD(pea, entry);
×
216

217
  buf_pool_release(&buf);
×
218
}
×
219

220
/**
221
 * pattern_config_observer - Notification that a Config Variable has changed - Implements ::observer_t - @ingroup observer_api
222
 *
223
 * The Address Book Window is affected by changes to `$sort_pattern`.
224
 */
225
static int pattern_config_observer(struct NotifyCallback *nc)
×
226
{
227
  if (nc->event_type != NT_CONFIG)
×
228
    return 0;
229
  if (!nc->global_data || !nc->event_data)
×
230
    return -1;
231

232
  struct EventConfig *ev_c = nc->event_data;
233

234
  if (!mutt_str_equal(ev_c->name, "pattern_format"))
×
235
    return 0;
236

237
  struct Menu *menu = nc->global_data;
×
238
  menu_queue_redraw(menu, MENU_REDRAW_FULL);
×
239
  mutt_debug(LL_DEBUG5, "config done, request WA_RECALC, MENU_REDRAW_FULL\n");
×
240

241
  return 0;
×
242
}
243

244
/**
245
 * pattern_window_observer - Notification that a Window has changed - Implements ::observer_t - @ingroup observer_api
246
 *
247
 * This function is triggered by changes to the windows.
248
 *
249
 * - Delete (this window): clean up the resources held by the Help Bar
250
 */
251
static int pattern_window_observer(struct NotifyCallback *nc)
×
252
{
253
  if (nc->event_type != NT_WINDOW)
×
254
    return 0;
255
  if (!nc->global_data || !nc->event_data)
×
256
    return -1;
257
  if (nc->event_subtype != NT_WINDOW_DELETE)
×
258
    return 0;
259

260
  struct MuttWindow *win_menu = nc->global_data;
261
  struct EventWindow *ev_w = nc->event_data;
262
  if (ev_w->win != win_menu)
×
263
    return 0;
264

265
  struct Menu *menu = win_menu->wdata;
×
266

267
  notify_observer_remove(NeoMutt->sub->notify, pattern_config_observer, menu);
×
268
  notify_observer_remove(win_menu->notify, pattern_window_observer, win_menu);
×
269

270
  mutt_debug(LL_DEBUG5, "window delete done\n");
×
271
  return 0;
×
272
}
273

274
/**
275
 * dlg_pattern - Show menu to select a Pattern - @ingroup gui_dlg
276
 * @param buf Buffer for the selected Pattern
277
 * @retval true A selection was made
278
 *
279
 * The Select Pattern Dialog shows the user a help page of Patterns.
280
 * They can select one to auto-complete some functions, e.g. `<limit>`
281
 */
282
bool dlg_pattern(struct Buffer *buf)
×
283
{
284
  struct PatternData *pd = pattern_data_new();
×
285

286
  struct SimpleDialogWindows sdw = simple_dialog_new(MENU_GENERIC, WT_DLG_PATTERN, PatternHelp);
×
287
  create_pattern_entries(&pd->entries);
×
288

289
  struct Menu *menu = sdw.menu;
×
290
  pd->menu = menu;
×
291
  pd->buf = buf;
×
292

293
  menu->mdata = pd;
×
294
  menu->mdata_free = pattern_data_free;
×
295
  menu->make_entry = pattern_make_entry;
×
296
  menu->max = ARRAY_SIZE(&pd->entries);
×
297

298
  // L10N: Pattern completion menu title
299
  sbar_set_title(sdw.sbar, _("Patterns"));
×
300

301
  // NT_COLOR is handled by the SimpleDialog
302
  notify_observer_add(NeoMutt->sub->notify, NT_CONFIG, pattern_config_observer, menu);
×
303
  notify_observer_add(menu->win->notify, NT_WINDOW, pattern_window_observer, menu->win);
×
304

305
  struct MuttWindow *old_focus = window_set_focus(menu->win);
×
306
  // ---------------------------------------------------------------------------
307
  // Event Loop
308
  int op = OP_NULL;
309
  do
310
  {
311
    menu_tagging_dispatcher(menu->win, op);
×
312
    window_redraw(NULL);
×
313

314
    op = km_dokey(MENU_DIALOG, GETCH_NO_FLAGS);
×
315
    mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
×
316
    if (op < 0)
×
317
      continue;
×
318
    if (op == OP_NULL)
×
319
    {
320
      km_error_key(MENU_GENERIC);
×
321
      continue;
×
322
    }
323
    mutt_clear_error();
×
324

325
    int rc = pattern_function_dispatcher(sdw.dlg, op);
×
326
    if (rc == FR_UNKNOWN)
×
327
      rc = menu_function_dispatcher(menu->win, op);
×
328
    if (rc == FR_UNKNOWN)
×
329
      rc = global_function_dispatcher(NULL, op);
×
330
  } while (!pd->done);
×
331
  // ---------------------------------------------------------------------------
332

333
  bool rc = pd->selection;
×
334

335
  window_set_focus(old_focus);
×
336
  simple_dialog_free(&sdw.dlg);
×
337

338
  return rc;
×
339
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc