NeoMutt  2020-06-26-250-g349c94
Teaching an old dog new tricks
DOXYGEN
curs_lib.h File Reference

GUI miscellaneous curses (window drawing) routines. More...

#include <stddef.h>
#include <stdbool.h>
#include <wchar.h>
#include "config/lib.h"
#include "mutt.h"
#include "browser.h"
#include "keymap.h"
#include "pager.h"
+ Include dependency graph for curs_lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define mutt_buffer_get_field(field, buf, complete)   mutt_buffer_get_field_full(field, buf, complete, false, NULL, NULL)
 
#define mutt_buffer_enter_fname(prompt, fname, mailbox)   mutt_buffer_enter_fname_full(prompt, fname, mailbox, false, NULL, NULL, MUTT_SEL_NO_FLAGS)
 
#define mutt_get_field(field, buf, buflen, complete)   mutt_get_field_full(field, buf, buflen, complete, false, NULL, NULL)
 
#define mutt_get_password(msg, buf, buflen)   mutt_get_field_unbuffered(msg, buf, buflen, MUTT_PASS)
 

Enumerations

enum  FormatJustify { JUSTIFY_LEFT = -1, JUSTIFY_CENTER = 0, JUSTIFY_RIGHT = 1 }
 Alignment for mutt_simple_format() More...
 

Functions

int mutt_addwch (wchar_t wc)
 addwch would be provided by an up-to-date curses library More...
 
int mutt_any_key_to_continue (const char *s)
 Prompt the user to 'press any key' and wait. More...
 
void mutt_beep (bool force)
 Irritate the user. More...
 
int mutt_do_pager (const char *banner, const char *tempfile, PagerFlags do_color, struct Pager *info)
 Display some page-able text to the user. More...
 
void mutt_edit_file (const char *editor, const char *file)
 Let the user edit a file. More...
 
void mutt_endwin (void)
 Shutdown curses/slang. More...
 
void mutt_flushinp (void)
 Empty all the keyboard buffers. More...
 
void mutt_flush_macro_to_endcond (void)
 Drop a macro from the input buffer. More...
 
void mutt_flush_unget_to_endcond (void)
 Clear entries from UngetKeyEvents. More...
 
void mutt_format_s (char *buf, size_t buflen, const char *prec, const char *s)
 Format a simple string. More...
 
void mutt_format_s_tree (char *buf, size_t buflen, const char *prec, const char *s)
 Format a simple string with tree characters. More...
 
void mutt_format_s_x (char *buf, size_t buflen, const char *prec, const char *s, bool arboreal)
 Format a string like snprintf() More...
 
void mutt_getch_timeout (int delay)
 Set the getch() timeout. More...
 
struct KeyEvent mutt_getch (void)
 Read a character from the input buffer. More...
 
int mutt_get_field_full (const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
 Ask the user for a string. More...
 
int mutt_get_field_unbuffered (const char *msg, char *buf, size_t buflen, CompletionFlags flags)
 Ask the user for a string (ignoring macro buffer) More...
 
int mutt_multi_choice (const char *prompt, const char *letters)
 Offer the user a multiple choice question. More...
 
void mutt_need_hard_redraw (void)
 Force a hard refresh. More...
 
void mutt_paddstr (int n, const char *s)
 Display a string on screen, padded if necessary. More...
 
void mutt_perror_debug (const char *s)
 Show the user an 'errno' message. More...
 
void mutt_push_macro_event (int ch, int op)
 Add the character/operation to the macro buffer. More...
 
void mutt_query_exit (void)
 Ask the user if they want to leave NeoMutt. More...
 
void mutt_refresh (void)
 Force a refresh of the screen. More...
 
void mutt_show_error (void)
 Show the user an error message. More...
 
void mutt_simple_format (char *buf, size_t buflen, int min_width, int max_width, enum FormatJustify justify, char pad_char, const char *s, size_t n, bool arboreal)
 Format a string, like snprintf() More...
 
int mutt_strwidth (const char *s)
 Measure a string's width in screen cells. More...
 
int mutt_strnwidth (const char *s, size_t len)
 Measure a string's width in screen cells. More...
 
void mutt_unget_event (int ch, int op)
 Return a keystroke to the input buffer. More...
 
void mutt_unget_string (const char *s)
 Return a string to the input buffer. More...
 
size_t mutt_wstr_trunc (const char *src, size_t maxlen, size_t maxwid, size_t *width)
 Work out how to truncate a widechar string. More...
 
enum QuadOption mutt_yesorno (const char *msg, enum QuadOption def)
 Ask the user a Yes/No question. More...
 
enum QuadOption query_quadoption (enum QuadOption opt, const char *prompt)
 Ask the user a quad-question. More...
 
int mutt_buffer_get_field_full (const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
 Ask the user for a string. More...
 
int mutt_buffer_enter_fname_full (const char *prompt, struct Buffer *fname, bool mailbox, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
 Ask the user to select a file. More...
 

Variables

bool C_MetaKey
 interpret ALT-x as ESC-x More...
 
int MuttGetchTimeout
 Timeout in ms for mutt_getch() More...
 

Detailed Description

GUI miscellaneous curses (window drawing) routines.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file curs_lib.h.

Macro Definition Documentation

◆ mutt_buffer_get_field

#define mutt_buffer_get_field (   field,
  buf,
  complete 
)    mutt_buffer_get_field_full(field, buf, complete, false, NULL, NULL)

Definition at line 85 of file curs_lib.h.

◆ mutt_buffer_enter_fname

#define mutt_buffer_enter_fname (   prompt,
  fname,
  mailbox 
)    mutt_buffer_enter_fname_full(prompt, fname, mailbox, false, NULL, NULL, MUTT_SEL_NO_FLAGS)

Definition at line 88 of file curs_lib.h.

◆ mutt_get_field

#define mutt_get_field (   field,
  buf,
  buflen,
  complete 
)    mutt_get_field_full(field, buf, buflen, complete, false, NULL, NULL)

Definition at line 91 of file curs_lib.h.

◆ mutt_get_password

#define mutt_get_password (   msg,
  buf,
  buflen 
)    mutt_get_field_unbuffered(msg, buf, buflen, MUTT_PASS)

Definition at line 92 of file curs_lib.h.

Enumeration Type Documentation

◆ FormatJustify

Alignment for mutt_simple_format()

Enumerator
JUSTIFY_LEFT 

Left justify the text.

JUSTIFY_CENTER 

Centre the text.

JUSTIFY_RIGHT 

Right justify the text.

Definition at line 45 of file curs_lib.h.

46 {
47  JUSTIFY_LEFT = -1,
48  JUSTIFY_CENTER = 0,
49  JUSTIFY_RIGHT = 1,
50 };
Left justify the text.
Definition: curs_lib.h:47
Right justify the text.
Definition: curs_lib.h:49
Centre the text.
Definition: curs_lib.h:48

Function Documentation

◆ mutt_addwch()

int mutt_addwch ( wchar_t  wc)

addwch would be provided by an up-to-date curses library

Parameters
wcWide char to display
Return values
0Success
-1Error

Definition at line 1058 of file curs_lib.c.

