NeoMutt  2019-11-11
Teaching an old dog new tricks
DOXYGEN
curs_lib.c File Reference

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

#include "config.h"
#include <stddef.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <langinfo.h>
#include <limits.h>
#include <regex.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <wchar.h>
#include "mutt/mutt.h"
#include "config/lib.h"
#include "mutt.h"
#include "curs_lib.h"
#include "browser.h"
#include "color.h"
#include "enter_state.h"
#include "globals.h"
#include "mutt_curses.h"
#include "mutt_logging.h"
#include "mutt_menu.h"
#include "mutt_window.h"
#include "opcodes.h"
#include "options.h"
#include "pager.h"
#include "protos.h"
+ Include dependency graph for curs_lib.c:

Go to the source code of this file.

Functions

void mutt_beep (bool force)
 Irritate the user. More...
 
void mutt_refresh (void)
 Force a refresh of the screen. More...
 
void mutt_need_hard_redraw (void)
 Force a hard refresh. 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_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_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...
 
void mutt_edit_file (const char *editor, const char *file)
 Let the user edit a file. More...
 
enum QuadOption mutt_yesorno (const char *msg, enum QuadOption def)
 Ask the user a Yes/No question. More...
 
void mutt_query_exit (void)
 Ask the user if they want to leave NeoMutt. More...
 
void mutt_show_error (void)
 Show the user an error message. More...
 
void mutt_endwin (void)
 Shutdown curses/slang. More...
 
void mutt_perror_debug (const char *s)
 Show the user an 'errno' message. More...
 
int mutt_any_key_to_continue (const char *s)
 Prompt the user to 'press any key' and wait. 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...
 
