NeoMutt  2019-12-07-60-g0cfa53
Teaching an old dog new tricks
DOXYGEN
pager.h File Reference

GUI display a file/email/help in a viewport with paging. More...

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
+ Include dependency graph for pager.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Pager
 An email being displayed. More...
 

Macros

#define MUTT_PAGER_NO_FLAGS   0
 No flags are set. More...
 
#define MUTT_SHOWFLAT   (1 << 0)
 Show characters (used for displaying help) More...
 
#define MUTT_SHOWCOLOR   (1 << 1)
 Show characters in color otherwise don't show characters. More...
 
#define MUTT_HIDE   (1 << 2)
 Don't show quoted text. More...
 
#define MUTT_SEARCH   (1 << 3)
 Resolve search patterns. More...
 
#define MUTT_TYPES   (1 << 4)
 Compute line's type. More...
 
#define MUTT_SHOW   (MUTT_SHOWCOLOR | MUTT_SHOWFLAT)
 
#define MUTT_PAGER_NSKIP   (1 << 5)
 Preserve whitespace with smartwrap. More...
 
#define MUTT_PAGER_MARKER   (1 << 6)
 Use markers if option is set. More...
 
#define MUTT_PAGER_RETWINCH   (1 << 7)
 Need reformatting on SIGWINCH. More...
 
#define MUTT_PAGER_ATTACHMENT   (1 << 8)
 Attachments may exist. More...
 
#define MUTT_PAGER_NOWRAP   (1 << 9)
 Format for term width, ignore $wrap. More...
 
#define MUTT_PAGER_LOGS   (1 << 10)
 Logview mode. More...
 
#define MUTT_PAGER_MESSAGE   (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER)
 
#define MUTT_DISPLAYFLAGS   (MUTT_SHOW | MUTT_PAGER_NSKIP | MUTT_PAGER_MARKER | MUTT_PAGER_LOGS)
 

Typedefs

typedef uint16_t PagerFlags
 Flags for mutt_pager(), e.g. MUTT_SHOWFLAT. More...
 

Functions

int mutt_pager (const char *banner, const char *fname, PagerFlags flags, struct Pager *extra)
 Display a file, or help, in a window. More...
 
void mutt_clear_pager_position (void)
 Reset the pager's viewing position. More...
 

Variables

bool C_AllowAnsi
 Config: Allow ANSI colour codes in rich text messages. More...
 
bool C_HeaderColorPartial
 Config: Only colour the part of the header matching the regex. More...
 
short C_PagerContext
 Config: Number of lines of overlap when changing pages in the pager. More...
 
short C_PagerIndexLines
 Config: Number of index lines to display above the pager. More...
 
bool C_PagerStop
 Config: Don't automatically open the next message when at the end of a message. More...
 
short C_SearchContext
 Config: Context to display around search matches. More...
 
short C_SkipQuotedOffset
 Config: Lines of context to show when skipping quoted text. More...
 
bool C_SmartWrap
 Config: Wrap text at word boundaries. More...
 
struct RegexC_Smileys
 Config: Regex to match smileys to prevent mistakes when quoting text. More...
 
bool C_Tilde
 Config: Character to pad blank lines in the pager. More...
 

Detailed Description

GUI display a file/email/help in a viewport with paging.

Authors
  • Michael R. Elkins

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 pager.h.

Macro Definition Documentation

◆ MUTT_PAGER_NO_FLAGS

#define MUTT_PAGER_NO_FLAGS   0

No flags are set.

Definition at line 43 of file pager.h.

◆ MUTT_SHOWFLAT

#define MUTT_SHOWFLAT   (1 << 0)

Show characters (used for displaying help)

Definition at line 44 of file pager.h.

◆ MUTT_SHOWCOLOR

#define MUTT_SHOWCOLOR   (1 << 1)

Show characters in color otherwise don't show characters.

Definition at line 45 of file pager.h.

◆ MUTT_HIDE

#define MUTT_HIDE   (1 << 2)

Don't show quoted text.

Definition at line 46 of file pager.h.

◆ MUTT_SEARCH

#define MUTT_SEARCH   (1 << 3)

Resolve search patterns.

Definition at line 47 of file pager.h.

◆ MUTT_TYPES

#define MUTT_TYPES   (1 << 4)

Compute line's type.

Definition at line 48 of file pager.h.

◆ MUTT_SHOW

#define MUTT_SHOW   (MUTT_SHOWCOLOR | MUTT_SHOWFLAT)

Definition at line 49 of file pager.h.

◆ MUTT_PAGER_NSKIP

#define MUTT_PAGER_NSKIP   (1 << 5)

Preserve whitespace with smartwrap.

Definition at line 52 of file pager.h.

◆ MUTT_PAGER_MARKER

#define MUTT_PAGER_MARKER   (1 << 6)

Use markers if option is set.

Definition at line 53 of file pager.h.

◆ MUTT_PAGER_RETWINCH

#define MUTT_PAGER_RETWINCH   (1 << 7)

Need reformatting on SIGWINCH.

Definition at line 54 of file pager.h.

◆ MUTT_PAGER_ATTACHMENT

#define MUTT_PAGER_ATTACHMENT   (1 << 8)

Attachments may exist.

Definition at line 55 of file pager.h.

◆ MUTT_PAGER_NOWRAP

#define MUTT_PAGER_NOWRAP   (1 << 9)

Format for term width, ignore $wrap.

Definition at line 56 of file pager.h.

◆ MUTT_PAGER_LOGS

#define MUTT_PAGER_LOGS   (1 << 10)

Logview mode.

Definition at line 57 of file pager.h.

◆ MUTT_PAGER_MESSAGE

#define MUTT_PAGER_MESSAGE   (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER)

Definition at line 58 of file pager.h.

◆ MUTT_DISPLAYFLAGS

#define MUTT_DISPLAYFLAGS   (MUTT_SHOW | MUTT_PAGER_NSKIP | MUTT_PAGER_MARKER | MUTT_PAGER_LOGS)

Definition at line 60 of file pager.h.

Typedef Documentation

◆ PagerFlags

typedef uint16_t PagerFlags

Flags for mutt_pager(), e.g. MUTT_SHOWFLAT.

Definition at line 42 of file pager.h.

Function Documentation

◆ mutt_pager()

int mutt_pager ( const char *  banner,
const char *  fname,
PagerFlags  flags,
struct Pager extra 
)

Display a file, or help, in a window.

Parameters
bannerTitle to display in status bar
fnameName of file to read
flagsFlags, e.g. MUTT_SHOWCOLOR
extraInfo about email to display
Return values
0Success
-1Error

This pager is actually not so simple as it once was. It now operates in two modes: one for viewing messages and the other for viewing help. These can be distinguished by whether or not "email" is NULL. The "email" arg is there so that we can do operations on the current message without the need to pop back out to the main-menu.

Definition at line 2205 of file pager.c.