1059 {
1060  char buf[MB_LEN_MAX * 2];
1061  mbstate_t mbstate;
1062  size_t n1, n2;
1063 
1064  memset(&mbstate, 0, sizeof(mbstate));
1065  if (((n1 = wcrtomb(buf, wc, &mbstate)) == (size_t)(-1)) ||
1066  ((n2 = wcrtomb(buf + n1, 0, &mbstate)) == (size_t)(-1)))
1067  {
1068  return -1; /* ERR */
1069  }
1070  else
1071  {
1072  return mutt_window_addstr(buf);
1073  }
1074 }
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:532
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_any_key_to_continue()

int mutt_any_key_to_continue ( const char *  s)

Prompt the user to 'press any key' and wait.

Parameters
sMessage prompt
Return values
numKey pressed
EOFError, or prompt aborted

Definition at line 603 of file curs_lib.c.

604 {
605  struct termios term;
606  struct termios old;
607 
608  int fd = open("/dev/tty", O_RDONLY);
609  if (fd < 0)
610  return EOF;
611 
612  tcgetattr(fd, &old); // Save the current tty settings
613 
614  term = old;
615  term.c_lflag &= ~(ICANON | ECHO); // Canonical (not line-buffered), don't echo the characters
616  term.c_cc[VMIN] = 1; // Wait for at least one character
617  term.c_cc[VTIME] = 255; // Wait for 25.5s
618  tcsetattr(fd, TCSANOW, &term);
619 
620  if (s)
621  fputs(s, stdout);
622  else
623  fputs(_("Press any key to continue..."), stdout);
624  fflush(stdout);
625 
626  char ch = '\0';
627  // Wait for a character. This might timeout, so loop.
628  while (read(fd, &ch, 1) == 0)
629  ; // do nothing
630 
631  // Change the tty settings to be non-blocking
632  term.c_cc[VMIN] = 0; // Returning with zero characters is acceptable
633  term.c_cc[VTIME] = 0; // Don't wait
634  tcsetattr(fd, TCSANOW, &term);
635 
636  char buf[64];
637  while (read(fd, buf, sizeof(buf)) > 0)
638  ; // Mop up any remaining chars
639 
640  tcsetattr(fd, TCSANOW, &old); // Restore the previous tty settings
641  close(fd);
642 
643  fputs("\r\n", stdout);
645  return (ch >= 0) ? ch : EOF;
646 }
#define _(a)
Definition: message.h:28
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_beep()

void mutt_beep ( bool  force)

Irritate the user.

Parameters
forceIf true, ignore the "$beep" config variable

Definition at line 98 of file curs_lib.c.

99 {
100  if (force || C_Beep)
101  beep();
102 }
WHERE bool C_Beep
Config: Make a noise when an error occurs.
Definition: mutt_globals.h:140
+ Here is the caller graph for this function:

◆ mutt_do_pager()

int mutt_do_pager ( const char *  banner,
const char *  tempfile,
PagerFlags  do_color,
struct Pager info 
)

Display some page-able text to the user.

Parameters
bannerMessage for status bar
tempfileFile to display
do_colorFlags, see PagerFlags
infoInfo about current mailbox (OPTIONAL)
Return values
0Success
-1Error

Definition at line 689 of file curs_lib.c.

