NeoMutt  2025-12-11-694-ga89709
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
GUI: Message Windows

The Message Window is a one-line interactive window at the bottom of the screen. More...

Functions

int mw_get_field (const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
 Ask the user for a string -.
 
int mw_change_flag (struct Mailbox *m, struct EmailArray *ea, bool bf)
 Change the flag on a Message -.
 
int mw_enter_fname (const char *prompt, struct Buffer *fname, bool mailbox, struct Mailbox *m, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
 Ask the user to select a file -.
 
void mw_what_key (void)
 Display the value of a key -.
 
int mw_multi_choice (const char *prompt, const char *letters)
 Offer the user a multiple choice question -.
 
static enum QuadOption mw_yesorno (const char *prompt, enum QuadOption def, struct ConfigDef *cdef, GetChFlags flags)
 Ask the user a Yes/No question offering help -.
 

Detailed Description

The Message Window is a one-line interactive window at the bottom of the screen.

It's used for asking the user questions, displaying messages and for a progress bar.

Behaviour

The Message Window has two modes of behaviour: passive, active.

Passive

Most of the time, the Message Window will be passively displaying messages to the user (or empty). This is characterised by the Window focus being somewhere else. In this mode, the Message Window is responsible for drawing itself.

See also
mutt_message(), mutt_error()

Active

The Message Window can be hijacked by other code to be used for user interaction, commonly for simple questions, "Are you sure? [Y/n]". In this active state the Window will have focus and it's the responsibility of the hijacker to perform the drawing.

See also
query_yesorno(), Progress Bar

Windows

Name Type Constructor
Message Window WT_MESSAGE msgwin_new()

Parent

Children

Data

The Message Window caches the formatted string.

Events

Once constructed, it is controlled by the following events:

Event Type Handler
NT_WINDOW msgwin_window_observer()
MuttWindow::recalc() msgwin_recalc()
MuttWindow::repaint() msgwin_repaint()

Function Documentation

◆ mw_get_field()

int mw_get_field ( const char * prompt,
struct Buffer * buf,
CompletionFlags complete,
enum HistoryClass hclass,
const struct CompleteOps * comp_api,
void * cdata )

Ask the user for a string -.

Parameters
[in]promptPrompt
[in]bufBuffer for the result
[in]hclassHistory class to use
[in]completeFlags, see CompletionFlags
[in]comp_apiAuto-completion API
[in]cdataAuto-completion private data
Return values
0Selection made
-1Aborted

This function uses the message window.

Ask the user to enter a free-form string. This function supports auto-completion and saves the result to the history.

It also supports readline style text editing. See OpEditor for a list of functions.

Definition at line 463 of file window.c.

465{
466 return mw_get_field_notify(prompt, buf, complete, hclass, comp_api, cdata,
467 NULL, NULL, NULL, NULL);
468}
int mw_get_field_notify(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata, get_field_callback_t callback, void *cb_data, const struct MenuDefinition *md, function_dispatcher_t fn_disp)
Ask the user for a string and call a notify function on keypress.
Definition window.c:265
+ Here is the call graph for this function:

◆ mw_change_flag()

int mw_change_flag ( struct Mailbox * m,
struct EmailArray * ea,
bool bf )

Change the flag on a Message -.

Parameters
mMailbox
eaArray of Emails to change
bftrue: set the flag; false: clear the flag
Return values
0Success
-1Failure

This function uses the message window.

Ask the user which flag they'd like to set/clear, e.g. Clear flag? (D/N/O/r/!):

Definition at line 451 of file flags.c.

452{
453 if (!m || !ea || ARRAY_EMPTY(ea))
454 return -1;
455
456 // blank window (0, 0)
457 struct MuttWindow *win = msgwin_new(true);
458 if (!win)
459 return -1;
460
461 char prompt[256] = { 0 };
462 snprintf(prompt, sizeof(prompt),
463 "%s? (D/N/O/r/*/!): ", bf ? _("Set flag") : _("Clear flag"));
464 msgwin_set_text(win, prompt, MT_COLOR_PROMPT);
465
467 struct MuttWindow *old_focus = window_set_focus(win);
468 window_redraw(win);
469
470 struct KeyEvent event = { 0, OP_NULL };
471 do
472 {
473 window_redraw(NULL);
474 event = mutt_getch(GETCH_NO_FLAGS);
475 } while ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT));
476
477 win = msgcont_pop_window();
478 window_set_focus(old_focus);
479 mutt_window_free(&win);
480
481 if (event.op == OP_ABORT)
482 return -1;
483
484 enum MessageType flag = MUTT_NONE;
485 switch (event.ch)
486 {
487 case 'd':
488 case 'D':
489 if (!bf)
491 flag = MUTT_DELETE;
492 break;
493
494 case 'N':
495 case 'n':
496 flag = MUTT_NEW;
497 break;
498
499 case 'o':
500 case 'O':
501 mutt_emails_set_flag(m, ea, MUTT_READ, !bf);
502 flag = MUTT_OLD;
503 break;
504
505 case 'r':
506 case 'R':
507 flag = MUTT_REPLIED;
508 break;
509
510 case '*':
511 flag = MUTT_TAG;
512 break;
513
514 case '!':
515 flag = MUTT_FLAG;
516 break;
517
518 default:
519 mutt_beep(false);
520 return -1;
521 }
522
523 mutt_emails_set_flag(m, ea, flag, bf);
524 return 0;
525}
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
@ MT_COLOR_PROMPT
Question/user input.
Definition color.h:56
void mutt_beep(bool force)
Irritate the user.
Definition curs_lib.c:68
void mutt_emails_set_flag(struct Mailbox *m, struct EmailArray *ea, enum MessageType flag, bool bf)
Set flag on messages.
Definition flags.c:358
struct KeyEvent mutt_getch(GetChFlags flags)
Read a character from the input buffer.
Definition get.c:201
#define GETCH_NO_FLAGS
No flags are set.
Definition get.h:34
void msgcont_push_window(struct MuttWindow *win)
Add a window to the Container Stack.
Definition msgcont.c:100
struct MuttWindow * msgcont_pop_window(void)
Remove the last Window from the Container Stack.
Definition msgcont.c:57
struct MuttWindow * msgwin_new(bool interactive)
Create the Message Window.
Definition msgwin.c:370
void msgwin_set_text(struct MuttWindow *win, const char *text, enum ColorId color)
Set the text for the Message Window.
Definition msgwin.c:483
#define _(a)
Definition message.h:28
MessageType
To set flags or match patterns.
Definition mutt.h:86
@ MUTT_READ
Messages that have been read.
Definition mutt.h:92
@ MUTT_OLD
Old messages.
Definition mutt.h:90
@ MUTT_PURGE
Messages to be purged (bypass trash)
Definition mutt.h:96
@ MUTT_NONE
No messages.
Definition mutt.h:88
@ MUTT_TAG
Tagged messages.
Definition mutt.h:99
@ MUTT_FLAG
Flagged messages.
Definition mutt.h:98
@ MUTT_DELETE
Messages to be deleted.
Definition mutt.h:94
@ MUTT_NEW
New messages.
Definition mutt.h:89
@ MUTT_REPLIED
Messages that have been replied to.
Definition mutt.h:91
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
struct MuttWindow * window_set_focus(struct MuttWindow *win)
Set the Window focus.
#define OP_TIMEOUT
1 second with no events
Definition opcodes.h:35
#define OP_REPAINT
Repaint is needed.
Definition opcodes.h:34
#define OP_ABORT
$abort_key pressed (Ctrl-G)
Definition opcodes.h:36
An event such as a keypress.
Definition get.h:50
int op
Function opcode, e.g. OP_HELP.
Definition get.h:52
int ch
Raw key pressed.
Definition get.h:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mw_enter_fname()

