NeoMutt  2025-01-09-117-gace867
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 273 of file window.c.

275{
278
280 if (complete & MUTT_COMP_UNBUFFERED)
281 flags = GETCH_IGNORE_MACRO;
282
283 int rc = 0;
284
285 struct EnterState *es = enter_state_new();
286
287 win->help_data = EditorHelp;
288 win->help_menu = MENU_EDITOR;
289
291 struct MuttWindow *old_focus = window_set_focus(win);
292
293 mbstate_t mbstate = { 0 };
294 // clang-format off
295 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 };
296 // clang-format on
297
298 win->wdata = &wdata;
299 win->wdata_free = NULL; // No need, we hold the data
300 win->recalc = enter_recalc;
301 win->repaint = enter_repaint;
303
304 window_redraw(win);
305
306 if (es->wbuf[0] == L'\0')
307 {
308 /* Initialise wbuf from buf */
309 wdata.state->wbuflen = 0;
310 wdata.state->lastchar = mutt_mb_mbstowcs(&wdata.state->wbuf, &wdata.state->wbuflen,
311 0, buf_string(wdata.buffer));
313 }
314 else
315 {
317 wdata.first = false;
318 }
319
320 do
321 {
322 memset(&mbstate, 0, sizeof(mbstate));
323
324 do
325 {
326 if (wdata.redraw != ENTER_REDRAW_NONE)
327 win->actions |= WA_REPAINT;
328
329 window_redraw(NULL);
330 struct KeyEvent event = km_dokey_event(MENU_EDITOR, flags);
331 if ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT))
332 {
333 continue;
334 }
335
336 if (event.op == OP_ABORT)
337 {
338 rc = -1;
339 goto bye;
340 }
341
342 if (event.op == OP_NULL)
343 {
344 if (complete & MUTT_COMP_PASS)
345 mutt_debug(LL_DEBUG5, "Got char *\n");
346 else
347 mutt_debug(LL_DEBUG5, "Got char %c (0x%02x)\n", event.ch, event.ch);
348
349 if (self_insert(&wdata, event.ch))
350 {
351 rc = 0;
352 goto bye;
353 }
354 win->actions |= WA_REPAINT;
355 continue;
356 }
357 else
358 {
359 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(event.op),
360 event.op);
361 }
362
363 wdata.first = false;
364 if ((event.op != OP_EDITOR_COMPLETE) && (event.op != OP_EDITOR_COMPLETE_QUERY))
365 wdata.tabs = 0;
367 int rc_disp = enter_function_dispatcher(win, event.op);
368 switch (rc_disp)
369 {
370 case FR_NO_ACTION:
371 {
372 if (self_insert(&wdata, event.ch))
373 {
374 rc = 0;
375 goto bye;
376 }
377 break;
378 }
379 case FR_CONTINUE: // repaint
380 rc = 1;
381 goto bye;
382
383 case FR_SUCCESS:
384 rc = 0;
385 break;
386
387 case FR_UNKNOWN:
388 case FR_ERROR:
389 default:
390 mutt_beep(false);
391 }
392 } while (!wdata.done);
393
394 bye:
396 FREE(&wdata.tempbuf);
397 completion_data_free(&wdata.cd);
398 } while (rc == 1);
399
401 window_set_focus(old_focus);
402 mutt_window_free(&win);
403
404 if (rc == 0)
405 buf_fix_dptr(buf);
406 else
407 buf_reset(buf);
408
409 enter_state_free(&es);
410
411 return rc;
412}
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:49
bool self_insert(struct EnterWindowData *wdata, int ch)
Insert a normal character.
Definition: window.c:89
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:175
static bool enter_recursor(struct MuttWindow *win)
Recursor the Window - Implements MuttWindow::recursor() -.
Definition: window.c:246
static int enter_repaint(struct MuttWindow *win)
Repaint the Window - Implements MuttWindow::repaint() -.
Definition: window.c:186
void mutt_hist_reset_state(enum HistoryClass hclass)
Move the 'current' position to the end of the History.
Definition: history.c:586
uint8_t GetChFlags
Flags for mutt_getch(), e.g. GETCH_NO_FLAGS.
Definition: lib.h:51
#define GETCH_IGNORE_MACRO
Don't use MacroEvents.
Definition: lib.h:53
#define GETCH_NO_FLAGS
No flags are set.
Definition: lib.h:52
@ 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:55
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.
Definition: mutt_window.c:599
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:205
struct MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
Definition: mutt_window.c:182
struct MuttWindow * window_set_focus(struct MuttWindow *win)
Set the Window focus.
Definition: mutt_window.c:649
@ 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.
Definition: mutt_window.h:111
#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:36
#define OP_REPAINT
Repaint is needed.
Definition: opcodes.h:34
#define OP_ABORT
$abort_key pressed (Ctrl-G)
Definition: opcodes.h:37
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:81
int op
Function opcode, e.g. OP_HELP.
Definition: lib.h:83
int ch
Raw key pressed.
Definition: lib.h:82
const struct Mapping * help_data
Data for the Help Bar.
Definition: mutt_window.h:142
int(* repaint)(struct MuttWindow *win)
Definition: mutt_window.h:187
void * wdata
Private data.
Definition: mutt_window.h:145
int(* recalc)(struct MuttWindow *win)
Definition: mutt_window.h:173
void(* wdata_free)(struct MuttWindow *win, void **ptr)
Definition: mutt_window.h:159
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
Definition: mutt_window.h:141
WindowActionFlags actions
Actions to be performed, e.g. WA_RECALC.
Definition: mutt_window.h:132
bool(* recursor)(struct MuttWindow *win)
Definition: mutt_window.h:205
@ 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 454 of file flags.c.

