NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
curs_lib.c
Go to the documentation of this file.
1 
30 #include "config.h"
31 #include <stddef.h>
32 #include <ctype.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <langinfo.h>
36 #include <limits.h>
37 #include <stdbool.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <termios.h>
42 #include <unistd.h>
43 #include <wchar.h>
44 #include "mutt/lib.h"
45 #include "config/lib.h"
46 #include "core/lib.h"
47 #include "mutt.h"
48 #include "curs_lib.h"
49 #include "pager/lib.h"
50 #include "browser.h"
51 #include "color.h"
52 #include "dialog.h"
53 #include "enter_state.h"
54 #include "keymap.h"
55 #include "mutt_curses.h"
56 #include "mutt_globals.h"
57 #include "mutt_logging.h"
58 #include "mutt_menu.h"
59 #include "mutt_thread.h"
60 #include "mutt_window.h"
61 #include "opcodes.h"
62 #include "options.h"
63 #include "protos.h"
64 #ifdef HAVE_ISWBLANK
65 #include <wctype.h>
66 #endif
67 #ifdef USE_INOTIFY
68 #include "monitor.h"
69 #endif
70 
71 /* These Config Variables are only used in curs_lib.c */
72 bool C_MetaKey;
73 
74 /* not possible to unget more than one char under some curses libs, and it
75  * is impossible to unget function keys in SLang, so roll our own input
76  * buffering routines.
77  */
78 
79 /* These are used for macros and exec/push commands.
80  * They can be temporarily ignored by setting OptIgnoreMacroEvents
81  */
82 static size_t MacroBufferCount = 0;
83 static size_t MacroBufferLen = 0;
84 static struct KeyEvent *MacroEvents;
85 
86 /* These are used in all other "normal" situations, and are not
87  * ignored when setting OptIgnoreMacroEvents
88  */
89 static size_t UngetCount = 0;
90 static size_t UngetLen = 0;
91 static struct KeyEvent *UngetKeyEvents;
92 
94 
99 void mutt_beep(bool force)
100 {
101  if (force || C_Beep)
102  beep();
103 }
104 
108 void mutt_refresh(void)
109 {
110  /* don't refresh when we are waiting for a child. */
111  if (OptKeepQuiet)
112  return;
113 
114  /* don't refresh in the middle of macros unless necessary */
116  return;
117 
118  /* else */
119  refresh();
120 }
121 
131 {
132  keypad(stdscr, true);
133  clearok(stdscr, true);
135 }
136 
146 void mutt_getch_timeout(int delay)
147 {
148  MuttGetchTimeout = delay;
149  timeout(delay);
150 }
151 
152 #ifdef USE_INOTIFY
153 
158 static int mutt_monitor_getch(void)
159 {
160  /* ncurses has its own internal buffer, so before we perform a poll,
161  * we need to make sure there isn't a character waiting */
162  timeout(0);
163  int ch = getch();
164  timeout(MuttGetchTimeout);
165  if (ch == ERR)
166  {
167  if (mutt_monitor_poll() != 0)
168  ch = ERR;
169  else
170  ch = getch();
171  }
172  return ch;
173 }
174 #endif /* USE_INOTIFY */
175 
189 struct KeyEvent mutt_getch(void)
190 {
191  int ch;
192  struct KeyEvent err = { -1, OP_NULL }, ret;
193  struct KeyEvent timeout = { -2, OP_NULL };
194 
195  if (UngetCount)
196  return UngetKeyEvents[--UngetCount];
197 
199  return MacroEvents[--MacroBufferCount];
200 
201  SigInt = 0;
202 
204 #ifdef KEY_RESIZE
205  /* ncurses 4.2 sends this when the screen is resized */
206  ch = KEY_RESIZE;
207  while (ch == KEY_RESIZE)
208 #endif /* KEY_RESIZE */
209 #ifdef USE_INOTIFY
211 #else
212  ch = getch();
213 #endif /* USE_INOTIFY */
215 
216  if (SigInt)
217  {
218  mutt_query_exit();
219  return err;
220  }
221 
222  /* either timeout, a sigwinch (if timeout is set), or the terminal
223  * has been lost */
224  if (ch == ERR)
225  {
226  if (!isatty(0))
227  mutt_exit(1);
228 
229  return timeout;
230  }
231 
232  if ((ch & 0x80) && C_MetaKey)
233  {
234  /* send ALT-x as ESC-x */
235  ch &= ~0x80;
236  mutt_unget_event(ch, 0);
237  ret.ch = '\033'; // Escape
238  ret.op = 0;
239  return ret;
240  }
241 
242  ret.ch = ch;
243  ret.op = 0;
244  return (ch == AbortKey) ? err : ret;
245 }
246 
260 int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete,
261  bool multiple, struct Mailbox *m, char ***files, int *numfiles)
262 {
263  int ret;
264  int col;
265 
266  struct EnterState *es = mutt_enter_state_new();
267 
268  do
269  {
270  if (SigWinch)
271  {
272  SigWinch = 0;
274  clearok(stdscr, true);
276  }
279  mutt_window_addstr(field);
281  mutt_refresh();
283  ret = mutt_enter_string_full(buf->data, buf->dsize, col, complete, multiple,
284  m, files, numfiles, es);
285  } while (ret == 1);
286 
287  if (ret == 0)
289  else
290  mutt_buffer_reset(buf);
291 
294 
295  return ret;
296 }
297 
311 int mutt_get_field(const char *field, char *buf, size_t buflen,
312  CompletionFlags complete, bool multiple, char ***files, int *numfiles)
313 {
314  if (!buf)
315  return -1;
316 
317  struct Buffer tmp = {
318  .data = buf,
319  .dptr = buf + mutt_str_len(buf),
320  .dsize = buflen,
321  };
322  return mutt_buffer_get_field(field, &tmp, complete, multiple, NULL, files, numfiles);
323 }
324 
335 int mutt_get_field_unbuffered(const char *msg, char *buf, size_t buflen, CompletionFlags flags)
336 {
337  bool reset_ignoremacro = false;
338 
340  {
341  OptIgnoreMacroEvents = true;
342  reset_ignoremacro = true;
343  }
344  int rc = mutt_get_field(msg, buf, buflen, flags, false, NULL, NULL);
345  if (reset_ignoremacro)
346  OptIgnoreMacroEvents = false;
347 
348  return rc;
349 }
350 
356 void mutt_edit_file(const char *editor, const char *file)
357 {
358  struct Buffer *cmd = mutt_buffer_pool_get();
359 
360  mutt_endwin();
361  mutt_buffer_file_expand_fmt_quote(cmd, editor, file);
362  if (mutt_system(mutt_buffer_string(cmd)) != 0)
363  {
364  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
365  }
366  /* the terminal may have been resized while the editor owned it */
368  keypad(stdscr, true);
369  clearok(stdscr, true);
370 
372 }
373 
380 enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
381 {
382  struct KeyEvent ch;
383  char *yes = _("yes");
384  char *no = _("no");
385  char *answer_string = NULL;
386  int answer_string_wid, msg_wid;
387  size_t trunc_msg_len;
388  bool redraw = true;
389  int prompt_lines = 1;
390 
391  char *expr = NULL;
392  regex_t reyes;
393  regex_t reno;
394  char answer[2];
395 
396  answer[1] = '\0';
397 
398  bool reyes_ok = (expr = nl_langinfo(YESEXPR)) && (expr[0] == '^') &&
399  (REG_COMP(&reyes, expr, REG_NOSUB) == 0);
400  bool reno_ok = (expr = nl_langinfo(NOEXPR)) && (expr[0] == '^') &&
401  (REG_COMP(&reno, expr, REG_NOSUB) == 0);
402 
403  /* In order to prevent the default answer to the question to wrapped
404  * around the screen in the even the question is wider than the screen,
405  * ensure there is enough room for the answer and truncate the question
406  * to fit. */
407  mutt_str_asprintf(&answer_string, " ([%s]/%s): ", (def == MUTT_YES) ? yes : no,
408  (def == MUTT_YES) ? no : yes);
409  answer_string_wid = mutt_strwidth(answer_string);
410  msg_wid = mutt_strwidth(msg);
411 
412  while (true)
413  {
414  if (redraw || SigWinch)
415  {
416  redraw = false;
417  if (SigWinch)
418  {
419  SigWinch = 0;
421  clearok(stdscr, true);
423  }
424  if (MessageWindow->state.cols)
425  {
426  prompt_lines = (msg_wid + answer_string_wid + MessageWindow->state.cols - 1) /
428  prompt_lines = MAX(1, MIN(3, prompt_lines));
429  }
430  if (prompt_lines != MessageWindow->state.rows)
431  {
432  mutt_window_reflow_message_rows(prompt_lines);
434  }
435 
436  /* maxlen here is sort of arbitrary, so pick a reasonable upper bound */
437  trunc_msg_len = mutt_wstr_trunc(
438  msg, (size_t) 4 * prompt_lines * MessageWindow->state.cols,
439  ((size_t) prompt_lines * MessageWindow->state.cols) - answer_string_wid, NULL);
440 
443  mutt_window_addnstr(msg, trunc_msg_len);
444  mutt_window_addstr(answer_string);
447  }
448 
449  mutt_refresh();
450  /* SigWinch is not processed unless timeout is set */
451  mutt_getch_timeout(30 * 1000);
452  ch = mutt_getch();
453  mutt_getch_timeout(-1);
454  if (ch.ch == -2)
455  continue;
456  if (CI_is_return(ch.ch))
457  break;
458  if (ch.ch < 0)
459  {
460  def = MUTT_ABORT;
461  break;
462  }
463 
464  answer[0] = ch.ch;
465  if (reyes_ok ? (regexec(&reyes, answer, 0, 0, 0) == 0) : (tolower(ch.ch) == 'y'))
466  {
467  def = MUTT_YES;
468  break;
469  }
470  else if (reno_ok ? (regexec(&reno, answer, 0, 0, 0) == 0) : (tolower(ch.ch) == 'n'))
471  {
472  def = MUTT_NO;
473  break;
474  }
475  else
476  {
477  mutt_beep(false);
478  }
479  }
480 
481  FREE(&answer_string);
482 
483  if (reyes_ok)
484  regfree(&reyes);
485  if (reno_ok)
486  regfree(&reno);
487 
488  if (MessageWindow->state.rows == 1)
489  {
491  }
492  else
493  {
496  }
497 
498  if (def == MUTT_ABORT)
499  {
500  /* when the users cancels with ^G, clear the message stored with
501  * mutt_message() so it isn't displayed when the screen is refreshed. */
503  }
504  else
505  {
506  mutt_window_addstr((char *) ((def == MUTT_YES) ? yes : no));
507  mutt_refresh();
508  }
509  return def;
510 }
511 
518 enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
519 {
520  switch (opt)
521  {
522  case MUTT_YES:
523  case MUTT_NO:
524  return opt;
525 
526  default:
527  opt = mutt_yesorno(prompt, (opt == MUTT_ASKYES) ? MUTT_YES : MUTT_NO);
529  return opt;
530  }
531 
532  /* not reached */
533 }
534 
540 void mutt_query_exit(void)
541 {
542  mutt_flushinp();
544  if (C_Timeout)
545  mutt_getch_timeout(-1); /* restore blocking operation */
546  if (mutt_yesorno(_("Exit NeoMutt?"), MUTT_YES) == MUTT_YES)
547  {
548  mutt_exit(1);
549  }
552  SigInt = 0;
553 }
554 
558 void mutt_show_error(void)
559 {
561  return;
562 
567 }
568 
572 void mutt_endwin(void)
573 {
574  if (OptNoCurses)
575  return;
576 
577  int e = errno;
578 
579  /* at least in some situations (screen + xterm under SuSE11/12) endwin()
580  * doesn't properly flush the screen without an explicit call. */
581  mutt_refresh();
582  endwin();
583 
584  errno = e;
585 }
586 
591 void mutt_perror_debug(const char *s)
592 {
593  char *p = strerror(errno);
594 
595  mutt_debug(LL_DEBUG1, "%s: %s (errno = %d)\n", s, p ? p : "unknown error", errno);
596  mutt_error("%s: %s (errno = %d)", s, p ? p : _("unknown error"), errno);
597 }
598 
605 int mutt_any_key_to_continue(const char *s)
606 {
607  struct termios term;
608  struct termios old;
609 
610  int fd = open("/dev/tty", O_RDONLY);
611  if (fd < 0)
612  return EOF;
613 
614  tcgetattr(fd, &old); // Save the current tty settings
615 
616  term = old;
617  term.c_lflag &= ~(ICANON | ECHO); // Canonical (not line-buffered), don't echo the characters
618  term.c_cc[VMIN] = 1; // Wait for at least one character
619  term.c_cc[VTIME] = 255; // Wait for 25.5s
620  tcsetattr(fd, TCSANOW, &term);
621 
622  if (s)
623  fputs(s, stdout);
624  else
625  fputs(_("Press any key to continue..."), stdout);
626  fflush(stdout);
627 
628  char ch = '\0';
629  // Wait for a character. This might timeout, so loop.
630  while (read(fd, &ch, 1) == 0)
631  ; // do nothing
632 
633  // Change the tty settings to be non-blocking
634  term.c_cc[VMIN] = 0; // Returning with zero characters is acceptable
635  term.c_cc[VTIME] = 0; // Don't wait
636  tcsetattr(fd, TCSANOW, &term);
637 
638  char buf[64];
639  while (read(fd, buf, sizeof(buf)) > 0)
640  ; // Mop up any remaining chars
641 
642  tcsetattr(fd, TCSANOW, &old); // Restore the previous tty settings
643  close(fd);
644 
645  fputs("\r\n", stdout);
647  return (ch >= 0) ? ch : EOF;
648 }
649 
654 {
655  if (!nc->event_data || !nc->global_data)
656  return -1;
657  if (nc->event_type != NT_CONFIG)
658  return 0;
659 
660  struct EventConfig *ec = nc->event_data;
661  struct MuttWindow *dlg = nc->global_data;
662 
663  if (!mutt_str_equal(ec->name, "status_on_top"))
664  return 0;
665 
666  struct MuttWindow *win_first = TAILQ_FIRST(&dlg->children);
667  if (!win_first)
668  return -1;
669 
670  if ((C_StatusOnTop && (win_first->type == WT_PAGER)) ||
671  (!C_StatusOnTop && (win_first->type != WT_PAGER)))
672  {
673  // Swap the Index and the IndexBar Windows
674  TAILQ_REMOVE(&dlg->children, win_first, entries);
675  TAILQ_INSERT_TAIL(&dlg->children, win_first, entries);
676  }
677 
678  mutt_window_reflow(dlg);
679  return 0;
680 }
681 
691 int mutt_do_pager(const char *banner, const char *tempfile, PagerFlags do_color,
692  struct Pager *info)
693 {
694  struct Pager info2 = { 0 };
695  if (!info)
696  info = &info2;
697 
698  struct MuttWindow *dlg =
701 
702  struct MuttWindow *pager =
705  dlg->focus = pager;
706 
707  struct MuttWindow *pbar =
710 
711  if (C_StatusOnTop)
712  {
713  mutt_window_add_child(dlg, pbar);
714  mutt_window_add_child(dlg, pager);
715  }
716  else
717  {
718  mutt_window_add_child(dlg, pager);
719  mutt_window_add_child(dlg, pbar);
720  }
721 
723  dialog_push(dlg);
724 
725  info->win_ibar = NULL;
726  info->win_index = NULL;
727  info->win_pbar = pbar;
728  info->win_pager = pager;
729 
730  int rc;
731 
732  if (!C_Pager || mutt_str_equal(C_Pager, "builtin"))
733  {
734  rc = mutt_pager(banner, tempfile, do_color, info);
735  }
736  else
737  {
738  struct Buffer *cmd = mutt_buffer_pool_get();
739 
740  mutt_endwin();
742  if (mutt_system(mutt_buffer_string(cmd)) == -1)
743  {
744  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
745  rc = -1;
746  }
747  else
748  rc = 0;
749  mutt_file_unlink(tempfile);
751  }
752 
753  dialog_pop();
755  mutt_window_free(&dlg);
756  return rc;
757 }
758 
772 int mutt_buffer_enter_fname(const char *prompt, struct Buffer *fname,
773  bool mailbox, struct Mailbox *m, bool multiple,
774  char ***files, int *numfiles, SelectFileFlags flags)
775 {
776  struct KeyEvent ch;
777 
779  mutt_window_mvaddstr(MessageWindow, 0, 0, prompt);
780  mutt_window_addstr(_(" ('?' for list): "));
782  if (!mutt_buffer_is_empty(fname))
785  mutt_refresh();
786 
787  do
788  {
789  ch = mutt_getch();
790  } while (ch.ch == -2);
791  if (ch.ch < 0)
792  {
794  return -1;
795  }
796  else if (ch.ch == '?')
797  {
798  mutt_refresh();
799  mutt_buffer_reset(fname);
800 
801  if (flags == MUTT_SEL_NO_FLAGS)
802  flags = MUTT_SEL_FOLDER;
803  if (multiple)
804  flags |= MUTT_SEL_MULTI;
805  if (mailbox)
806  flags |= MUTT_SEL_MAILBOX;
807  mutt_buffer_select_file(fname, flags, m, files, numfiles);
808  }
809  else
810  {
811  char *pc = mutt_mem_malloc(mutt_str_len(prompt) + 3);
812 
813  sprintf(pc, "%s: ", prompt);
814  if (ch.op == OP_NULL)
815  mutt_unget_event(ch.ch, 0);
816  else
817  mutt_unget_event(0, ch.op);
818 
819  mutt_buffer_alloc(fname, 1024);
820  if (mutt_buffer_get_field(pc, fname, (mailbox ? MUTT_EFILE : MUTT_FILE) | MUTT_CLEAR,
821  multiple, m, files, numfiles) != 0)
822  {
823  mutt_buffer_reset(fname);
824  }
825  FREE(&pc);
826  }
827 
828  return 0;
829 }
830 
838 void mutt_unget_event(int ch, int op)
839 {
840  struct KeyEvent tmp;
841 
842  tmp.ch = ch;
843  tmp.op = op;
844 
845  if (UngetCount >= UngetLen)
846  mutt_mem_realloc(&UngetKeyEvents, (UngetLen += 16) * sizeof(struct KeyEvent));
847 
848  UngetKeyEvents[UngetCount++] = tmp;
849 }
850 
857 void mutt_unget_string(const char *s)
858 {
859  const char *p = s + mutt_str_len(s) - 1;
860 
861  while (p >= s)
862  {
863  mutt_unget_event((unsigned char) *p--, 0);
864  }
865 }
866 
876 {
877  struct KeyEvent tmp;
878 
879  tmp.ch = ch;
880  tmp.op = op;
881 
883  mutt_mem_realloc(&MacroEvents, (MacroBufferLen += 128) * sizeof(struct KeyEvent));
884 
885  MacroEvents[MacroBufferCount++] = tmp;
886 }
887 
895 {
896  UngetCount = 0;
897  while (MacroBufferCount > 0)
898  {
899  if (MacroEvents[--MacroBufferCount].op == OP_END_COND)
900  return;
901  }
902 }
903 
912 {
913  while (UngetCount > 0)
914  {
915  if (UngetKeyEvents[--UngetCount].op == OP_END_COND)
916  return;
917  }
918 }
919 
923 void mutt_flushinp(void)
924 {
925  UngetCount = 0;
926  MacroBufferCount = 0;
927  flushinp();
928 }
929 
937 int mutt_multi_choice(const char *prompt, const char *letters)
938 {
939  struct KeyEvent ch;
940  int choice;
941  bool redraw = true;
942  int prompt_lines = 1;
943 
944  bool opt_cols = ((Colors->defs[MT_COLOR_OPTIONS] != 0) &&
946 
947  while (true)
948  {
949  if (redraw || SigWinch)
950  {
951  redraw = false;
952  if (SigWinch)
953  {
954  SigWinch = 0;
956  clearok(stdscr, true);
958  }
959  if (MessageWindow->state.cols)
960  {
961  int width = mutt_strwidth(prompt) + 2; // + '?' + space
962  /* If we're going to colour the options,
963  * make an assumption about the modified prompt size. */
964  if (opt_cols)
965  width -= 2 * mutt_str_len(letters);
966 
967  prompt_lines =
968  (width + MessageWindow->state.cols - 1) / MessageWindow->state.cols;
969  prompt_lines = MAX(1, MIN(3, prompt_lines));
970  }
971  if (prompt_lines != MessageWindow->state.rows)
972  {
973  mutt_window_reflow_message_rows(prompt_lines);
975  }
976 
978 
979  if ((Colors->defs[MT_COLOR_OPTIONS] != 0) &&
981  {
982  char *cur = NULL;
983 
984  while ((cur = strchr(prompt, '(')))
985  {
986  // write the part between prompt and cur using MT_COLOR_PROMPT
988  mutt_window_addnstr(prompt, cur - prompt);
989 
990  if (isalnum(cur[1]) && (cur[2] == ')'))
991  {
992  // we have a single letter within parentheses
994  mutt_window_addch(cur[1]);
995  prompt = cur + 3;
996  }
997  else
998  {
999  // we have a parenthesis followed by something else
1000  mutt_window_addch(cur[0]);
1001  prompt = cur + 1;
1002  }
1003  }
1004  }
1005 
1007  mutt_window_addstr(prompt);
1009 
1010  mutt_window_addch(' ');
1012  }
1013 
1014  mutt_refresh();
1015  /* SigWinch is not processed unless timeout is set */
1016  mutt_getch_timeout(30 * 1000);
1017  ch = mutt_getch();
1018  mutt_getch_timeout(-1);
1019  if (ch.ch == -2)
1020  continue;
1021  /* (ch.ch == 0) is technically possible. Treat the same as < 0 (abort) */
1022  if ((ch.ch <= 0) || CI_is_return(ch.ch))
1023  {
1024  choice = -1;
1025  break;
1026  }
1027  else
1028  {
1029  char *p = strchr(letters, ch.ch);
1030  if (p)
1031  {
1032  choice = p - letters + 1;
1033  break;
1034  }
1035  else if ((ch.ch <= '9') && (ch.ch > '0'))
1036  {
1037  choice = ch.ch - '0';
1038  if (choice <= mutt_str_len(letters))
1039  break;
1040  }
1041  }
1042  mutt_beep(false);
1043  }
1044  if (MessageWindow->state.rows == 1)
1045  {
1047  }
1048  else
1049  {
1052  }
1053  mutt_refresh();
1054  return choice;
1055 }
1056 
1063 int mutt_addwch(wchar_t wc)
1064 {
1065  char buf[MB_LEN_MAX * 2];
1066  mbstate_t mbstate;
1067  size_t n1, n2;
1068 
1069  memset(&mbstate, 0, sizeof(mbstate));
1070  if (((n1 = wcrtomb(buf, wc, &mbstate)) == (size_t)(-1)) ||
1071  ((n2 = wcrtomb(buf + n1, 0, &mbstate)) == (size_t)(-1)))
1072  {
1073  return -1; /* ERR */
1074  }
1075  else
1076  {
1077  return mutt_window_addstr(buf);
1078  }
1079 }
1080 
1097 void mutt_simple_format(char *buf, size_t buflen, int min_width, int max_width,
1098  enum FormatJustify justify, char pad_char,
1099  const char *s, size_t n, bool arboreal)
1100 {
1101  wchar_t wc;
1102  int w;
1103  size_t k, k2;
1104  char scratch[MB_LEN_MAX];
1105  mbstate_t mbstate1, mbstate2;
1106  bool escaped = false;
1107 
1108  memset(&mbstate1, 0, sizeof(mbstate1));
1109  memset(&mbstate2, 0, sizeof(mbstate2));
1110  buflen--;
1111  char *p = buf;
1112  for (; n && (k = mbrtowc(&wc, s, n, &mbstate1)); s += k, n -= k)
1113  {
1114  if ((k == (size_t)(-1)) || (k == (size_t)(-2)))
1115  {
1116  if ((k == (size_t)(-1)) && (errno == EILSEQ))
1117  memset(&mbstate1, 0, sizeof(mbstate1));
1118 
1119  k = (k == (size_t)(-1)) ? 1 : n;
1120  wc = ReplacementChar;
1121  }
1122  if (escaped)
1123  {
1124  escaped = false;
1125  w = 0;
1126  }
1127  else if (arboreal && (wc == MUTT_SPECIAL_INDEX))
1128  {
1129  escaped = true;
1130  w = 0;
1131  }
1132  else if (arboreal && (wc < MUTT_TREE_MAX))
1133  {
1134  w = 1; /* hack */
1135  }
1136  else
1137  {
1138 #ifdef HAVE_ISWBLANK
1139  if (iswblank(wc))
1140  wc = ' ';
1141  else
1142 #endif
1143  if (!IsWPrint(wc))
1144  wc = '?';
1145  w = wcwidth(wc);
1146  }
1147  if (w >= 0)
1148  {
1149  if ((w > max_width) || ((k2 = wcrtomb(scratch, wc, &mbstate2)) > buflen))
1150  continue;
1151  min_width -= w;
1152  max_width -= w;
1153  strncpy(p, scratch, k2);
1154  p += k2;
1155  buflen -= k2;
1156  }
1157  }
1158  w = ((int) buflen < min_width) ? buflen : min_width;
1159  if (w <= 0)
1160  *p = '\0';
1161  else if (justify == JUSTIFY_RIGHT) /* right justify */
1162  {
1163  p[w] = '\0';
1164  while (--p >= buf)
1165  p[w] = *p;
1166  while (--w >= 0)
1167  buf[w] = pad_char;
1168  }
1169  else if (justify == JUSTIFY_CENTER) /* center */
1170  {
1171  char *savedp = p;
1172  int half = (w + 1) / 2; /* half of cushion space */
1173 
1174  p[w] = '\0';
1175 
1176  /* move str to center of buffer */
1177  while (--p >= buf)
1178  p[half] = *p;
1179 
1180  /* fill rhs */
1181  p = savedp + half;
1182  while (--w >= half)
1183  *p++ = pad_char;
1184 
1185  /* fill lhs */
1186  while (half--)
1187  buf[half] = pad_char;
1188  }
1189  else /* left justify */
1190  {
1191  while (--w >= 0)
1192  *p++ = pad_char;
1193  *p = '\0';
1194  }
1195 }
1196 
1211 void mutt_format_s_x(char *buf, size_t buflen, const char *prec, const char *s, bool arboreal)
1212 {
1213  enum FormatJustify justify = JUSTIFY_RIGHT;
1214  char *p = NULL;
1215  int min_width;
1216  int max_width = INT_MAX;
1217 
1218  if (*prec == '-')
1219  {
1220  prec++;
1221  justify = JUSTIFY_LEFT;
1222  }
1223  else if (*prec == '=')
1224  {
1225  prec++;
1226  justify = JUSTIFY_CENTER;
1227  }
1228  min_width = strtol(prec, &p, 10);
1229  if (*p == '.')
1230  {
1231  prec = p + 1;
1232  max_width = strtol(prec, &p, 10);
1233  if (p <= prec)
1234  max_width = INT_MAX;
1235  }
1236 
1237  mutt_simple_format(buf, buflen, min_width, max_width, justify, ' ', s,
1238  mutt_str_len(s), arboreal);
1239 }
1240 
1248 void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
1249 {
1250  mutt_format_s_x(buf, buflen, prec, s, false);
1251 }
1252 
1260 void mutt_format_s_tree(char *buf, size_t buflen, const char *prec, const char *s)
1261 {
1262  mutt_format_s_x(buf, buflen, prec, s, true);
1263 }
1264 
1270 void mutt_paddstr(int n, const char *s)
1271 {
1272  wchar_t wc;
1273  size_t k;
1274  size_t len = mutt_str_len(s);
1275  mbstate_t mbstate;
1276 
1277  memset(&mbstate, 0, sizeof(mbstate));
1278  for (; len && (k = mbrtowc(&wc, s, len, &mbstate)); s += k, len -= k)
1279  {
1280  if ((k == (size_t)(-1)) || (k == (size_t)(-2)))
1281  {
1282  if (k == (size_t)(-1))
1283  memset(&mbstate, 0, sizeof(mbstate));
1284  k = (k == (size_t)(-1)) ? 1 : len;
1285  wc = ReplacementChar;
1286  }
1287  if (!IsWPrint(wc))
1288  wc = '?';
1289  const int w = wcwidth(wc);
1290  if (w >= 0)
1291  {
1292  if (w > n)
1293  break;
1294  mutt_window_addnstr((char *) s, k);
1295  n -= w;
1296  }
1297  }
1298  while (n-- > 0)
1299  mutt_window_addch(' ');
1300 }
1301 
1313 size_t mutt_wstr_trunc(const char *src, size_t maxlen, size_t maxwid, size_t *width)
1314 {
1315  wchar_t wc;
1316  size_t n, w = 0, l = 0, cl;
1317  int cw;
1318  mbstate_t mbstate;
1319 
1320  if (!src)
1321  goto out;
1322 
1323  n = mutt_str_len(src);
1324 
1325  memset(&mbstate, 0, sizeof(mbstate));
1326  for (w = 0; n && (cl = mbrtowc(&wc, src, n, &mbstate)); src += cl, n -= cl)
1327  {
1328  if ((cl == (size_t)(-1)) || (cl == (size_t)(-2)))
1329  {
1330  if (cl == (size_t)(-1))
1331  memset(&mbstate, 0, sizeof(mbstate));
1332  cl = (cl == (size_t)(-1)) ? 1 : n;
1333  wc = ReplacementChar;
1334  }
1335  cw = wcwidth(wc);
1336  /* hack because MUTT_TREE symbols aren't turned into characters
1337  * until rendered by print_enriched_string() */
1338  if ((cw < 0) && (src[0] == MUTT_SPECIAL_INDEX))
1339  {
1340  cl = 2; /* skip the index coloring sequence */
1341  cw = 0;
1342  }
1343  else if ((cw < 0) && (cl == 1) && (src[0] != '\0') && (src[0] < MUTT_TREE_MAX))
1344  cw = 1;
1345  else if (cw < 0)
1346  cw = 0; /* unprintable wchar */
1347  if ((cl + l > maxlen) || (cw + w > maxwid))
1348  break;
1349  l += cl;
1350  w += cw;
1351  }
1352 out:
1353  if (width)
1354  *width = w;
1355  return l;
1356 }
1357 
1363 int mutt_strwidth(const char *s)
1364 {
1365  if (!s)
1366  return 0;
1367  return mutt_strnwidth(s, mutt_str_len(s));
1368 }
1369 
1376 int mutt_strnwidth(const char *s, size_t n)
1377 {
1378  if (!s)
1379  return 0;
1380 
1381  wchar_t wc;
1382  int w;
1383  size_t k;
1384  mbstate_t mbstate;
1385 
1386  memset(&mbstate, 0, sizeof(mbstate));
1387  for (w = 0; n && (k = mbrtowc(&wc, s, n, &mbstate)); s += k, n -= k)
1388  {
1389  if (*s == MUTT_SPECIAL_INDEX)
1390  {
1391  s += 2; /* skip the index coloring sequence */
1392  k = 0;
1393  continue;
1394  }
1395 
1396  if ((k == (size_t)(-1)) || (k == (size_t)(-2)))
1397  {
1398  if (k == (size_t)(-1))
1399  memset(&mbstate, 0, sizeof(mbstate));
1400  k = (k == (size_t)(-1)) ? 1 : n;
1401  wc = ReplacementChar;
1402  }
1403  if (!IsWPrint(wc))
1404  wc = '?';
1405  w += wcwidth(wc);
1406  }
1407  return w;
1408 }
CI_is_return
#define CI_is_return(ch)
Definition: mutt_curses.h:71
mutt_curses_set_cursor
void mutt_curses_set_cursor(enum MuttCursorState state)
Set the cursor state.
Definition: mutt_curses.c:78
mutt_endwin
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:572
UngetKeyEvents
static struct KeyEvent * UngetKeyEvents
Definition: curs_lib.c:91
mutt_beep
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:99
dialog_pop
void dialog_pop(void)
Hide a Window from the user.
Definition: dialog.c:98
C_Timeout
WHERE short C_Timeout
Config: Time to wait for user input in menus.
Definition: mutt_globals.h:115
WT_PAGER
@ WT_PAGER
Window containing paged free-form text.
Definition: mutt_window.h:97
mutt_window_clrtoeol
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:244
SigInt
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:74
lib.h
QuadOption
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
NotifyCallback
Data passed to a notification function.
Definition: observer.h:39
WT_PAGER_BAR
@ WT_PAGER_BAR
Pager Bar containing status info about the Pager.
Definition: mutt_window.h:98
mutt_window_move
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:382
SigWinch
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:75
mutt_getch_timeout
void mutt_getch_timeout(int delay)
Set the getch() timeout.
Definition: curs_lib.c:146
MessageWindow
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
_
#define _(a)
Definition: message.h:28
Mailbox
A mailbox.
Definition: mailbox.h:81
mutt_addwch
int mutt_addwch(wchar_t wc)
addwch would be provided by an up-to-date curses library
Definition: curs_lib.c:1063
curs_lib.h
mutt_system
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
MT_COLOR_ERROR
@ MT_COLOR_ERROR
Error message.
Definition: color.h:70
enter_state.h
NT_CONFIG
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:37
Buffer
String manipulation buffer.
Definition: buffer.h:33
mutt_show_error
void mutt_show_error(void)
Show the user an error message.
Definition: curs_lib.c:558
mutt_unget_string
void mutt_unget_string(const char *s)
Return a string to the input buffer.
Definition: curs_lib.c:857
mutt_window_addnstr
int mutt_window_addnstr(const char *str, int num)
Write a partial string to a Window.
Definition: mutt_window.c:504
mutt_buffer_is_empty
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
dialog_push
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: dialog.c:66
mutt_strnwidth
int mutt_strnwidth(const char *s, size_t n)
Measure a string's width in screen cells.
Definition: curs_lib.c:1376
mutt_window_clearline
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:232
MUTT_SEL_NO_FLAGS
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition: browser.h:41
NeoMutt::notify
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
MuttWindow
A division of the screen.
Definition: mutt_window.h:115
mutt_multi_choice
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:937
monitor.h
FormatJustify
FormatJustify
Alignment for mutt_simple_format()
Definition: curs_lib.h:46
UngetCount
static size_t UngetCount
Definition: curs_lib.c:89
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
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()
Definition: curs_lib.c:1211
mutt_globals.h
mutt_file_unlink
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
LL_DEBUG1
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
mutt_strwidth
int mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:1363
mutt_enter_state_new
struct EnterState * mutt_enter_state_new(void)
Create a new EnterState.
Definition: enter.c:128
FREE
#define FREE(x)
Definition: memory.h:40
options.h
mutt_window_reflow_message_rows
void mutt_window_reflow_message_rows(int mw_rows)
Resize the Message Window.
Definition: mutt_window.c:459
TAILQ_INSERT_TAIL
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
Buffer::dsize
size_t dsize
Length of data.
Definition: buffer.h:37
MUTT_ABORT
@ MUTT_ABORT
User aborted the question (with Ctrl-G)
Definition: quad.h:38
OptNoCurses
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
mutt_buffer_reset
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
OptIgnoreMacroEvents
WHERE bool OptIgnoreMacroEvents
(pseudo) don't process macro/push/exec events while set
Definition: options.h:38
EILSEQ
#define EILSEQ
Definition: charset.c:49
MUTT_WIN_SIZE_MAXIMISE
@ MUTT_WIN_SIZE_MAXIMISE
Window wants as much space as possible.
Definition: mutt_window.h:45
mutt_perror_debug
void mutt_perror_debug(const char *s)
Show the user an 'errno' message.
Definition: curs_lib.c:591
MT_COLOR_NORMAL
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:77
mutt_buffer_alloc
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
mutt_getch
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:189
mutt_pager
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:2327
MUTT_CURSOR_RESTORE_LAST
@ MUTT_CURSOR_RESTORE_LAST
Restore the previous cursor state.
Definition: mutt_curses.h:79
mutt_str_equal
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
lib.h
MUTT_FILE
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
TAILQ_REMOVE
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
protos.h
Pager::win_index
struct MuttWindow * win_index
Definition: lib.h:73
mutt_window.h
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:716
mutt_buffer_file_expand_fmt_quote
void mutt_buffer_file_expand_fmt_quote(struct Buffer *dest, const char *fmt, const char *src)
Replace s in a string with a filename.
Definition: file.c:1432
mutt_any_key_to_continue
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:605
query_quadoption
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:518
Pager::win_pbar
struct MuttWindow * win_pbar
Definition: lib.h:74
MT_COLOR_MESSAGE
@ MT_COLOR_MESSAGE
Informational message.
Definition: color.h:75
mutt_need_hard_redraw
void mutt_need_hard_redraw(void)
Force a hard refresh.
Definition: curs_lib.c:130
JUSTIFY_LEFT
@ JUSTIFY_LEFT
Left justify the text.
Definition: curs_lib.h:48
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
MuttWindow::focus
struct MuttWindow * focus
Focussed Window.
Definition: mutt_window.h:133
ErrorBuf
WHERE char ErrorBuf[256]
Copy of the last error message.
Definition: mutt_globals.h:45
mutt_monitor_poll
int mutt_monitor_poll(void)
Check for filesystem changes.
Definition: monitor.c:399
JUSTIFY_RIGHT
@ JUSTIFY_RIGHT
Right justify the text.
Definition: curs_lib.h:50
mutt_edit_file
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:356
MUTT_EFILE
#define MUTT_EFILE
Do file completion, plus incoming folders.
Definition: mutt.h:59
mutt_paddstr
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1270
MuttGetchTimeout
int MuttGetchTimeout
Timeout in ms for mutt_getch()
Definition: curs_lib.c:93
MUTT_WIN_ORIENT_VERTICAL
@ MUTT_WIN_ORIENT_VERTICAL
Window uses all available vertical space.
Definition: mutt_window.h:35
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.
Definition: curs_lib.c:691
keymap.h
lib.h
OptForceRefresh
WHERE bool OptForceRefresh
(pseudo) refresh even during macros
Definition: options.h:37
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()
Definition: curs_lib.c:1097
notify_observer_remove
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:207
MUTT_SEL_FOLDER
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: browser.h:44
mutt_flush_unget_to_endcond
void mutt_flush_unget_to_endcond(void)
Clear entries from UngetKeyEvents.
Definition: curs_lib.c:911
mutt_sig_allow_interrupt
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
Definition: signal.c:238
mutt_menu.h
lib.h
C_Beep
WHERE bool C_Beep
Config: Make a noise when an error occurs.
Definition: mutt_globals.h:138
mutt_clear_error
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
mutt_resize_screen
void mutt_resize_screen(void)
Update NeoMutt's opinion about the window size (CURSES)
Definition: resize.c:101
MAX
#define MAX(a, b)
Definition: memory.h:30
MUTT_SEL_MULTI
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:43
mutt_window_new
struct MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
Definition: mutt_window.c:166
NotifyCallback::global_data
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
MT_COLOR_OPTIONS
@ MT_COLOR_OPTIONS
Options in prompt.
Definition: color.h:78
KeyEvent::op
int op
function op
Definition: keymap.h:66
AbortKey
keycode_t AbortKey
code of key to abort prompts, normally Ctrl-G
Definition: keymap.c:147
Colors
Definition: color.h:129
mutt_exit
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:140
KeyEvent
An event such as a keypress.
Definition: keymap.h:63
mutt_window_addch
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:492
mutt_mem_realloc
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
MUTT_TREE_MAX
@ MUTT_TREE_MAX
Definition: mutt_thread.h:69
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
MT_COLOR_PROMPT
@ MT_COLOR_PROMPT
Question/user input.
Definition: color.h:80
MUTT_WIN_SIZE_UNLIMITED
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:49
MUTT_NO
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition: quad.h:39
REG_COMP
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:54
Pager::win_pager
struct MuttWindow * win_pager
Definition: lib.h:75
notify_observer_add
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:169
WT_DLG_DO_PAGER
@ WT_DLG_DO_PAGER
Pager Dialog, mutt_do_pager()
Definition: mutt_window.h:81
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.
Definition: curs_lib.c:260
MacroBufferLen
static size_t MacroBufferLen
Definition: curs_lib.c:83
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
WindowState::rows
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
EventConfig
A config-change event.
Definition: subset.h:70
mutt_push_macro_event
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition: curs_lib.c:875
mutt_format_s
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1248
NotifyCallback::event_data
void * event_data
Data from notify_send()
Definition: observer.h:44
MacroBufferCount
static size_t MacroBufferCount
Definition: curs_lib.c:82
JUSTIFY_CENTER
@ JUSTIFY_CENTER
Centre the text.
Definition: curs_lib.h:49
mutt_logging.h
mutt_flushinp
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:923
mutt_buffer_select_file
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:1142
MuttWindow::state
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
dialog.h
UngetLen
static size_t UngetLen
Definition: curs_lib.c:90
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.
Definition: curs_lib.c:1260
mutt_flush_macro_to_endcond
void mutt_flush_macro_to_endcond(void)
Drop a macro from the input buffer.
Definition: curs_lib.c:894
mutt_thread.h
MUTT_SPECIAL_INDEX
@ MUTT_SPECIAL_INDEX
Colour indicator.
Definition: mutt_thread.h:71
mutt_menu_set_current_redraw_full
void mutt_menu_set_current_redraw_full(void)
Flag the current menu to be fully redrawn.
Definition: menu.c:1072
mutt_monitor_getch
static int mutt_monitor_getch(void)
Get a character and poll the filesystem monitor.
Definition: curs_lib.c:158
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.
Definition: curs_lib.c:1313
mutt_mem_malloc
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
EnterState
Keep our place when entering a string.
Definition: enter_state.h:32
Pager::win_ibar
struct MuttWindow * win_ibar
Definition: lib.h:72
mutt_buffer_fix_dptr
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
EventConfig::name
const char * name
Name of config item that changed.
Definition: subset.h:73
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
mutt.h
mutt_enter_string_full
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:180
ReplacementChar
wchar_t ReplacementChar
When a Unicode character can't be displayed, use this instead.
Definition: charset.c:58
OptMsgErr
WHERE bool OptMsgErr
(pseudo) used by mutt_error/mutt_message
Definition: options.h:41
MUTT_SEL_MAILBOX
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition: browser.h:42
mutt_query_exit
void mutt_query_exit(void)
Ask the user if they want to leave NeoMutt.
Definition: curs_lib.c:540
C_Pager
WHERE char * C_Pager
Config: External command for viewing messages, or 'builtin' to use NeoMutt's.
Definition: mutt_globals.h:99
MuttWindow::type
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:137
mutt_curses_set_color
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:57
MacroEvents
static struct KeyEvent * MacroEvents
Definition: curs_lib.c:84
mutt_menu_current_redraw
void mutt_menu_current_redraw(void)
Redraw the current menu.
Definition: menu.c:1107
MUTT_CURSOR_VISIBLE
@ MUTT_CURSOR_VISIBLE
Display a normal cursor.
Definition: mutt_curses.h:81
MUTT_WIN_SIZE_FIXED
@ MUTT_WIN_SIZE_FIXED
Window has a fixed size.
Definition: mutt_window.h:44
MUTT_CLEAR
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:62
mutt_refresh
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:108
ErrorBufMessage
WHERE bool ErrorBufMessage
true if the last message was an error
Definition: mutt_globals.h:44
browser.h
C_MetaKey
bool C_MetaKey
Config: Interpret 'ALT-x' as 'ESC-x'.
Definition: curs_lib.c:72
color.h
C_StatusOnTop
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: mutt_globals.h:164
OptKeepQuiet
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program
Definition: options.h:39
mutt_window_mvaddstr
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
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.
Definition: curs_lib.c:311
SelectFileFlags
uint8_t SelectFileFlags
Flags for mutt_select_file(), e.g. MUTT_SEL_MAILBOX.
Definition: browser.h:40
WindowState::cols
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
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.
Definition: curs_lib.c:772
Colors::defs
int * defs
Array of all fixed colours, see enum ColorId.
Definition: color.h:131
NotifyCallback::event_type
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
mutt_window_add_child
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:565
opcodes.h
Pager
An email being displayed.
Definition: lib.h:64
mutt_curses.h
mutt_window_addstr
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:522
MUTT_ASKYES
@ MUTT_ASKYES
Ask the user, defaulting to 'Yes'.
Definition: quad.h:42
MuttWindow::children
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:129
mutt_yesorno
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:380
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
mutt_enter_state_free
void mutt_enter_state_free(struct EnterState **ptr)
Free an EnterState.
Definition: enter.c:842
mutt_str_asprintf
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1095
mutt_unget_event
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:838
KeyEvent::ch
int ch
raw key pressed
Definition: keymap.h:65
CompletionFlags
uint16_t CompletionFlags
Flags for mutt_enter_string_full(), e.g. MUTT_ALIAS.
Definition: mutt.h:55
mutt_window_get_coords
void mutt_window_get_coords(struct MuttWindow *win, int *col, int *row)
Get the cursor position in the Window.
Definition: mutt_window.c:322
mutt_dlg_dopager_observer
static int mutt_dlg_dopager_observer(struct NotifyCallback *nc)
Listen for config changes affecting the dopager menus - Implements observer_t.
Definition: curs_lib.c:653
PagerFlags
uint16_t PagerFlags
Flags for mutt_pager(), e.g. MUTT_SHOWFLAT.
Definition: lib.h:41
mutt_window_free
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:186
MIN
#define MIN(a, b)
Definition: memory.h:31
mutt_error
#define mutt_error(...)
Definition: logging.h:84
mutt_window_reflow
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:433
IsWPrint
#define IsWPrint(wc)
Definition: mbyte.h:40
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)
Definition: curs_lib.c:335