691 {
692  struct Pager info2 = { 0 };
693  if (!info)
694  info = &info2;
695 
696  struct MuttWindow *dlg =
699 
700  struct MuttWindow *pager =
703  dlg->focus = pager;
704 
705  struct MuttWindow *pbar =
708 
709  if (C_StatusOnTop)
710  {
711  mutt_window_add_child(dlg, pbar);
712  mutt_window_add_child(dlg, pager);
713  }
714  else
715  {
716  mutt_window_add_child(dlg, pager);
717  mutt_window_add_child(dlg, pbar);
718  }
719 
721  dialog_push(dlg);
722 
723  info->win_ibar = NULL;
724  info->win_index = NULL;
725  info->win_pbar = pbar;
726  info->win_pager = pager;
727 
728  int rc;
729 
730  if (!C_Pager || mutt_str_equal(C_Pager, "builtin"))
731  rc = mutt_pager(banner, tempfile, do_color, info);
732  else
733  {
734  struct Buffer *cmd = mutt_buffer_pool_get();
735 
736  mutt_endwin();
738  if (mutt_system(mutt_b2s(cmd)) == -1)
739  {
740  mutt_error(_("Error running \"%s\""), mutt_b2s(cmd));
741  rc = -1;
742  }
743  else
744  rc = 0;
745  mutt_file_unlink(tempfile);
747  }
748 
749  dialog_pop();
751  mutt_window_free(&dlg);
752  return rc;
753 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
struct MuttWindow * win_index
Definition: pager.h:74
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
Pager Bar containing status info about the Pager.
Definition: mutt_window.h:98
Window uses all available vertical space.
Definition: mutt_window.h:35
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
A division of the screen.
Definition: mutt_window.h:115
An email being displayed.
Definition: pager.h:65
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:186
struct MuttWindow * focus
Focussed Window.
Definition: mutt_window.h:133
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: dialog.c:66
static int mutt_dlg_dopager_observer(struct NotifyCallback *nc)
Listen for config changes affecting the dopager menus - Implements observer_t.
Definition: curs_lib.c:651
Window has a fixed size.
Definition: mutt_window.h:44
struct MuttWindow * win_pager
Definition: pager.h:76
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:570
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:49
Pager Dialog, mutt_do_pager()
Definition: mutt_window.h:81
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
bool notify_observer_add(struct Notify *notify, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:153
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:575
Window containing paged free-form text.
Definition: mutt_window.h:97
WHERE char * C_Pager
Config: External command for viewing messages, or &#39;builtin&#39; to use NeoMutt&#39;s.
Definition: mutt_globals.h:100
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: mutt_globals.h:166
#define mutt_error(...)
Definition: logging.h:84
void dialog_pop(void)
Hide a Window from the user.
Definition: dialog.c:98
void mutt_buffer_file_expand_fmt_quote(struct Buffer *dest, const char *fmt, const char *src)
Replace s in a string with a filename.
Definition: file.c:1432
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:185
struct MuttWindow * win_ibar
Definition: pager.h:73
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:166
int mutt_pager(const char *banner, const char *fname, PagerFlags flags, struct Pager *extra)
Display a file, or help, in a window.
Definition: pager.c:2250
Window wants as much space as possible.
Definition: mutt_window.h:45
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
struct MuttWindow * win_pbar
Definition: pager.h:75
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_edit_file()

void mutt_edit_file ( const char *  editor,
const char *  file 
)

Let the user edit a file.

Parameters
editorUser's editor config
fileFile to edit

Definition at line 354 of file curs_lib.c.

355 {
356  struct Buffer *cmd = mutt_buffer_pool_get();
357 
358  mutt_endwin();
360  if (mutt_system(mutt_b2s(cmd)) != 0)
361  {
362  mutt_error(_("Error running \"%s\""), mutt_b2s(cmd));
363  }
364  /* the terminal may have been resized while the editor owned it */
366  keypad(stdscr, true);
367  clearok(stdscr, true);
368 
370 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:570
#define mutt_error(...)
Definition: logging.h:84
void mutt_buffer_file_expand_fmt_quote(struct Buffer *dest, const char *fmt, const char *src)
Replace s in a string with a filename.
Definition: file.c:1432
int const char * file
Definition: acutest.h:617
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_endwin()

void mutt_endwin ( void  )

Shutdown curses/slang.

Definition at line 570 of file curs_lib.c.

571 {
572  if (OptNoCurses)
573  return;
574 
575  int e = errno;
576 
577  /* at least in some situations (screen + xterm under SuSE11/12) endwin()
578  * doesn't properly flush the screen without an explicit call. */
579  mutt_refresh();
580  endwin();
581 
582  errno = e;
583 }
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:107
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_flushinp()

void mutt_flushinp ( void  )

Empty all the keyboard buffers.

Definition at line 918 of file curs_lib.c.

919 {
920  UngetCount = 0;
921  MacroBufferCount = 0;
922  flushinp();
923 }
static size_t MacroBufferCount
Definition: curs_lib.c:81
static size_t UngetCount
Definition: curs_lib.c:88
+ Here is the caller graph for this function:

◆ mutt_flush_macro_to_endcond()

void mutt_flush_macro_to_endcond ( void  )

Drop a macro from the input buffer.

All the macro text is deleted until an OP_END_COND command, or the buffer is empty.

Definition at line 889 of file curs_lib.c.

890 {
891  UngetCount = 0;
892  while (MacroBufferCount > 0)
893  {
894  if (MacroEvents[--MacroBufferCount].op == OP_END_COND)
895  return;
896  }
897 }
static struct KeyEvent * MacroEvents
Definition: curs_lib.c:83
static size_t MacroBufferCount
Definition: curs_lib.c:81
static size_t UngetCount
Definition: curs_lib.c:88
+ Here is the caller graph for this function:

◆ mutt_flush_unget_to_endcond()

void mutt_flush_unget_to_endcond ( void  )

Clear entries from UngetKeyEvents.

Normally, OP_END_COND should only be in the MacroEvent buffer. km_error_key() (ab)uses OP_END_COND as a barrier in the unget buffer, and calls this function to flush.

Definition at line 906 of file curs_lib.c.

907 {
908  while (UngetCount > 0)
909  {
910  if (UngetKeyEvents[--UngetCount].op == OP_END_COND)
911  return;
912  }
913 }
static size_t UngetCount
Definition: curs_lib.c:88
static struct KeyEvent * UngetKeyEvents
Definition: curs_lib.c:90
+ Here is the caller graph for this function:

◆ mutt_format_s()

void mutt_format_s ( char *  buf,
size_t  buflen,
const char *  prec,
const char *  s 
)

Format a simple string.

Parameters
[out]bufBuffer in which to save string
[in]buflenBuffer length
[in]precField precision, e.g. "-3.4"
[in]sString to format

Definition at line 1243 of file curs_lib.c.

1244 {
1245  mutt_format_s_x(buf, buflen, prec, s, false);
1246 }
void mutt_format_s_x(char *buf, size_t buflen, const char *prec, const char *s, bool arboreal)
Format a string like snprintf()
Definition: curs_lib.c:1206
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_format_s_tree()

void mutt_format_s_tree ( char *  buf,
size_t  buflen,
const char *  prec,
const char *  s 
)

Format a simple string with tree characters.

Parameters
[out]bufBuffer in which to save string
[in]buflenBuffer length
[in]precField precision, e.g. "-3.4"
[in]sString to format

Definition at line 1255 of file curs_lib.c.

1256 {
1257  mutt_format_s_x(buf, buflen, prec, s, true);
1258 }
void mutt_format_s_x(char *buf, size_t buflen, const char *prec, const char *s, bool arboreal)
Format a string like snprintf()
Definition: curs_lib.c:1206
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_format_s_x()

void mutt_format_s_x ( char *  buf,
size_t  buflen,
const char *  prec,
const char *  s,
bool  arboreal 
)

Format a string like snprintf()

Parameters
[out]bufBuffer in which to save string
[in]buflenBuffer length
[in]precField precision, e.g. "-3.4"
[in]sString to format
[in]arborealIf true, string contains graphical tree characters

This formats a string rather like:

  • snprintf(fmt, sizeof(fmt), "%%%ss", prec);
  • snprintf(buf, buflen, fmt, s); except that the numbers in the conversion specification refer to the number of character cells when printed.

Definition at line 1206 of file curs_lib.c.

1207 {
1208  enum FormatJustify justify = JUSTIFY_RIGHT;
1209  char *p = NULL;
1210  int min_width;
1211  int max_width = INT_MAX;
1212 
1213  if (*prec == '-')
1214  {
1215  prec++;
1216  justify = JUSTIFY_LEFT;
1217  }
1218  else if (*prec == '=')
1219  {
1220  prec++;
1221  justify = JUSTIFY_CENTER;
1222  }
1223  min_width = strtol(prec, &p, 10);
1224  if (*p == '.')
1225  {
1226  prec = p + 1;
1227  max_width = strtol(prec, &p, 10);
1228  if (p <= prec)
1229  max_width = INT_MAX;
1230  }
1231 
1232  mutt_simple_format(buf, buflen, min_width, max_width, justify, ' ', s,
1233  mutt_str_len(s), arboreal);
1234 }
Left justify the text.
Definition: curs_lib.h:47
FormatJustify
Alignment for mutt_simple_format()
Definition: curs_lib.h:45
Right justify the text.
Definition: curs_lib.h:49
Centre the text.
Definition: curs_lib.h:48
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
void mutt_simple_format(char *buf, size_t buflen, int min_width, int max_width, enum FormatJustify justify, char pad_char, const char *s, size_t n, bool arboreal)
Format a string, like snprintf()
Definition: curs_lib.c:1092
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_getch_timeout()

void mutt_getch_timeout ( int  delay)

Set the getch() timeout.

Parameters
delayTimeout delay in ms

delay is just like for timeout() or poll(): the number of milliseconds mutt_getch() should block for input.

  • delay == 0 means mutt_getch() is non-blocking.
  • delay < 0 means mutt_getch is blocking.

Definition at line 145 of file curs_lib.c.

146 {
147  MuttGetchTimeout = delay;
148  timeout(delay);
149 }
int MuttGetchTimeout
Timeout in ms for mutt_getch()
Definition: curs_lib.c:92
+ Here is the caller graph for this function:

◆ mutt_getch()

struct KeyEvent mutt_getch ( void  )

Read a character from the input buffer.

Return values
objKeyEvent to process

The priority for reading events is:

  1. UngetKeyEvents buffer
  2. MacroEvents buffer
  3. Keyboard

This function can return:

  • Error { -1, OP_NULL }
  • Timeout { -2, OP_NULL }

Definition at line 188 of file curs_lib.c.

189 {
190  int ch;
191  struct KeyEvent err = { -1, OP_NULL }, ret;
192  struct KeyEvent timeout = { -2, OP_NULL };
193 
194  if (UngetCount)
195  return UngetKeyEvents[--UngetCount];
196 
198  return MacroEvents[--MacroBufferCount];
199 
200  SigInt = 0;
201 
203 #ifdef KEY_RESIZE
204  /* ncurses 4.2 sends this when the screen is resized */
205  ch = KEY_RESIZE;
206  while (ch == KEY_RESIZE)
207 #endif /* KEY_RESIZE */
208 #ifdef USE_INOTIFY
209  ch = mutt_monitor_getch();
210 #else
211  ch = getch();
212 #endif /* USE_INOTIFY */
214 
215  if (SigInt)
216  {
217  mutt_query_exit();
218  return err;
219  }
220 
221  /* either timeout, a sigwinch (if timeout is set), or the terminal
222  * has been lost */
223  if (ch == ERR)
224  {
225  if (!isatty(0))
226  mutt_exit(1);
227 
228  return timeout;
229  }
230 
231  if ((ch & 0x80) && C_MetaKey)
232  {
233  /* send ALT-x as ESC-x */
234  ch &= ~0x80;
235  mutt_unget_event(ch, 0);
236  ret.ch = '\033'; // Escape
237  ret.op = 0;
238  return ret;
239  }
240 
241  ret.ch = ch;
242  ret.op = 0;
243  return (ch == AbortKey) ? err : ret;
244 }
static struct KeyEvent * MacroEvents
Definition: curs_lib.c:83
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:74
static size_t MacroBufferCount
Definition: curs_lib.c:81
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:833
int ch
raw key pressed
Definition: keymap.h:63
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:38
void mutt_query_exit(void)
Ask the user if they want to leave NeoMutt.
Definition: curs_lib.c:538
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
Definition: signal.c:238
static size_t UngetCount
Definition: curs_lib.c:88
static struct KeyEvent * UngetKeyEvents
Definition: curs_lib.c:90
static int mutt_monitor_getch(void)
Get a character and poll the filesystem monitor.
Definition: curs_lib.c:157
An event such as a keypress.
Definition: keymap.h:61
keycode_t AbortKey
code of key to abort prompts, normally Ctrl-G
Definition: keymap.c:147
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:137
bool C_MetaKey
Config: Interpret &#39;ALT-x&#39; as &#39;ESC-x&#39;.
Definition: curs_lib.c:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_field_full()

int mutt_get_field_full ( const char *  field,
char *  buf,
size_t  buflen,
CompletionFlags  complete,
bool  multiple,
char ***  files,
int *  numfiles 
)

Ask the user for a string.

Parameters
[in]fieldPrompt
[in]bufBuffer for the result
[in]buflenLength of buffer
[in]completeFlags, see CompletionFlags
[in]multipleAllow multiple selections
[out]filesList of files selected
[out]numfilesNumber of files selected
Return values
1Redraw the screen and call the function again
0Selection made
-1Aborted

Definition at line 309 of file curs_lib.c.

311 {
312  if (!buf)
313  return -1;
314 
315  struct Buffer tmp = {
316  .data = buf,
317  .dptr = buf + mutt_str_len(buf),
318  .dsize = buflen,
319  };
320  return mutt_buffer_get_field_full(field, &tmp, complete, multiple, files, numfiles);
321 }
String manipulation buffer.
Definition: buffer.h:33
int mutt_buffer_get_field_full(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:258
char * data
Pointer to data.
Definition: buffer.h:35
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
+ Here is the call graph for this function:

◆ mutt_get_field_unbuffered()

int mutt_get_field_unbuffered ( const char *  msg,
char *  buf,
size_t  buflen,
CompletionFlags  flags 
)

Ask the user for a string (ignoring macro buffer)

Parameters
msgPrompt
bufBuffer for the result
buflenLength of buffer
flagsFlags, see CompletionFlags
Return values
1Redraw the screen and call the function again
0Selection made
-1Aborted

Definition at line 333 of file curs_lib.c.

334 {
335  bool reset_ignoremacro = false;
336 
338  {
339  OptIgnoreMacroEvents = true;
340  reset_ignoremacro = true;
341  }
342  int rc = mutt_get_field(msg, buf, buflen, flags);
343  if (reset_ignoremacro)
344  OptIgnoreMacroEvents = false;
345 
346  return rc;
347 }
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:38
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
+ Here is the caller graph for this function:

◆ mutt_multi_choice()

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

Offer the user a multiple choice question.

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

Definition at line 932 of file curs_lib.c.

933 {
934  struct KeyEvent ch;
935  int choice;
936  bool redraw = true;
937  int prompt_lines = 1;
938 
939  bool opt_cols = ((Colors->defs[MT_COLOR_OPTIONS] != 0) &&
941 
942  while (true)
943  {
944  if (redraw || SigWinch)
945  {
946  redraw = false;
947  if (SigWinch)
948  {
949  SigWinch = 0;
951  clearok(stdscr, true);
953  }
954  if (MessageWindow->state.cols)
955  {
956  int width = mutt_strwidth(prompt) + 2; // + '?' + space
957  /* If we're going to colour the options,
958  * make an assumption about the modified prompt size. */
959  if (opt_cols)
960  width -= 2 * mutt_str_len(letters);
961 
962  prompt_lines =
963  (width + MessageWindow->state.cols - 1) / MessageWindow->state.cols;
964  prompt_lines = MAX(1, MIN(3, prompt_lines));
965  }
966  if (prompt_lines != MessageWindow->state.rows)
967  {
968  mutt_window_reflow_message_rows(prompt_lines);
970  }
971 
973 
974  if ((Colors->defs[MT_COLOR_OPTIONS] != 0) &&
976  {
977  char *cur = NULL;
978 
979  while ((cur = strchr(prompt, '(')))
980  {
981  // write the part between prompt and cur using MT_COLOR_PROMPT
983  mutt_window_addnstr(prompt, cur - prompt);
984 
985  if (isalnum(cur[1]) && (cur[2] == ')'))
986  {
987  // we have a single letter within parentheses
989  mutt_window_addch(cur[1]);
990  prompt = cur + 3;
991  }
992  else
993  {
994  // we have a parenthesis followed by something else
995  mutt_window_addch(cur[0]);
996  prompt = cur + 1;
997  }
998  }
999  }
1000 
1002  mutt_window_addstr(prompt);
1004 
1005  mutt_window_addch(' ');
1007  }
1008 
1009  mutt_refresh();
1010  /* SigWinch is not processed unless timeout is set */
1011  mutt_getch_timeout(30 * 1000);
1012  ch = mutt_getch();
1013  mutt_getch_timeout(-1);
1014  if (ch.ch == -2)
1015  continue;
1016  /* (ch.ch == 0) is technically possible. Treat the same as < 0 (abort) */
1017  if ((ch.ch <= 0) || CI_is_return(ch.ch))
1018  {
1019  choice = -1;
1020  break;
1021  }
1022  else
1023  {
1024  char *p = strchr(letters, ch.ch);
1025  if (p)
1026  {
1027  choice = p - letters + 1;
1028  break;
1029  }
1030  else if ((ch.ch <= '9') && (ch.ch > '0'))
1031  {
1032  choice = ch.ch - '0';
1033  if (choice <= mutt_str_len(letters))
1034  break;
1035  }
1036  }
1037  mutt_beep(false);
1038  }
1039  if (MessageWindow->state.rows == 1)
1040  {
1042  }
1043  else
1044  {
1047  }
1048  mutt_refresh();
1049  return choice;
1050 }
#define CI_is_return(ch)
Definition: mutt_curses.h:71
#define MIN(a, b)
Definition: memory.h:31
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
int * defs
Array of all fixed colours, see enum ColorId.
Definition: color.h:131
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:254
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:101
int ch
raw key pressed
Definition: keymap.h:63
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:392
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:98
#define MAX(a, b)
Definition: memory.h:30
int mutt_window_addnstr(const char *str, int num)
Write a partial string to a Window.
Definition: mutt_window.c:514
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:232
Plain text.
Definition: color.h:77
void mutt_window_reflow_message_rows(int mw_rows)
Resize the Message Window.
Definition: mutt_window.c:469
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:107
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1358
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
An event such as a keypress.
Definition: keymap.h:61
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:188
Definition: color.h:129
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:502
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:145
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:532
Options in prompt.
Definition: color.h:78
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:75
Question/user input.
Definition: color.h:80
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_need_hard_redraw()

void mutt_need_hard_redraw ( void  )

Force a hard refresh.

Make sure that the next refresh does a full refresh. This could be optimized by not doing it at all if DISPLAY is set as this might indicate that a GUI based pinentry was used. Having an option to customize this is of course the NeoMutt way.

Definition at line 129 of file curs_lib.c.

130 {
131  keypad(stdscr, true);
132  clearok(stdscr, true);
134 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_paddstr()

void mutt_paddstr ( int  n,
const char *  s 
)

Display a string on screen, padded if necessary.

Parameters
nFinal width of field
sString to display

Definition at line 1265 of file curs_lib.c.

1266 {
1267  wchar_t wc;
1268  size_t k;
1269  size_t len = mutt_str_len(s);
1270  mbstate_t mbstate;
1271 
1272  memset(&mbstate, 0, sizeof(mbstate));
1273  for (; len && (k = mbrtowc(&wc, s, len, &mbstate)); s += k, len -= k)
1274  {
1275  if ((k == (size_t)(-1)) || (k == (size_t)(-2)))
1276  {
1277  if (k == (size_t)(-1))
1278  memset(&mbstate, 0, sizeof(mbstate));
1279  k = (k == (size_t)(-1)) ? 1 : len;
1280  wc = ReplacementChar;
1281  }
1282  if (!IsWPrint(wc))
1283  wc = '?';
1284  const int w = wcwidth(wc);
1285  if (w >= 0)
1286  {
1287  if (w > n)
1288  break;
1289  mutt_window_addnstr((char *) s, k);
1290  n -= w;
1291  }
1292  }
1293  while (n-- > 0)
1294  mutt_window_addch(' ');
1295 }
#define IsWPrint(wc)
Definition: mbyte.h:40
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:58
int mutt_window_addnstr(const char *str, int num)
Write a partial string to a Window.
Definition: mutt_window.c:514
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:502
int n
Definition: acutest.h:492
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_perror_debug()

void mutt_perror_debug ( const char *  s)

Show the user an 'errno' message.

Parameters
sAdditional text to show

Definition at line 589 of file curs_lib.c.

590 {
591  char *p = strerror(errno);
592 
593  mutt_debug(LL_DEBUG1, "%s: %s (errno = %d)\n", s, p ? p : "unknown error", errno);
594  mutt_error("%s: %s (errno = %d)", s, p ? p : _("unknown error"), errno);
595 }
#define _(a)
Definition: message.h:28
Log at debug level 1.
Definition: logging.h:40
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81

◆ mutt_push_macro_event()

void mutt_push_macro_event ( int  ch,
int  op 
)

Add the character/operation to the macro buffer.

Parameters
chCharacter to add
opOperation to add

Adds the ch/op to the macro buffer. This should be used for macros, push, and exec commands only.

Definition at line 870 of file curs_lib.c.

871 {
872  struct KeyEvent tmp;
873 
874  tmp.ch = ch;
875  tmp.op = op;
876 
878  mutt_mem_realloc(&MacroEvents, (MacroBufferLen += 128) * sizeof(struct KeyEvent));
879 
880  MacroEvents[MacroBufferCount++] = tmp;
881 }
static struct KeyEvent * MacroEvents
Definition: curs_lib.c:83
static size_t MacroBufferCount
Definition: curs_lib.c:81
int op
function op
Definition: keymap.h:64
int ch
raw key pressed
Definition: keymap.h:63
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
An event such as a keypress.
Definition: keymap.h:61
static size_t MacroBufferLen
Definition: curs_lib.c:82
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_query_exit()

void mutt_query_exit ( void  )

Ask the user if they want to leave NeoMutt.

This function is called when the user presses the abort key.

Definition at line 538 of file curs_lib.c.

539 {
540  mutt_flushinp();
542  if (C_Timeout)
543  mutt_getch_timeout(-1); /* restore blocking operation */
544  if (mutt_yesorno(_("Exit NeoMutt?"), MUTT_YES) == MUTT_YES)
545  {
546  mutt_exit(1);
547  }
550  SigInt = 0;
551 }
WHERE short C_Timeout
Config: Time to wait for user input in menus.
Definition: mutt_globals.h:116
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:74
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:918
#define _(a)
Definition: message.h:28
void mutt_curses_set_cursor(enum MuttCursorState state)
Set the cursor state.
Definition: mutt_curses.c:76
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:378
Display a normal cursor.
Definition: mutt_curses.h:81
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
Restore the previous cursor state.
Definition: mutt_curses.h:79
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:137
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:145
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_refresh()

void mutt_refresh ( void  )

Force a refresh of the screen.

Definition at line 107 of file curs_lib.c.

108 {
109  /* don't refresh when we are waiting for a child. */
110  if (OptKeepQuiet)
111  return;
112 
113  /* don't refresh in the middle of macros unless necessary */
115  return;
116 
117  /* else */
118  refresh();
119 }
static size_t MacroBufferCount
Definition: curs_lib.c:81
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:38
WHERE bool OptForceRefresh
(pseudo) refresh even during macros
Definition: options.h:37
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program ...
Definition: options.h:39
+ Here is the caller graph for this function:

◆ mutt_show_error()

void mutt_show_error ( void  )

Show the user an error message.

Definition at line 556 of file curs_lib.c.

557 {
559  return;
560 
565 }
Informational message.
Definition: color.h:75
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:254
WHERE char ErrorBuf[256]
Copy of the last error message.
Definition: mutt_globals.h:45
int mutt_window_mvaddstr(struct MuttWindow *win, int col, int row, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:406
Plain text.
Definition: color.h:77
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
Error message.
Definition: color.h:70
WHERE bool OptMsgErr
(pseudo) used by mutt_error/mutt_message
Definition: options.h:41
WHERE bool ErrorBufMessage
true if the last message was an error
Definition: mutt_globals.h:44
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program ...
Definition: options.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_simple_format()

void mutt_simple_format ( char *  buf,
size_t  buflen,
int  min_width,
int  max_width,
enum FormatJustify  justify,
char  pad_char,
const char *  s,
size_t  n,
bool  arboreal 
)

Format a string, like snprintf()

Parameters
[out]bufBuffer in which to save string
[in]buflenBuffer length
[in]min_widthMinimum width
[in]max_widthMaximum width
[in]justifyJustification, e.g. JUSTIFY_RIGHT
[in]pad_charPadding character
[in]sString to format
[in]nNumber of bytes of string to format
[in]arborealIf true, string contains graphical tree characters

This formats a string, a bit like snprintf(buf, buflen, "%-*.*s", min_width, max_width, s), except that the widths refer to the number of character cells when printed.

Definition at line 1092 of file curs_lib.c.

1095 {
1096  wchar_t wc;
1097  int w;
1098  size_t k, k2;
1099  char scratch[MB_LEN_MAX];
1100  mbstate_t mbstate1, mbstate2;
1101  bool escaped = false;
1102 
1103  memset(&mbstate1, 0, sizeof(mbstate1));
1104  memset(&mbstate2, 0, sizeof(mbstate2));
1105  buflen--;
1106  char *p = buf;
1107  for (; n && (k = mbrtowc(&wc, s, n, &mbstate1)); s += k, n -= k)
1108  {
1109  if ((k == (size_t)(-1)) || (k == (size_t)(-2)))
1110  {
1111  if ((k == (size_t)(-1)) && (errno == EILSEQ))
1112  memset(&mbstate1, 0, sizeof(mbstate1));
1113 
1114  k = (k == (size_t)(-1)) ? 1 : n;
1115  wc = ReplacementChar;
1116  }
1117  if (escaped)
1118  {
1119  escaped = false;
1120  w = 0;
1121  }
1122  else if (arboreal && (wc == MUTT_SPECIAL_INDEX))
1123  {
1124  escaped = true;
1125  w = 0;
1126  }
1127  else if (arboreal && (wc < MUTT_TREE_MAX))
1128  {
1129  w = 1; /* hack */
1130  }
1131  else
1132  {
1133 #ifdef HAVE_ISWBLANK
1134  if (iswblank(wc))
1135  wc = ' ';
1136  else
1137 #endif
1138  if (!IsWPrint(wc))
1139  wc = '?';
1140  w = wcwidth(wc);
1141  }
1142  if (w >= 0)
1143  {
1144  if ((w > max_width) || ((k2 = wcrtomb(scratch, wc, &mbstate2)) > buflen))
1145  continue;
1146  min_width -= w;
1147  max_width -= w;
1148  strncpy(p, scratch, k2);
1149  p += k2;
1150  buflen -= k2;
1151  }
1152  }
1153  w = ((int) buflen < min_width) ? buflen : min_width;
1154  if (w <= 0)
1155  *p = '\0';
1156  else if (justify == JUSTIFY_RIGHT) /* right justify */
1157  {
1158  p[w] = '\0';
1159  while (--p >= buf)
1160  p[w] = *p;
1161  while (--w >= 0)
1162  buf[w] = pad_char;
1163  }
1164  else if (justify == JUSTIFY_CENTER) /* center */
1165  {
1166  char *savedp = p;
1167  int half = (w + 1) / 2; /* half of cushion space */
1168 
1169  p[w] = '\0';
1170 
1171  /* move str to center of buffer */
1172  while (--p >= buf)
1173  p[half] = *p;
1174 
1175  /* fill rhs */
1176  p = savedp + half;
1177  while (--w >= half)
1178  *p++ = pad_char;
1179 
1180  /* fill lhs */
1181  while (half--)
1182  buf[half] = pad_char;
1183  }
1184  else /* left justify */
1185  {
1186  while (--w >= 0)
1187  *p++ = pad_char;
1188  *p = '\0';
1189  }
1190 }
#define IsWPrint(wc)
Definition: mbyte.h:40
Right justify the text.
Definition: curs_lib.h:49
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:58
Centre the text.
Definition: curs_lib.h:48
Colour indicator.
Definition: mutt_menu.h:74
int n
Definition: acutest.h:492
#define EILSEQ
Definition: charset.c:49
+ Here is the caller graph for this function:

◆ mutt_strwidth()

int mutt_strwidth ( const char *  s)

Measure a string's width in screen cells.

Parameters
sString to be measured
Return values
numScreen cells string would use

Definition at line 1358 of file curs_lib.c.

1359 {
1360  if (!s)
1361  return 0;
1362  return mutt_strnwidth(s, mutt_str_len(s));
1363 }
int mutt_strnwidth(const char *s, size_t n)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1371
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_strnwidth()

int mutt_strnwidth ( const char *  s,
size_t  n 
)

Measure a string's width in screen cells.

Parameters
sString to be measured
nLength of string to be measured
Return values
numScreen cells string would use

Definition at line 1371 of file curs_lib.c.

1372 {
1373  if (!s)
1374  return 0;
1375 
1376  wchar_t wc;
1377  int w;
1378  size_t k;
1379  mbstate_t mbstate;
1380 
1381  memset(&mbstate, 0, sizeof(mbstate));
1382  for (w = 0; n && (k = mbrtowc(&wc, s, n, &mbstate)); s += k, n -= k)
1383  {
1384  if (*s == MUTT_SPECIAL_INDEX)
1385  {
1386  s += 2; /* skip the index coloring sequence */
1387  k = 0;
1388  continue;
1389  }
1390 
1391  if ((k == (size_t)(-1)) || (k == (size_t)(-2)))
1392  {
1393  if (k == (size_t)(-1))
1394  memset(&mbstate, 0, sizeof(mbstate));
1395  k = (k == (size_t)(-1)) ? 1 : n;
1396  wc = ReplacementChar;
1397  }
1398  if (!IsWPrint(wc))
1399  wc = '?';
1400  w += wcwidth(wc);
1401  }
1402  return w;
1403 }
#define IsWPrint(wc)
Definition: mbyte.h:40
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:58
Colour indicator.
Definition: mutt_menu.h:74
int n
Definition: acutest.h:492
+ Here is the caller graph for this function:

◆ mutt_unget_event()

void mutt_unget_event ( int  ch,
int  op 
)

Return a keystroke to the input buffer.

Parameters
chKey press
opOperation, e.g. OP_DELETE

This puts events into the UngetKeyEvents buffer

Definition at line 833 of file curs_lib.c.

834 {
835  struct KeyEvent tmp;
836 
837  tmp.ch = ch;
838  tmp.op = op;
839 
840  if (UngetCount >= UngetLen)
841  mutt_mem_realloc(&UngetKeyEvents, (UngetLen += 16) * sizeof(struct KeyEvent));
842 
843  UngetKeyEvents[UngetCount++] = tmp;
844 }
int op
function op
Definition: keymap.h:64
int ch
raw key pressed
Definition: keymap.h:63
static size_t UngetCount
Definition: curs_lib.c:88
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
static struct KeyEvent * UngetKeyEvents
Definition: curs_lib.c:90
An event such as a keypress.
Definition: keymap.h:61
static size_t UngetLen
Definition: curs_lib.c:89
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_unget_string()

void mutt_unget_string ( const char *  s)

Return a string to the input buffer.

Parameters
sString to return

This puts events into the UngetKeyEvents buffer

Definition at line 852 of file curs_lib.c.

853 {
854  const char *p = s + mutt_str_len(s) - 1;
855 
856  while (p >= s)
857  {
858  mutt_unget_event((unsigned char) *p--, 0);
859  }
860 }
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:833
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_wstr_trunc()

size_t mutt_wstr_trunc ( const char *  src,
size_t  maxlen,
size_t  maxwid,
size_t *  width 
)

Work out how to truncate a widechar string.

Parameters
[in]srcString to measure
[in]maxlenMaximum length of string in bytes
[in]maxwidMaximum width in screen columns
[out]widthSave the truncated screen column width
Return values
numBytes to use

See how many bytes to copy from string so it's at most maxlen bytes long and maxwid columns wide

Definition at line 1308 of file curs_lib.c.

1309 {
1310  wchar_t wc;
1311  size_t n, w = 0, l = 0, cl;
1312  int cw;
1313  mbstate_t mbstate;
1314 
1315  if (!src)
1316  goto out;
1317 
1318  n = mutt_str_len(src);
1319 
1320  memset(&mbstate, 0, sizeof(mbstate));
1321  for (w = 0; n && (cl = mbrtowc(&wc, src, n, &mbstate)); src += cl, n -= cl)
1322  {
1323  if ((cl == (size_t)(-1)) || (cl == (size_t)(-2)))
1324  {
1325  if (cl == (size_t)(-1))
1326  memset(&mbstate, 0, sizeof(mbstate));
1327  cl = (cl == (size_t)(-1)) ? 1 : n;
1328  wc = ReplacementChar;
1329  }
1330  cw = wcwidth(wc);
1331  /* hack because MUTT_TREE symbols aren't turned into characters
1332  * until rendered by print_enriched_string() */
1333  if ((cw < 0) && (src[0] == MUTT_SPECIAL_INDEX))
1334  {
1335  cl = 2; /* skip the index coloring sequence */
1336  cw = 0;
1337  }
1338  else if ((cw < 0) && (cl == 1) && (src[0] != '\0') && (src[0] < MUTT_TREE_MAX))
1339  cw = 1;
1340  else if (cw < 0)
1341  cw = 0; /* unprintable wchar */
1342  if ((cl + l > maxlen) || (cw + w > maxwid))
1343  break;
1344  l += cl;
1345  w += cw;
1346  }
1347 out:
1348  if (width)
1349  *width = w;
1350  return l;
1351 }
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:58
Colour indicator.
Definition: mutt_menu.h:74
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
int n
Definition: acutest.h:492
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_yesorno()

enum QuadOption mutt_yesorno ( const char *  msg,
enum QuadOption  def 
)

Ask the user a Yes/No question.

Parameters
msgPrompt
defDefault answer, MUTT_YES or MUTT_NO (see QuadOption)
Return values
numSelection made, see QuadOption

Definition at line 378 of file curs_lib.c.

379 {
380  struct KeyEvent ch;
381  char *yes = _("yes");
382  char *no = _("no");
383  char *answer_string = NULL;
384  int answer_string_wid, msg_wid;
385  size_t trunc_msg_len;
386  bool redraw = true;
387  int prompt_lines = 1;
388 
389  char *expr = NULL;
390  regex_t reyes;
391  regex_t reno;
392  char answer[2];
393 
394  answer[1] = '\0';
395 
396  bool reyes_ok = (expr = nl_langinfo(YESEXPR)) && (expr[0] == '^') &&
397  (REG_COMP(&reyes, expr, REG_NOSUB) == 0);
398  bool reno_ok = (expr = nl_langinfo(NOEXPR)) && (expr[0] == '^') &&
399  (REG_COMP(&reno, expr, REG_NOSUB) == 0);
400 
401  /* In order to prevent the default answer to the question to wrapped
402  * around the screen in the even the question is wider than the screen,
403  * ensure there is enough room for the answer and truncate the question
404  * to fit. */
405  mutt_str_asprintf(&answer_string, " ([%s]/%s): ", (def == MUTT_YES) ? yes : no,
406  (def == MUTT_YES) ? no : yes);
407  answer_string_wid = mutt_strwidth(answer_string);
408  msg_wid = mutt_strwidth(msg);
409 
410  while (true)
411  {
412  if (redraw || SigWinch)
413  {
414  redraw = false;
415  if (SigWinch)
416  {
417  SigWinch = 0;
419  clearok(stdscr, true);
421  }
422  if (MessageWindow->state.cols)
423  {
424  prompt_lines = (msg_wid + answer_string_wid + MessageWindow->state.cols - 1) /
426  prompt_lines = MAX(1, MIN(3, prompt_lines));
427  }
428  if (prompt_lines != MessageWindow->state.rows)
429  {
430  mutt_window_reflow_message_rows(prompt_lines);
432  }
433 
434  /* maxlen here is sort of arbitrary, so pick a reasonable upper bound */
435  trunc_msg_len = mutt_wstr_trunc(
436  msg, (size_t) 4 * prompt_lines * MessageWindow->state.cols,
437  ((size_t) prompt_lines * MessageWindow->state.cols) - answer_string_wid, NULL);
438 
441  mutt_window_addnstr(msg, trunc_msg_len);
442  mutt_window_addstr(answer_string);
445  }
446 
447  mutt_refresh();
448  /* SigWinch is not processed unless timeout is set */
449  mutt_getch_timeout(30 * 1000);
450  ch = mutt_getch();
451  mutt_getch_timeout(-1);
452  if (ch.ch == -2)
453  continue;
454  if (CI_is_return(ch.ch))
455  break;
456  if (ch.ch < 0)
457  {
458  def = MUTT_ABORT;
459  break;
460  }
461 
462  answer[0] = ch.ch;
463  if (reyes_ok ? (regexec(&reyes, answer, 0, 0, 0) == 0) : (tolower(ch.ch) == 'y'))
464  {
465  def = MUTT_YES;
466  break;
467  }
468  else if (reno_ok ? (regexec(&reno, answer, 0, 0, 0) == 0) : (tolower(ch.ch) == 'n'))
469  {
470  def = MUTT_NO;
471  break;
472  }
473  else
474  {
475  mutt_beep(false);
476  }
477  }
478 
479  FREE(&answer_string);
480 
481  if (reyes_ok)
482  regfree(&reyes);
483  if (reno_ok)
484  regfree(&reno);
485 
486  if (MessageWindow->state.rows == 1)
487  {
489  }
490  else
491  {
494  }
495 
496  if (def == MUTT_ABORT)
497  {
498  /* when the users cancels with ^G, clear the message stored with
499  * mutt_message() so it isn't displayed when the screen is refreshed. */
501  }
502  else
503  {
504  mutt_window_addstr((char *) ((def == MUTT_YES) ? yes : no));
505  mutt_refresh();
506  }
507  return def;
508 }
#define CI_is_return(ch)
Definition: mutt_curses.h:71
#define MIN(a, b)
Definition: memory.h:31
User aborted the question (with Ctrl-G)
Definition: quad.h:38
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:254
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:101
#define _(a)
Definition: message.h:28
int ch
raw key pressed
Definition: keymap.h:63
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:392
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:98
#define MAX(a, b)
Definition: memory.h:30
int mutt_window_addnstr(const char *str, int num)
Write a partial string to a Window.
Definition: mutt_window.c:514
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:232
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:53
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
Plain text.
Definition: color.h:77
void mutt_window_reflow_message_rows(int mw_rows)
Resize the Message Window.
Definition: mutt_window.c:469
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:107
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1358
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
size_t mutt_wstr_trunc(const char *src, size_t maxlen, size_t maxwid, size_t *width)
Work out how to truncate a widechar string.
Definition: curs_lib.c:1308
An event such as a keypress.
Definition: keymap.h:61
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:188
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:145
#define FREE(x)
Definition: memory.h:40
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:532
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1100
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:75
Question/user input.
Definition: color.h:80
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_quadoption()

enum QuadOption query_quadoption ( enum QuadOption  opt,
const char *  prompt 
)

Ask the user a quad-question.

Parameters
optOption to use
promptMessage to show to the user
Return values
QuadOptionResult, e.g. MUTT_NO

Definition at line 516 of file curs_lib.c.

517 {
518  switch (opt)
519  {
520  case MUTT_YES:
521  case MUTT_NO:
522  return opt;
523 
524  default:
525  opt = mutt_yesorno(prompt, (opt == MUTT_ASKYES) ? MUTT_YES : MUTT_NO);
527  return opt;
528  }
529 
530  /* not reached */
531 }
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
Ask the user, defaulting to &#39;Yes&#39;.
Definition: quad.h:42
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:378
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:232
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_get_field_full()

int mutt_buffer_get_field_full ( const char *  field,
struct Buffer buf,
CompletionFlags  complete,
bool  multiple,
char ***  files,
int *  numfiles 
)

Ask the user for a string.

Parameters
[in]fieldPrompt
[in]bufBuffer for the result
[in]completeFlags, see CompletionFlags
[in]multipleAllow multiple selections
[out]filesList of files selected
[out]numfilesNumber of files selected
Return values
1Redraw the screen and call the function again
0Selection made
-1Aborted

Definition at line 258 of file curs_lib.c.

260 {
261  int ret;
262  int col;
263 
264  struct EnterState *es = mutt_enter_state_new();
265 
266  do
267  {
268  if (SigWinch)
269  {
270  SigWinch = 0;
272  clearok(stdscr, true);
274  }
277  mutt_window_addstr(field);
279  mutt_refresh();
281  ret = mutt_enter_string_full(buf->data, buf->dsize, col, complete, multiple,
282  files, numfiles, es);
283  } while (ret == 1);
284 
285  if (ret == 0)
287  else
288  mutt_buffer_reset(buf);
289 
292 
293  return ret;
294 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:101
int mutt_enter_string_full(char *buf, size_t buflen, int col, CompletionFlags flags, bool multiple, char ***files, int *numfiles, struct EnterState *state)
Ask the user for a string.
Definition: enter.c:178
size_t dsize
Length of data.
Definition: buffer.h:37
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:232
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
Plain text.
Definition: color.h:77
Keep our place when entering a string.
Definition: enter_state.h:32
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:107
void mutt_window_get_coords(struct MuttWindow *win, int *col, int *row)
Get the cursor position in the Window.
Definition: mutt_window.c:332
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
void mutt_enter_state_free(struct EnterState **ptr)
Free an EnterState.
Definition: enter.c:840
char * data
Pointer to data.
Definition: buffer.h:35
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:532
struct EnterState * mutt_enter_state_new(void)
Create a new EnterState.
Definition: enter.c:127
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:75
Question/user input.
Definition: color.h:80
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_enter_fname_full()

int mutt_buffer_enter_fname_full ( const char *  prompt,
struct Buffer fname,
bool  mailbox,
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
[out]filesList of files selected
[out]numfilesNumber of files selected
[in]flagsFlags, see SelectFileFlags
Return values
0Success
-1Error

Definition at line 767 of file curs_lib.c.

770 {
771  struct KeyEvent ch;
772 
774  mutt_window_mvaddstr(MessageWindow, 0, 0, prompt);
775  mutt_window_addstr(_(" ('?' for list): "));
777  if (!mutt_buffer_is_empty(fname))
780  mutt_refresh();
781 
782  do
783  {
784  ch = mutt_getch();
785  } while (ch.ch == -2);
786  if (ch.ch < 0)
787  {
789  return -1;
790  }
791  else if (ch.ch == '?')
792  {
793  mutt_refresh();
794  mutt_buffer_reset(fname);
795 
796  if (flags == MUTT_SEL_NO_FLAGS)
797  flags = MUTT_SEL_FOLDER;
798  if (multiple)
799  flags |= MUTT_SEL_MULTI;
800  if (mailbox)
801  flags |= MUTT_SEL_MAILBOX;
802  mutt_buffer_select_file(fname, flags, files, numfiles);
803  }
804  else
805  {
806  char *pc = mutt_mem_malloc(mutt_str_len(prompt) + 3);
807 
808  sprintf(pc, "%s: ", prompt);
809  if (ch.op == OP_NULL)
810  mutt_unget_event(ch.ch, 0);
811  else
812  mutt_unget_event(0, ch.op);
813 
814  mutt_buffer_alloc(fname, 1024);
815  if (mutt_buffer_get_field_full(pc, fname, (mailbox ? MUTT_EFILE : MUTT_FILE) | MUTT_CLEAR,
816  multiple, files, numfiles) != 0)
817  {
818  mutt_buffer_reset(fname);
819  }
820  FREE(&pc);
821  }
822 
823  return 0;
824 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:62
void mutt_buffer_select_file(struct Buffer *file, SelectFileFlags flags, char ***files, int *numfiles)
Let the user select a file.
Definition: browser.c:1158
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:254
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:833
#define _(a)
Definition: message.h:28
int ch
raw key pressed
Definition: keymap.h:63
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition: browser.h:40
int mutt_window_mvaddstr(struct MuttWindow *win, int col, int row, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:406
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: browser.h:43
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:232
Plain text.
Definition: color.h:77
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:107
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
int mutt_buffer_get_field_full(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:258
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
An event such as a keypress.
Definition: keymap.h:61
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:188
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:42
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition: browser.h:41
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
#define MUTT_EFILE
Do file completion, plus incoming folders.
Definition: mutt.h:59
#define FREE(x)
Definition: memory.h:40
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:532
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
Question/user input.
Definition: color.h:80
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_MetaKey

bool C_MetaKey

interpret ALT-x as ESC-x

interpret ALT-x as ESC-x

Definition at line 71 of file curs_lib.c.

◆ MuttGetchTimeout

int MuttGetchTimeout

Timeout in ms for mutt_getch()

Definition at line 92 of file curs_lib.c.