int mw_enter_fname ( const char * prompt,
struct Buffer * fname,
bool mailbox,
struct Mailbox * m,
bool multiple,
char *** files,
int * numfiles,
SelectFileFlags flags )

Ask the user to select a file -.

Parameters
[in]promptPrompt
[in]fnameBuffer for the result
[in]mailboxIf true, select mailboxes
[in]multipleAllow multiple selections
[in]mMailbox
[out]filesList of files selected
[out]numfilesNumber of files selected
[in]flagsFlags, see SelectFileFlags
Return values
0Success
-1Error

This function uses the message window.

Allow the user to enter a filename. If they hit '?' then the browser will be started. See: dlg_browser()

Definition at line 236 of file curs_lib.c.

239{
240 struct MuttWindow *win = msgwin_new(true);
241 if (!win)
242 return -1;
243
244 int rc = -1;
245
246 struct Buffer *text = buf_pool_get();
247 const struct AttrColor *ac_normal = simple_color_get(MT_COLOR_NORMAL);
248 const struct AttrColor *ac_prompt = merged_color_overlay(ac_normal,
250
251 msgwin_add_text(win, prompt, ac_prompt);
252 msgwin_add_text(win, _(" ('?' for list): "), ac_prompt);
253 if (!buf_is_empty(fname))
254 msgwin_add_text(win, buf_string(fname), ac_normal);
255
257 struct MuttWindow *old_focus = window_set_focus(win);
258
259 struct KeyEvent event = { 0, OP_NULL };
260 do
261 {
262 window_redraw(NULL);
263 event = mutt_getch(GETCH_NO_FLAGS);
264 } while ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT));
265
266 mutt_refresh();
267 win = msgcont_pop_window();
268 window_set_focus(old_focus);
269 mutt_window_free(&win);
270
271 if (event.ch < 0)
272 goto done;
273
274 if (event.ch == '?')
275 {
276 buf_reset(fname);
277
278 if (flags == MUTT_SEL_NO_FLAGS)
279 flags = MUTT_SEL_FOLDER;
280 if (multiple)
281 flags |= MUTT_SEL_MULTI;
282 if (mailbox)
283 flags |= MUTT_SEL_MAILBOX;
284 dlg_browser(fname, flags, m, files, numfiles);
285 }
286 else
287 {
288 char *pc = NULL;
289 mutt_str_asprintf(&pc, "%s: ", prompt);
290 if (event.op == OP_NULL)
291 mutt_unget_ch(event.ch);
292 else
293 mutt_unget_op(event.op);
294
295 buf_alloc(fname, 1024);
296 struct FileCompletionData cdata = { multiple, m, files, numfiles, NULL };
297 enum HistoryClass hclass = mailbox ? HC_MAILBOX : HC_FILE;
298 if (mw_get_field(pc, fname, MUTT_COMP_CLEAR, hclass, &CompleteMailboxOps, &cdata) != 0)
299 {
300 buf_reset(fname);
301 }
302 FREE(&pc);
303 }
304
305 rc = 0;
306
307done:
308 buf_pool_release(&text);
309 return rc;
310}
const struct CompleteOps CompleteMailboxOps
Auto-Completion of Files / Mailboxes.
Definition complete.c:159
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition lib.h:59
#define MUTT_SEL_FOLDER
Select a local directory.
Definition lib.h:61
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition lib.h:60
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition lib.h:58
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:291
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition buffer.c:337
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
Definition simple.c:95
@ MT_COLOR_NORMAL
Plain text.
Definition color.h:53
void mutt_refresh(void)
Force a refresh of the screen.
Definition curs_lib.c:78
#define MUTT_COMP_CLEAR
Clear input if printable character is pressed.
Definition wdata.h:43
void mutt_unget_op(int op)
Return an operation to the input buffer.
Definition get.c:133
void mutt_unget_ch(int ch)
Return a keystroke to the input buffer.
Definition get.c:122
void dlg_browser(struct Buffer *file, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
Let the user select a file -.
int mw_get_field(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
Ask the user for a string -.
Definition window.c:463
HistoryClass
Type to differentiate different histories.
Definition lib.h:54
@ HC_FILE
Files.
Definition lib.h:58
@ HC_MAILBOX
Mailboxes.
Definition lib.h:61
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
const struct AttrColor * merged_color_overlay(const struct AttrColor *base, const struct AttrColor *over)
Combine two colours.
Definition merged.c:107
void msgwin_add_text(struct MuttWindow *win, const char *text, const struct AttrColor *ac_color)
Add text to the Message Window.
Definition msgwin.c:418
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition string.c:808
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
A curses colour and its attributes.
Definition attr.h:65
String manipulation buffer.
Definition buffer.h:36
Input for the file completion function.
Definition curs_lib.h:39
char *** files
List of files selected.
Definition curs_lib.h:42
struct Mailbox * mailbox
Mailbox.
Definition curs_lib.h:41
bool multiple
Allow multiple selections.
Definition curs_lib.h:40
int * numfiles
Number of files selected.
Definition curs_lib.h:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mw_what_key()

void mw_what_key ( void )

Display the value of a key -.

This function uses the message window.

Displays the octal value back to the user. e.g. Char = h, Octal = 150, Decimal = 104

Press the $abort_key (default Ctrl-G) to exit.

Definition at line 503 of file curs_lib.c.

504{
505 struct MuttWindow *win = msgwin_new(true);
506 if (!win)
507 return;
508
509 struct Buffer *key = buf_pool_get();
510 struct Buffer *prompt = buf_pool_get();
511 struct Buffer *text = buf_pool_get();
512
514
515 buf_printf(prompt, _("Enter keys (%s to abort): "), buf_string(key));
517
519 struct MuttWindow *old_focus = window_set_focus(win);
520 window_redraw(win);
521
522 const struct AttrColor *ac_normal = simple_color_get(MT_COLOR_NORMAL);
523 const struct AttrColor *ac_prompt = simple_color_get(MT_COLOR_PROMPT);
524
525 // ---------------------------------------------------------------------------
526 // Event Loop
527 timeout(1000); // 1 second
528 while (true)
529 {
530 int ch = getch();
531 if (ch == AbortKey)
532 break;
533
534 if (ch == KEY_RESIZE)
535 {
536 timeout(0);
537 while ((ch = getch()) == KEY_RESIZE)
538 {
539 // do nothing
540 }
541 }
542
543 if (ch == ERR)
544 {
545 if (!isatty(STDIN_FILENO)) // terminal was lost
546 mutt_exit(1);
547
548 if (SigWinch)
549 {
550 SigWinch = false;
552 window_redraw(NULL);
553 }
554 else
555 {
557 }
558
559 continue;
560 }
561
563
564 buf_reset(key);
565 keymap_get_name(ch, key);
566
567 buf_printf(text, _("Char = %s, Octal = %o, Decimal = %d\n"), buf_string(key), ch, ch);
568
569 msgwin_add_text(win, buf_string(text), ac_normal);
570 msgwin_add_text(win, buf_string(prompt), ac_prompt);
571 msgwin_add_text(win, NULL, NULL);
572 window_redraw(NULL);
573 }
574 // ---------------------------------------------------------------------------
575
576 buf_pool_release(&key);
577 buf_pool_release(&prompt);
578 buf_pool_release(&text);
579
580 win = msgcont_pop_window();
581 window_set_focus(old_focus);
582 mutt_window_free(&win);
583}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition exit.c:41
keycode_t AbortKey
code of key to abort prompts, normally Ctrl-G
Definition init.c:47
void keymap_get_name(int c, struct Buffer *buf)
Get the human name for a key.
Definition keymap.c:185
void msgwin_clear_text(struct MuttWindow *win)
Clear the text in the Message Window.
Definition msgwin.c:518
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_TIMEOUT
Timeout has occurred.
Definition notify_type.h:56
@ NT_RESIZE
Window has been resized.
Definition notify_type.h:52
volatile sig_atomic_t SigWinch
true after SIGWINCH is received
Definition signal.c:69
Container for Accounts, Notifications.
Definition neomutt.h:41
struct Notify * notify_timeout
Timeout notifications handler.
Definition neomutt.h:47
struct Notify * notify_resize
Window resize notifications handler.
Definition neomutt.h:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mw_multi_choice()

int mw_multi_choice ( const char * prompt,
const char * letters )

Offer the user a multiple choice question -.

Parameters
promptMessage prompt
lettersAllowable selection keys
Return values
>=11-based user selection
-1Selection aborted

This function uses a message window.

Ask the user a multiple-choice question, using shortcut letters, e.g. PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, s/(m)ime or (c)lear?

Colours:

  • Question: color prompt
  • Shortcuts: color options

Definition at line 62 of file question.c.

63{
64 if (!prompt || !letters)
65 return -1;
66
67 struct MuttWindow *win = msgwin_new(true);
68 if (!win)
69 return -1;
70
71 int choice = 0;
72
73 const struct AttrColor *ac_normal = simple_color_get(MT_COLOR_NORMAL);
74 const struct AttrColor *ac_prompt = merged_color_overlay(ac_normal,
76
78 {
79 const struct AttrColor *ac_opts = merged_color_overlay(ac_prompt,
81 char *cur = NULL;
82
83 while ((cur = strchr(prompt, '(')))
84 {
85 // write the part between prompt and cur using MT_COLOR_PROMPT
86 msgwin_add_text_n(win, prompt, cur - prompt, ac_prompt);
87
88 if (mutt_isalnum(cur[1]) && (cur[2] == ')'))
89 {
90 // we have a single letter within parentheses - MT_COLOR_OPTIONS
91 msgwin_add_text_n(win, cur + 1, 1, ac_opts);
92 prompt = cur + 3;
93 }
94 else
95 {
96 // we have a parenthesis followed by something else
97 msgwin_add_text_n(win, cur, 1, ac_prompt);
98 prompt = cur + 1;
99 }
100 }
101 }
102
103 msgwin_add_text(win, prompt, ac_prompt);
104 msgwin_add_text(win, " ", ac_normal);
105
107 struct MuttWindow *old_focus = window_set_focus(win);
108 window_redraw(win);
109
110 // ---------------------------------------------------------------------------
111 // Event Loop
112 struct KeyEvent event = { 0, OP_NULL };
113 while (true)
114 {
115 event = mutt_getch(GETCH_NO_FLAGS);
116 mutt_debug(LL_DEBUG1, "mw_multi_choice: EVENT(%d,%d)\n", event.ch, event.op);
117
118 if (event.op == OP_REPAINT)
119 window_redraw(NULL);
120
121 if ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT))
122 continue;
123
124 if ((event.op == OP_ABORT) || key_is_return(event.ch))
125 {
126 choice = -1;
127 break;
128 }
129
130 char *p = (event.ch != 0) ? strchr(letters, event.ch) : NULL;
131 if (p)
132 {
133 choice = p - letters + 1;
134 break;
135 }
136
137 if ((event.ch > '0') && (event.ch <= '9'))
138 {
139 choice = event.ch - '0';
140 if (choice <= mutt_str_len(letters))
141 break;
142 }
143 }
144 // ---------------------------------------------------------------------------
145
146 win = msgcont_pop_window();
147 window_set_focus(old_focus);
148 mutt_window_free(&win);
149
150 return choice;
151}
bool simple_color_is_set(enum ColorId cid)
Is the object coloured?
Definition simple.c:116
@ MT_COLOR_OPTIONS
Options in prompt.
Definition color.h:54
bool mutt_isalnum(int arg)
Wrapper for isalnum(3)
Definition ctype.c:40
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
void msgwin_add_text_n(struct MuttWindow *win, const char *text, int bytes, const struct AttrColor *ac_color)
Add some text to the Message Window.
Definition msgwin.c:449
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
#define key_is_return(ch)
Definition mutt_curses.h:57
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mw_yesorno()

static enum QuadOption mw_yesorno ( const char * prompt,
enum QuadOption def,
struct ConfigDef * cdef,
GetChFlags flags )
static

Ask the user a Yes/No question offering help -.

Parameters
promptPrompt
defDefault answer, e.g. MUTT_YES
cdefConfig definition for help
flagsmutt_getch Flags, e.g. GETCH_IGNORE_MACRO
Return values
enumQuadOption, Selection made

This function uses a message window.

Ask the user a yes/no question, using shortcut letters, e.g. Quit NeoMutt? ([yes]/no):

This question can be answered using locale-dependent letters, e.g.

  • English, [+1yY] or [-0nN]
  • Serbian, [+1yYdDДд] or [-0nNНн]

If a config variable (cdef) is given, then help is offered. The options change to: ([yes]/no/?)

Pressing '?' will show the name and one-line description of the config variable. Additionally, if $help is set, a link to the config's documentation is shown.

Definition at line 176 of file question.c.

178{
179 struct MuttWindow *win = msgwin_new(true);
180 if (!win)
181 return MUTT_ABORT;
182
183 char *yes = N_("yes");
184 char *no = N_("no");
185 char *trans_yes = _(yes);
186 char *trans_no = _(no);
187
188 regex_t reyes = { 0 };
189 regex_t reno = { 0 };
190
191 bool reyes_ok = false;
192 bool reno_ok = false;
193
194#ifdef OpenBSD
195 /* OpenBSD only supports locale C and UTF-8
196 * so there is no suitable base system's locale identification
197 * Remove this code immediately if this situation changes! */
198 char rexyes[16] = "^[+1YyYy]";
199 rexyes[6] = mutt_toupper(trans_yes[0]);
200 rexyes[7] = mutt_tolower(trans_yes[0]);
201
202 char rexno[16] = "^[-0NnNn]";
203 rexno[6] = mutt_toupper(trans_no[0]);
204 rexno[7] = mutt_tolower(trans_no[0]);
205
206 if (REG_COMP(&reyes, rexyes, REG_NOSUB) == 0)
207 reyes_ok = true;
208
209 if (REG_COMP(&reno, rexno, REG_NOSUB) == 0)
210 reno_ok = true;
211
212#else
213 char *expr = NULL;
214 reyes_ok = (expr = nl_langinfo(YESEXPR)) && (expr[0] == '^') &&
215 (REG_COMP(&reyes, expr, REG_NOSUB) == 0);
216 reno_ok = (expr = nl_langinfo(NOEXPR)) && (expr[0] == '^') &&
217 (REG_COMP(&reno, expr, REG_NOSUB) == 0);
218#endif
219
220 if ((yes != trans_yes) && (no != trans_no) && reyes_ok && reno_ok)
221 {
222 // If all parts of the translation succeeded...
223 yes = trans_yes;
224 no = trans_no;
225 }
226 else
227 {
228 // otherwise, fallback to English
229 if (reyes_ok)
230 {
231 regfree(&reyes);
232 reyes_ok = false;
233 }
234 if (reno_ok)
235 {
236 regfree(&reno);
237 reno_ok = false;
238 }
239 }
240
241 bool show_help_prompt = cdef;
242
243 struct Buffer *text = buf_pool_get();
244 buf_printf(text, "%s ([%s]/%s%s): ", prompt, (def == MUTT_YES) ? yes : no,
245 (def == MUTT_YES) ? no : yes, show_help_prompt ? "/?" : "");
246
249 struct MuttWindow *old_focus = window_set_focus(win);
250
251 struct KeyEvent event = { 0, OP_NULL };
252 window_redraw(NULL);
253 while (true)
254 {
255 event = mutt_getch(flags);
256 if ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT))
257 {
258 window_redraw(NULL);
259 mutt_refresh();
260 continue;
261 }
262
263 if (key_is_return(event.ch))
264 break; // Do nothing, use default
265
266 if (event.op == OP_ABORT)
267 {
268 def = MUTT_ABORT;
269 break;
270 }
271
272 char answer[4] = { 0 };
273 answer[0] = event.ch;
274 if (reyes_ok ? (regexec(&reyes, answer, 0, 0, 0) == 0) : (mutt_tolower(event.ch) == 'y'))
275 {
276 def = MUTT_YES;
277 break;
278 }
279 if (reno_ok ? (regexec(&reno, answer, 0, 0, 0) == 0) : (mutt_tolower(event.ch) == 'n'))
280 {
281 def = MUTT_NO;
282 break;
283 }
284 if (show_help_prompt && (event.ch == '?'))
285 {
286 show_help_prompt = false;
288 buf_printf(text, "$%s - %s\n", cdef->name, cdef->docs);
289
290 char hyphen[128] = { 0 };
291 mutt_str_hyphenate(hyphen, sizeof(hyphen), cdef->name);
292 buf_add_printf(text, "https://neomutt.org/guide/reference#%s\n", hyphen);
293
295
296 buf_printf(text, "%s ([%s]/%s): ", prompt, (def == MUTT_YES) ? yes : no,
297 (def == MUTT_YES) ? no : yes);
299 msgwin_add_text(win, NULL, NULL);
300
301 window_redraw(NULL);
302 mutt_refresh();
303 }
304
305 mutt_beep(false);
306 }
307
308 win = msgcont_pop_window();
309 window_set_focus(old_focus);
310 mutt_window_free(&win);
311
312 if (reyes_ok)
313 regfree(&reyes);
314 if (reno_ok)
315 regfree(&reno);
316
317 buf_pool_release(&text);
318 return def;
319}
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:204
int mutt_toupper(int arg)
Wrapper for toupper(3)
Definition ctype.c:140
int mutt_tolower(int arg)
Wrapper for tolower(3)
Definition ctype.c:126
#define N_(a)
Definition message.h:32
void mutt_str_hyphenate(char *buf, size_t buflen, const char *str)
Hyphenate a snake-case string.
Definition string.c:854
@ MUTT_ABORT
User aborted the question (with Ctrl-G)
Definition quad.h:37
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition quad.h:38
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition quad.h:39
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition regex3.h:49
const char * name
User-visible name.
Definition set.h:66
const char * docs
One-liner description.
Definition set.h:84
+ Here is the call graph for this function:
+ Here is the caller graph for this function: