NeoMutt  2025-12-11-769-g906513
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 467 of file window.c.

469{
470 return mw_get_field_notify(prompt, buf, complete, hclass, comp_api, cdata,
471 NULL, NULL, NULL, NULL);
472}
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:266
+ 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:69
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:105
struct MuttWindow * msgcont_pop_window(void)
Remove the last Window from the Container Stack.
Definition msgcont.c:60
struct MuttWindow * msgwin_new(bool interactive)
Create the Message Window.
Definition msgwin.c:372
void msgwin_set_text(struct MuttWindow *win, const char *text, enum ColorId color)
Set the text for the Message Window.
Definition msgwin.c:487
#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 238 of file curs_lib.c.

241{
242 struct MuttWindow *win = msgwin_new(true);
243 if (!win)
244 return -1;
245
246 int rc = -1;
247
248 struct Buffer *text = buf_pool_get();
249 const struct AttrColor *ac_normal = simple_color_get(MT_COLOR_NORMAL);
250 const struct AttrColor *ac_prompt = merged_color_overlay(ac_normal,
252
253 msgwin_add_text(win, prompt, ac_prompt);
254 msgwin_add_text(win, _(" ('?' for list): "), ac_prompt);
255 if (!buf_is_empty(fname))
256 msgwin_add_text(win, buf_string(fname), ac_normal);
257
259 struct MuttWindow *old_focus = window_set_focus(win);
260
261 struct KeyEvent event = { 0, OP_NULL };
262 do
263 {
264 window_redraw(NULL);
265 event = mutt_getch(GETCH_NO_FLAGS);
266 } while ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT));
267
268 mutt_refresh();
269 win = msgcont_pop_window();
270 window_set_focus(old_focus);
271 mutt_window_free(&win);
272
273 if (event.ch < 0)
274 goto done;
275
276 if (event.ch == '?')
277 {
278 buf_reset(fname);
279
280 if (flags == MUTT_SEL_NO_FLAGS)
281 flags = MUTT_SEL_FOLDER;
282 if (multiple)
283 flags |= MUTT_SEL_MULTI;
284 if (mailbox)
285 flags |= MUTT_SEL_MAILBOX;
286 dlg_browser(fname, flags, m, files, numfiles);
287 }
288 else
289 {
290 char *pc = NULL;
291 mutt_str_asprintf(&pc, "%s: ", prompt);
292 if (event.op == OP_NULL)
293 mutt_unget_ch(event.ch);
294 else
295 mutt_unget_op(event.op);
296
297 buf_alloc(fname, 1024);
298 struct FileCompletionData cdata = { multiple, m, files, numfiles, NULL };
299 enum HistoryClass hclass = mailbox ? HC_MAILBOX : HC_FILE;
300 if (mw_get_field(pc, fname, MUTT_COMP_CLEAR, hclass, &CompleteMailboxOps, &cdata) != 0)
301 {
302 buf_reset(fname);
303 }
304 FREE(&pc);
305 }
306
307 rc = 0;
308
309done:
310 buf_pool_release(&text);
311 return rc;
312}
const struct CompleteOps CompleteMailboxOps
Auto-Completion of Files / Mailboxes.
Definition complete.c:159
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition lib.h:56
#define MUTT_SEL_FOLDER
Select a local directory.
Definition lib.h:58
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition lib.h:57
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition lib.h:55
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:97
@ MT_COLOR_NORMAL
Plain text.
Definition color.h:53
void mutt_refresh(void)
Force a refresh of the screen.
Definition curs_lib.c:79
#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:130
void mutt_unget_ch(int ch)
Return a keystroke to the input buffer.
Definition get.c:118
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:467
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:110
void msgwin_add_text(struct MuttWindow *win, const char *text, const struct AttrColor *ac_color)
Add text to the Message Window.
Definition msgwin.c:422
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 505 of file curs_lib.c.

506{
507 struct MuttWindow *win = msgwin_new(true);
508 if (!win)
509 return;
510
512 struct Buffer *key = buf_pool_get();
513 struct Buffer *prompt = buf_pool_get();
514 struct Buffer *text = buf_pool_get();
515
516 keymap_get_name(key_mod_data->abort_key, key);
517
518 buf_printf(prompt, _("Enter keys (%s to abort): "), buf_string(key));
520
522 struct MuttWindow *old_focus = window_set_focus(win);
523 window_redraw(win);
524
525 const struct AttrColor *ac_normal = simple_color_get(MT_COLOR_NORMAL);
526 const struct AttrColor *ac_prompt = simple_color_get(MT_COLOR_PROMPT);
527
528 // ---------------------------------------------------------------------------
529 // Event Loop
530 timeout(1000); // 1 second
531 while (true)
532 {
533 int ch = getch();
534 if (ch == key_mod_data->abort_key)
535 break;
536
537 if (ch == KEY_RESIZE)
538 {
539 timeout(0);
540 while ((ch = getch()) == KEY_RESIZE)
541 {
542 // do nothing
543 }
544 }
545
546 if (ch == ERR)
547 {
548 if (!isatty(STDIN_FILENO)) // terminal was lost
549 mutt_exit(1);
550
551 if (SigWinch)
552 {
553 SigWinch = false;
555 window_redraw(NULL);
556 }
557 else
558 {
560 }
561
562 continue;
563 }
564
566
567 buf_reset(key);
568 keymap_get_name(ch, key);
569
570 buf_printf(text, _("Char = %s, Octal = %o, Decimal = %d\n"), buf_string(key), ch, ch);
571
572 msgwin_add_text(win, buf_string(text), ac_normal);
573 msgwin_add_text(win, buf_string(prompt), ac_prompt);
574 msgwin_add_text(win, NULL, NULL);
575 window_redraw(NULL);
576 }
577 // ---------------------------------------------------------------------------
578
579 buf_pool_release(&key);
580 buf_pool_release(&prompt);
581 buf_pool_release(&text);
582
583 win = msgcont_pop_window();
584 window_set_focus(old_focus);
585 mutt_window_free(&win);
586}
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
void keymap_get_name(int c, struct Buffer *buf)
Get the human name for a key.
Definition keymap.c:195
@ MODULE_ID_KEY
ModuleKey, Key mappings
Definition module_api.h:73
void msgwin_clear_text(struct MuttWindow *win)
Clear the text in the Message Window.
Definition msgwin.c:522
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
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:665
@ 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
Key private Module data.
Definition module_data.h:34
keycode_t abort_key
Key to abort prompts, normally Ctrl-G.
Definition module_data.h:38
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:119
@ 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:453
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: