NeoMutt  2025-09-05-55-g97fc89
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 272 of file window.c.

274{
277
279 if (complete & MUTT_COMP_UNBUFFERED)
280 flags = GETCH_IGNORE_MACRO;
281
282 int rc = 0;
283
284 struct EnterState *es = enter_state_new();
285
286 win->help_data = EditorHelp;
287 win->help_menu = MENU_EDITOR;
288
290 struct MuttWindow *old_focus = window_set_focus(win);
291
292 mbstate_t mbstate = { 0 };
293 // clang-format off
294 struct EnterWindowData wdata = { buf, complete, es, hclass, comp_api, cdata, prompt, ENTER_REDRAW_NONE, (complete & MUTT_COMP_PASS), true, NULL, 0, &mbstate, 0, false, NULL, 0, 0 };
295 // clang-format on
296
297 win->wdata = &wdata;
298 win->wdata_free = NULL; // No need, we hold the data
299 win->recalc = enter_recalc;
300 win->repaint = enter_repaint;
302
303 window_redraw(win);
304
305 if (es->wbuf[0] == L'\0')
306 {
307 /* Initialise wbuf from buf */
308 wdata.state->wbuflen = 0;
309 wdata.state->lastchar = mutt_mb_mbstowcs(&wdata.state->wbuf, &wdata.state->wbuflen,
310 0, buf_string(wdata.buffer));
312 }
313 else
314 {
316 wdata.first = false;
317 }
318
319 do
320 {
321 memset(&mbstate, 0, sizeof(mbstate));
322
323 do
324 {
325 if (wdata.redraw != ENTER_REDRAW_NONE)
326 win->actions |= WA_REPAINT;
327
328 window_redraw(NULL);
329 struct KeyEvent event = km_dokey_event(MENU_EDITOR, flags);
330 if ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT))
331 {
332 continue;
333 }
334
335 if (event.op == OP_ABORT)
336 {
337 rc = -1;
338 goto bye;
339 }
340
341 if (event.op == OP_NULL)
342 {
343 if (complete & MUTT_COMP_PASS)
344 mutt_debug(LL_DEBUG5, "Got char *\n");
345 else
346 mutt_debug(LL_DEBUG5, "Got char %c (0x%02x)\n", event.ch, event.ch);
347
348 if (self_insert(&wdata, event.ch))
349 {
350 rc = 0;
351 goto bye;
352 }
353 win->actions |= WA_REPAINT;
354 continue;
355 }
356 else
357 {
358 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(event.op),
359 event.op);
360 }
361
362 wdata.first = false;
363 if ((event.op != OP_EDITOR_COMPLETE) && (event.op != OP_EDITOR_COMPLETE_QUERY))
364 wdata.tabs = 0;
366 int rc_disp = enter_function_dispatcher(win, event.op);
367 switch (rc_disp)
368 {
369 case FR_NO_ACTION:
370 {
371 if (self_insert(&wdata, event.ch))
372 {
373 rc = 0;
374 goto bye;
375 }
376 break;
377 }
378 case FR_CONTINUE: // repaint
379 rc = 1;
380 goto bye;
381
382 case FR_SUCCESS:
383 rc = 0;
384 break;
385
386 case FR_UNKNOWN:
387 case FR_ERROR:
388 default:
389 mutt_beep(false);
390 }
391 } while (!wdata.done);
392
393 bye:
395 FREE(&wdata.tempbuf);
396 } while (rc == 1);
397
398 completion_data_free(&wdata.cd);
400 window_set_focus(old_focus);
401 mutt_window_free(&win);
402
403 if (rc == 0)
404 buf_fix_dptr(buf);
405 else
406 buf_reset(buf);
407
408 enter_state_free(&es);
409
410 return rc;
411}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition buffer.c:182
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
void mutt_beep(bool force)
Irritate the user.
Definition curs_lib.c:69
void completion_data_free(struct CompletionData **ptr)
Free the Completion Data.
Definition data.c:53
@ FR_SUCCESS
Valid function - successfully performed.
Definition dispatcher.h:39
@ FR_UNKNOWN
Unknown function.
Definition dispatcher.h:33
@ FR_ERROR
Valid function - error occurred.
Definition dispatcher.h:38
@ FR_CONTINUE
Remain in the Dialog.
Definition dispatcher.h:34
@ FR_NO_ACTION
Valid function - no action performed.
Definition dispatcher.h:37
struct EnterState * enter_state_new(void)
Create a new EnterState.
Definition state.c:74
void enter_state_free(struct EnterState **ptr)
Free an EnterState.
Definition state.c:38
@ ENTER_REDRAW_NONE
Nothing to redraw.
Definition wdata.h:37
@ ENTER_REDRAW_LINE
Redraw entire line.
Definition wdata.h:39
@ ENTER_REDRAW_INIT
Go to end of line and redraw.
Definition wdata.h:38
static const struct Mapping EditorHelp[]
Help Bar for the Command Line Editor.
Definition window.c:48
bool self_insert(struct EnterWindowData *wdata, int ch)
Insert a normal character.
Definition window.c:88
struct KeyEvent km_dokey_event(enum MenuType mtype, GetChFlags flags)
Determine what a keypress should do.
Definition get.c:419
int enter_function_dispatcher(struct MuttWindow *win, int op)
Perform an Enter function - Implements function_dispatcher_t -.
Definition functions.c:482
#define mutt_debug(LEVEL,...)
Definition logging2.h:90
static int enter_recalc(struct MuttWindow *win)
Recalculate the Window data - Implements MuttWindow::recalc() -.
Definition window.c:174
static bool enter_recursor(struct MuttWindow *win)
Recursor the Window - Implements MuttWindow::recursor() -.
Definition window.c:245
static int enter_repaint(struct MuttWindow *win)
Repaint the Window - Implements MuttWindow::repaint() -.
Definition window.c:185
void mutt_hist_reset_state(enum HistoryClass hclass)
Move the 'current' position to the end of the History.
Definition history.c:578
uint8_t GetChFlags
Flags for mutt_getch(), e.g. GETCH_NO_FLAGS.
Definition lib.h:52
#define GETCH_IGNORE_MACRO
Don't use MacroEvents.
Definition lib.h:54
#define GETCH_NO_FLAGS
No flags are set.
Definition lib.h:53
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:48
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:44
size_t mutt_mb_mbstowcs(wchar_t **pwbuf, size_t *pwbuflen, size_t i, const char *buf)
Convert a string from multibyte to wide characters.
Definition mbyte.c:291
#define FREE(x)
Definition memory.h:62
void msgcont_push_window(struct MuttWindow *win)
Add a window to the Container Stack.
Definition msgcont.c:93
struct MuttWindow * msgcont_pop_window(void)
Remove the last Window from the Container Stack.
Definition msgcont.c:57
#define MUTT_COMP_PASS
Password mode (no echo)
Definition mutt.h:58
#define MUTT_COMP_UNBUFFERED
Ignore macro buffer.
Definition mutt.h:59
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 * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
struct MuttWindow * window_set_focus(struct MuttWindow *win)
Set the Window focus.
@ WT_CUSTOM
Window with a custom drawing function.
Definition mutt_window.h:95
@ MUTT_WIN_ORIENT_VERTICAL
Window uses all available vertical space.
Definition mutt_window.h:39
#define WA_REPAINT
Redraw the contents of the Window.
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition mutt_window.h:53
@ MUTT_WIN_SIZE_FIXED
Window has a fixed size.
Definition mutt_window.h:48
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition opcodes.c:48
#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
Keep our place when entering a string.
Definition state.h:32
size_t wbuflen
Length of buffer.
Definition state.h:34
wchar_t * wbuf
Buffer for the string being entered.
Definition state.h:33
size_t lastchar
Position of the last character.
Definition state.h:35
Data to fill the Enter Window.
Definition wdata.h:46
int tabs
Number of times the user has hit tab.
Definition wdata.h:63
void * cdata
Auto-Completion private data.
Definition wdata.h:53
struct CompletionData * cd
Auto-completion state data.
Definition wdata.h:67
struct Buffer * buffer
struct Buffer for the result
Definition wdata.h:48
bool done
Is text-entry done?
Definition wdata.h:65
bool first
First time through, no input yet.
Definition wdata.h:59
wchar_t * tempbuf
Buffer used by completion.
Definition wdata.h:60
const struct CompleteOps * comp_api
Auto-Completion API.
Definition wdata.h:52
const char * prompt
Prompt.
Definition wdata.h:56
struct EnterState * state
Current state of text entry.
Definition wdata.h:50
enum EnterRedrawFlags redraw
What needs redrawing? See EnterRedrawFlags.
Definition wdata.h:57
mbstate_t * mbstate
Multi-byte state.
Definition wdata.h:62
enum HistoryClass hclass
History to use, e.g. HC_NEO_COMMAND.
Definition wdata.h:51
An event such as a keypress.
Definition lib.h:82
int op
Function opcode, e.g. OP_HELP.
Definition lib.h:84
int ch
Raw key pressed.
Definition lib.h:83
const struct Mapping * help_data
Data for the Help Bar.
int(* repaint)(struct MuttWindow *win)
void * wdata
Private data.
int(* recalc)(struct MuttWindow *win)
void(* wdata_free)(struct MuttWindow *win, void **ptr)
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
WindowActionFlags actions
Actions to be performed, e.g. WA_RECALC.
bool(* recursor)(struct MuttWindow *win)
@ MENU_EDITOR
Text entry area.
Definition type.h:44
+ 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 453 of file flags.c.

454{
455 if (!m || !ea || ARRAY_EMPTY(ea))
456 return -1;
457
458 // blank window (0, 0)
459 struct MuttWindow *win = msgwin_new(true);
460 if (!win)
461 return -1;
462
463 char prompt[256] = { 0 };
464 snprintf(prompt, sizeof(prompt),
465 "%s? (D/N/O/r/*/!): ", bf ? _("Set flag") : _("Clear flag"));
466 msgwin_set_text(win, prompt, MT_COLOR_PROMPT);
467
469 struct MuttWindow *old_focus = window_set_focus(win);
470 window_redraw(win);
471
472 struct KeyEvent event = { 0, OP_NULL };
473 do
474 {
475 window_redraw(NULL);
476 event = mutt_getch(GETCH_NO_FLAGS);
477 } while ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT));
478
479 win = msgcont_pop_window();
480 window_set_focus(old_focus);
481 mutt_window_free(&win);
482
483 if (event.op == OP_ABORT)
484 return -1;
485
486 enum MessageType flag = MUTT_NONE;
487 switch (event.ch)
488 {
489 case 'd':
490 case 'D':
491 if (!bf)
493 flag = MUTT_DELETE;
494 break;
495
496 case 'N':
497 case 'n':
498 flag = MUTT_NEW;
499 break;
500
501 case 'o':
502 case 'O':
503 mutt_emails_set_flag(m, ea, MUTT_READ, !bf);
504 flag = MUTT_OLD;
505 break;
506
507 case 'r':
508 case 'R':
509 flag = MUTT_REPLIED;
510 break;
511
512 case '*':
513 flag = MUTT_TAG;
514 break;
515
516 case '!':
517 flag = MUTT_FLAG;
518 break;
519
520 default:
521 mutt_beep(false);
522 return -1;
523 }
524
525 mutt_emails_set_flag(m, ea, flag, bf);
526 return 0;
527}
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
@ MT_COLOR_PROMPT
Question/user input.
Definition color.h:57
void mutt_emails_set_flag(struct Mailbox *m, struct EmailArray *ea, enum MessageType flag, bool bf)
Set flag on messages.
Definition flags.c:360
struct KeyEvent mutt_getch(GetChFlags flags)
Read a character from the input buffer.
Definition get.c:210
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:67
@ MUTT_READ
Messages that have been read.
Definition mutt.h:73
@ MUTT_OLD
Old messages.
Definition mutt.h:71
@ MUTT_PURGE
Messages to be purged (bypass trash)
Definition mutt.h:77
@ MUTT_NONE
No messages.
Definition mutt.h:69
@ MUTT_TAG
Tagged messages.
Definition mutt.h:80
@ MUTT_FLAG
Flagged messages.
Definition mutt.h:79
@ MUTT_DELETE
Messages to be deleted.
Definition mutt.h:75
@ MUTT_NEW
New messages.
Definition mutt.h:70
@ MUTT_REPLIED
Messages that have been replied to.
Definition mutt.h:72
+ 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 237 of file curs_lib.c.

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

502{
503 struct MuttWindow *win = msgwin_new(true);
504 if (!win)
505 return;
506
507 struct Buffer *key = buf_pool_get();
508 struct Buffer *prompt = buf_pool_get();
509 struct Buffer *text = buf_pool_get();
510
511 km_keyname(AbortKey, key);
512
513 buf_printf(prompt, _("Enter keys (%s to abort): "), buf_string(key));
515
517 struct MuttWindow *old_focus = window_set_focus(win);
518 window_redraw(win);
519
520 const struct AttrColor *ac_normal = simple_color_get(MT_COLOR_NORMAL);
521 const struct AttrColor *ac_prompt = simple_color_get(MT_COLOR_PROMPT);
522
523 // ---------------------------------------------------------------------------
524 // Event Loop
525 timeout(1000); // 1 second
526 while (true)
527 {
528 int ch = getch();
529 if (ch == AbortKey)
530 break;
531
532 if (ch == KEY_RESIZE)
533 {
534 timeout(0);
535 while ((ch = getch()) == KEY_RESIZE)
536 {
537 // do nothing
538 }
539 }
540
541 if (ch == ERR)
542 {
543 if (!isatty(STDIN_FILENO)) // terminal was lost
544 mutt_exit(1);
545
546 if (SigWinch)
547 {
548 SigWinch = false;
550 window_redraw(NULL);
551 }
552 else
553 {
555 }
556
557 continue;
558 }
559
561
562 buf_reset(key);
563 km_keyname(ch, key);
564
565 buf_printf(text, _("Char = %s, Octal = %o, Decimal = %d\n"), buf_string(key), ch, ch);
566
567 msgwin_add_text(win, buf_string(text), ac_normal);
568 msgwin_add_text(win, buf_string(prompt), ac_prompt);
569 msgwin_add_text(win, NULL, NULL);
570 window_redraw(NULL);
571 }
572 // ---------------------------------------------------------------------------
573
574 buf_pool_release(&key);
575 buf_pool_release(&prompt);
576 buf_pool_release(&text);
577
578 win = msgcont_pop_window();
579 window_set_focus(old_focus);
580 mutt_window_free(&win);
581}
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 lib.c:122
void km_keyname(int c, struct Buffer *buf)
Get the human name for a key.
Definition lib.c:390
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:43
struct Notify * notify_timeout
Timeout notifications handler.
Definition neomutt.h:46
struct Notify * notify_resize
Window resize notifications handler.
Definition neomutt.h:45
+ 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 61 of file question.c.

62{
63 struct MuttWindow *win = msgwin_new(true);
64 if (!win)
65 return -1;
66
67 int choice = 0;
68
69 const struct AttrColor *ac_normal = simple_color_get(MT_COLOR_NORMAL);
70 const struct AttrColor *ac_prompt = merged_color_overlay(ac_normal,
72
74 {
75 const struct AttrColor *ac_opts = merged_color_overlay(ac_prompt,
77 char *cur = NULL;
78
79 while ((cur = strchr(prompt, '(')))
80 {
81 // write the part between prompt and cur using MT_COLOR_PROMPT
82 msgwin_add_text_n(win, prompt, cur - prompt, ac_prompt);
83
84 if (mutt_isalnum(cur[1]) && (cur[2] == ')'))
85 {
86 // we have a single letter within parentheses - MT_COLOR_OPTIONS
87 msgwin_add_text_n(win, cur + 1, 1, ac_opts);
88 prompt = cur + 3;
89 }
90 else
91 {
92 // we have a parenthesis followed by something else
93 msgwin_add_text_n(win, cur, 1, ac_prompt);
94 prompt = cur + 1;
95 }
96 }
97 }
98
99 msgwin_add_text(win, prompt, ac_prompt);
100 msgwin_add_text(win, " ", ac_normal);
101
103 struct MuttWindow *old_focus = window_set_focus(win);
104 window_redraw(win);
105
106 // ---------------------------------------------------------------------------
107 // Event Loop
108 struct KeyEvent event = { 0, OP_NULL };
109 while (true)
110 {
111 event = mutt_getch(GETCH_NO_FLAGS);
112 mutt_debug(LL_DEBUG1, "mw_multi_choice: EVENT(%d,%d)\n", event.ch, event.op);
113
114 if (event.op == OP_REPAINT)
115 window_redraw(NULL);
116
117 if ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT))
118 continue;
119
120 if ((event.op == OP_ABORT) || key_is_return(event.ch))
121 {
122 choice = -1;
123 break;
124 }
125
126 char *p = strchr(letters, event.ch);
127 if (p)
128 {
129 choice = p - letters + 1;
130 break;
131 }
132
133 if ((event.ch > '0') && (event.ch <= '9'))
134 {
135 choice = event.ch - '0';
136 if (choice <= mutt_str_len(letters))
137 break;
138 }
139 }
140 // ---------------------------------------------------------------------------
141
142 win = msgcont_pop_window();
143 window_set_focus(old_focus);
144 mutt_window_free(&win);
145
146 return choice;
147}
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:55
bool mutt_isalnum(int arg)
Wrapper for isalnum(3)
Definition ctype.c:39
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:498
#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 172 of file question.c.

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