455{
456 if (!m || !ea || ARRAY_EMPTY(ea))
457 return -1;
458
459 // blank window (0, 0)
460 struct MuttWindow *win = msgwin_new(true);
461 if (!win)
462 return -1;
463
464 char prompt[256] = { 0 };
465 snprintf(prompt, sizeof(prompt),
466 "%s? (D/N/O/r/*/!): ", bf ? _("Set flag") : _("Clear flag"));
467 msgwin_set_text(win, prompt, MT_COLOR_PROMPT);
468
470 struct MuttWindow *old_focus = window_set_focus(win);
471 window_redraw(win);
472
473 struct KeyEvent event = { 0, OP_NULL };
474 do
475 {
476 window_redraw(NULL);
477 event = mutt_getch(GETCH_NO_FLAGS);
478 } while ((event.op == OP_TIMEOUT) || (event.op == OP_REPAINT));
479
480 win = msgcont_pop_window();
481 window_set_focus(old_focus);
482 mutt_window_free(&win);
483
484 if (event.op == OP_ABORT)
485 return -1;
486
487 enum MessageType flag = MUTT_NONE;
488 switch (event.ch)
489 {
490 case 'd':
491 case 'D':
492 if (!bf)
494 flag = MUTT_DELETE;
495 break;
496
497 case 'N':
498 case 'n':
499 flag = MUTT_NEW;
500 break;
501
502 case 'o':
503 case 'O':
504 mutt_emails_set_flag(m, ea, MUTT_READ, !bf);
505 flag = MUTT_OLD;
506 break;
507
508 case 'r':
509 case 'R':
510 flag = MUTT_REPLIED;
511 break;
512
513 case '*':
514 flag = MUTT_TAG;
515 break;
516
517 case '!':
518 flag = MUTT_FLAG;
519 break;
520
521 default:
522 mutt_beep(false);
523 return -1;
524 }
525
526 mutt_emails_set_flag(m, ea, flag, bf);
527 return 0;
528}
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:74
@ MT_COLOR_PROMPT
Question/user input.
Definition: color.h:58
struct KeyEvent mutt_getch(GetChFlags flags)
Read a character from the input buffer.
Definition: get.c:210
void mutt_emails_set_flag(struct Mailbox *m, struct EmailArray *ea, enum MessageType flag, bool bf)
Set flag on messages.
Definition: flags.c:361
struct MuttWindow * msgwin_new(bool interactive)
Create the Message Window.
Definition: msgwin.c:371
void msgwin_set_text(struct MuttWindow *win, const char *text, enum ColorId color)
Set the text for the Message Window.
Definition: msgwin.c:484
#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:160
#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:55
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 -.
Definition: dlg_browser.c:853
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:273
HistoryClass
Type to differentiate different histories.
Definition: lib.h:52
@ HC_FILE
Files.
Definition: lib.h:56
@ HC_MAILBOX
Mailboxes.
Definition: lib.h:59
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:419
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:804
#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:40
char *** files
List of files selected.
Definition: curs_lib.h:43
struct Mailbox * mailbox
Mailbox.
Definition: curs_lib.h:42
bool multiple
Allow multiple selections.
Definition: curs_lib.h:41
int * numfiles
Number of files selected.
Definition: curs_lib.h:44
+ 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:121
void km_keyname(int c, struct Buffer *buf)
Get the human name for a key.
Definition: lib.c:465
void msgwin_clear_text(struct MuttWindow *win)
Clear the text in the Message Window.
Definition: msgwin.c:519
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:70
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 63 of file question.c.

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

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