2206 {
2207  static char searchbuf[256] = { 0 };
2208  char buf[1024];
2209  int ch = 0, rc = -1;
2210  bool first = true;
2211  int searchctx = 0;
2212  bool wrapped = false;
2213 
2214  struct Menu *pager_menu = NULL;
2215  int old_PagerIndexLines; /* some people want to resize it while inside the pager */
2216 #ifdef USE_NNTP
2217  char *followup_to = NULL;
2218 #endif
2219 
2220  if (!(flags & MUTT_SHOWCOLOR))
2221  flags |= MUTT_SHOWFLAT;
2222 
2223  int index_space = C_PagerIndexLines;
2224  if (extra->ctx && extra->ctx->mailbox)
2225  index_space = MIN(index_space, extra->ctx->mailbox->vcount);
2226 
2227  struct PagerRedrawData rd = { 0 };
2228  rd.banner = banner;
2229  rd.flags = flags;
2230  rd.extra = extra;
2231  rd.indexlen = index_space;
2232  rd.indicator = rd.indexlen / 3;
2233  rd.searchbuf = searchbuf;
2234  rd.has_types = (IsEmail(extra) || (flags & MUTT_SHOWCOLOR)) ? MUTT_TYPES : 0; /* main message or rfc822 attachment */
2235 
2236  rd.fp = fopen(fname, "r");
2237  if (!rd.fp)
2238  {
2239  mutt_perror(fname);
2240  return -1;
2241  }
2242 
2243  if (stat(fname, &rd.sb) != 0)
2244  {
2245  mutt_perror(fname);
2246  mutt_file_fclose(&rd.fp);
2247  return -1;
2248  }
2249  unlink(fname);
2250 
2251  if (rd.extra->win_index)
2252  {
2254  rd.extra->win_index->req_rows = index_space;
2256  }
2257  rd.extra->win_pager->parent->state.visible = true;
2260 
2261  /* Initialize variables */
2262 
2263  if (Context && IsEmail(extra) && !extra->email->read)
2264  {
2265  Context->msg_not_read_yet = extra->email->msgno;
2266  mutt_set_flag(Context->mailbox, extra->email, MUTT_READ, true);
2267  }
2268 
2269  rd.max_line = LINES; /* number of lines on screen, from curses */
2270  rd.line_info = mutt_mem_calloc(rd.max_line, sizeof(struct Line));
2271  for (size_t i = 0; i < rd.max_line; i++)
2272  {
2273  rd.line_info[i].type = -1;
2274  rd.line_info[i].search_cnt = -1;
2275  rd.line_info[i].syntax = mutt_mem_malloc(sizeof(struct TextSyntax));
2276  (rd.line_info[i].syntax)[0].first = -1;
2277  (rd.line_info[i].syntax)[0].last = -1;
2278  }
2279 
2280  struct Buffer helpstr = mutt_buffer_make(0);
2281  mutt_compile_help(buf, sizeof(buf), MENU_PAGER, PagerHelp);
2282  mutt_buffer_strcpy(&helpstr, buf);
2283  if (IsEmail(extra))
2284  {
2285  mutt_compile_help(buf, sizeof(buf), MENU_PAGER,
2286 #ifdef USE_NNTP
2287  (Context && (Context->mailbox->magic == MUTT_NNTP)) ?
2289 #endif
2290  PagerHelpExtra);
2291  mutt_buffer_addch(&helpstr, ' ');
2292  mutt_buffer_addstr(&helpstr, buf);
2293  }
2294  if (!InHelp)
2295  {
2296  mutt_make_help(buf, sizeof(buf), _("Help"), MENU_PAGER, OP_HELP);
2297  mutt_buffer_addch(&helpstr, ' ');
2298  mutt_buffer_addstr(&helpstr, buf);
2299  }
2300  rd.helpstr = mutt_b2s(&helpstr);
2301 
2302  pager_menu = mutt_menu_new(MENU_PAGER);
2303  pager_menu->pagelen = extra->win_pager->state.rows;
2304  pager_menu->win_index = extra->win_pager;
2305  pager_menu->win_ibar = extra->win_pbar;
2306 
2308  pager_menu->redraw_data = &rd;
2309  mutt_menu_push_current(pager_menu);
2310 
2311  while (ch != -1)
2312  {
2314 
2315  pager_custom_redraw(pager_menu);
2316 
2317  if (C_BrailleFriendly)
2318  {
2319  if (braille_line != -1)
2320  {
2322  braille_line = -1;
2323  }
2324  }
2325  else
2327 
2328  mutt_refresh();
2329 
2330  if (IsEmail(extra) && (OldEmail == extra->email) && (TopLine != rd.topline) &&
2331  (rd.line_info[rd.curline].offset < (rd.sb.st_size - 1)))
2332  {
2333  if ((TopLine - rd.topline) > rd.lines)
2334  rd.topline += rd.lines;
2335  else
2336  rd.topline = TopLine;
2337  continue;
2338  }
2339  else
2340  OldEmail = NULL;
2341 
2342  ch = km_dokey(MENU_PAGER);
2343  if (ch >= 0)
2344  {
2345  mutt_clear_error();
2346  }
2348 
2349  bool do_new_mail = false;
2350 
2351  if (Context && Context->mailbox && !OptAttachMsg)
2352  {
2353  int index_hint = 0; /* used to restore cursor position */
2354  int oldcount = Context->mailbox->msg_count;
2355  /* check for new mail */
2356  int check = mx_mbox_check(Context->mailbox, &index_hint);
2357  if (check < 0)
2358  {
2360  {
2361  /* fatal error occurred */
2362  ctx_free(&Context);
2363  pager_menu->redraw = REDRAW_FULL;
2364  break;
2365  }
2366  }
2367  else if ((check == MUTT_NEW_MAIL) || (check == MUTT_REOPENED) || (check == MUTT_FLAGS))
2368  {
2369  /* notify user of newly arrived mail */
2370  if (check == MUTT_NEW_MAIL)
2371  {
2372  for (size_t i = oldcount; i < Context->mailbox->msg_count; i++)
2373  {
2374  struct Email *e = Context->mailbox->emails[i];
2375 
2376  if (e && !e->read)
2377  {
2378  mutt_message(_("New mail in this mailbox"));
2379  do_new_mail = true;
2380  break;
2381  }
2382  }
2383  }
2384 
2385  if ((check == MUTT_NEW_MAIL) || (check == MUTT_REOPENED))
2386  {
2387  if (rd.menu && Context && Context->mailbox)
2388  {
2389  /* After the mailbox has been updated,
2390  * rd.menu->current might be invalid */
2391  rd.menu->current =
2392  MIN(rd.menu->current, MAX(Context->mailbox->msg_count - 1, 0));
2393  struct Email *e = mutt_get_virt_email(Context->mailbox, rd.menu->current);
2394  if (!e)
2395  continue;
2396 
2397  index_hint = e->index;
2398 
2399  bool q = Context->mailbox->quiet;
2400  Context->mailbox->quiet = true;
2401  update_index(rd.menu, Context, check, oldcount, index_hint);
2402  Context->mailbox->quiet = q;
2403 
2404  rd.menu->max = Context->mailbox->vcount;
2405 
2406  /* If these header pointers don't match, then our email may have
2407  * been deleted. Make the pointer safe, then leave the pager.
2408  * This have a unpleasant behaviour to close the pager even the
2409  * deleted message is not the opened one, but at least it's safe. */
2411  if (extra->email != e)
2412  {
2413  extra->email = e;
2414  break;
2415  }
2416  }
2417 
2418  pager_menu->redraw = REDRAW_FULL;
2419  OptSearchInvalid = true;
2420  }
2421  }
2422 
2423  if (mutt_mailbox_notify(Context ? Context->mailbox : NULL) || do_new_mail)
2424  {
2425  if (C_BeepNew)
2426  mutt_beep(true);
2427  if (C_NewMailCommand)
2428  {
2429  char cmd[1024];
2430  menu_status_line(cmd, sizeof(cmd), rd.menu, NONULL(C_NewMailCommand));
2431  if (mutt_system(cmd) != 0)
2432  mutt_error(_("Error running \"%s\""), cmd);
2433  }
2434  }
2435  }
2436 
2437  if (SigWinch)
2438  {
2439  SigWinch = 0;
2441  clearok(stdscr, true); /* force complete redraw */
2442 
2443  if (flags & MUTT_PAGER_RETWINCH)
2444  {
2445  /* Store current position. */
2446  rd.lines = -1;
2447  for (size_t i = 0; i <= rd.topline; i++)
2448  if (!rd.line_info[i].continuation)
2449  rd.lines++;
2450 
2451  Resize = mutt_mem_malloc(sizeof(struct Resize));
2452 
2453  Resize->line = rd.lines;
2456 
2457  ch = -1;
2458  rc = OP_REFORMAT_WINCH;
2459  }
2460  else
2461  {
2462  /* note: mutt_resize_screen() -> mutt_window_reflow() sets
2463  * REDRAW_FULL and REDRAW_FLOW */
2464  ch = 0;
2465  }
2466  continue;
2467  }
2468 
2469  if (ch < 0)
2470  {
2471  ch = 0;
2473  continue;
2474  }
2475 
2476  rc = ch;
2477 
2478  switch (ch)
2479  {
2480  case OP_EXIT:
2481  rc = -1;
2482  ch = -1;
2483  break;
2484 
2485  case OP_QUIT:
2486  if (query_quadoption(C_Quit, _("Quit NeoMutt?")) == MUTT_YES)
2487  {
2488  /* avoid prompting again in the index menu */
2489  cs_subset_str_native_set(NeoMutt->sub, "quit", MUTT_YES, NULL);
2490  ch = -1;
2491  }
2492  break;
2493 
2494  case OP_NEXT_PAGE:
2495  if (rd.line_info[rd.curline].offset < (rd.sb.st_size - 1))
2496  {
2498  }
2499  else if (C_PagerStop)
2500  {
2501  /* emulate "less -q" and don't go on to the next message. */
2502  mutt_error(_("Bottom of message is shown"));
2503  }
2504  else
2505  {
2506  /* end of the current message, so display the next message. */
2507  rc = OP_MAIN_NEXT_UNDELETED;
2508  ch = -1;
2509  }
2510  break;
2511 
2512  case OP_PREV_PAGE:
2513  if (rd.topline == 0)
2514  {
2515  mutt_message(_("Top of message is shown"));
2516  }
2517  else
2518  {
2520  rd.line_info, rd.topline, rd.hide_quoted);
2521  }
2522  break;
2523 
2524  case OP_NEXT_LINE:
2525  if (rd.line_info[rd.curline].offset < (rd.sb.st_size - 1))
2526  {
2527  rd.topline++;
2528  if (rd.hide_quoted)
2529  {
2530  while ((rd.line_info[rd.topline].type == MT_COLOR_QUOTED) &&
2531  (rd.topline < rd.last_line))
2532  {
2533  rd.topline++;
2534  }
2535  }
2536  }
2537  else
2538  mutt_message(_("Bottom of message is shown"));
2539  break;
2540 
2541  case OP_PREV_LINE:
2542  if (rd.topline)
2543  rd.topline = up_n_lines(1, rd.line_info, rd.topline, rd.hide_quoted);
2544  else
2545  mutt_error(_("Top of message is shown"));
2546  break;
2547 
2548  case OP_PAGER_TOP:
2549  if (rd.topline)
2550  rd.topline = 0;
2551  else
2552  mutt_error(_("Top of message is shown"));
2553  break;
2554 
2555  case OP_HALF_UP:
2556  if (rd.topline)
2557  {
2558  rd.topline = up_n_lines(rd.extra->win_pager->state.rows / 2 +
2559  (rd.extra->win_pager->state.rows % 2),
2560  rd.line_info, rd.topline, rd.hide_quoted);
2561  }
2562  else
2563  mutt_error(_("Top of message is shown"));
2564  break;
2565 
2566  case OP_HALF_DOWN:
2567  if (rd.line_info[rd.curline].offset < (rd.sb.st_size - 1))
2568  {
2569  rd.topline = up_n_lines(rd.extra->win_pager->state.rows / 2,
2570  rd.line_info, rd.curline, rd.hide_quoted);
2571  }
2572  else if (C_PagerStop)
2573  {
2574  /* emulate "less -q" and don't go on to the next message. */
2575  mutt_error(_("Bottom of message is shown"));
2576  }
2577  else
2578  {
2579  /* end of the current message, so display the next message. */
2580  rc = OP_MAIN_NEXT_UNDELETED;
2581  ch = -1;
2582  }
2583  break;
2584 
2585  case OP_SEARCH_NEXT:
2586  case OP_SEARCH_OPPOSITE:
2587  if (rd.search_compiled)
2588  {
2589  wrapped = false;
2590 
2591  if (C_SearchContext < rd.extra->win_pager->state.rows)
2592  searchctx = C_SearchContext;
2593  else
2594  searchctx = 0;
2595 
2596  search_next:
2597  if ((!rd.search_back && (ch == OP_SEARCH_NEXT)) ||
2598  (rd.search_back && (ch == OP_SEARCH_OPPOSITE)))
2599  {
2600  /* searching forward */
2601  int i;
2602  for (i = wrapped ? 0 : rd.topline + searchctx + 1; i < rd.last_line; i++)
2603  {
2604  if ((!rd.hide_quoted || (rd.line_info[i].type != MT_COLOR_QUOTED)) &&
2605  !rd.line_info[i].continuation && (rd.line_info[i].search_cnt > 0))
2606  {
2607  break;
2608  }
2609  }
2610 
2611  if (i < rd.last_line)
2612  rd.topline = i;
2613  else if (wrapped || !C_WrapSearch)
2614  mutt_error(_("Not found"));
2615  else
2616  {
2617  mutt_message(_("Search wrapped to top"));
2618  wrapped = true;
2619  goto search_next;
2620  }
2621  }
2622  else
2623  {
2624  /* searching backward */
2625  int i;
2626  for (i = wrapped ? rd.last_line : rd.topline + searchctx - 1; i >= 0; i--)
2627  {
2628  if ((!rd.hide_quoted ||
2629  (rd.has_types && (rd.line_info[i].type != MT_COLOR_QUOTED))) &&
2630  !rd.line_info[i].continuation && (rd.line_info[i].search_cnt > 0))
2631  {
2632  break;
2633  }
2634  }
2635 
2636  if (i >= 0)
2637  rd.topline = i;
2638  else if (wrapped || !C_WrapSearch)
2639  mutt_error(_("Not found"));
2640  else
2641  {
2642  mutt_message(_("Search wrapped to bottom"));
2643  wrapped = true;
2644  goto search_next;
2645  }
2646  }
2647 
2648  if (rd.line_info[rd.topline].search_cnt > 0)
2649  {
2650  rd.search_flag = MUTT_SEARCH;
2651  /* give some context for search results */
2652  if (rd.topline - searchctx > 0)
2653  rd.topline -= searchctx;
2654  }
2655 
2656  break;
2657  }
2658  /* no previous search pattern */
2659  /* fallthrough */
2660 
2661  case OP_SEARCH:
2662  case OP_SEARCH_REVERSE:
2663  mutt_str_strfcpy(buf, searchbuf, sizeof(buf));
2664  if (mutt_get_field(((ch == OP_SEARCH) || (ch == OP_SEARCH_NEXT)) ?
2665  _("Search for: ") :
2666  _("Reverse search for: "),
2667  buf, sizeof(buf), MUTT_CLEAR) != 0)
2668  {
2669  break;
2670  }
2671 
2672  if (strcmp(buf, searchbuf) == 0)
2673  {
2674  if (rd.search_compiled)
2675  {
2676  /* do an implicit search-next */
2677  if (ch == OP_SEARCH)
2678  ch = OP_SEARCH_NEXT;
2679  else
2680  ch = OP_SEARCH_OPPOSITE;
2681 
2682  wrapped = false;
2683  goto search_next;
2684  }
2685  }
2686 
2687  if (buf[0] == '\0')
2688  break;
2689 
2690  mutt_str_strfcpy(searchbuf, buf, sizeof(searchbuf));
2691 
2692  /* leave search_back alone if ch == OP_SEARCH_NEXT */
2693  if (ch == OP_SEARCH)
2694  rd.search_back = false;
2695  else if (ch == OP_SEARCH_REVERSE)
2696  rd.search_back = true;
2697 
2698  if (rd.search_compiled)
2699  {
2700  regfree(&rd.search_re);
2701  for (size_t i = 0; i < rd.last_line; i++)
2702  {
2703  FREE(&(rd.line_info[i].search));
2704  rd.line_info[i].search_cnt = -1;
2705  }
2706  }
2707 
2708  int rflags = mutt_mb_is_lower(searchbuf) ? REG_ICASE : 0;
2709  int err = REG_COMP(&rd.search_re, searchbuf, REG_NEWLINE | rflags);
2710  if (err != 0)
2711  {
2712  regerror(err, &rd.search_re, buf, sizeof(buf));
2713  mutt_error("%s", buf);
2714  for (size_t i = 0; i < rd.max_line; i++)
2715  {
2716  /* cleanup */
2717  FREE(&(rd.line_info[i].search));
2718  rd.line_info[i].search_cnt = -1;
2719  }
2720  rd.search_flag = 0;
2721  rd.search_compiled = false;
2722  }
2723  else
2724  {
2725  rd.search_compiled = true;
2726  /* update the search pointers */
2727  int line_num = 0;
2728  while (display_line(rd.fp, &rd.last_pos, &rd.line_info, line_num,
2729  &rd.last_line, &rd.max_line,
2730  MUTT_SEARCH | (flags & MUTT_PAGER_NSKIP) | (flags & MUTT_PAGER_NOWRAP),
2731  &rd.quote_list, &rd.q_level, &rd.force_redraw,
2732  &rd.search_re, rd.extra->win_pager) == 0)
2733  {
2734  line_num++;
2735  }
2736 
2737  if (!rd.search_back)
2738  {
2739  /* searching forward */
2740  int i;
2741  for (i = rd.topline; i < rd.last_line; i++)
2742  {
2743  if ((!rd.hide_quoted || (rd.line_info[i].type != MT_COLOR_QUOTED)) &&
2744  !rd.line_info[i].continuation && (rd.line_info[i].search_cnt > 0))
2745  {
2746  break;
2747  }
2748  }
2749 
2750  if (i < rd.last_line)
2751  rd.topline = i;
2752  }
2753  else
2754  {
2755  /* searching backward */
2756  int i;
2757  for (i = rd.topline; i >= 0; i--)
2758  {
2759  if ((!rd.hide_quoted || (rd.line_info[i].type != MT_COLOR_QUOTED)) &&
2760  !rd.line_info[i].continuation && (rd.line_info[i].search_cnt > 0))
2761  {
2762  break;
2763  }
2764  }
2765 
2766  if (i >= 0)
2767  rd.topline = i;
2768  }
2769 
2770  if (rd.line_info[rd.topline].search_cnt == 0)
2771  {
2772  rd.search_flag = 0;
2773  mutt_error(_("Not found"));
2774  }
2775  else
2776  {
2777  rd.search_flag = MUTT_SEARCH;
2778  /* give some context for search results */
2779  if (C_SearchContext < rd.extra->win_pager->state.rows)
2780  searchctx = C_SearchContext;
2781  else
2782  searchctx = 0;
2783  if (rd.topline - searchctx > 0)
2784  rd.topline -= searchctx;
2785  }
2786  }
2787  pager_menu->redraw = REDRAW_BODY;
2788  break;
2789 
2790  case OP_SEARCH_TOGGLE:
2791  if (rd.search_compiled)
2792  {
2793  rd.search_flag ^= MUTT_SEARCH;
2794  pager_menu->redraw = REDRAW_BODY;
2795  }
2796  break;
2797 
2798  case OP_SORT:
2799  case OP_SORT_REVERSE:
2800  CHECK_MODE(IsEmail(extra))
2801  if (mutt_select_sort((ch == OP_SORT_REVERSE)) == 0)
2802  {
2803  OptNeedResort = true;
2804  ch = -1;
2805  rc = OP_DISPLAY_MESSAGE;
2806  }
2807  break;
2808 
2809  case OP_HELP:
2810  if (InHelp)
2811  {
2812  /* don't let the user enter the help-menu from the help screen! */
2813  mutt_error(_("Help is currently being shown"));
2814  break;
2815  }
2816 
2817  InHelp = true;
2818  mutt_help(MENU_PAGER, pager_menu->win_index->state.cols);
2819  pager_menu->redraw = REDRAW_FULL;
2820  InHelp = false;
2821  break;
2822 
2823  case OP_PAGER_HIDE_QUOTED:
2824  if (rd.has_types)
2825  {
2826  rd.hide_quoted ^= MUTT_HIDE;
2827  if (rd.hide_quoted && (rd.line_info[rd.topline].type == MT_COLOR_QUOTED))
2828  rd.topline = up_n_lines(1, rd.line_info, rd.topline, rd.hide_quoted);
2829  else
2830  pager_menu->redraw = REDRAW_BODY;
2831  }
2832  break;
2833 
2834  case OP_PAGER_SKIP_QUOTED:
2835  if (rd.has_types)
2836  {
2837  int dretval = 0;
2838  int new_topline = rd.topline;
2839 
2840  /* Skip all the email headers */
2841  if (IS_HEADER(rd.line_info[new_topline].type))
2842  {
2843  while (((new_topline < rd.last_line) ||
2844  (0 == (dretval = display_line(
2845  rd.fp, &rd.last_pos, &rd.line_info, new_topline, &rd.last_line,
2846  &rd.max_line, MUTT_TYPES | (flags & MUTT_PAGER_NOWRAP),
2847  &rd.quote_list, &rd.q_level, &rd.force_redraw,
2848  &rd.search_re, rd.extra->win_pager)))) &&
2849  IS_HEADER(rd.line_info[new_topline].type))
2850  {
2851  new_topline++;
2852  }
2853  rd.topline = new_topline;
2854  break;
2855  }
2856 
2857  while ((((new_topline + C_SkipQuotedOffset) < rd.last_line) ||
2858  (0 == (dretval = display_line(
2859  rd.fp, &rd.last_pos, &rd.line_info, new_topline, &rd.last_line,
2860  &rd.max_line, MUTT_TYPES | (flags & MUTT_PAGER_NOWRAP),
2861  &rd.quote_list, &rd.q_level, &rd.force_redraw,
2862  &rd.search_re, rd.extra->win_pager)))) &&
2863  (rd.line_info[new_topline + C_SkipQuotedOffset].type != MT_COLOR_QUOTED))
2864  {
2865  new_topline++;
2866  }
2867 
2868  if (dretval < 0)
2869  {
2870  mutt_error(_("No more quoted text"));
2871  break;
2872  }
2873 
2874  while ((((new_topline + C_SkipQuotedOffset) < rd.last_line) ||
2875  (0 == (dretval = display_line(
2876  rd.fp, &rd.last_pos, &rd.line_info, new_topline, &rd.last_line,
2877  &rd.max_line, MUTT_TYPES | (flags & MUTT_PAGER_NOWRAP),
2878  &rd.quote_list, &rd.q_level, &rd.force_redraw,
2879  &rd.search_re, rd.extra->win_pager)))) &&
2880  (rd.line_info[new_topline + C_SkipQuotedOffset].type == MT_COLOR_QUOTED))
2881  {
2882  new_topline++;
2883  }
2884 
2885  if (dretval < 0)
2886  {
2887  mutt_error(_("No more unquoted text after quoted text"));
2888  break;
2889  }
2890  rd.topline = new_topline;
2891  }
2892  break;
2893 
2894  case OP_PAGER_BOTTOM: /* move to the end of the file */
2895  if (rd.line_info[rd.curline].offset < (rd.sb.st_size - 1))
2896  {
2897  int line_num = rd.curline;
2898  /* make sure the types are defined to the end of file */
2899  while (display_line(rd.fp, &rd.last_pos, &rd.line_info, line_num, &rd.last_line,
2900  &rd.max_line, rd.has_types | (flags & MUTT_PAGER_NOWRAP),
2901  &rd.quote_list, &rd.q_level, &rd.force_redraw,
2902  &rd.search_re, rd.extra->win_pager) == 0)
2903  {
2904  line_num++;
2905  }
2907  rd.last_line, rd.hide_quoted);
2908  }
2909  else
2910  mutt_error(_("Bottom of message is shown"));
2911  break;
2912 
2913  case OP_REDRAW:
2914  mutt_window_reflow(NULL);
2915  clearok(stdscr, true);
2916  pager_menu->redraw = REDRAW_FULL;
2917  break;
2918 
2919  case OP_NULL:
2921  break;
2922 
2923  /* --------------------------------------------------------------------
2924  * The following are operations on the current message rather than
2925  * adjusting the view of the message. */
2926 
2927  case OP_BOUNCE_MESSAGE:
2928  {
2929  struct Mailbox *m = Context ? Context->mailbox : NULL;
2930  CHECK_MODE(IsEmail(extra) || IsMsgAttach(extra))
2931  CHECK_ATTACH;
2932  if (IsMsgAttach(extra))
2933  mutt_attach_bounce(m, extra->fp, extra->actx, extra->body);
2934  else
2935  {
2936  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
2937  emaillist_add_email(&el, extra->email);
2938  ci_bounce_message(m, &el);
2939  emaillist_clear(&el);
2940  }
2941  break;
2942  }
2943 
2944  case OP_RESEND:
2945  CHECK_MODE(IsEmail(extra) || IsMsgAttach(extra))
2946  CHECK_ATTACH;
2947  if (IsMsgAttach(extra))
2948  mutt_attach_resend(extra->fp, extra->actx, extra->body);
2949  else
2950  mutt_resend_message(NULL, extra->ctx, extra->email);
2951  pager_menu->redraw = REDRAW_FULL;
2952  break;
2953 
2954  case OP_COMPOSE_TO_SENDER:
2955  CHECK_MODE(IsEmail(extra) || IsMsgAttach(extra));
2956  CHECK_ATTACH;
2957  if (IsMsgAttach(extra))
2958  mutt_attach_mail_sender(extra->fp, extra->email, extra->actx, extra->body);
2959  else
2960  {
2961  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
2962  emaillist_add_email(&el, extra->email);
2963  ci_send_message(SEND_TO_SENDER, NULL, NULL, extra->ctx, &el);
2964  emaillist_clear(&el);
2965  }
2966  pager_menu->redraw = REDRAW_FULL;
2967  break;
2968 
2969  case OP_CHECK_TRADITIONAL:
2970  CHECK_MODE(IsEmail(extra));
2971  if (!(WithCrypto & APPLICATION_PGP))
2972  break;
2973  if (!(extra->email->security & PGP_TRADITIONAL_CHECKED))
2974  {
2975  ch = -1;
2976  rc = OP_CHECK_TRADITIONAL;
2977  }
2978  break;
2979 
2980  case OP_CREATE_ALIAS:
2981  CHECK_MODE(IsEmail(extra) || IsMsgAttach(extra));
2982  if (IsMsgAttach(extra))
2983  mutt_alias_create(extra->body->email->env, NULL);
2984  else
2985  mutt_alias_create(extra->email->env, NULL);
2986  break;
2987 
2988  case OP_PURGE_MESSAGE:
2989  case OP_DELETE:
2990  CHECK_MODE(IsEmail(extra));
2992  /* L10N: CHECK_ACL */
2993  CHECK_ACL(MUTT_ACL_DELETE, _("Can't delete message"));
2994 
2995  mutt_set_flag(Context->mailbox, extra->email, MUTT_DELETE, true);
2996  mutt_set_flag(Context->mailbox, extra->email, MUTT_PURGE, (ch == OP_PURGE_MESSAGE));
2997  if (C_DeleteUntag)
2998  mutt_set_flag(Context->mailbox, extra->email, MUTT_TAG, false);
2999  pager_menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
3000  if (C_Resolve)
3001  {
3002  ch = -1;
3003  rc = OP_MAIN_NEXT_UNDELETED;
3004  }
3005  break;
3006 
3007  case OP_MAIN_SET_FLAG:
3008  case OP_MAIN_CLEAR_FLAG:
3009  {
3010  CHECK_MODE(IsEmail(extra));
3012 
3013  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3014  emaillist_add_email(&el, extra->email);
3015 
3016  if (mutt_change_flag(Context->mailbox, &el, (ch == OP_MAIN_SET_FLAG)) == 0)
3017  pager_menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
3018  if (extra->email->deleted && C_Resolve)
3019  {
3020  ch = -1;
3021  rc = OP_MAIN_NEXT_UNDELETED;
3022  }
3023  emaillist_clear(&el);
3024  break;
3025  }
3026 
3027  case OP_DELETE_THREAD:
3028  case OP_DELETE_SUBTHREAD:
3029  case OP_PURGE_THREAD:
3030  {
3031  CHECK_MODE(IsEmail(extra));
3033  /* L10N: CHECK_ACL */
3034  /* L10N: Due to the implementation details we do not know whether we
3035  delete zero, 1, 12, ... messages. So in English we use
3036  "messages". Your language might have other means to express this.
3037  */
3038  CHECK_ACL(MUTT_ACL_DELETE, _("Can't delete messages"));
3039 
3040  int subthread = (ch == OP_DELETE_SUBTHREAD);
3041  int r = mutt_thread_set_flag(extra->email, MUTT_DELETE, 1, subthread);
3042  if (r == -1)
3043  break;
3044  if (ch == OP_PURGE_THREAD)
3045  {
3046  r = mutt_thread_set_flag(extra->email, MUTT_PURGE, true, subthread);
3047  if (r == -1)
3048  break;
3049  }
3050 
3051  if (C_DeleteUntag)
3052  mutt_thread_set_flag(extra->email, MUTT_TAG, 0, subthread);
3053  if (C_Resolve)
3054  {
3055  rc = OP_MAIN_NEXT_UNDELETED;
3056  ch = -1;
3057  }
3058 
3059  if (!C_Resolve && (C_PagerIndexLines != 0))
3060  pager_menu->redraw = REDRAW_FULL;
3061  else
3062  pager_menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
3063 
3064  break;
3065  }
3066 
3067  case OP_DISPLAY_ADDRESS:
3068  CHECK_MODE(IsEmail(extra) || IsMsgAttach(extra));
3069  if (IsMsgAttach(extra))
3070  mutt_display_address(extra->body->email->env);
3071  else
3072  mutt_display_address(extra->email->env);
3073  break;
3074 
3075  case OP_ENTER_COMMAND:
3076  old_PagerIndexLines = C_PagerIndexLines;
3077 
3079  pager_menu->redraw = REDRAW_FULL;
3080 
3081  if (OptNeedResort)
3082  {
3083  OptNeedResort = false;
3084  CHECK_MODE(IsEmail(extra));
3085  OptNeedResort = true;
3086  }
3087 
3088  if (old_PagerIndexLines != C_PagerIndexLines)
3089  {
3090  mutt_menu_free(&rd.menu);
3091  }
3092 
3093  if ((pager_menu->redraw & REDRAW_FLOW) && (flags & MUTT_PAGER_RETWINCH))
3094  {
3095  ch = -1;
3096  rc = OP_REFORMAT_WINCH;
3097  continue;
3098  }
3099 
3100  ch = 0;
3101  break;
3102 
3103  case OP_FLAG_MESSAGE:
3104  CHECK_MODE(IsEmail(extra));
3106  /* L10N: CHECK_ACL */
3107  CHECK_ACL(MUTT_ACL_WRITE, "Can't flag message");
3108 
3109  mutt_set_flag(Context->mailbox, extra->email, MUTT_FLAG, !extra->email->flagged);
3110  pager_menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
3111  if (C_Resolve)
3112  {
3113  ch = -1;
3114  rc = OP_MAIN_NEXT_UNDELETED;
3115  }
3116  break;
3117 
3118  case OP_PIPE:
3119  CHECK_MODE(IsEmail(extra) || IsAttach(extra));
3120  if (IsAttach(extra))
3121  mutt_pipe_attachment_list(extra->actx, extra->fp, false, extra->body, false);
3122  else
3123  {
3124  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3125  el_add_tagged(&el, extra->ctx, extra->email, false);
3126  mutt_pipe_message(extra->ctx->mailbox, &el);
3127  emaillist_clear(&el);
3128  }
3129  break;
3130 
3131  case OP_PRINT:
3132  CHECK_MODE(IsEmail(extra) || IsAttach(extra));
3133  if (IsAttach(extra))
3134  mutt_print_attachment_list(extra->actx, extra->fp, false, extra->body);
3135  else
3136  {
3137  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3138  el_add_tagged(&el, extra->ctx, extra->email, false);
3139  mutt_print_message(extra->ctx->mailbox, &el);
3140  emaillist_clear(&el);
3141  }
3142  break;
3143 
3144  case OP_MAIL:
3145  CHECK_MODE(IsEmail(extra) && !IsAttach(extra));
3146  CHECK_ATTACH;
3147  ci_send_message(SEND_NO_FLAGS, NULL, NULL, extra->ctx, NULL);
3148  pager_menu->redraw = REDRAW_FULL;
3149  break;
3150 
3151 #ifdef USE_NNTP
3152  case OP_POST:
3153  CHECK_MODE(IsEmail(extra) && !IsAttach(extra));
3154  CHECK_ATTACH;
3155  if (extra->ctx && (extra->ctx->mailbox->magic == MUTT_NNTP) &&
3156  !((struct NntpMboxData *) extra->ctx->mailbox->mdata)->allowed && (query_quadoption(C_PostModerated, _("Posting to this group not allowed, may be moderated. Continue?")) != MUTT_YES))
3157  {
3158  break;
3159  }
3160  ci_send_message(SEND_NEWS, NULL, NULL, extra->ctx, NULL);
3161  pager_menu->redraw = REDRAW_FULL;
3162  break;
3163 
3164  case OP_FORWARD_TO_GROUP:
3165  CHECK_MODE(IsEmail(extra) || IsMsgAttach(extra));
3166  CHECK_ATTACH;
3167  if (extra->ctx && (extra->ctx->mailbox->magic == MUTT_NNTP) &&
3168  !((struct NntpMboxData *) extra->ctx->mailbox->mdata)->allowed && (query_quadoption(C_PostModerated, _("Posting to this group not allowed, may be moderated. Continue?")) != MUTT_YES))
3169  {
3170  break;
3171  }
3172  if (IsMsgAttach(extra))
3173  mutt_attach_forward(extra->fp, extra->email, extra->actx, extra->body, SEND_NEWS);
3174  else
3175  {
3176  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3177  emaillist_add_email(&el, extra->email);
3178  ci_send_message(SEND_NEWS | SEND_FORWARD, NULL, NULL, extra->ctx, &el);
3179  emaillist_clear(&el);
3180  }
3181  pager_menu->redraw = REDRAW_FULL;
3182  break;
3183 
3184  case OP_FOLLOWUP:
3185  CHECK_MODE(IsEmail(extra) || IsMsgAttach(extra));
3186  CHECK_ATTACH;
3187 
3188  if (IsMsgAttach(extra))
3189  followup_to = extra->body->email->env->followup_to;
3190  else
3191  followup_to = extra->email->env->followup_to;
3192 
3193  if (!followup_to || (mutt_str_strcasecmp(followup_to, "poster") != 0) ||
3195  _("Reply by mail as poster prefers?")) != MUTT_YES))
3196  {
3197  if (extra->ctx && (extra->ctx->mailbox->magic == MUTT_NNTP) &&
3198  !((struct NntpMboxData *) extra->ctx->mailbox->mdata)->allowed && (query_quadoption(C_PostModerated, _("Posting to this group not allowed, may be moderated. Continue?")) != MUTT_YES))
3199  {
3200  break;
3201  }
3202  if (IsMsgAttach(extra))
3203  {
3204  mutt_attach_reply(extra->fp, extra->email, extra->actx, extra->body,
3205  SEND_NEWS | SEND_REPLY);
3206  }
3207  else
3208  {
3209  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3210  emaillist_add_email(&el, extra->email);
3211  ci_send_message(SEND_NEWS | SEND_REPLY, NULL, NULL, extra->ctx, &el);
3212  emaillist_clear(&el);
3213  }
3214  pager_menu->redraw = REDRAW_FULL;
3215  break;
3216  }
3217 #endif
3218  /* fallthrough */
3219  case OP_REPLY:
3220  case OP_GROUP_REPLY:
3221  case OP_GROUP_CHAT_REPLY:
3222  case OP_LIST_REPLY:
3223  {
3224  CHECK_MODE(IsEmail(extra) || IsMsgAttach(extra));
3225  CHECK_ATTACH;
3226 
3227  SendFlags replyflags = SEND_REPLY;
3228  if (ch == OP_GROUP_REPLY)
3229  replyflags |= SEND_GROUP_REPLY;
3230  else if (ch == OP_GROUP_CHAT_REPLY)
3231  replyflags |= SEND_GROUP_CHAT_REPLY;
3232  else if (ch == OP_LIST_REPLY)
3233  replyflags |= SEND_LIST_REPLY;
3234 
3235  if (IsMsgAttach(extra))
3236  mutt_attach_reply(extra->fp, extra->email, extra->actx, extra->body, replyflags);
3237  else
3238  {
3239  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3240  emaillist_add_email(&el, extra->email);
3241  ci_send_message(replyflags, NULL, NULL, extra->ctx, &el);
3242  emaillist_clear(&el);
3243  }
3244  pager_menu->redraw = REDRAW_FULL;
3245  break;
3246  }
3247 
3248  case OP_RECALL_MESSAGE:
3249  {
3250  CHECK_MODE(IsEmail(extra) && !IsAttach(extra));
3251  CHECK_ATTACH;
3252  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3253  emaillist_add_email(&el, extra->email);
3254  ci_send_message(SEND_POSTPONED, NULL, NULL, extra->ctx, &el);
3255  emaillist_clear(&el);
3256  pager_menu->redraw = REDRAW_FULL;
3257  break;
3258  }
3259 
3260  case OP_FORWARD_MESSAGE:
3261  CHECK_MODE(IsEmail(extra) || IsMsgAttach(extra));
3262  CHECK_ATTACH;
3263  if (IsMsgAttach(extra))
3264  mutt_attach_forward(extra->fp, extra->email, extra->actx, extra->body, SEND_NO_FLAGS);
3265  else
3266  {
3267  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3268  emaillist_add_email(&el, extra->email);
3269  ci_send_message(SEND_FORWARD, NULL, NULL, extra->ctx, &el);
3270  emaillist_clear(&el);
3271  }
3272  pager_menu->redraw = REDRAW_FULL;
3273  break;
3274 
3275  case OP_DECRYPT_SAVE:
3276  if (!WithCrypto)
3277  {
3278  ch = -1;
3279  break;
3280  }
3281  /* fallthrough */
3282  case OP_SAVE:
3283  if (IsAttach(extra))
3284  {
3285  mutt_save_attachment_list(extra->actx, extra->fp, false, extra->body,
3286  extra->email, NULL);
3287  break;
3288  }
3289  /* fallthrough */
3290  case OP_COPY_MESSAGE:
3291  case OP_DECODE_SAVE:
3292  case OP_DECODE_COPY:
3293  case OP_DECRYPT_COPY:
3294  {
3295  if (!(WithCrypto != 0) && (ch == OP_DECRYPT_COPY))
3296  {
3297  ch = -1;
3298  break;
3299  }
3300  CHECK_MODE(IsEmail(extra));
3301  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3302  emaillist_add_email(&el, extra->email);
3303  if ((mutt_save_message(Context->mailbox, &el,
3304  (ch == OP_DECRYPT_SAVE) || (ch == OP_SAVE) || (ch == OP_DECODE_SAVE),
3305  (ch == OP_DECODE_SAVE) || (ch == OP_DECODE_COPY),
3306  (ch == OP_DECRYPT_SAVE) || (ch == OP_DECRYPT_COPY)) == 0) &&
3307  ((ch == OP_SAVE) || (ch == OP_DECODE_SAVE) || (ch == OP_DECRYPT_SAVE)))
3308  {
3309  if (C_Resolve)
3310  {
3311  ch = -1;
3312  rc = OP_MAIN_NEXT_UNDELETED;
3313  }
3314  else
3315  pager_menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
3316  }
3317  emaillist_clear(&el);
3318  break;
3319  }
3320 
3321  case OP_SHELL_ESCAPE:
3323  break;
3324 
3325  case OP_TAG:
3326  CHECK_MODE(IsEmail(extra));
3327  if (Context)
3328  {
3329  mutt_set_flag(Context->mailbox, extra->email, MUTT_TAG, !extra->email->tagged);
3330 
3331  Context->last_tag =
3332  extra->email->tagged ?
3333  extra->email :
3334  ((Context->last_tag == extra->email && !extra->email->tagged) ?
3335  NULL :
3336  Context->last_tag);
3337  }
3338 
3339  pager_menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
3340  if (C_Resolve)
3341  {
3342  ch = -1;
3343  rc = OP_NEXT_ENTRY;
3344  }
3345  break;
3346 
3347  case OP_TOGGLE_NEW:
3348  CHECK_MODE(IsEmail(extra));
3350  /* L10N: CHECK_ACL */
3351  CHECK_ACL(MUTT_ACL_SEEN, _("Can't toggle new"));
3352 
3353  if (extra->email->read || extra->email->old)
3354  mutt_set_flag(Context->mailbox, extra->email, MUTT_NEW, true);
3355  else if (!first)
3356  mutt_set_flag(Context->mailbox, extra->email, MUTT_READ, true);
3357  first = false;
3358  Context->msg_not_read_yet = -1;
3359  pager_menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
3360  if (C_Resolve)
3361  {
3362  ch = -1;
3363  rc = OP_MAIN_NEXT_UNDELETED;
3364  }
3365  break;
3366 
3367  case OP_UNDELETE:
3368  CHECK_MODE(IsEmail(extra));
3370  /* L10N: CHECK_ACL */
3371  CHECK_ACL(MUTT_ACL_DELETE, _("Can't undelete message"));
3372 
3373  mutt_set_flag(Context->mailbox, extra->email, MUTT_DELETE, false);
3374  mutt_set_flag(Context->mailbox, extra->email, MUTT_PURGE, false);
3375  pager_menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
3376  if (C_Resolve)
3377  {
3378  ch = -1;
3379  rc = OP_NEXT_ENTRY;
3380  }
3381  break;
3382 
3383  case OP_UNDELETE_THREAD:
3384  case OP_UNDELETE_SUBTHREAD:
3385  {
3386  CHECK_MODE(IsEmail(extra));
3388  /* L10N: CHECK_ACL */
3389  /* L10N: Due to the implementation details we do not know whether we
3390  undelete zero, 1, 12, ... messages. So in English we use
3391  "messages". Your language might have other means to express this. */
3392  CHECK_ACL(MUTT_ACL_DELETE, _("Can't undelete messages"));
3393 
3394  int r = mutt_thread_set_flag(extra->email, MUTT_DELETE, false,
3395  (ch != OP_UNDELETE_THREAD));
3396  if (r != -1)
3397  {
3398  r = mutt_thread_set_flag(extra->email, MUTT_PURGE, false,
3399  (ch != OP_UNDELETE_THREAD));
3400  }
3401  if (r != -1)
3402  {
3403  if (C_Resolve)
3404  {
3405  rc = (ch == OP_DELETE_THREAD) ? OP_MAIN_NEXT_THREAD : OP_MAIN_NEXT_SUBTHREAD;
3406  ch = -1;
3407  }
3408 
3409  if (!C_Resolve && (C_PagerIndexLines != 0))
3410  pager_menu->redraw = REDRAW_FULL;
3411  else
3412  pager_menu->redraw |= REDRAW_STATUS | REDRAW_INDEX;
3413  }
3414  break;
3415  }
3416 
3417  case OP_VERSION:
3419  break;
3420 
3421  case OP_MAILBOX_LIST:
3423  break;
3424 
3425  case OP_VIEW_ATTACHMENTS:
3426  if (flags & MUTT_PAGER_ATTACHMENT)
3427  {
3428  ch = -1;
3429  rc = OP_ATTACH_COLLAPSE;
3430  break;
3431  }
3432  CHECK_MODE(IsEmail(extra));
3433  mutt_view_attachments(extra->email);
3434  if (Context && extra->email->attach_del)
3435  Context->mailbox->changed = true;
3436  pager_menu->redraw = REDRAW_FULL;
3437  break;
3438 
3439  case OP_MAIL_KEY:
3440  {
3441  if (!(WithCrypto & APPLICATION_PGP))
3442  {
3443  ch = -1;
3444  break;
3445  }
3446  CHECK_MODE(IsEmail(extra));
3447  CHECK_ATTACH;
3448  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3449  emaillist_add_email(&el, extra->email);
3450  ci_send_message(SEND_KEY, NULL, NULL, extra->ctx, &el);
3451  emaillist_clear(&el);
3452  pager_menu->redraw = REDRAW_FULL;
3453  break;
3454  }
3455 
3456  case OP_EDIT_LABEL:
3457  {
3458  CHECK_MODE(IsEmail(extra));
3459 
3460  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3461  emaillist_add_email(&el, extra->email);
3462  rc = mutt_label_message(Context->mailbox, &el);
3463  emaillist_clear(&el);
3464 
3465  if (rc > 0)
3466  {
3467  Context->mailbox->changed = true;
3468  pager_menu->redraw = REDRAW_FULL;
3469  mutt_message(ngettext("%d label changed", "%d labels changed", rc), rc);
3470  }
3471  else
3472  {
3473  mutt_message(_("No labels changed"));
3474  }
3475  break;
3476  }
3477 
3478  case OP_FORGET_PASSPHRASE:
3480  break;
3481 
3482  case OP_EXTRACT_KEYS:
3483  {
3484  if (!WithCrypto)
3485  {
3486  ch = -1;
3487  break;
3488  }
3489  CHECK_MODE(IsEmail(extra));
3490  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
3491  emaillist_add_email(&el, extra->email);
3493  emaillist_clear(&el);
3494  pager_menu->redraw = REDRAW_FULL;
3495  break;
3496  }
3497 
3498  case OP_WHAT_KEY:
3499  mutt_what_key();
3500  break;
3501 
3502  case OP_CHECK_STATS:
3503  mutt_check_stats();
3504  break;
3505 
3506 #ifdef USE_SIDEBAR
3507  case OP_SIDEBAR_NEXT:
3508  case OP_SIDEBAR_NEXT_NEW:
3509  case OP_SIDEBAR_PAGE_DOWN:
3510  case OP_SIDEBAR_PAGE_UP:
3511  case OP_SIDEBAR_PREV:
3512  case OP_SIDEBAR_PREV_NEW:
3514  break;
3515 
3516  case OP_SIDEBAR_TOGGLE_VISIBLE:
3517  bool_str_toggle(NeoMutt->sub, "sidebar_visible", NULL);
3519  break;
3520 #endif
3521 
3522  default:
3523  ch = -1;
3524  break;
3525  }
3526  }
3527 
3528  mutt_file_fclose(&rd.fp);
3529  if (IsEmail(extra))
3530  {
3531  if (Context)
3532  Context->msg_not_read_yet = -1;
3533  switch (rc)
3534  {
3535  case -1:
3536  case OP_DISPLAY_HEADERS:
3538  break;
3539  default:
3540  TopLine = rd.topline;
3541  OldEmail = extra->email;
3542  break;
3543  }
3544  }
3545 
3547 
3548  for (size_t i = 0; i < rd.max_line; i++)
3549  {
3550  FREE(&(rd.line_info[i].syntax));
3551  if (rd.search_compiled && rd.line_info[i].search)
3552  FREE(&(rd.line_info[i].search));
3553  }
3554  if (rd.search_compiled)
3555  {
3556  regfree(&rd.search_re);
3557  rd.search_compiled = false;
3558  }
3559  FREE(&rd.line_info);
3560  mutt_menu_pop_current(pager_menu);
3561  mutt_menu_free(&pager_menu);
3562  mutt_menu_free(&rd.menu);
3563 
3564  mutt_buffer_dealloc(&helpstr);
3565 
3566  if (rd.extra->win_index)
3567  {
3568  rd.extra->win_index->parent->state.visible = true;
3573  }
3574  rd.extra->win_pager->parent->state.visible = false;
3576 
3577  return (rc != -1) ? rc : 0;
3578 }
int km_dokey(enum MenuType menu)
Determine what a keypress should do.
Definition: keymap.c:617
struct Menu * menu
the Pager Index (PI)
Definition: pager.c:189
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
int mutt_save_message(struct Mailbox *m, struct EmailList *el, bool delete_original, bool decode, bool decrypt)
Save an email.
Definition: commands.c:1024
The "current" mailbox.
Definition: context.h:36
void mutt_window_move_abs(int row, int col)
Move the cursor to an absolute screen position.
Definition: mutt_window.c:445
FILE * fp
Source stream.
Definition: pager.h:70
#define MUTT_TYPES
Compute line&#39;s type.
Definition: pager.h:48
struct MuttWindow * win_index
Definition: pager.h:74
int mutt_thread_set_flag(struct Email *e, int flag, bool bf, bool subthread)
Set a flag on an entire thread.
Definition: flags.c:374
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
bool mutt_mailbox_list(void)
List the mailboxes with new mail.
Definition: mutt_mailbox.c:203
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
int msg_count
Total number of messages.
Definition: mailbox.h:90
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:70
short C_PagerContext
Config: Number of lines of overlap when changing pages in the pager.
Definition: pager.c:86
#define SEND_TO_SENDER
Compose new email to sender.
Definition: send.h:100
const char * banner
Definition: pager.c:194
void mutt_pipe_message(struct Mailbox *m, struct EmailList *el)
Pipe a message.
Definition: commands.c:698
The envelope/body of an email.
Definition: email.h:37
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:68
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
Definition: context.c:414
PagerFlags hide_quoted
Definition: pager.c:184
#define MIN(a, b)
Definition: memory.h:31
#define mutt_perror(...)
Definition: logging.h:85
GUI selectable list of items.
Definition: mutt_menu.h:82
WHERE bool C_BeepNew
Config: Make a noise when new mail arrives.
Definition: globals.h:204
int mx_mbox_check(struct Mailbox *m, int *index_hint)
Check for new mail - Wrapper for MxOps::mbox_check()
Definition: mx.c:1073
PagerFlags search_flag
Definition: pager.c:192
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:51
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3360
#define mutt_message(...)
Definition: logging.h:83
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
Definition: email.c:144
Keep track when the pager needs redrawing.
Definition: pager.c:170
static int up_n_lines(int nlines, struct Line *info, int cur, bool hiding)
Reposition the pager&#39;s view up by n lines.
Definition: pager.c:1907
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
WHERE unsigned char C_Quit
Config: Prompt before exiting NeoMutt.
Definition: globals.h:184
void mutt_display_address(struct Envelope *env)
Display the address of a message.
Definition: commands.c:907
#define MUTT_SHOWCOLOR
Show characters in color otherwise don&#39;t show characters.
Definition: pager.h:45
#define REDRAW_FLOW
Used by pager to reflow text.
Definition: mutt_menu.h:49
WHERE unsigned char C_FollowupToPoster
Config: (nntp) Reply to the poster if &#39;poster&#39; is in the &#39;Followup-To&#39; header.
Definition: globals.h:190
void mutt_view_attachments(struct Email *e)
Show the attachments in a Menu.
Definition: recvattach.c:1407
static int TopLine
Definition: pager.c:203
static void cleanup_quote(struct QClass **quote_list)
Free a quote list.
Definition: pager.c:561
void mutt_save_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, struct Email *e, struct Menu *menu)
Save a list of attachments.
Definition: recvattach.c:647
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
#define CHECK_ACL(aclbit, action)
Definition: pager.c:277
#define SEND_FORWARD
Forward email.
Definition: send.h:91
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:100
WHERE bool OptNeedResort
(pseudo) used to force a re-sort
Definition: options.h:41
void mutt_check_stats(void)
Forcibly update mailbox stats.
Definition: commands.c:1390
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
Definition: crypt.c:103
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
#define IsMsgAttach(pager)
Definition: pager.c:247
void mutt_enter_command(void)
enter a neomutt command
Definition: commands.c:861
static void pager_custom_redraw(struct Menu *pager_menu)
Redraw the pager window - Implements Menu::menu_custom_redraw()
Definition: pager.c:1931
String manipulation buffer.
Definition: buffer.h:33
Flagged messages.
Definition: mutt.h:106
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: ncrypt.h:136
#define _(a)
Definition: message.h:28
const char * helpstr
Definition: pager.c:195
WHERE bool C_WrapSearch
Config: Wrap around when the search hits the end.
Definition: globals.h:261
struct Line * line_info
Definition: pager.c:197
WHERE bool C_BrailleFriendly
Config: Move the cursor to the beginning of the line.
Definition: globals.h:205
void menu_status_line(char *buf, size_t buflen, struct Menu *menu, const char *p)
Create the status line.
Definition: status.c:409
struct Body * body
Current attachment.
Definition: pager.h:69
Messages to be purged (bypass trash)
Definition: mutt.h:104
PagerFlags flags
Definition: pager.c:172
static bool InHelp
Definition: pager.c:206
bool search_back
Definition: pager.c:164
bool search_compiled
Definition: pager.c:163
short type
Definition: pager.c:136
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: pager.h:56
uint16_t SendFlags
Flags for ci_send_message(), e.g. SEND_REPLY.
Definition: send.h:86
Pager: quoted text.
Definition: color.h:82
#define SEND_POSTPONED
Recall a postponed email.
Definition: send.h:92
Container for Accounts, Notifications.
Definition: neomutt.h:35
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:65
static int display_line(FILE *fp, LOFF_T *last_pos, struct Line **line_info, int n, int *last, int *max, PagerFlags flags, struct QClass **quote_list, int *q_level, bool *force_redraw, regex_t *search_re, struct MuttWindow *win_pager)
Print a line on screen.
Definition: pager.c:1625
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:92
int vcount
The number of virtual messages.
Definition: mailbox.h:101
#define MUTT_PAGER_ATTACHMENT
Attachments may exist.
Definition: pager.h:55
LOFF_T last_pos
Definition: pager.c:187
void mutt_print_message(struct Mailbox *m, struct EmailList *el)
Print a message.
Definition: commands.c:720
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:87
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:97
#define MAX(a, b)
Definition: memory.h:30
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:243
int line
Definition: pager.c:162
void mutt_attach_reply(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *e_cur, SendFlags flags)
Attach a reply.
Definition: recvcmd.c:903
Pager pager (email viewer)
Definition: keymap.h:78
bool tagged
Email is tagged.
Definition: email.h:44
void * redraw_data
Definition: mutt_menu.h:150
bool read
Email is read.
Definition: email.h:51
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1022
void mutt_curses_set_cursor(enum MuttCursorState state)
Set the cursor state.
Definition: mutt_curses.c:76
struct Mailbox * mailbox
Definition: context.h:50
static int braille_line
Definition: pager.c:208
bool old
Email is seen, but unread.
Definition: email.h:50
int indexlen
Definition: pager.c:174
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
struct MuttWindow * win_ibar
Definition: mutt_menu.h:96
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
void mutt_what_key(void)
Ask the user to press a key.
Definition: keymap.c:1578
struct Envelope * env
Envelope information.
Definition: email.h:89
int has_types
Definition: pager.c:183
Display a normal cursor.
Definition: mutt_curses.h:82
FILE * fp
Definition: pager.c:198
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:52
bool mutt_mailbox_notify(struct Mailbox *m_cur)
Notify the user if there&#39;s new mail.
Definition: mutt_mailbox.c:190
short continuation
Definition: pager.c:137
void mutt_shell_escape(void)
invoke a command in a subshell
Definition: commands.c:833
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.h:80
void(* menu_custom_redraw)(struct Menu *menu)
Redraw the menu.
Definition: mutt_menu.h:149
WHERE unsigned char C_PostModerated
Config: (nntp) Allow posting to moderated newsgroups.
Definition: globals.h:189
#define MUTT_PAGER_NSKIP
Preserve whitespace with smartwrap.
Definition: pager.h:52
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:90
static struct Mapping PagerNewsHelpExtra[]
Definition: pager.c:235
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
bool force_redraw
Definition: pager.c:182
void * mdata
Driver specific data.
Definition: mailbox.h:135
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:73
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
#define SEND_KEY
Mail a PGP public key.
Definition: send.h:95
Window has a fixed size.
Definition: mutt_window.h:42
int msg_not_read_yet
Which msg "new" in pager, -1 if none.
Definition: context.h:44
struct MuttWindow * win_pager
Definition: pager.h:76
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:56
#define mutt_b2s(buf)
Definition: buffer.h:41
struct Pager * extra
Definition: pager.c:173
struct Context * ctx
Current mailbox.
Definition: pager.h:67
void mutt_alias_create(struct Envelope *cur, struct AddressList *al)
Create a new Alias from an Envelope or an Address.
Definition: alias.c:375
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:106
Window size depends on its children.
Definition: mutt_window.h:44
void mutt_attach_bounce(struct Mailbox *m, FILE *fp, struct AttachCtx *actx, struct Body *cur)
Bounce function, from the attachment menu.
Definition: recvcmd.c:167
short search_cnt
Definition: pager.c:139
struct TextSyntax * search
Definition: pager.c:141
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:91
WHERE bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:31
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
bool visible
Window is visible.
Definition: mutt_window.h:54
bool search_compiled
Definition: pager.c:191
void km_error_key(enum MenuType menu)
Handle an unbound key sequence.
Definition: keymap.c:1052
#define CHECK_ATTACH
Definition: pager.c:269
Messages to be deleted.
Definition: mutt.h:102
A mailbox.
Definition: mailbox.h:80
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:47
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:55
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
Nondestructive flags change (IMAP)
Definition: mx.h:75
WHERE bool C_Resolve
Config: Move to the next email whenever a command modifies an email.
Definition: globals.h:246
#define IS_HEADER(x)
Definition: pager.c:244
struct AttachCtx * actx
Attachment information.
Definition: pager.h:71
Tagged messages.
Definition: mutt.h:107
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:239
int max_line
Definition: pager.c:178
WHERE char * C_NewMailCommand
Config: External command to run when new mail arrives.
Definition: globals.h:137
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
#define CHECK_READONLY
Definition: pager.c:261
A line of text in the pager.
Definition: pager.c:133
New messages.
Definition: mutt.h:97
Messages that have been read.
Definition: mutt.h:100
static const struct Mapping PagerHelp[]
Definition: pager.c:219
int last_line
Definition: pager.c:179
static const struct Mapping PagerHelpExtra[]
Definition: pager.c:226
bool quiet
Inhibit status messages?
Definition: mailbox.h:117
#define SEND_NEWS
Reply to a news article.
Definition: send.h:102
int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el)
Send an email.
Definition: send.c:1880
WHERE bool OptSearchInvalid
(pseudo) used to invalidate the search pattern
Definition: options.h:50
enum MuttWindowSize size
Type of Window, e.g. MUTT_WIN_SIZE_FIXED.
Definition: mutt_window.h:95
#define MUTT_HIDE
Don&#39;t show quoted text.
Definition: pager.h:46
void update_index(struct Menu *menu, struct Context *ctx, int check, int oldcount, int index_hint)
Update the index.
Definition: index.c:612
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:92
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
#define SEND_REPLY
Reply to sender.
Definition: send.h:88
NNTP-specific Mailbox data -.
Definition: nntp.h:138
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:279
void mutt_clear_pager_position(void)
Reset the pager&#39;s viewing position.
Definition: pager.c:1922
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int max
Number of entries in the menu.
Definition: mutt_menu.h:88
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
struct MuttWindow * mutt_window_dialog(struct MuttWindow *win)
Find the parent Dialog of a Window.
Definition: mutt_window.c:558
WHERE bool C_DeleteUntag
Config: Untag messages when they are marked for deletion.
Definition: globals.h:209
bool C_PagerStop
Config: Don&#39;t automatically open the next message when at the end of a message.
Definition: pager.c:88
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
void mutt_attach_forward(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
Forward an Attachment.
Definition: recvcmd.c:755
struct QClass * quote_list
Definition: pager.c:186
#define IsEmail(pager)
Definition: pager.c:249
int indicator
the indicator line of the PI
Definition: pager.c:175
void mutt_pipe_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, bool filter)
Pipe a list of attachments to a command.
Definition: recvattach.c:872
struct Email * email
Current message.
Definition: pager.h:68
Highlighting for a line of text.
Definition: pager.c:123
void ci_bounce_message(struct Mailbox *m, struct EmailList *el)
Bounce an email.
Definition: commands.c:407
#define MUTT_PAGER_RETWINCH
Need reformatting on SIGWINCH.
Definition: pager.h:54
#define SEND_GROUP_REPLY
Reply to all.
Definition: send.h:89
#define MUTT_SEARCH
Resolve search patterns.
Definition: pager.h:47
#define REDRAW_BODY
Redraw the pager.
Definition: mutt_menu.h:48
int mutt_label_message(struct Mailbox *m, struct EmailList *el)
Let the user label a message.
Definition: mutt_header.c:125
char * searchbuf
Definition: pager.c:196
bool flagged
Marked important?
Definition: email.h:43
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:123
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
void mutt_help(enum MenuType menu, int wraplen)
Display the help menu.
Definition: help.c:443
bool deleted
Email is deleted.
Definition: email.h:45
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:346
struct MuttWindow * parent
Parent Window.
Definition: mutt_window.h:98
#define mutt_error(...)
Definition: logging.h:84
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
void mutt_timeout_hook(void)
Execute any timeout hooks.
Definition: hook.c:807
int mutt_select_sort(bool reverse)
Ask the user for a sort method.
Definition: commands.c:759
short C_SkipQuotedOffset
Config: Lines of context to show when skipping quoted text.
Definition: pager.c:90
int index
The absolute (unsorted) message number.
Definition: email.h:85
#define FREE(x)
Definition: memory.h:40
void crypt_extract_keys_from_messages(struct Mailbox *m, struct EmailList *el)
Extract keys from a message.
Definition: crypt.c:851
#define MUTT_ACL_SEEN
Change the &#39;seen&#39; status of a message.
Definition: mailbox.h:72
Hide the cursor.
Definition: mutt_curses.h:81
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
void mutt_attach_mail_sender(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur)
Compose an email to the sender in the email attachment.
Definition: recvcmd.c:1073
short req_rows
Number of rows required.
Definition: mutt_window.h:88
struct TextSyntax * syntax
Definition: pager.c:140
void mutt_make_help(char *buf, size_t buflen, const char *txt, enum MenuType menu, int op)
Create one entry for the help bar.
Definition: help.c:92
bool changed
Mailbox has been modified.
Definition: mailbox.h:113
int mutt_change_flag(struct Mailbox *m, struct EmailList *el, bool bf)
Change the flag on a Message.
Definition: flags.c:432
Keep track of screen resizing.
Definition: pager.c:160
void ctx_free(struct Context **ptr)
Free a Context.
Definition: context.c:49
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:38
New mail received in Mailbox.
Definition: mx.h:72
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
Definition: send.h:101
struct stat sb
Definition: pager.c:199
#define IsAttach(pager)
Definition: pager.c:246
int current
Current entry.
Definition: mutt_menu.h:87
int el_add_tagged(struct EmailList *el, struct Context *ctx, struct Email *e, bool use_tagged)
Get a list of the tagged Emails.
Definition: context.c:366
struct Buffer pathbuf
Definition: mailbox.h:82
struct MuttWindow * win_index
Definition: mutt_menu.h:95
char * mutt_compile_help(char *buf, size_t buflen, enum MenuType menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:115
Window wants as much space as possible.
Definition: mutt_window.h:43
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
LOFF_T offset
Definition: pager.c:135
Mailbox was reopened.
Definition: mx.h:74
int mutt_resend_message(FILE *fp, struct Context *ctx, struct Email *e_cur)
Resend an email.
Definition: send.c:1505
short C_SearchContext
Config: Context to display around search matches.
Definition: pager.c:89
#define CHECK_MODE(test)
Definition: pager.c:253
bool mutt_mb_is_lower(const char *s)
Does a multi-byte string contain only lowercase characters?
Definition: mbyte.c:358
struct Email * email
header information for message/rfc822
Definition: body.h:55
#define WithCrypto
Definition: ncrypt.h:160
#define MUTT_SHOWFLAT
Show characters (used for displaying help)
Definition: pager.h:44
void mutt_attach_resend(FILE *fp, struct AttachCtx *actx, struct Body *cur)
resend-message, from the attachment menu
Definition: recvcmd.c:290
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:52
static struct Email * OldEmail
Definition: pager.c:204
short C_PagerIndexLines
Config: Number of index lines to display above the pager.
Definition: pager.c:87
struct Email * last_tag
Last tagged msg (used to link threads)
Definition: context.h:41
regex_t search_re
Definition: pager.c:190
int msgno
Number displayed to the user.
Definition: email.h:86
const char * mutt_make_version(void)
Generate the NeoMutt version string.
Definition: muttlib.c:1559
bool search_back
Definition: pager.c:193
struct MuttWindow * win_pbar
Definition: pager.h:75
+ Here is the caller graph for this function:

◆ mutt_clear_pager_position()

void mutt_clear_pager_position ( void  )

Reset the pager's viewing position.

Definition at line 1922 of file pager.c.

1923 {
1924  TopLine = 0;
1925  OldEmail = NULL;
1926 }
static int TopLine
Definition: pager.c:203
static struct Email * OldEmail
Definition: pager.c:204
+ Here is the caller graph for this function:

Variable Documentation

◆ C_AllowAnsi

bool C_AllowAnsi

Config: Allow ANSI colour codes in rich text messages.

Definition at line 84 of file pager.c.

◆ C_HeaderColorPartial

bool C_HeaderColorPartial

Config: Only colour the part of the header matching the regex.

Definition at line 85 of file pager.c.

◆ C_PagerContext

short C_PagerContext

Config: Number of lines of overlap when changing pages in the pager.

Definition at line 86 of file pager.c.

◆ C_PagerIndexLines

short C_PagerIndexLines

Config: Number of index lines to display above the pager.

Definition at line 87 of file pager.c.

◆ C_PagerStop

bool C_PagerStop

Config: Don't automatically open the next message when at the end of a message.

Definition at line 88 of file pager.c.

◆ C_SearchContext

short C_SearchContext

Config: Context to display around search matches.

Definition at line 89 of file pager.c.

◆ C_SkipQuotedOffset

short C_SkipQuotedOffset

Config: Lines of context to show when skipping quoted text.

Definition at line 90 of file pager.c.

◆ C_SmartWrap

bool C_SmartWrap

Config: Wrap text at word boundaries.

Definition at line 91 of file pager.c.

◆ C_Smileys

struct Regex* C_Smileys

Config: Regex to match smileys to prevent mistakes when quoting text.

Definition at line 92 of file pager.c.

◆ C_Tilde

bool C_Tilde

Config: Character to pad blank lines in the pager.

Definition at line 93 of file pager.c.