NeoMutt  2021-02-05-329-g9e03b7
Teaching an old dog new tricks
DOXYGEN
curs_lib.h File Reference

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

#include <stdbool.h>
#include <wchar.h>
#include "config/lib.h"
#include "mutt.h"
#include "browser.h"
#include "keymap.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.

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_buffer_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. More...
 
int mutt_buffer_get_field (const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
 Ask the user for a string. 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 (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...
 

Variables

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.

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 41 of file curs_lib.h.

42 {
43  JUSTIFY_LEFT = -1,
44  JUSTIFY_CENTER = 0,
45  JUSTIFY_RIGHT = 1,
46 };
Left justify the text.
Definition: curs_lib.h:43
Right justify the text.
Definition: curs_lib.h:45
Centre the text.
Definition: curs_lib.h:44

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 949 of file curs_lib.c.

950 {
951  char buf[MB_LEN_MAX * 2];
952  mbstate_t mbstate;
953  size_t n1, n2;
954 
955  memset(&mbstate, 0, sizeof(mbstate));
956  if (((n1 = wcrtomb(buf, wc, &mbstate)) == (size_t) (-1)) ||
957  ((n2 = wcrtomb(buf + n1, 0, &mbstate)) == (size_t) (-1)))
958  {
959  return -1; /* ERR */
960  }
961  else
962  {
963  return mutt_window_addstr(buf);
964  }
965 }
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:519
+ 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 601 of file curs_lib.c.

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

93 {
94  const bool c_beep = cs_subset_bool(NeoMutt->sub, "beep");
95  if (force || c_beep)
96  beep();
97 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:71
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_enter_fname()

int mutt_buffer_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

Definition at line 659 of file curs_lib.c.

662 {
663  struct KeyEvent ch;
664 
666  mutt_window_mvaddstr(MessageWindow, 0, 0, prompt);
667  mutt_window_addstr(_(" ('?' for list): "));
669  if (!mutt_buffer_is_empty(fname))
672  mutt_refresh();
673 
674  do
675  {
676  ch = mutt_getch();
677  } while (ch.ch == -2);
678  if (ch.ch < 0)
679  {
681  return -1;
682  }
683  else if (ch.ch == '?')
684  {
685  mutt_refresh();
686  mutt_buffer_reset(fname);
687 
688  if (flags == MUTT_SEL_NO_FLAGS)
689  flags = MUTT_SEL_FOLDER;
690  if (multiple)
691  flags |= MUTT_SEL_MULTI;
692  if (mailbox)
693  flags |= MUTT_SEL_MAILBOX;
694  mutt_buffer_select_file(fname, flags, m, files, numfiles);
695  }
696  else
697  {
698  char *pc = mutt_mem_malloc(mutt_str_len(prompt) + 3);
699 
700  sprintf(pc, "%s: ", prompt);
701  if (ch.op == OP_NULL)
702  mutt_unget_event(ch.ch, 0);
703  else
704  mutt_unget_event(0, ch.op);
705 
706  mutt_buffer_alloc(fname, 1024);
707  if (mutt_buffer_get_field(pc, fname, (mailbox ? MUTT_EFILE : MUTT_FILE) | MUTT_CLEAR,
708  multiple, m, files, numfiles) != 0)
709  {
710  mutt_buffer_reset(fname);
711  }
712  FREE(&pc);
713  }
714 
715  return 0;
716 }
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:58
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:255
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:56
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:242
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:725
#define _(a)
Definition: message.h:28
int ch
raw key pressed
Definition: keymap.h:65
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition: browser.h:36
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:396
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: browser.h:39
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:230
Plain text.
Definition: color.h:58
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:102
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:45
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:63
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:183
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:38
#define MUTT_FILE
Do file completion.
Definition: mutt.h:54
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition: browser.h:37
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
#define MUTT_EFILE
Do file completion, plus incoming folders.
Definition: mutt.h:55
void mutt_buffer_select_file(struct Buffer *file, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
Let the user select a file.
Definition: browser.c:1161
#define FREE(x)
Definition: memory.h:40
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:519
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
Question/user input.
Definition: color.h:61
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:

◆ mutt_buffer_get_field()

int mutt_buffer_get_field ( const char *  field,
struct Buffer buf,
CompletionFlags  complete,
bool  multiple,
struct Mailbox m,
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
[in]mMailbox
[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 255 of file curs_lib.c.

257 {
258  int ret;
259  int col;
260 
261  struct EnterState *es = mutt_enter_state_new();
262 
263  do
264  {
265  if (SigWinch)
266  {
267  SigWinch = 0;
269  clearok(stdscr, true);
270  window_redraw(RootWindow, true);
271  }
274  mutt_window_addstr(field);
276  mutt_refresh();
278  ret = mutt_enter_string_full(buf->data, buf->dsize, col, complete, multiple,
279  m, files, numfiles, es);
280  } while (ret == 1);
281 
282  if (ret == 0)
284  else
285  mutt_buffer_reset(buf);
286 
289 
290  return ret;
291 }
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:56
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:101
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:230
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:58
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:102
void mutt_window_get_coords(struct MuttWindow *win, int *col, int *row)
Get the cursor position in the Window.
Definition: mutt_window.c:321
int mutt_enter_string_full(char *buf, size_t buflen, int col, CompletionFlags flags, bool multiple, struct Mailbox *m, char ***files, int *numfiles, struct EnterState *state)
Ask the user for a string.
Definition: enter.c:148
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:45
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: mutt_window.c:43
void mutt_enter_state_free(struct EnterState **ptr)
Free an EnterState.
Definition: enter.c:812
char * data
Pointer to data.
Definition: buffer.h:35
void window_redraw(struct MuttWindow *win, bool force)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:744
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:519
struct EnterState * mutt_enter_state_new(void)
Create a new EnterState.
Definition: enter.c:128
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:68
Question/user input.
Definition: color.h:61
+ 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 351 of file curs_lib.c.

352 {
353  struct Buffer *cmd = mutt_buffer_pool_get();
354 
355  mutt_endwin();
356  mutt_buffer_file_expand_fmt_quote(cmd, editor, file);
357  if (mutt_system(mutt_buffer_string(cmd)) != 0)
358  {
359  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
360  }
361  /* the terminal may have been resized while the editor owned it */
363  keypad(stdscr, true);
364  clearok(stdscr, true);
365 
367 }
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
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:568
#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:1435
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 568 of file curs_lib.c.

569 {
570  if (OptNoCurses)
571  return;
572 
573  int e = errno;
574 
575  /* at least in some situations (screen + xterm under SuSE11/12) endwin()
576  * doesn't properly flush the screen without an explicit call. */
577  mutt_refresh();
578  endwin();
579 
580  errno = e;
581 }
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:102
+ 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 810 of file curs_lib.c.

811 {
812  UngetCount = 0;
813  MacroBufferCount = 0;
814  flushinp();
815 }
static size_t MacroBufferCount
Definition: curs_lib.c:75
static size_t UngetCount
Definition: curs_lib.c:82
+ 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 781 of file curs_lib.c.

782 {
783  UngetCount = 0;
784  while (MacroBufferCount > 0)
785  {
786  if (MacroEvents[--MacroBufferCount].op == OP_END_COND)
787  return;
788  }
789 }
static struct KeyEvent * MacroEvents
Definition: curs_lib.c:77
static size_t MacroBufferCount
Definition: curs_lib.c:75
static size_t UngetCount
Definition: curs_lib.c:82
+ 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 798 of file curs_lib.c.

799 {
800  while (UngetCount > 0)
801  {
802  if (UngetKeyEvents[--UngetCount].op == OP_END_COND)
803  return;
804  }
805 }
static size_t UngetCount
Definition: curs_lib.c:82
static struct KeyEvent * UngetKeyEvents
Definition: curs_lib.c:84
+ 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 1134 of file curs_lib.c.

1135 {
1136  mutt_format_s_x(buf, buflen, prec, s, false);
1137 }
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:1097
+ 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 1146 of file curs_lib.c.

1147 {
1148  mutt_format_s_x(buf, buflen, prec, s, true);
1149 }
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:1097
+ 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 1097 of file curs_lib.c.

1098 {
1099  enum FormatJustify justify = JUSTIFY_RIGHT;
1100  char *p = NULL;
1101  int min_width;
1102  int max_width = INT_MAX;
1103 
1104  if (*prec == '-')
1105  {
1106  prec++;
1107  justify = JUSTIFY_LEFT;
1108  }
1109  else if (*prec == '=')
1110  {
1111  prec++;
1112  justify = JUSTIFY_CENTER;
1113  }
1114  min_width = strtol(prec, &p, 10);
1115  if (*p == '.')
1116  {
1117  prec = p + 1;
1118  max_width = strtol(prec, &p, 10);
1119  if (p <= prec)
1120  max_width = INT_MAX;
1121  }
1122 
1123  mutt_simple_format(buf, buflen, min_width, max_width, justify, ' ', s,
1124  mutt_str_len(s), arboreal);
1125 }
Left justify the text.
Definition: curs_lib.h:43
FormatJustify
Alignment for mutt_simple_format()
Definition: curs_lib.h:41
Right justify the text.
Definition: curs_lib.h:45
Centre the text.
Definition: curs_lib.h:44
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
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:983
+ 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 140 of file curs_lib.c.

141 {
142  MuttGetchTimeout = delay;
143  timeout(delay);
144 }
int MuttGetchTimeout
Timeout in ms for mutt_getch()
Definition: curs_lib.c:86
+ 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 183 of file curs_lib.c.

184 {
185  int ch;
186  struct KeyEvent err = { -1, OP_NULL }, ret;
187  struct KeyEvent timeout = { -2, OP_NULL };
188 
189  if (UngetCount)
190  return UngetKeyEvents[--UngetCount];
191 
193  return MacroEvents[--MacroBufferCount];
194 
195  SigInt = 0;
196 
198 #ifdef KEY_RESIZE
199  /* ncurses 4.2 sends this when the screen is resized */
200  ch = KEY_RESIZE;
201  while (ch == KEY_RESIZE)
202 #endif /* KEY_RESIZE */
203 #ifdef USE_INOTIFY
204  ch = mutt_monitor_getch();
205 #else
206  ch = getch();
207 #endif /* USE_INOTIFY */
209 
210  if (SigInt)
211  {
212  mutt_query_exit();
213  return err;
214  }
215 
216  /* either timeout, a sigwinch (if timeout is set), or the terminal
217  * has been lost */
218  if (ch == ERR)
219  {
220  if (!isatty(0))
221  mutt_exit(1);
222 
223  return timeout;
224  }
225 
226  const bool c_meta_key = cs_subset_bool(NeoMutt->sub, "meta_key");
227  if ((ch & 0x80) && c_meta_key)
228  {
229  /* send ALT-x as ESC-x */
230  ch &= ~0x80;
231  mutt_unget_event(ch, 0);
232  ret.ch = '\033'; // Escape
233  ret.op = 0;
234  return ret;
235  }
236 
237  ret.ch = ch;
238  ret.op = 0;
239  return (ch == AbortKey) ? err : ret;
240 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:71
static struct KeyEvent * MacroEvents
Definition: curs_lib.c:77
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:67
static size_t MacroBufferCount
Definition: curs_lib.c:75
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:725
int ch
raw key pressed
Definition: keymap.h:65
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:535
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
Definition: signal.c:238
static size_t UngetCount
Definition: curs_lib.c:82
static struct KeyEvent * UngetKeyEvents
Definition: curs_lib.c:84
static int mutt_monitor_getch(void)
Get a character and poll the filesystem monitor.
Definition: curs_lib.c:152
An event such as a keypress.
Definition: keymap.h:63
keycode_t AbortKey
code of key to abort prompts, normally Ctrl-G
Definition: keymap.c:150
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:141
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_field()

int mutt_get_field ( 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 306 of file curs_lib.c.

308 {
309  if (!buf)
310  return -1;
311 
312  struct Buffer tmp = {
313  .data = buf,
314  .dptr = buf + mutt_str_len(buf),
315  .dsize = buflen,
316  };
317  return mutt_buffer_get_field(field, &tmp, complete, multiple, NULL, files, numfiles);
318 }
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:255
String manipulation buffer.
Definition: buffer.h:33
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:631
+ Here is the call graph for this function:
+ Here is the caller 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 330 of file curs_lib.c.

331 {
332  bool reset_ignoremacro = false;
333 
335  {
336  OptIgnoreMacroEvents = true;
337  reset_ignoremacro = true;
338  }
339  int rc = mutt_get_field(msg, buf, buflen, flags, false, NULL, NULL);
340  if (reset_ignoremacro)
341  OptIgnoreMacroEvents = false;
342 
343  return rc;
344 }
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:306
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:38
+ Here is the call graph for this function:
+ 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 824 of file curs_lib.c.

825 {
826  struct KeyEvent ch;
827  int choice;
828  bool redraw = true;
829  int prompt_lines = 1;
830 
831  const bool opt_cols = ((mutt_color(MT_COLOR_OPTIONS) != 0) &&
833 
834  while (true)
835  {
836  if (redraw || SigWinch)
837  {
838  redraw = false;
839  if (SigWinch)
840  {
841  SigWinch = 0;
843  clearok(stdscr, true);
844  window_redraw(RootWindow, true);
845  }
846  if (MessageWindow->state.cols)
847  {
848  int width = mutt_strwidth(prompt) + 2; // + '?' + space
849  /* If we're going to colour the options,
850  * make an assumption about the modified prompt size. */
851  if (opt_cols)
852  width -= 2 * mutt_str_len(letters);
853 
854  prompt_lines =
855  (width + MessageWindow->state.cols - 1) / MessageWindow->state.cols;
856  prompt_lines = MAX(1, MIN(3, prompt_lines));
857  }
858  if (prompt_lines != MessageWindow->state.rows)
859  {
860  mutt_window_reflow_message_rows(prompt_lines);
861  window_redraw(RootWindow, true);
862  }
863 
865 
866  if (opt_cols)
867  {
868  char *cur = NULL;
869 
870  while ((cur = strchr(prompt, '(')))
871  {
872  // write the part between prompt and cur using MT_COLOR_PROMPT
874  mutt_window_addnstr(prompt, cur - prompt);
875 
876  if (isalnum(cur[1]) && (cur[2] == ')'))
877  {
878  // we have a single letter within parentheses
880  mutt_window_addch(cur[1]);
881  prompt = cur + 3;
882  }
883  else
884  {
885  // we have a parenthesis followed by something else
886  mutt_window_addch(cur[0]);
887  prompt = cur + 1;
888  }
889  }
890  }
891 
893  mutt_window_addstr(prompt);
895 
896  mutt_window_addch(' ');
898  }
899 
900  mutt_refresh();
901  /* SigWinch is not processed unless timeout is set */
902  mutt_getch_timeout(30 * 1000);
903  ch = mutt_getch();
904  mutt_getch_timeout(-1);
905  if (ch.ch == -2)
906  continue;
907  /* (ch.ch == 0) is technically possible. Treat the same as < 0 (abort) */
908  if ((ch.ch <= 0) || CI_is_return(ch.ch))
909  {
910  choice = -1;
911  break;
912  }
913  else
914  {
915  char *p = strchr(letters, ch.ch);
916  if (p)
917  {
918  choice = p - letters + 1;
919  break;
920  }
921  else if ((ch.ch <= '9') && (ch.ch > '0'))
922  {
923  choice = ch.ch - '0';
924  if (choice <= mutt_str_len(letters))
925  break;
926  }
927  }
928  mutt_beep(false);
929  }
930  if (MessageWindow->state.rows == 1)
931  {
933  }
934  else
935  {
937  window_redraw(RootWindow, true);
938  }
939  mutt_refresh();
940  return choice;
941 }
#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:56
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:242
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:65
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:382
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:92
#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:501
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:230
Plain text.
Definition: color.h:58
void mutt_window_reflow_message_rows(int mw_rows)
Resize the Message Window.
Definition: mutt_window.c:456
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:102
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:122
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:45
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: mutt_window.c:43
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1249
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:59
An event such as a keypress.
Definition: keymap.h:63
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:183
int mutt_color(enum ColorId id)
Return the color of an object.
Definition: color.c:1393
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:489
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:140
void window_redraw(struct MuttWindow *win, bool force)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:744
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:519
Options in prompt.
Definition: color.h:59
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:68
Question/user input.
Definition: color.h:61
+ 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 124 of file curs_lib.c.

125 {
126  keypad(stdscr, true);
127  clearok(stdscr, true);
128  window_redraw(RootWindow, true);
129 }
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: mutt_window.c:43
void window_redraw(struct MuttWindow *win, bool force)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:744
+ 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 1156 of file curs_lib.c.

1157 {
1158  wchar_t wc;
1159  size_t k;
1160  size_t len = mutt_str_len(s);
1161  mbstate_t mbstate;
1162 
1163  memset(&mbstate, 0, sizeof(mbstate));
1164  for (; len && (k = mbrtowc(&wc, s, len, &mbstate)); s += k, len -= k)
1165  {
1166  if ((k == (size_t) (-1)) || (k == (size_t) (-2)))
1167  {
1168  if (k == (size_t) (-1))
1169  memset(&mbstate, 0, sizeof(mbstate));
1170  k = (k == (size_t) (-1)) ? 1 : len;
1171  wc = ReplacementChar;
1172  }
1173  if (!IsWPrint(wc))
1174  wc = '?';
1175  const int w = wcwidth(wc);
1176  if (w >= 0)
1177  {
1178  if (w > n)
1179  break;
1180  mutt_window_addnstr((char *) s, k);
1181  n -= w;
1182  }
1183  }
1184  while (n-- > 0)
1185  mutt_window_addch(' ');
1186 }
#define IsWPrint(wc)
Definition: mbyte.h:39
int mutt_window_addnstr(const char *str, int num)
Write a partial string to a Window.
Definition: mutt_window.c:501
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:57
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:489
+ 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 587 of file curs_lib.c.

588 {
589  char *p = strerror(errno);
590 
591  mutt_debug(LL_DEBUG1, "%s: %s (errno = %d)\n", s, p ? p : "unknown error", errno);
592  mutt_error("%s: %s (errno = %d)", s, p ? p : _("unknown error"), errno);
593 }
#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 762 of file curs_lib.c.

763 {
764  struct KeyEvent tmp;
765 
766  tmp.ch = ch;
767  tmp.op = op;
768 
770  mutt_mem_realloc(&MacroEvents, (MacroBufferLen += 128) * sizeof(struct KeyEvent));
771 
772  MacroEvents[MacroBufferCount++] = tmp;
773 }
static struct KeyEvent * MacroEvents
Definition: curs_lib.c:77
static size_t MacroBufferCount
Definition: curs_lib.c:75
int op
function op
Definition: keymap.h:66
int ch
raw key pressed
Definition: keymap.h:65
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:63
static size_t MacroBufferLen
Definition: curs_lib.c:76
+ 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 535 of file curs_lib.c.

536 {
537  mutt_flushinp();
539  const short c_timeout = cs_subset_number(NeoMutt->sub, "timeout");
540  if (c_timeout)
541  mutt_getch_timeout(-1); /* restore blocking operation */
542  if (mutt_yesorno(_("Exit NeoMutt?"), MUTT_YES) == MUTT_YES)
543  {
544  mutt_exit(1);
545  }
548  SigInt = 0;
549 }
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:67
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:810
#define _(a)
Definition: message.h:28
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:159
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mutt_curses_set_cursor(enum MuttCursorState state)
Set the cursor state.
Definition: mutt_curses.c:71
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:375
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:112
Restore the previous cursor state.
Definition: mutt_curses.h:79
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:141
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:140
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
+ 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 102 of file curs_lib.c.

103 {
104  /* don't refresh when we are waiting for a child. */
105  if (OptKeepQuiet)
106  return;
107 
108  /* don't refresh in the middle of macros unless necessary */
110  return;
111 
112  /* else */
113  refresh();
114 }
static size_t MacroBufferCount
Definition: curs_lib.c:75
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 554 of file curs_lib.c.

555 {
557  return;
558 
563 }
Informational message.
Definition: color.h:56
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:56
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:242
WHERE char ErrorBuf[256]
Copy of the last error message.
Definition: mutt_globals.h:43
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:396
Plain text.
Definition: color.h:58
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:45
Error message.
Definition: color.h:51
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:42
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 983 of file curs_lib.c.

986 {
987  wchar_t wc;
988  int w;
989  size_t k, k2;
990  char scratch[MB_LEN_MAX];
991  mbstate_t mbstate1, mbstate2;
992  bool escaped = false;
993 
994  memset(&mbstate1, 0, sizeof(mbstate1));
995  memset(&mbstate2, 0, sizeof(mbstate2));
996  buflen--;
997  char *p = buf;
998  for (; n && (k = mbrtowc(&wc, s, n, &mbstate1)); s += k, n -= k)
999  {
1000  if ((k == (size_t) (-1)) || (k == (size_t) (-2)))
1001  {
1002  if ((k == (size_t) (-1)) && (errno == EILSEQ))
1003  memset(&mbstate1, 0, sizeof(mbstate1));
1004 
1005  k = (k == (size_t) (-1)) ? 1 : n;
1006  wc = ReplacementChar;
1007  }
1008  if (escaped)
1009  {
1010  escaped = false;
1011  w = 0;
1012  }
1013  else if (arboreal && (wc == MUTT_SPECIAL_INDEX))
1014  {
1015  escaped = true;
1016  w = 0;
1017  }
1018  else if (arboreal && (wc < MUTT_TREE_MAX))
1019  {
1020  w = 1; /* hack */
1021  }
1022  else
1023  {
1024 #ifdef HAVE_ISWBLANK
1025  if (iswblank(wc))
1026  wc = ' ';
1027  else
1028 #endif
1029  if (!IsWPrint(wc))
1030  wc = '?';
1031  w = wcwidth(wc);
1032  }
1033  if (w >= 0)
1034  {
1035  if ((w > max_width) || ((k2 = wcrtomb(scratch, wc, &mbstate2)) > buflen))
1036  continue;
1037  min_width -= w;
1038  max_width -= w;
1039  strncpy(p, scratch, k2);
1040  p += k2;
1041  buflen -= k2;
1042  }
1043  }
1044  w = ((int) buflen < min_width) ? buflen : min_width;
1045  if (w <= 0)
1046  *p = '\0';
1047  else if (justify == JUSTIFY_RIGHT) /* right justify */
1048  {
1049  p[w] = '\0';
1050  while (--p >= buf)
1051  p[w] = *p;
1052  while (--w >= 0)
1053  buf[w] = pad_char;
1054  }
1055  else if (justify == JUSTIFY_CENTER) /* center */
1056  {
1057  char *savedp = p;
1058  int half = (w + 1) / 2; /* half of cushion space */
1059 
1060  p[w] = '\0';
1061 
1062  /* move str to center of buffer */
1063  while (--p >= buf)
1064  p[half] = *p;
1065 
1066  /* fill rhs */
1067  p = savedp + half;
1068  while (--w >= half)
1069  *p++ = pad_char;
1070 
1071  /* fill lhs */
1072  while (half--)
1073  buf[half] = pad_char;
1074  }
1075  else /* left justify */
1076  {
1077  while (--w >= 0)
1078  *p++ = pad_char;
1079  *p = '\0';
1080  }
1081 }
#define IsWPrint(wc)
Definition: mbyte.h:39
Right justify the text.
Definition: curs_lib.h:45
Centre the text.
Definition: curs_lib.h:44
#define EILSEQ
Definition: charset.c:51
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:57
Colour indicator.
Definition: mutt_thread.h:57
+ 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 1249 of file curs_lib.c.

1250 {
1251  if (!s)
1252  return 0;
1253  return mutt_strnwidth(s, mutt_str_len(s));
1254 }
int mutt_strnwidth(const char *s, size_t n)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1262
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
+ 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 1262 of file curs_lib.c.

1263 {
1264  if (!s)
1265  return 0;
1266 
1267  wchar_t wc;
1268  int w;
1269  size_t k;
1270  mbstate_t mbstate;
1271 
1272  memset(&mbstate, 0, sizeof(mbstate));
1273  for (w = 0; n && (k = mbrtowc(&wc, s, n, &mbstate)); s += k, n -= k)
1274  {
1275  if (*s == MUTT_SPECIAL_INDEX)
1276  {
1277  s += 2; /* skip the index coloring sequence */
1278  k = 0;
1279  continue;
1280  }
1281 
1282  if ((k == (size_t) (-1)) || (k == (size_t) (-2)))
1283  {
1284  if (k == (size_t) (-1))
1285  memset(&mbstate, 0, sizeof(mbstate));
1286  k = (k == (size_t) (-1)) ? 1 : n;
1287  wc = ReplacementChar;
1288  }
1289  if (!IsWPrint(wc))
1290  wc = '?';
1291  w += wcwidth(wc);
1292  }
1293  return w;
1294 }
#define IsWPrint(wc)
Definition: mbyte.h:39
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:57
Colour indicator.
Definition: mutt_thread.h:57
+ 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 725 of file curs_lib.c.

726 {
727  struct KeyEvent tmp;
728 
729  tmp.ch = ch;
730  tmp.op = op;
731 
732  if (UngetCount >= UngetLen)
733  mutt_mem_realloc(&UngetKeyEvents, (UngetLen += 16) * sizeof(struct KeyEvent));
734 
735  UngetKeyEvents[UngetCount++] = tmp;
736 }
int op
function op
Definition: keymap.h:66
int ch
raw key pressed
Definition: keymap.h:65
static size_t UngetCount
Definition: curs_lib.c:82
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:84
An event such as a keypress.
Definition: keymap.h:63
static size_t UngetLen
Definition: curs_lib.c:83
+ 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 744 of file curs_lib.c.

745 {
746  const char *p = s + mutt_str_len(s) - 1;
747 
748  while (p >= s)
749  {
750  mutt_unget_event((unsigned char) *p--, 0);
751  }
752 }
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:725
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
+ 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 1199 of file curs_lib.c.

1200 {
1201  wchar_t wc;
1202  size_t n, w = 0, l = 0, cl;
1203  int cw;
1204  mbstate_t mbstate;
1205 
1206  if (!src)
1207  goto out;
1208 
1209  n = mutt_str_len(src);
1210 
1211  memset(&mbstate, 0, sizeof(mbstate));
1212  for (w = 0; n && (cl = mbrtowc(&wc, src, n, &mbstate)); src += cl, n -= cl)
1213  {
1214  if ((cl == (size_t) (-1)) || (cl == (size_t) (-2)))
1215  {
1216  if (cl == (size_t) (-1))
1217  memset(&mbstate, 0, sizeof(mbstate));
1218  cl = (cl == (size_t) (-1)) ? 1 : n;
1219  wc = ReplacementChar;
1220  }
1221  cw = wcwidth(wc);
1222  /* hack because MUTT_TREE symbols aren't turned into characters
1223  * until rendered by print_enriched_string() */
1224  if ((cw < 0) && (src[0] == MUTT_SPECIAL_INDEX))
1225  {
1226  cl = 2; /* skip the index coloring sequence */
1227  cw = 0;
1228  }
1229  else if ((cw < 0) && (cl == 1) && (src[0] != '\0') && (src[0] < MUTT_TREE_MAX))
1230  cw = 1;
1231  else if (cw < 0)
1232  cw = 0; /* unprintable wchar */
1233  if ((cl + l > maxlen) || (cw + w > maxwid))
1234  break;
1235  l += cl;
1236  w += cw;
1237  }
1238 out:
1239  if (width)
1240  *width = w;
1241  return l;
1242 }
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:57
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
Colour indicator.
Definition: mutt_thread.h:57
+ 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 375 of file curs_lib.c.

376 {
377  struct KeyEvent ch;
378  char *yes = _("yes");
379  char *no = _("no");
380  char *answer_string = NULL;
381  int answer_string_wid, msg_wid;
382  size_t trunc_msg_len;
383  bool redraw = true;
384  int prompt_lines = 1;
385 
386  char *expr = NULL;
387  regex_t reyes;
388  regex_t reno;
389  char answer[2];
390 
391  answer[1] = '\0';
392 
393  bool reyes_ok = (expr = nl_langinfo(YESEXPR)) && (expr[0] == '^') &&
394  (REG_COMP(&reyes, expr, REG_NOSUB) == 0);
395  bool reno_ok = (expr = nl_langinfo(NOEXPR)) && (expr[0] == '^') &&
396  (REG_COMP(&reno, expr, REG_NOSUB) == 0);
397 
398  /* In order to prevent the default answer to the question to wrapped
399  * around the screen in the even the question is wider than the screen,
400  * ensure there is enough room for the answer and truncate the question
401  * to fit. */
402  mutt_str_asprintf(&answer_string, " ([%s]/%s): ", (def == MUTT_YES) ? yes : no,
403  (def == MUTT_YES) ? no : yes);
404  answer_string_wid = mutt_strwidth(answer_string);
405  msg_wid = mutt_strwidth(msg);
406 
407  while (true)
408  {
409  if (redraw || SigWinch)
410  {
411  redraw = false;
412  if (SigWinch)
413  {
414  SigWinch = 0;
416  clearok(stdscr, true);
417  window_redraw(RootWindow, true);
418  }
419  if (MessageWindow->state.cols)
420  {
421  prompt_lines = (msg_wid + answer_string_wid + MessageWindow->state.cols - 1) /
423  prompt_lines = MAX(1, MIN(3, prompt_lines));
424  }
425  if (prompt_lines != MessageWindow->state.rows)
426  {
427  mutt_window_reflow_message_rows(prompt_lines);
428  window_redraw(RootWindow, true);
429  }
430 
431  /* maxlen here is sort of arbitrary, so pick a reasonable upper bound */
432  trunc_msg_len = mutt_wstr_trunc(
433  msg, (size_t) 4 * prompt_lines * MessageWindow->state.cols,
434  ((size_t) prompt_lines * MessageWindow->state.cols) - answer_string_wid, NULL);
435 
438  mutt_window_addnstr(msg, trunc_msg_len);
439  mutt_window_addstr(answer_string);
442  }
443 
444  mutt_refresh();
445  /* SigWinch is not processed unless timeout is set */
446  mutt_getch_timeout(30 * 1000);
447  ch = mutt_getch();
448  mutt_getch_timeout(-1);
449  if (ch.ch == -2)
450  continue;
451  if (CI_is_return(ch.ch))
452  break;
453  if (ch.ch < 0)
454  {
455  def = MUTT_ABORT;
456  break;
457  }
458 
459  answer[0] = ch.ch;
460  if (reyes_ok ? (regexec(&reyes, answer, 0, 0, 0) == 0) : (tolower(ch.ch) == 'y'))
461  {
462  def = MUTT_YES;
463  break;
464  }
465  else if (reno_ok ? (regexec(&reno, answer, 0, 0, 0) == 0) : (tolower(ch.ch) == 'n'))
466  {
467  def = MUTT_NO;
468  break;
469  }
470  else
471  {
472  mutt_beep(false);
473  }
474  }
475 
476  FREE(&answer_string);
477 
478  if (reyes_ok)
479  regfree(&reyes);
480  if (reno_ok)
481  regfree(&reno);
482 
483  if (MessageWindow->state.rows == 1)
484  {
486  }
487  else
488  {
490  window_redraw(RootWindow, true);
491  }
492 
493  if (def == MUTT_ABORT)
494  {
495  /* when the users cancels with ^G, clear the message stored with
496  * mutt_message() so it isn't displayed when the screen is refreshed. */
498  }
499  else
500  {
501  mutt_window_addstr((char *) ((def == MUTT_YES) ? yes : no));
502  mutt_refresh();
503  }
504  return def;
505 }
#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:56
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:242
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
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:54
int ch
raw key pressed
Definition: keymap.h:65
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:382
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:92
#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:501
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:230
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
User aborted the question (with Ctrl-G)
Definition: quad.h:37
Plain text.
Definition: color.h:58
void mutt_window_reflow_message_rows(int mw_rows)
Resize the Message Window.
Definition: mutt_window.c:456
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:102
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:122
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:45
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: mutt_window.c:43
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1249
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:59
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:1199
An event such as a keypress.
Definition: keymap.h:63
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:183
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:140
#define FREE(x)
Definition: memory.h:40
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
void window_redraw(struct MuttWindow *win, bool force)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:744
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:519
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1095
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:68
Question/user input.
Definition: color.h:61
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
+ 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 513 of file curs_lib.c.

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

Variable Documentation

◆ MuttGetchTimeout

int MuttGetchTimeout

Timeout in ms for mutt_getch()

Definition at line 86 of file curs_lib.c.