int mutt_enter_fname_full (const char *prompt, char *buf, size_t buflen, bool mailbox, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
 Ask the user to select a file. 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...
 
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...
 
void mutt_push_macro_event (int ch, int op)
 Add the character/operation to the macro buffer. 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_flushinp (void)
 Empty all the keyboard buffers. More...
 
int mutt_multi_choice (const char *prompt, const char *letters)
 Offer the user a multiple choice question. More...
 
int mutt_addwch (wchar_t wc)
 addwch would be provided by an up-to-date curses library 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...
 
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_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_paddstr (int n, const char *s)
 Display a string on screen, padded if necessary. 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...
 
int mutt_strwidth (const char *s)
 Measure a string's width in screen cells. More...
 

Variables

bool C_MetaKey
 Config: Interpret 'ALT-x' as 'ESC-x'. More...
 
static size_t MacroBufferCount = 0
 
static size_t MacroBufferLen = 0
 
static struct KeyEventMacroEvents
 
static size_t UngetCount = 0
 
static size_t UngetLen = 0
 
static struct KeyEventUngetKeyEvents
 
int MuttGetchTimeout = -1
 Timeout in ms for mutt_getch() More...
 

Detailed Description

GUI miscellaneous curses (window drawing) routines.

Authors
  • Michael R. Elkins
  • g10 Code GmbH

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.c.

Function Documentation

◆ mutt_beep()

void mutt_beep ( bool  force)

Irritate the user.

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

Definition at line 96 of file curs_lib.c.

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

◆ mutt_refresh()

void mutt_refresh ( void  )

Force a refresh of the screen.

Definition at line 105 of file curs_lib.c.

106 {
107  /* don't refresh when we are waiting for a child. */
108  if (OptKeepQuiet)
109  return;
110 
111  /* don't refresh in the middle of macros unless necessary */
113  return;
114 
115  /* else */
116  refresh();
117 }
static size_t MacroBufferCount
Definition: curs_lib.c:79
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:36
WHERE bool OptForceRefresh
(pseudo) refresh even during macros
Definition: options.h:35
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program...
Definition: options.h:37
+ 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 127 of file curs_lib.c.

128 {
129  keypad(stdscr, true);
132 }
void mutt_window_clear_screen(void)
Clear the entire screen.
Definition: mutt_window.c:437
+ 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 143 of file curs_lib.c.

144 {
145  MuttGetchTimeout = delay;
146  timeout(delay);
147 }
int MuttGetchTimeout
Timeout in ms for mutt_getch()
Definition: curs_lib.c:90
+ Here is the call graph for this function:
+ 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 186 of file curs_lib.c.

187 {
188  int ch;
189  struct KeyEvent err = { -1, OP_NULL }, ret;
190  struct KeyEvent timeout = { -2, OP_NULL };
191 
192  if (UngetCount)
193  return UngetKeyEvents[--UngetCount];
194 
196  return MacroEvents[--MacroBufferCount];
197 
198  SigInt = 0;
199 
201 #ifdef KEY_RESIZE
202  /* ncurses 4.2 sends this when the screen is resized */
203  ch = KEY_RESIZE;
204  while (ch == KEY_RESIZE)
205 #endif /* KEY_RESIZE */
206 #ifdef USE_INOTIFY
207  ch = mutt_monitor_getch();
208 #else
209  ch = getch();
210 #endif /* USE_INOTIFY */
212 
213  if (SigInt)
214  {
215  mutt_query_exit();
216  return err;
217  }
218 
219  /* either timeout, a sigwinch (if timeout is set), or the terminal
220  * has been lost */
221  if (ch == ERR)
222  {
223  if (!isatty(0))
224  mutt_exit(1);
225 
226  return timeout;
227  }
228 
229  if ((ch & 0x80) && C_MetaKey)
230  {
231  /* send ALT-x as ESC-x */
232  ch &= ~0x80;
233  mutt_unget_event(ch, 0);
234  ret.ch = '\033'; // Escape
235  ret.op = 0;
236  return ret;
237  }
238 
239  ret.ch = ch;
240  ret.op = 0;
241  return (ch == ctrl('G')) ? err : ret;
242 }
static struct KeyEvent * MacroEvents
Definition: curs_lib.c:81
static size_t MacroBufferCount
Definition: curs_lib.c:79
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: globals.h:81
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:763
int ch
raw key pressed
Definition: keymap.h:62
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:36
void mutt_query_exit(void)
Ask the user if they want to leave NeoMutt.
Definition: curs_lib.c:512
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
Definition: signal.c:238
static size_t UngetCount
Definition: curs_lib.c:86
#define ctrl(ch)
Definition: mutt_curses.h:67
static struct KeyEvent * UngetKeyEvents
Definition: curs_lib.c:88
An event such as a keypress.
Definition: keymap.h:60
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:210
bool C_MetaKey
Config: Interpret &#39;ALT-x&#39; as &#39;ESC-x&#39;.
Definition: curs_lib.c:69
+ 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 256 of file curs_lib.c.

258 {
259  int ret;
260  int col;
261 
262  struct EnterState *es = mutt_enter_state_new();
263 
264  do
265  {
266  if (SigWinch)
267  {
268  SigWinch = 0;
272  }
275  mutt_window_addstr(field);
277  mutt_refresh();
279  ret = mutt_enter_string_full(buf->data, buf->dsize, col, complete, multiple,
280  files, numfiles, es);
281  } while (ret == 1);
282 
283  if (ret == 0)
285  else
286  mutt_buffer_reset(buf);
287 
290 
291  return ret;
292 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
void mutt_window_get_coords(struct MuttWindow *win, int *row, int *col)
Get the cursor position in the Window.
Definition: mutt_window.c:162
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:49
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:100
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_clear_screen(void)
Clear the entire screen.
Definition: mutt_window.c:437
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:95
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.h:82
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:78
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:105
void mutt_enter_state_free(struct EnterState **ptr)
Free an EnterState.
Definition: enter.c:822
char * data
Pointer to data.
Definition: buffer.h:35
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:42
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:396
struct EnterState * mutt_enter_state_new(void)
Create a new EnterState.
Definition: enter.c:127
Question/user input.
Definition: color.h:81
+ 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 307 of file curs_lib.c.

309 {
310  struct Buffer *tmp = mutt_buffer_pool_get();
311 
312  mutt_buffer_addstr(tmp, buf);
313  int rc = mutt_buffer_get_field_full(field, tmp, complete, multiple, files, numfiles);
314  mutt_str_strfcpy(buf, mutt_b2s(tmp), buflen);
315 
317  return rc;
318 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
String manipulation buffer.
Definition: buffer.h:33
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
#define mutt_b2s(buf)
Definition: buffer.h:41
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:256
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
+ 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 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);
340  if (reset_ignoremacro)
341  OptIgnoreMacroEvents = false;
342 
343  return rc;
344 }
WHERE bool OptIgnoreMacroEvents
(pseudo) don&#39;t process macro/push/exec events while set
Definition: options.h:36
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
+ 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_b2s(cmd)) != 0)
358  {
359  mutt_error(_("Error running \"%s\""), mutt_b2s(cmd));
360  }
361  /* the terminal may have been resized while the editor owned it */
363  keypad(stdscr, true);
365 
367 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:100
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
void mutt_window_clear_screen(void)
Clear the entire screen.
Definition: mutt_window.c:437
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:544
#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:1419
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_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;
418  }
419  if (MuttMessageWindow->cols)
420  {
421  prompt_lines = (msg_wid + answer_string_wid + MuttMessageWindow->cols - 1) /
423  prompt_lines = MAX(1, MIN(3, prompt_lines));
424  }
425  if (prompt_lines != MuttMessageWindow->rows)
426  {
427  mutt_window_reflow_message_rows(prompt_lines);
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 * MuttMessageWindow->cols,
434  ((size_t) prompt_lines * MuttMessageWindow->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 (MuttMessageWindow->rows == 1)
484  {
486  }
487  else
488  {
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:72
#define MIN(a, b)
Definition: memory.h:31
User aborted the question (with Ctrl-G)
Definition: quad.h:37
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:49
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:117
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:100
#define _(a)
Definition: message.h:28
int ch
raw key pressed
Definition: keymap.h:62
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:96
#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:378
void mutt_window_clear_screen(void)
Clear the entire screen.
Definition: mutt_window.c:437
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:95
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:52
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.h:82
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:115
Plain text.
Definition: color.h:78
void mutt_window_reflow_message_rows(int mw_rows)
Resize the Message Window.
Definition: mutt_window.c:320
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:105
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1287
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
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:1237
An event such as a keypress.
Definition: keymap.h:60
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:186
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:198
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:143
#define FREE(x)
Definition: memory.h:40
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:42
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:396
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1194
Question/user input.
Definition: color.h:81
+ 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 512 of file curs_lib.c.

513 {
514  mutt_flushinp();
516  if (C_Timeout)
517  mutt_getch_timeout(-1); /* restore blocking operation */
518  if (mutt_yesorno(_("Exit NeoMutt?"), MUTT_YES) == MUTT_YES)
519  {
520  mutt_exit(1);
521  }
524  SigInt = 0;
525 }
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: globals.h:81
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:848
#define _(a)
Definition: message.h:28
void mutt_curses_set_cursor(enum MuttCursorState state)
Set the cursor state.
Definition: mutt_curses.c:70
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:82
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:115
WHERE short C_Timeout
Config: Time to wait for user input in menus.
Definition: globals.h:153
Restore the previous cursor state.
Definition: mutt_curses.h:80
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:210
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:143
+ Here is the call graph for this function:
+ 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 530 of file curs_lib.c.

531 {
533  return;
534 
539 }
Informational message.
Definition: color.h:76
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:49
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:117
Plain text.
Definition: color.h:78
WHERE char ErrorBuf[256]
Copy of the last error message.
Definition: globals.h:47
WHERE bool ErrorBufMessage
true if the last message was an error
Definition: globals.h:46
int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:212
Error message.
Definition: color.h:71
WHERE bool OptMsgErr
(pseudo) used by mutt_error/mutt_message
Definition: options.h:39
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:42
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program...
Definition: options.h:37
+ 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 544 of file curs_lib.c.

545 {
546  if (OptNoCurses)
547  return;
548 
549  int e = errno;
550 
551  /* at least in some situations (screen + xterm under SuSE11/12) endwin()
552  * doesn't properly flush the screen without an explicit call. */
553  mutt_refresh();
554  endwin();
555 
556  errno = e;
557 }
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:46
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:105
+ 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 563 of file curs_lib.c.

564 {
565  char *p = strerror(errno);
566 
567  mutt_debug(LL_DEBUG1, "%s: %s (errno = %d)\n", s, p ? p : "unknown error", errno);
568  mutt_error("%s: %s (errno = %d)", s, p ? p : _("unknown error"), errno);
569 }
#define _(a)
Definition: message.h:28
Log at debug level 1.
Definition: logging.h:56
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81

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

578 {
579  struct termios term;
580  struct termios old;
581 
582  int fd = open("/dev/tty", O_RDONLY);
583  if (fd < 0)
584  return EOF;
585 
586  tcgetattr(fd, &old); // Save the current tty settings
587 
588  term = old;
589  term.c_lflag &= ~(ICANON | ECHO); // Canonical (not line-buffered), don't echo the characters
590  term.c_cc[VMIN] = 1; // Wait for at least one character
591  term.c_cc[VTIME] = 255; // Wait for 25.5s
592  tcsetattr(fd, TCSANOW, &term);
593 
594  if (s)
595  fputs(s, stdout);
596  else
597  fputs(_("Press any key to continue..."), stdout);
598  fflush(stdout);
599 
600  char ch = '\0';
601  // Wait for a character. This might timeout, so loop.
602  while (read(fd, &ch, 1) == 0)
603  ;
604 
605  // Change the tty settings to be non-blocking
606  term.c_cc[VMIN] = 0; // Returning with zero characters is acceptable
607  term.c_cc[VTIME] = 0; // Don't wait
608  tcsetattr(fd, TCSANOW, &term);
609 
610  char buf[64];
611  while (read(fd, buf, sizeof(buf)) > 0) // Mop up any remaining chars
612  ;
613 
614  tcsetattr(fd, TCSANOW, &old); // Restore the previous tty settings
615  close(fd);
616 
617  fputs("\r\n", stdout);
619  return (ch >= 0) ? ch : EOF;
620 }
#define _(a)
Definition: message.h:28
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:115
+ Here is the call graph for this function:
+ 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 631 of file curs_lib.c.

633 {
634  int rc;
635 
636  if (!C_Pager || (mutt_str_strcmp(C_Pager, "builtin") == 0))
637  rc = mutt_pager(banner, tempfile, do_color, info);
638  else
639  {
640  struct Buffer *cmd = mutt_buffer_pool_get();
641 
642  mutt_endwin();
644  if (mutt_system(mutt_b2s(cmd)) == -1)
645  {
646  mutt_error(_("Error running \"%s\""), mutt_b2s(cmd));
647  rc = -1;
648  }
649  else
650  rc = 0;
651  mutt_file_unlink(tempfile);
653  }
654 
655  return rc;
656 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:194
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:544
#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:1419
WHERE char * C_Pager
Config: External command for viewing messages, or &#39;builtin&#39; to use NeoMutt&#39;s.
Definition: globals.h:134
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:2244
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
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_enter_fname_full()

int mutt_enter_fname_full ( const char *  prompt,
char *  buf,
size_t  buflen,
bool  mailbox,
bool  multiple,
char ***  files,
int *  numfiles,
SelectFileFlags  flags 
)

Ask the user to select a file.

Parameters
[in]promptPrompt
[in]bufBuffer for the result
[in]buflenLength of the buffer
[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 671 of file curs_lib.c.

673 {
674  struct Buffer *fname = mutt_buffer_pool_get();
675 
676  mutt_buffer_addstr(fname, NONULL(buf));
677  int rc = mutt_buffer_enter_fname_full(prompt, fname, mailbox, multiple, files,
678  numfiles, flags);
679  mutt_str_strfcpy(buf, mutt_b2s(fname), buflen);
680 
681  mutt_buffer_pool_release(&fname);
682  return rc;
683 }
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
String manipulation buffer.
Definition: buffer.h:33
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
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.
Definition: curs_lib.c:697
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
+ Here is the call 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 697 of file curs_lib.c.

700 {
701  struct KeyEvent ch;
702 
705  mutt_window_addstr(_(" ('?' for list): "));
707  if (!mutt_buffer_is_empty(fname))
710  mutt_refresh();
711 
712  do
713  {
714  ch = mutt_getch();
715  } while (ch.ch == -2);
716  if (ch.ch < 0)
717  {
719  return -1;
720  }
721  else if (ch.ch == '?')
722  {
723  mutt_refresh();
724  mutt_buffer_reset(fname);
725 
726  if (flags == MUTT_SEL_NO_FLAGS)
727  flags = MUTT_SEL_FOLDER;
728  if (multiple)
729  flags |= MUTT_SEL_MULTI;
730  if (mailbox)
731  flags |= MUTT_SEL_MAILBOX;
732  mutt_buffer_select_file(fname, flags, files, numfiles);
733  }
734  else
735  {
736  char *pc = mutt_mem_malloc(mutt_str_strlen(prompt) + 3);
737 
738  sprintf(pc, "%s: ", prompt);
739  if (ch.op == OP_NULL)
740  mutt_unget_event(ch.ch, 0);
741  else
742  mutt_unget_event(0, ch.op);
743 
744  mutt_buffer_alloc(fname, 1024);
745  if (mutt_buffer_get_field_full(pc, fname, (mailbox ? MUTT_EFILE : MUTT_FILE) | MUTT_CLEAR,
746  multiple, files, numfiles) != 0)
747  {
748  mutt_buffer_reset(fname);
749  }
750  FREE(&pc);
751  }
752 
753  return 0;
754 }
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:68
void mutt_buffer_select_file(struct Buffer *file, SelectFileFlags flags, char ***files, int *numfiles)
Let the user select a file.
Definition: browser.c:1148
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:49
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:117
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:763
#define _(a)
Definition: message.h:28
int ch
raw key pressed
Definition: keymap.h:62
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition: browser.h:44
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: browser.h:47
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:95
Plain text.
Definition: color.h:78
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:105
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:256
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:60
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:186
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:46
int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:212
#define MUTT_FILE
Do file completion.
Definition: mutt.h:64
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition: browser.h:45
#define MUTT_EFILE
Do file completion, plus incoming folders.
Definition: mutt.h:65
#define FREE(x)
Definition: memory.h:40
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:42
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:396
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
Question/user input.
Definition: color.h:81
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_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 763 of file curs_lib.c.

764 {
765  struct KeyEvent tmp;
766 
767  tmp.ch = ch;
768  tmp.op = op;
769 
770  if (UngetCount >= UngetLen)
771  mutt_mem_realloc(&UngetKeyEvents, (UngetLen += 16) * sizeof(struct KeyEvent));
772 
773  UngetKeyEvents[UngetCount++] = tmp;
774 }
int op
function op
Definition: keymap.h:63
int ch
raw key pressed
Definition: keymap.h:62
static size_t UngetCount
Definition: curs_lib.c:86
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:88
An event such as a keypress.
Definition: keymap.h:60
static size_t UngetLen
Definition: curs_lib.c:87
+ 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 782 of file curs_lib.c.

783 {
784  const char *p = s + mutt_str_strlen(s) - 1;
785 
786  while (p >= s)
787  {
788  mutt_unget_event((unsigned char) *p--, 0);
789  }
790 }
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:763
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

801 {
802  struct KeyEvent tmp;
803 
804  tmp.ch = ch;
805  tmp.op = op;
806 
808  mutt_mem_realloc(&MacroEvents, (MacroBufferLen += 128) * sizeof(struct KeyEvent));
809 
810  MacroEvents[MacroBufferCount++] = tmp;
811 }
static struct KeyEvent * MacroEvents
Definition: curs_lib.c:81
static size_t MacroBufferCount
Definition: curs_lib.c:79
int op
function op
Definition: keymap.h:63
int ch
raw key pressed
Definition: keymap.h:62
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:60
static size_t MacroBufferLen
Definition: curs_lib.c:80
+ Here is the call graph for this function:
+ 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 819 of file curs_lib.c.

820 {
821  UngetCount = 0;
822  while (MacroBufferCount > 0)
823  {
824  if (MacroEvents[--MacroBufferCount].op == OP_END_COND)
825  return;
826  }
827 }
static struct KeyEvent * MacroEvents
Definition: curs_lib.c:81
static size_t MacroBufferCount
Definition: curs_lib.c:79
int op
function op
Definition: keymap.h:63
static size_t UngetCount
Definition: curs_lib.c:86
+ 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 836 of file curs_lib.c.

837 {
838  while (UngetCount > 0)
839  {
840  if (UngetKeyEvents[--UngetCount].op == OP_END_COND)
841  return;
842  }
843 }
int op
function op
Definition: keymap.h:63
static size_t UngetCount
Definition: curs_lib.c:86
static struct KeyEvent * UngetKeyEvents
Definition: curs_lib.c:88
+ Here is the caller graph for this function:

◆ mutt_flushinp()

void mutt_flushinp ( void  )

Empty all the keyboard buffers.

Definition at line 848 of file curs_lib.c.

849 {
850  UngetCount = 0;
851  MacroBufferCount = 0;
852  flushinp();
853 }
static size_t MacroBufferCount
Definition: curs_lib.c:79
static size_t UngetCount
Definition: curs_lib.c:86
+ 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 862 of file curs_lib.c.

863 {
864  struct KeyEvent ch;
865  int choice;
866  bool redraw = true;
867  int prompt_lines = 1;
868 
869  bool opt_cols = ((Colors->defs[MT_COLOR_OPTIONS] != 0) &&
871 
872  while (true)
873  {
874  if (redraw || SigWinch)
875  {
876  redraw = false;
877  if (SigWinch)
878  {
879  SigWinch = 0;
883  }
884  if (MuttMessageWindow->cols)
885  {
886  int width = mutt_strwidth(prompt) + 2; // + '?' + space
887  /* If we're going to colour the options,
888  * make an assumption about the modified prompt size. */
889  if (opt_cols)
890  width -= 2 * mutt_str_strlen(letters);
891 
892  prompt_lines = (width + MuttMessageWindow->cols - 1) / MuttMessageWindow->cols;
893  prompt_lines = MAX(1, MIN(3, prompt_lines));
894  }
895  if (prompt_lines != MuttMessageWindow->rows)
896  {
897  mutt_window_reflow_message_rows(prompt_lines);
899  }
900 
902 
903  if ((Colors->defs[MT_COLOR_OPTIONS] != 0) &&
905  {
906  char *cur = NULL;
907 
908  while ((cur = strchr(prompt, '(')))
909  {
910  // write the part between prompt and cur using MT_COLOR_PROMPT
912  mutt_window_addnstr(prompt, cur - prompt);
913 
914  if (isalnum(cur[1]) && (cur[2] == ')'))
915  {
916  // we have a single letter within parentheses
918  mutt_window_addch(cur[1]);
919  prompt = cur + 3;
920  }
921  else
922  {
923  // we have a parenthesis followed by something else
924  mutt_window_addch(cur[0]);
925  prompt = cur + 1;
926  }
927  }
928  }
929 
931  mutt_window_addstr(prompt);
933 
934  mutt_window_addch(' ');
936  }
937 
938  mutt_refresh();
939  /* SigWinch is not processed unless timeout is set */
940  mutt_getch_timeout(30 * 1000);
941  ch = mutt_getch();
942  mutt_getch_timeout(-1);
943  if (ch.ch == -2)
944  continue;
945  /* (ch.ch == 0) is technically possible. Treat the same as < 0 (abort) */
946  if ((ch.ch <= 0) || CI_is_return(ch.ch))
947  {
948  choice = -1;
949  break;
950  }
951  else
952  {
953  char *p = strchr(letters, ch.ch);
954  if (p)
955  {
956  choice = p - letters + 1;
957  break;
958  }
959  else if ((ch.ch <= '9') && (ch.ch > '0'))
960  {
961  choice = ch.ch - '0';
962  if (choice <= mutt_str_strlen(letters))
963  break;
964  }
965  }
966  mutt_beep(false);
967  }
968  if (MuttMessageWindow->rows == 1)
969  {
971  }
972  else
973  {
976  }
977  mutt_refresh();
978  return choice;
979 }
#define CI_is_return(ch)
Definition: mutt_curses.h:72
#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:49
int * defs
Array of all fixed colours, see enum ColorId.
Definition: color.h:132
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:117
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:100
int ch
raw key pressed
Definition: keymap.h:62
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:96
#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:378
void mutt_window_clear_screen(void)
Clear the entire screen.
Definition: mutt_window.c:437
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:95
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.h:82
Plain text.
Definition: color.h:78
void mutt_window_reflow_message_rows(int mw_rows)
Resize the Message Window.
Definition: mutt_window.c:320
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:105
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1287
An event such as a keypress.
Definition: keymap.h:60
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:186
Definition: color.h:130
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:198
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:366
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:143
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:42
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:396
Options in prompt.
Definition: color.h:79
Question/user input.
Definition: color.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

988 {
989  char buf[MB_LEN_MAX * 2];
990  mbstate_t mbstate;
991  size_t n1, n2;
992 
993  memset(&mbstate, 0, sizeof(mbstate));
994  if (((n1 = wcrtomb(buf, wc, &mbstate)) == (size_t)(-1)) ||
995  ((n2 = wcrtomb(buf + n1, 0, &mbstate)) == (size_t)(-1)))
996  {
997  return -1; /* ERR */
998  }
999  else
1000  {
1001  return mutt_window_addstr(buf);
1002  }
1003 }
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:396
+ 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 1021 of file curs_lib.c.

1024 {
1025  wchar_t wc;
1026  int w;
1027  size_t k, k2;
1028  char scratch[MB_LEN_MAX];
1029  mbstate_t mbstate1, mbstate2;
1030  bool escaped = false;
1031 
1032  memset(&mbstate1, 0, sizeof(mbstate1));
1033  memset(&mbstate2, 0, sizeof(mbstate2));
1034  buflen--;
1035  char *p = buf;
1036  for (; n && (k = mbrtowc(&wc, s, n, &mbstate1)); s += k, n -= k)
1037  {
1038  if ((k == (size_t)(-1)) || (k == (size_t)(-2)))
1039  {
1040  if ((k == (size_t)(-1)) && (errno == EILSEQ))
1041  memset(&mbstate1, 0, sizeof(mbstate1));
1042 
1043  k = (k == (size_t)(-1)) ? 1 : n;
1044  wc = ReplacementChar;
1045  }
1046  if (escaped)
1047  {
1048  escaped = false;
1049  w = 0;
1050  }
1051  else if (arboreal && (wc == MUTT_SPECIAL_INDEX))
1052  {
1053  escaped = true;
1054  w = 0;
1055  }
1056  else if (arboreal && (wc < MUTT_TREE_MAX))
1057  {
1058  w = 1; /* hack */
1059  }
1060  else
1061  {
1062 #ifdef HAVE_ISWBLANK
1063  if (iswblank(wc))
1064  wc = ' ';
1065  else
1066 #endif
1067  if (!IsWPrint(wc))
1068  wc = '?';
1069  w = wcwidth(wc);
1070  }
1071  if (w >= 0)
1072  {
1073  if ((w > max_width) || ((k2 = wcrtomb(scratch, wc, &mbstate2)) > buflen))
1074  continue;
1075  min_width -= w;
1076  max_width -= w;
1077  strncpy(p, scratch, k2);
1078  p += k2;
1079  buflen -= k2;
1080  }
1081  }
1082  w = ((int) buflen < min_width) ? buflen : min_width;
1083  if (w <= 0)
1084  *p = '\0';
1085  else if (justify == JUSTIFY_RIGHT) /* right justify */
1086  {
1087  p[w] = '\0';
1088  while (--p >= buf)
1089  p[w] = *p;
1090  while (--w >= 0)
1091  buf[w] = pad_char;
1092  }
1093  else if (justify == JUSTIFY_CENTER) /* center */
1094  {
1095  char *savedp = p;
1096  int half = (w + 1) / 2; /* half of cushion space */
1097 
1098  p[w] = '\0';
1099 
1100  /* move str to center of buffer */
1101  while (--p >= buf)
1102  p[half] = *p;
1103 
1104  /* fill rhs */
1105  p = savedp + half;
1106  while (--w >= half)
1107  *p++ = pad_char;
1108 
1109  /* fill lhs */
1110  while (half--)
1111  buf[half] = pad_char;
1112  }
1113  else /* left justify */
1114  {
1115  while (--w >= 0)
1116  *p++ = pad_char;
1117  *p = '\0';
1118  }
1119 }
#define IsWPrint(wc)
Definition: mbyte.h:39
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:59
Centre the text.
Definition: curs_lib.h:48
Colour indicator.
Definition: mutt_menu.h:76
#define EILSEQ
Definition: charset.c:50
+ 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 1135 of file curs_lib.c.

1136 {
1137  enum FormatJustify justify = JUSTIFY_RIGHT;
1138  char *p = NULL;
1139  int min_width;
1140  int max_width = INT_MAX;
1141 
1142  if (*prec == '-')
1143  {
1144  prec++;
1145  justify = JUSTIFY_LEFT;
1146  }
1147  else if (*prec == '=')
1148  {
1149  prec++;
1150  justify = JUSTIFY_CENTER;
1151  }
1152  min_width = strtol(prec, &p, 10);
1153  if (*p == '.')
1154  {
1155  prec = p + 1;
1156  max_width = strtol(prec, &p, 10);
1157  if (p <= prec)
1158  max_width = INT_MAX;
1159  }
1160 
1161  mutt_simple_format(buf, buflen, min_width, max_width, justify, ' ', s,
1162  mutt_str_strlen(s), arboreal);
1163 }
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
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
Centre the text.
Definition: curs_lib.h:48
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:1021
+ Here is the call graph for this function:
+ 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 1172 of file curs_lib.c.

1173 {
1174  mutt_format_s_x(buf, buflen, prec, s, false);
1175 }
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:1135
+ 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 1184 of file curs_lib.c.

1185 {
1186  mutt_format_s_x(buf, buflen, prec, s, true);
1187 }
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:1135
+ 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 1194 of file curs_lib.c.

1195 {
1196  wchar_t wc;
1197  size_t k;
1198  size_t len = mutt_str_strlen(s);
1199  mbstate_t mbstate;
1200 
1201  memset(&mbstate, 0, sizeof(mbstate));
1202  for (; len && (k = mbrtowc(&wc, s, len, &mbstate)); s += k, len -= k)
1203  {
1204  if ((k == (size_t)(-1)) || (k == (size_t)(-2)))
1205  {
1206  if (k == (size_t)(-1))
1207  memset(&mbstate, 0, sizeof(mbstate));
1208  k = (k == (size_t)(-1)) ? 1 : len;
1209  wc = ReplacementChar;
1210  }
1211  if (!IsWPrint(wc))
1212  wc = '?';
1213  const int w = wcwidth(wc);
1214  if (w >= 0)
1215  {
1216  if (w > n)
1217  break;
1218  mutt_window_addnstr((char *) s, k);
1219  n -= w;
1220  }
1221  }
1222  while (n-- > 0)
1223  mutt_window_addch(' ');
1224 }
#define IsWPrint(wc)
Definition: mbyte.h:39
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:59
int mutt_window_addnstr(const char *str, int num)
Write a partial string to a Window.
Definition: mutt_window.c:378
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:366
+ 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 1237 of file curs_lib.c.

1238 {
1239  wchar_t wc;
1240  size_t n, w = 0, l = 0, cl;
1241  int cw;
1242  mbstate_t mbstate;
1243 
1244  if (!src)
1245  goto out;
1246 
1247  n = mutt_str_strlen(src);
1248 
1249  memset(&mbstate, 0, sizeof(mbstate));
1250  for (w = 0; n && (cl = mbrtowc(&wc, src, n, &mbstate)); src += cl, n -= cl)
1251  {
1252  if ((cl == (size_t)(-1)) || (cl == (size_t)(-2)))
1253  {
1254  if (cl == (size_t)(-1))
1255  memset(&mbstate, 0, sizeof(mbstate));
1256  cl = (cl == (size_t)(-1)) ? 1 : n;
1257  wc = ReplacementChar;
1258  }
1259  cw = wcwidth(wc);
1260  /* hack because MUTT_TREE symbols aren't turned into characters
1261  * until rendered by print_enriched_string() */
1262  if ((cw < 0) && (src[0] == MUTT_SPECIAL_INDEX))
1263  {
1264  cl = 2; /* skip the index coloring sequence */
1265  cw = 0;
1266  }
1267  else if ((cw < 0) && (cl == 1) && (src[0] != '\0') && (src[0] < MUTT_TREE_MAX))
1268  cw = 1;
1269  else if (cw < 0)
1270  cw = 0; /* unprintable wchar */
1271  if ((cl + l > maxlen) || (cw + w > maxwid))
1272  break;
1273  l += cl;
1274  w += cw;
1275  }
1276 out:
1277  if (width)
1278  *width = w;
1279  return l;
1280 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:59
Colour indicator.
Definition: mutt_menu.h:76
+ Here is the call graph for this function:
+ 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 1287 of file curs_lib.c.

1288 {
1289  if (!s)
1290  return 0;
1291 
1292  wchar_t wc;
1293  int w;
1294  size_t k;
1295  mbstate_t mbstate;
1296 
1297  size_t n = mutt_str_strlen(s);
1298 
1299  memset(&mbstate, 0, sizeof(mbstate));
1300  for (w = 0; n && (k = mbrtowc(&wc, s, n, &mbstate)); s += k, n -= k)
1301  {
1302  if (*s == MUTT_SPECIAL_INDEX)
1303  {
1304  s += 2; /* skip the index coloring sequence */
1305  k = 0;
1306  continue;
1307  }
1308 
1309  if ((k == (size_t)(-1)) || (k == (size_t)(-2)))
1310  {
1311  if (k == (size_t)(-1))
1312  memset(&mbstate, 0, sizeof(mbstate));
1313  k = (k == (size_t)(-1)) ? 1 : n;
1314  wc = ReplacementChar;
1315  }
1316  if (!IsWPrint(wc))
1317  wc = '?';
1318  w += wcwidth(wc);
1319  }
1320  return w;
1321 }
#define IsWPrint(wc)
Definition: mbyte.h:39
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
wchar_t ReplacementChar
When a Unicode character can&#39;t be displayed, use this instead.
Definition: charset.c:59
Colour indicator.
Definition: mutt_menu.h:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_MetaKey

bool C_MetaKey

Config: Interpret 'ALT-x' as 'ESC-x'.

interpret ALT-x as ESC-x

Definition at line 69 of file curs_lib.c.

◆ MacroBufferCount

size_t MacroBufferCount = 0
static

Definition at line 79 of file curs_lib.c.

◆ MacroBufferLen

size_t MacroBufferLen = 0
static

Definition at line 80 of file curs_lib.c.

◆ MacroEvents

struct KeyEvent* MacroEvents
static

Definition at line 81 of file curs_lib.c.

◆ UngetCount

size_t UngetCount = 0
static

Definition at line 86 of file curs_lib.c.

◆ UngetLen

size_t UngetLen = 0
static

Definition at line 87 of file curs_lib.c.

◆ UngetKeyEvents

struct KeyEvent* UngetKeyEvents
static

Definition at line 88 of file curs_lib.c.

◆ MuttGetchTimeout

int MuttGetchTimeout = -1

Timeout in ms for mutt_getch()

Definition at line 90 of file curs_lib.c.