NeoMutt  2022-04-29-145-g9b6a0e
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference

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

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

Go to the source code of this file.

Data Structures

struct  PagerData
 Data to be displayed by PagerView. More...
 
struct  PagerView
 Paged view into some data. 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_BOTTOM   (1 << 11)
 Start at the bottom. More...
 
#define MUTT_PAGER_MESSAGE   (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER)
 
#define MUTT_DISPLAYFLAGS   (MUTT_SHOW | MUTT_PAGER_NSKIP | MUTT_PAGER_MARKER | MUTT_PAGER_LOGS)
 
#define NT_PAGER_NO_FLAGS   0
 No flags are set. More...
 
#define NT_PAGER_DELETE   (1 << 0)
 Pager Private Data is about to be freed. More...
 
#define NT_PAGER_VIEW   (1 << 1)
 Pager View has changed. More...
 
#define PAGER_REDRAW_NO_FLAGS   0
 No flags are set. More...
 
#define PAGER_REDRAW_PAGER   (1 << 1)
 Redraw the pager. More...
 
#define PAGER_REDRAW_FLOW   (1 << 2)
 Reflow the pager. More...
 

Typedefs

typedef uint16_t PagerFlags
 Flags for mutt_pager(), e.g. MUTT_SHOWFLAT. More...
 
typedef uint8_t NotifyPager
 Flags, e.g. NT_PAGER_DELETE. More...
 
typedef uint8_t PagerRedrawFlags
 Flags, e.g. PAGER_REDRAW_PAGER. More...
 

Enumerations

enum  PagerMode {
  PAGER_MODE_UNKNOWN = 0 , PAGER_MODE_EMAIL , PAGER_MODE_ATTACH , PAGER_MODE_ATTACH_E ,
  PAGER_MODE_HELP , PAGER_MODE_OTHER , PAGER_MODE_MAX
}
 Determine the behaviour of the Pager. More...
 
enum  PagerLoopMode { PAGER_LOOP_CONTINUE = -7 , PAGER_LOOP_QUIT = -6 , PAGER_LOOP_RELOAD = -5 }
 What the Pager Event Loop should do next. More...
 

Functions

int mutt_pager (struct PagerView *pview)
 Display an email, attachment, or help, in a window. More...
 
int mutt_do_pager (struct PagerView *pview, struct Email *e)
 Display some page-able text to the user (help or attachment) More...
 
void mutt_buffer_strip_formatting (struct Buffer *dest, const char *src, bool strip_markers)
 Removes ANSI and backspace formatting. More...
 
struct MuttWindowppanel_new (bool status_on_top, struct IndexSharedData *shared)
 Create the Windows for the Pager panel. More...
 
struct MuttWindowpager_window_new (struct IndexSharedData *shared, struct PagerPrivateData *priv)
 Create a new Pager Window (list of Emails) More...
 
int mutt_display_message (struct MuttWindow *win_index, struct IndexSharedData *shared)
 Display a message in the pager. More...
 
int external_pager (struct Mailbox *m, struct Email *e, const char *command)
 Display a message in an external program. More...
 
void pager_queue_redraw (struct PagerPrivateData *priv, PagerRedrawFlags redraw)
 Queue a request for a redraw. More...
 
int mutt_is_quote_line (char *buf, regmatch_t *pmatch)
 Is a line of message text a quote? More...
 
void mutt_clear_pager_position (void)
 
void dump_text_syntax (struct TextSyntax *ts, int num)
 
void dump_line (int i, struct Line *line)
 
void dump_pager (struct PagerPrivateData *priv)
 

Variables

int braille_row
 
int braille_col
 

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

Macro Definition Documentation

◆ MUTT_PAGER_NO_FLAGS

#define MUTT_PAGER_NO_FLAGS   0

No flags are set.

Definition at line 58 of file lib.h.

◆ MUTT_SHOWFLAT

#define MUTT_SHOWFLAT   (1 << 0)

Show characters (used for displaying help)

Definition at line 59 of file lib.h.

◆ MUTT_SHOWCOLOR

#define MUTT_SHOWCOLOR   (1 << 1)

Show characters in color otherwise don't show characters.

Definition at line 60 of file lib.h.

◆ MUTT_HIDE

#define MUTT_HIDE   (1 << 2)

Don't show quoted text.

Definition at line 61 of file lib.h.

◆ MUTT_SEARCH

#define MUTT_SEARCH   (1 << 3)

Resolve search patterns.

Definition at line 62 of file lib.h.

◆ MUTT_TYPES

#define MUTT_TYPES   (1 << 4)

Compute line's type.

Definition at line 63 of file lib.h.

◆ MUTT_SHOW

#define MUTT_SHOW   (MUTT_SHOWCOLOR | MUTT_SHOWFLAT)

Definition at line 64 of file lib.h.

◆ MUTT_PAGER_NSKIP

#define MUTT_PAGER_NSKIP   (1 << 5)

Preserve whitespace with smartwrap.

Definition at line 67 of file lib.h.

◆ MUTT_PAGER_MARKER

#define MUTT_PAGER_MARKER   (1 << 6)

Use markers if option is set.

Definition at line 68 of file lib.h.

◆ MUTT_PAGER_RETWINCH

#define MUTT_PAGER_RETWINCH   (1 << 7)

Need reformatting on SIGWINCH.

Definition at line 69 of file lib.h.

◆ MUTT_PAGER_ATTACHMENT

#define MUTT_PAGER_ATTACHMENT   (1 << 8)

Attachments may exist.

Definition at line 70 of file lib.h.

◆ MUTT_PAGER_NOWRAP

#define MUTT_PAGER_NOWRAP   (1 << 9)

Format for term width, ignore $wrap.

Definition at line 71 of file lib.h.

◆ MUTT_PAGER_LOGS

#define MUTT_PAGER_LOGS   (1 << 10)

Logview mode.

Definition at line 72 of file lib.h.

◆ MUTT_PAGER_BOTTOM

#define MUTT_PAGER_BOTTOM   (1 << 11)

Start at the bottom.

Definition at line 73 of file lib.h.

◆ MUTT_PAGER_MESSAGE

#define MUTT_PAGER_MESSAGE   (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER)

Definition at line 74 of file lib.h.

◆ MUTT_DISPLAYFLAGS

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

Definition at line 76 of file lib.h.

◆ NT_PAGER_NO_FLAGS

#define NT_PAGER_NO_FLAGS   0

No flags are set.

Definition at line 182 of file lib.h.

◆ NT_PAGER_DELETE

#define NT_PAGER_DELETE   (1 << 0)

Pager Private Data is about to be freed.

Definition at line 183 of file lib.h.

◆ NT_PAGER_VIEW

#define NT_PAGER_VIEW   (1 << 1)

Pager View has changed.

Definition at line 184 of file lib.h.

◆ PAGER_REDRAW_NO_FLAGS

#define PAGER_REDRAW_NO_FLAGS   0

No flags are set.

Definition at line 187 of file lib.h.

◆ PAGER_REDRAW_PAGER

#define PAGER_REDRAW_PAGER   (1 << 1)

Redraw the pager.

Definition at line 188 of file lib.h.

◆ PAGER_REDRAW_FLOW

#define PAGER_REDRAW_FLOW   (1 << 2)

Reflow the pager.

Definition at line 189 of file lib.h.

Typedef Documentation

◆ PagerFlags

typedef uint16_t PagerFlags

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

Definition at line 57 of file lib.h.

◆ NotifyPager

typedef uint8_t NotifyPager

Flags, e.g. NT_PAGER_DELETE.

Definition at line 181 of file lib.h.

◆ PagerRedrawFlags

typedef uint8_t PagerRedrawFlags

Flags, e.g. PAGER_REDRAW_PAGER.

Definition at line 186 of file lib.h.

Enumeration Type Documentation

◆ PagerMode

enum PagerMode

Determine the behaviour of the Pager.

Enumerator
PAGER_MODE_UNKNOWN 

A default and invalid mode, should never be used.

PAGER_MODE_EMAIL 

Pager is invoked via 1st path. The mime part is selected automatically.

PAGER_MODE_ATTACH 

Pager is invoked via 2nd path. A user-selected attachment (mime part or a nested email) will be shown.

PAGER_MODE_ATTACH_E 

A special case of PAGER_MODE_ATTACH - attachment is a full-blown email message.

PAGER_MODE_HELP 

Pager is invoked via 3rd path to show help.

PAGER_MODE_OTHER 

Pager is invoked via 3rd path. Non-email content is likely to be shown.

PAGER_MODE_MAX 

Another invalid mode, should never be used.

Definition at line 131 of file lib.h.

132 {
133  PAGER_MODE_UNKNOWN = 0,
134 
140 
142 };
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition: lib.h:139
@ PAGER_MODE_HELP
Pager is invoked via 3rd path to show help.
Definition: lib.h:138
@ PAGER_MODE_ATTACH
Pager is invoked via 2nd path. A user-selected attachment (mime part or a nested email) will be shown...
Definition: lib.h:136
@ PAGER_MODE_EMAIL
Pager is invoked via 1st path. The mime part is selected automatically.
Definition: lib.h:135
@ PAGER_MODE_ATTACH_E
A special case of PAGER_MODE_ATTACH - attachment is a full-blown email message.
Definition: lib.h:137
@ PAGER_MODE_UNKNOWN
A default and invalid mode, should never be used.
Definition: lib.h:133
@ PAGER_MODE_MAX
Another invalid mode, should never be used.
Definition: lib.h:141

◆ PagerLoopMode

What the Pager Event Loop should do next.

Enumerator
PAGER_LOOP_CONTINUE 

Stay in the Pager Event Loop.

PAGER_LOOP_QUIT 

Quit the Pager.

PAGER_LOOP_RELOAD 

Reload the Pager from scratch.

Definition at line 147 of file lib.h.

148 {
149  PAGER_LOOP_CONTINUE = -7,
150  PAGER_LOOP_QUIT = -6,
151  PAGER_LOOP_RELOAD = -5,
152 };
@ PAGER_LOOP_RELOAD
Reload the Pager from scratch.
Definition: lib.h:151
@ PAGER_LOOP_QUIT
Quit the Pager.
Definition: lib.h:150
@ PAGER_LOOP_CONTINUE
Stay in the Pager Event Loop.
Definition: lib.h:149

Function Documentation

◆ mutt_pager()

int mutt_pager ( struct PagerView pview)

Display an email, attachment, or help, in a window.

Parameters
pviewPager view settings
Return values
0Success
-1Error

This pager is actually not so simple as it once was. But it will be again. Currently it operates in 3 modes:

  • viewing messages. (PAGER_MODE_EMAIL)
  • viewing attachments. (PAGER_MODE_ATTACH)
  • viewing other stuff (e.g. help). (PAGER_MODE_OTHER) These can be distinguished by PagerMode in PagerView. Data is not yet polymorphic and is fused into a single struct (PagerData). Different elements of PagerData are expected to be present depending on the mode:
  • PAGER_MODE_EMAIL expects data->email and not expects data->body
  • PAGER_MODE_ATTACH expects data->email and data->body special sub-case of this mode is viewing attached email message it is recognized by presence of data->fp and data->body->email
  • PAGER_MODE_OTHER does not expect data->email or data->body

Definition at line 223 of file dlg_pager.c.

224 {
225  //===========================================================================
226  // ACT 1 - Ensure sanity of the caller and determine the mode
227  //===========================================================================
228  assert(pview);
229  assert((pview->mode > PAGER_MODE_UNKNOWN) && (pview->mode < PAGER_MODE_MAX));
230  assert(pview->pdata); // view can't exist in a vacuum
231  assert(pview->win_pager);
232  assert(pview->win_pbar);
233 
234  struct MuttWindow *dlg = dialog_find(pview->win_pager);
235  struct IndexSharedData *shared = dlg->wdata;
236  struct MuttWindow *win_sidebar = window_find_child(dlg, WT_SIDEBAR);
237 
238  switch (pview->mode)
239  {
240  case PAGER_MODE_EMAIL:
241  // This case was previously identified by IsEmail macro
242  // we expect data to contain email and not contain body
243  // We also expect email to always belong to some mailbox
244  assert(shared->mailboxview);
245  assert(shared->mailbox);
246  assert(shared->email);
247  assert(!pview->pdata->body);
248  break;
249 
250  case PAGER_MODE_ATTACH:
251  // this case was previously identified by IsAttach and IsMsgAttach
252  // macros, we expect data to contain:
253  // - body (viewing regular attachment)
254  // - fp and body->email in special case of viewing an attached email.
255  assert(pview->pdata->body);
256  if (pview->pdata->fp && pview->pdata->body->email)
257  {
258  // Special case: attachment is a full-blown email message.
259  // Yes, emails can contain other emails.
260  pview->mode = PAGER_MODE_ATTACH_E;
261  }
262  break;
263 
264  case PAGER_MODE_HELP:
265  case PAGER_MODE_OTHER:
266  assert(!shared->mailboxview);
267  assert(!shared->email);
268  assert(!pview->pdata->body);
269  break;
270 
271  case PAGER_MODE_UNKNOWN:
272  case PAGER_MODE_MAX:
273  default:
274  // Unexpected mode. Catch fire and explode.
275  // This *should* happen if mode is PAGER_MODE_ATTACH_E, since
276  // we do not expect any caller to pass it to us.
277  assert(false);
278  break;
279  }
280 
281  //===========================================================================
282  // ACT 2 - Declare, initialize local variables, read config, etc.
283  //===========================================================================
284 
285  //---------- local variables ------------------------------------------------
286  int op = 0;
287  enum MailboxType mailbox_type = shared->mailbox ? shared->mailbox->type : MUTT_UNKNOWN;
288  struct PagerPrivateData *priv = pview->win_pager->parent->wdata;
289  priv->rc = -1;
290  priv->searchctx = 0;
291  priv->first = true;
292  priv->wrapped = false;
293  priv->delay_read_timestamp = 0;
294  priv->pager_redraw = false;
295 
296  {
297  // Wipe any previous state info
298  struct Notify *notify = priv->notify;
299  int rc = priv->rc;
300  memset(priv, 0, sizeof(*priv));
301  priv->rc = rc;
302  priv->notify = notify;
303  TAILQ_INIT(&priv->ansi_list);
304  }
305 
306  //---------- setup flags ----------------------------------------------------
307  if (!(pview->flags & MUTT_SHOWCOLOR))
308  pview->flags |= MUTT_SHOWFLAT;
309 
310  if ((pview->mode == PAGER_MODE_EMAIL) && !shared->email->read)
311  {
312  if (shared->mailboxview)
313  shared->mailboxview->msg_in_pager = shared->email->msgno;
314  const short c_pager_read_delay = cs_subset_number(NeoMutt->sub, "pager_read_delay");
315  if (c_pager_read_delay == 0)
316  {
317  mutt_set_flag(shared->mailbox, shared->email, MUTT_READ, true);
318  }
319  else
320  {
321  priv->delay_read_timestamp = mutt_date_epoch_ms() + (1000 * c_pager_read_delay);
322  }
323  }
324  //---------- setup help menu ------------------------------------------------
325  pview->win_pager->help_data = pager_resolve_help_mapping(pview->mode, mailbox_type);
326  pview->win_pager->help_menu = MENU_PAGER;
327 
328  //---------- initialize redraw pdata -----------------------------------------
330  priv->lines_max = LINES; // number of lines on screen, from curses
331  priv->lines = mutt_mem_calloc(priv->lines_max, sizeof(struct Line));
332  priv->fp = fopen(pview->pdata->fname, "r");
333  priv->has_types = ((pview->mode == PAGER_MODE_EMAIL) || (pview->flags & MUTT_SHOWCOLOR)) ?
334  MUTT_TYPES :
335  0; // main message or rfc822 attachment
336 
337  for (size_t i = 0; i < priv->lines_max; i++)
338  {
339  priv->lines[i].cid = -1;
340  priv->lines[i].search_arr_size = -1;
341  priv->lines[i].syntax = mutt_mem_calloc(1, sizeof(struct TextSyntax));
342  (priv->lines[i].syntax)[0].first = -1;
343  (priv->lines[i].syntax)[0].last = -1;
344  }
345 
346  // ---------- try to open the pdata file -------------------------------------
347  if (!priv->fp)
348  {
349  mutt_perror(pview->pdata->fname);
350  return -1;
351  }
352 
353  if (stat(pview->pdata->fname, &priv->st) != 0)
354  {
355  mutt_perror(pview->pdata->fname);
356  mutt_file_fclose(&priv->fp);
357  return -1;
358  }
359  unlink(pview->pdata->fname);
360  priv->pview = pview;
361 
362  //---------- show windows, set focus and visibility --------------------------
363  window_set_visible(pview->win_pager->parent, true);
364  mutt_window_reflow(dlg);
366 
367  window_set_focus(pview->win_pager);
368 
369  //---------- jump to the bottom if requested ------------------------------
370  if (pview->flags & MUTT_PAGER_BOTTOM)
371  {
372  jump_to_bottom(priv, pview);
373  }
374 
375  //-------------------------------------------------------------------------
376  // ACT 3: Read user input and decide what to do with it
377  // ...but also do a whole lot of other things.
378  //-------------------------------------------------------------------------
379 
380  // Force an initial paint, which will populate priv->lines
382  window_redraw(NULL);
383 
384  priv->loop = PAGER_LOOP_CONTINUE;
385  do
386  {
388  {
389  mutt_set_flag(shared->mailbox, shared->email, MUTT_READ, true);
390  }
391 
393  notify_send(priv->notify, NT_PAGER, NT_PAGER_VIEW, priv);
394  window_redraw(NULL);
395 
396  const bool c_braille_friendly = cs_subset_bool(NeoMutt->sub, "braille_friendly");
397  if (c_braille_friendly)
398  {
399  if (braille_row != -1)
400  {
402  braille_row = -1;
403  }
404  }
405  else
406  mutt_window_move(priv->pview->win_pbar, priv->pview->win_pager->state.cols - 1, 0);
407 
408  // force redraw of the screen at every iteration of the event loop
409  mutt_refresh();
410 
411  //-------------------------------------------------------------------------
412  // Check if information in the status bar needs an update
413  // This is done because pager is a single-threaded application, which
414  // tries to emulate concurrency.
415  //-------------------------------------------------------------------------
416  bool do_new_mail = false;
417  if (shared->mailbox && !OptAttachMsg)
418  {
419  int oldcount = shared->mailbox->msg_count;
420  /* check for new mail */
421  enum MxStatus check = mx_mbox_check(shared->mailbox);
422  if (check == MX_STATUS_ERROR)
423  {
424  if (!shared->mailbox || mutt_buffer_is_empty(&shared->mailbox->pathbuf))
425  {
426  /* fatal error occurred */
428  break;
429  }
430  }
431  else if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED) ||
432  (check == MX_STATUS_FLAGS))
433  {
434  /* notify user of newly arrived mail */
435  if (check == MX_STATUS_NEW_MAIL)
436  {
437  for (size_t i = oldcount; i < shared->mailbox->msg_count; i++)
438  {
439  struct Email *e = shared->mailbox->emails[i];
440 
441  if (e && !e->read)
442  {
443  mutt_message(_("New mail in this mailbox"));
444  do_new_mail = true;
445  break;
446  }
447  }
448  }
449 
450  if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED))
451  {
453  OptSearchInvalid = true;
454  }
455  }
456 
457  if (mutt_mailbox_notify(shared->mailbox) || do_new_mail)
458  {
459  const bool c_beep_new = cs_subset_bool(NeoMutt->sub, "beep_new");
460  if (c_beep_new)
461  mutt_beep(true);
462  const char *const c_new_mail_command = cs_subset_string(NeoMutt->sub, "new_mail_command");
463  if (c_new_mail_command)
464  {
465  char cmd[1024];
466  menu_status_line(cmd, sizeof(cmd), shared, NULL, sizeof(cmd),
467  NONULL(c_new_mail_command));
468  if (mutt_system(cmd) != 0)
469  mutt_error(_("Error running \"%s\""), cmd);
470  }
471  }
472  }
473  //-------------------------------------------------------------------------
474 
475  if (priv->pager_redraw)
476  {
477  priv->pager_redraw = false;
479  clearok(stdscr, true); /* force complete redraw */
481 
483  if (pview->flags & MUTT_PAGER_RETWINCH)
484  {
485  /* Store current position. */
486  priv->win_height = -1;
487  for (size_t i = 0; i <= priv->top_line; i++)
488  if (!priv->lines[i].cont_line)
489  priv->win_height++;
490 
491  Resize = mutt_mem_malloc(sizeof(struct Resize));
492 
493  Resize->line = priv->win_height;
495  Resize->search_back = priv->search_back;
496 
497  op = OP_ABORT;
498  priv->rc = OP_REFORMAT_WINCH;
499  break;
500  }
501  else
502  {
503  /* note: mutt_resize_screen() -> mutt_window_reflow() sets
504  * PAGER_REDRAW_PAGER and PAGER_REDRAW_FLOW */
505  op = OP_NULL;
506  }
507  continue;
508  }
509 
510 #ifdef USE_DEBUG_COLOR
511  dump_pager(priv);
512 #endif
513 
514  //-------------------------------------------------------------------------
515  // Finally, read user's key press
516  //-------------------------------------------------------------------------
517  // km_dokey() reads not only user's key strokes, but also a MacroBuffer
518  // MacroBuffer may contain OP codes of the operations.
519  // MacroBuffer is global
520  // OP codes inserted into the MacroBuffer by various functions.
521  // One of such functions is `mutt_enter_command()`
522  // Some OP codes are not handled by pager, they cause pager to quit returning
523  // OP code to index. Index handles the operation and then restarts pager
524  op = km_dokey(MENU_PAGER);
525  if (SigWinch)
526  priv->pager_redraw = true;
527 
528  if (op >= OP_NULL)
530 
531  mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
532 
533  if (op < OP_NULL)
534  {
535  op = OP_NULL;
537  continue;
538  }
539 
540  if (op == OP_NULL)
541  {
543  continue;
544  }
545 
546  int rc = pager_function_dispatcher(priv->pview->win_pager, op);
547 
548  if ((rc == FR_UNKNOWN) && priv->pview->win_index)
549  rc = index_function_dispatcher(priv->pview->win_index, op);
550 #ifdef USE_SIDEBAR
551  if (rc == FR_UNKNOWN)
552  rc = sb_function_dispatcher(win_sidebar, op);
553 #endif
554  if (rc == FR_UNKNOWN)
555  rc = global_function_dispatcher(NULL, op);
556 
557  if ((rc == FR_UNKNOWN) &&
558  ((pview->mode == PAGER_MODE_ATTACH) || (pview->mode == PAGER_MODE_ATTACH_E)))
559  {
560  // Some attachment functions still need to be delegated
561  priv->rc = op;
562  break;
563  }
564  } while (priv->loop == PAGER_LOOP_CONTINUE);
565 
566  //-------------------------------------------------------------------------
567  // END OF ACT 3: Read user input loop - while (op != OP_ABORT)
568  //-------------------------------------------------------------------------
569 
571  {
572  mutt_set_flag(shared->mailbox, shared->email, MUTT_READ, true);
573  }
574  mutt_file_fclose(&priv->fp);
575  if (pview->mode == PAGER_MODE_EMAIL)
576  {
577  if (shared->mailboxview)
578  shared->mailboxview->msg_in_pager = -1;
579  }
580 
582 
583  for (size_t i = 0; i < priv->lines_max; i++)
584  {
585  FREE(&(priv->lines[i].syntax));
586  if (priv->search_compiled && priv->lines[i].search)
587  FREE(&(priv->lines[i].search));
588  }
589  if (priv->search_compiled)
590  {
591  regfree(&priv->search_re);
592  priv->search_compiled = false;
593  }
594  FREE(&priv->lines);
596  {
597  struct AttrColor *ac = NULL;
598  int count = 0;
599  TAILQ_FOREACH(ac, &priv->ansi_list, entries)
600  {
601  count++;
602  }
603  color_debug(LL_DEBUG5, "AnsiColors %d\n", count);
604  }
605 
606  priv->pview = NULL;
607 
608  if (priv->loop == PAGER_LOOP_RELOAD)
609  return PAGER_LOOP_RELOAD;
610 
611  return (priv->rc != -1) ? priv->rc : 0;
612 }
void attr_color_list_clear(struct AttrColorList *acl)
Free the contents of an AttrColorList.
Definition: attr.c:97
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:250
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:140
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:130
uint64_t mutt_date_epoch_ms(void)
Return the number of milliseconds since the Unix epoch.
Definition: date.c:436
void dump_pager(struct PagerPrivateData *priv)
Definition: pager.c:102
int color_debug(enum LogLevel level, const char *format,...)
Write to the log file.
Definition: debug.c:44
struct MuttWindow * dialog_find(struct MuttWindow *win)
Find the parent Dialog of a Window.
Definition: dialog.c:83
@ FR_UNKNOWN
Unknown function.
Definition: dispatcher.h:33
static const struct Mapping * pager_resolve_help_mapping(enum PagerMode mode, enum MailboxType type)
Determine help mapping based on pager mode and mailbox type.
Definition: dlg_pager.c:155
int braille_col
Definition: dlg_pager.c:81
static bool check_read_delay(uint64_t *timestamp)
Is it time to mark the message read?
Definition: dlg_pager.c:192
void pager_queue_redraw(struct PagerPrivateData *priv, PagerRedrawFlags redraw)
Queue a request for a redraw.
Definition: dlg_pager.c:143
int braille_row
Definition: dlg_pager.c:80
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
int pager_function_dispatcher(struct MuttWindow *win, int op)
Perform a Pager function - Implements function_dispatcher_t -.
Definition: functions.c:789
int sb_function_dispatcher(struct MuttWindow *win, int op)
Perform a Sidebar function - Implements function_dispatcher_t -.
Definition: functions.c:375
int global_function_dispatcher(struct MuttWindow *win, int op)
Perform a Global function - Implements function_dispatcher_t -.
Definition: global.c:164
int index_function_dispatcher(struct MuttWindow *win, int op)
Perform an Index function - Implements function_dispatcher_t -.
Definition: functions.c:2810
#define mutt_error(...)
Definition: logging.h:87
#define mutt_message(...)
Definition: logging.h:86
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
#define mutt_perror(...)
Definition: logging.h:88
void mutt_timeout_hook(void)
Execute any timeout hooks.
Definition: hook.c:882
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:795
void km_error_key(enum MenuType mtype)
Handle an unbound key sequence.
Definition: keymap.c:1059
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
MailboxType
Supported mailbox formats.
Definition: mailbox.h:41
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:44
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define FREE(x)
Definition: memory.h:43
void msgwin_clear_text(void)
Clear the text in the Message Window.
Definition: msgwin.c:247
#define _(a)
Definition: message.h:28
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:171
@ MUTT_READ
Messages that have been read.
Definition: mutt.h:93
void mutt_resize_screen(void)
Update NeoMutt's opinion about the window size (CURSES)
Definition: resize.c:73
SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:70
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:74
bool mutt_mailbox_notify(struct Mailbox *m_cur)
Notify the user if there's new mail.
Definition: mutt_mailbox.c:230
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:604
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:340
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:293
struct MuttWindow * window_set_focus(struct MuttWindow *win)
Set the Window focus.
Definition: mutt_window.c:659
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:522
void window_set_visible(struct MuttWindow *win, bool visible)
Set a Window visible or hidden.
Definition: mutt_window.c:164
void window_invalidate_all(void)
Mark all windows as in need of repaint.
Definition: mutt_window.c:742
@ WT_SIDEBAR
Side panel containing Accounts or groups of data.
Definition: mutt_window.h:101
@ MUTT_WIN_SIZE_MAXIMISE
Window wants as much space as possible.
Definition: mutt_window.h:48
enum MxStatus mx_mbox_check(struct Mailbox *m)
Check for new mail - Wrapper for MxOps::mbox_check()
Definition: mx.c:1126
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close()
Definition: mxapi.h:84
@ MX_STATUS_ERROR
An error occurred.
Definition: mxapi.h:85
@ MX_STATUS_FLAGS
Nondestructive flags change (IMAP)
Definition: mxapi.h:90
@ MX_STATUS_REOPENED
Mailbox was reopened.
Definition: mxapi.h:89
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Definition: mxapi.h:87
@ NT_PAGER
Pager data has changed, NotifyPager, PagerPrivateData.
Definition: notify_type.h:52
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition: opcodes.c:46
#define OP_ABORT
Definition: opcodes.h:33
bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:37
bool OptSearchInvalid
(pseudo) used to invalidate the search pattern
Definition: options.h:57
bool jump_to_bottom(struct PagerPrivateData *priv, struct PagerView *pview)
Make sure the bottom line is displayed.
Definition: functions.c:105
#define MUTT_PAGER_RETWINCH
Need reformatting on SIGWINCH.
Definition: lib.h:69
#define NT_PAGER_VIEW
Pager View has changed.
Definition: lib.h:184
#define MUTT_TYPES
Compute line's type.
Definition: lib.h:63
#define MUTT_SHOWCOLOR
Show characters in color otherwise don't show characters.
Definition: lib.h:60
#define PAGER_REDRAW_FLOW
Reflow the pager.
Definition: lib.h:189
#define MUTT_PAGER_BOTTOM
Start at the bottom.
Definition: lib.h:73
#define PAGER_REDRAW_PAGER
Redraw the pager.
Definition: lib.h:188
#define MUTT_SHOWFLAT
Show characters (used for displaying help)
Definition: lib.h:59
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:64
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define TAILQ_INIT(head)
Definition: queue.h:765
void qstyle_free_tree(struct QuoteStyle **quote_list)
Free an entire tree of QuoteStyle.
Definition: quoted.c:206
void menu_status_line(char *buf, size_t buflen, struct IndexSharedData *shared, struct Menu *menu, int cols, const char *fmt)
Create the status line.
Definition: status.c:445
#define NONULL(x)
Definition: string2.h:37
A curses colour and its attributes.
Definition: attr.h:35
struct Email * email
header information for message/rfc822
Definition: body.h:73
The envelope/body of an email.
Definition: email.h:37
bool read
Email is read.
Definition: email.h:48
int msgno
Number displayed to the user.
Definition: email.h:111
Data shared between Index, Pager and Sidebar.
Definition: shared_data.h:37
struct MailboxView * mailboxview
Current Mailbox view.
Definition: shared_data.h:39
struct Email * email
Currently selected Email.
Definition: shared_data.h:42
struct Mailbox * mailbox
Current Mailbox.
Definition: shared_data.h:41
A line of text in the pager.
Definition: display.h:51
short search_arr_size
Number of items in search array.
Definition: display.h:60
struct TextSyntax * search
Array of search text in the line.
Definition: display.h:61
bool cont_line
Continuation of a previous line (wrapped by NeoMutt)
Definition: display.h:54
short cid
Default line colour, e.g. MT_COLOR_QUOTED.
Definition: display.h:53
struct TextSyntax * syntax
Array of coloured text in the line.
Definition: display.h:58
int msg_in_pager
Message currently shown in the pager.
Definition: mview.h:43
int msg_count
Total number of messages.
Definition: mailbox.h:88
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
struct Email ** emails
Array of Emails.
Definition: mailbox.h:96
struct Buffer pathbuf
Path of the Mailbox.
Definition: mailbox.h:80
const struct Mapping * help_data
Data for the Help Bar.
Definition: mutt_window.h:142
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
void * wdata
Private data.
Definition: mutt_window.h:145
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
Definition: mutt_window.h:141
struct MuttWindow * parent
Parent Window.
Definition: mutt_window.h:135
enum MuttWindowSize size
Type of Window, e.g. MUTT_WIN_SIZE_FIXED.
Definition: mutt_window.h:131
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Notification API.
Definition: notify.c:51
const char * fname
Name of the file to read.
Definition: lib.h:162
FILE * fp
Source stream.
Definition: lib.h:160
struct Body * body
Current attachment.
Definition: lib.h:159
Private state data for the Pager.
Definition: private_data.h:41
int rc
Return code from functions.
Definition: private_data.h:73
bool wrapped
Has the search/next wrapped around?
Definition: private_data.h:76
bool pager_redraw
Force a complete redraw.
Definition: private_data.h:78
int lines_max
Capacity of lines array (total entries)
Definition: private_data.h:50
uint64_t delay_read_timestamp
Time that email was first shown.
Definition: private_data.h:77
enum PagerLoopMode loop
What the Event Loop should do next, e.g. PAGER_LOOP_CONTINUE.
Definition: private_data.h:79
struct Line * lines
Array of text lines in pager.
Definition: private_data.h:48
int has_types
Set to MUTT_TYPES for PAGER_MODE_EMAIL or MUTT_SHOWCOLOR.
Definition: private_data.h:56
struct Notify * notify
Notifications: NotifyPager, PagerPrivateData.
Definition: private_data.h:71
int top_line
First visible line on screen.
Definition: private_data.h:55
struct stat st
Stats about Email file.
Definition: private_data.h:45
bool first
First time flag for toggle-new.
Definition: private_data.h:75
bool search_back
Search backwards.
Definition: private_data.h:66
struct QuoteStyle * quote_list
Tree of quoting levels.
Definition: private_data.h:58
struct PagerView * pview
Object to view in the pager.
Definition: private_data.h:42
struct AttrColorList ansi_list
List of ANSI colours used in the Pager.
Definition: private_data.h:70
int searchctx
Space to show around search matches.
Definition: private_data.h:74
regex_t search_re
Compiled search string.
Definition: private_data.h:65
int win_height
Number of lines in the Window.
Definition: private_data.h:54
FILE * fp
File containing decrypted/decoded/weeded Email.
Definition: private_data.h:44
bool search_compiled
Search regex is in use.
Definition: private_data.h:64
struct MuttWindow * win_index
Index Window.
Definition: lib.h:175
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:170
enum PagerMode mode
Pager mode.
Definition: lib.h:171
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:172
struct MuttWindow * win_pbar
Pager Bar Window.
Definition: lib.h:176
struct MuttWindow * win_pager
Pager Window.
Definition: lib.h:177
Keep track of screen resizing.
Definition: dlg_pager.c:74
bool search_compiled
Definition: dlg_pager.c:76
bool search_back
Definition: dlg_pager.c:77
int line
Definition: dlg_pager.c:75
Highlighting for a piece of text.
Definition: display.h:40
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_do_pager()

int mutt_do_pager ( struct PagerView pview,
struct Email e 
)

Display some page-able text to the user (help or attachment)

Parameters
pviewPagerView to construct Pager object
eEmail to use
Return values
0Success
-1Error

Definition at line 120 of file do_pager.c.

121 {
122  assert(pview);
123  assert(pview->pdata);
124  assert(pview->pdata->fname);
125  assert((pview->mode == PAGER_MODE_ATTACH) ||
126  (pview->mode == PAGER_MODE_HELP) || (pview->mode == PAGER_MODE_OTHER));
127 
131 
132  struct IndexSharedData *shared = index_shared_data_new();
133  shared->email = e;
134 
135  notify_set_parent(shared->notify, dlg->notify);
136 
137  dlg->wdata = shared;
139 
140  const bool c_status_on_top = cs_subset_bool(NeoMutt->sub, "status_on_top");
141  struct MuttWindow *panel_pager = ppanel_new(c_status_on_top, shared);
142  dlg->focus = panel_pager;
143  mutt_window_add_child(dlg, panel_pager);
144 
147  dialog_push(dlg);
148 
149  pview->win_index = NULL;
150  pview->win_pbar = window_find_child(panel_pager, WT_STATUS_BAR);
151  pview->win_pager = window_find_child(panel_pager, WT_CUSTOM);
152 
153  int rc;
154 
155  const char *const c_pager = cs_subset_string(NeoMutt->sub, "pager");
156  if (!c_pager || mutt_str_equal(c_pager, "builtin"))
157  {
158  rc = mutt_pager(pview);
159  }
160  else
161  {
162  struct Buffer *cmd = mutt_buffer_pool_get();
163 
164  mutt_endwin();
165  mutt_buffer_file_expand_fmt_quote(cmd, c_pager, pview->pdata->fname);
166  if (mutt_system(mutt_buffer_string(cmd)) == -1)
167  {
168  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
169  rc = -1;
170  }
171  else
172  rc = 0;
173  mutt_file_unlink(pview->pdata->fname);
175  }
176 
177  dialog_pop();
178  mutt_window_free(&dlg);
179  return rc;
180 }
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
void mutt_endwin(void)
Shutdown curses.
Definition: curs_lib.c:355
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: dialog.c:103
void dialog_pop(void)
Hide a Window from the user.
Definition: dialog.c:137
int mutt_pager(struct PagerView *pview)
Display an email, attachment, or help, in a window.
Definition: dlg_pager.c:223
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:194
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:1488
static int dopager_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: do_pager.c:75
static int dopager_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: do_pager.c:93
void index_shared_data_free(struct MuttWindow *win, void **ptr)
Free Shared Index Data - Implements MuttWindow::wdata_free() -.
Definition: shared_data.c:269
struct IndexSharedData * index_shared_data_new(void)
Create new Index Data.
Definition: shared_data.c:296
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:189
void notify_set_parent(struct Notify *notify, struct Notify *parent)
Set the parent notification handler.
Definition: notify.c:93
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:784
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:201
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:439
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:181
@ WT_CUSTOM
Window with a custom drawing function.
Definition: mutt_window.h:95
@ WT_STATUS_BAR
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
@ WT_DLG_DO_PAGER
Pager Dialog, mutt_do_pager()
Definition: mutt_window.h:84
@ MUTT_WIN_ORIENT_VERTICAL
Window uses all available vertical space.
Definition: mutt_window.h:38
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:52
@ NT_WINDOW
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:55
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:43
struct MuttWindow * ppanel_new(bool status_on_top, struct IndexSharedData *shared)
Create the Windows for the Pager panel.
Definition: ppanel.c:119
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
String manipulation buffer.
Definition: buffer.h:34
struct Notify * notify
Notifications: NotifyIndex, IndexSharedData.
Definition: shared_data.h:44
struct MuttWindow * focus
Focused Window.
Definition: mutt_window.h:140
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
void(* wdata_free)(struct MuttWindow *win, void **ptr)
Definition: mutt_window.h:160
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_strip_formatting()

void mutt_buffer_strip_formatting ( struct Buffer dest,
const char *  src,
bool  strip_markers 
)

Removes ANSI and backspace formatting.

Parameters
destBuffer for the result
srcString to strip
strip_markersRemove

Removes ANSI and backspace formatting, and optionally markers. This is separated out so that it can be used both by the pager and the autoview handler.

This logic is pulled from the pager fill_buffer() function, for use in stripping reply-quoted autoview output of ansi sequences.

Definition at line 667 of file display.c.

668 {
669  const char *s = src;
670 
671  mutt_buffer_reset(dest);
672 
673  if (!s)
674  return;
675 
676  while (s[0] != '\0')
677  {
678  if ((s[0] == '\010') && (s > src))
679  {
680  if (s[1] == '_') /* underline */
681  s += 2;
682  else if (s[1] && mutt_buffer_len(dest)) /* bold or overstrike */
683  {
684  dest->dptr--;
685  mutt_buffer_addch(dest, s[1]);
686  s += 2;
687  }
688  else /* ^H */
689  mutt_buffer_addch(dest, *s++);
690  continue;
691  }
692 
693  int len = ansi_color_seq_length(s);
694  if (len > 0)
695  {
696  s += len;
697  }
698  else if (strip_markers && (s[0] == '\033') && (s[1] == ']') &&
700  {
701  mutt_debug(LL_DEBUG2, "Seen attachment marker\n");
702  while (*s++ != '\a')
703  ; /* skip pseudo-ANSI sequence */
704  }
705  else
706  mutt_buffer_addch(dest, *s++);
707  }
708 }
int ansi_color_seq_length(const char *str)
Is this an ANSI escape sequence?
Definition: ansi.c:78
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:354
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:238
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:81
static int check_protected_header_marker(const char *p)
Check that the unique marker is present.
Definition: display.c:289
static int check_attachment_marker(const char *p)
Check that the unique marker is present.
Definition: display.c:279
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
char * dptr
Current read/write position.
Definition: buffer.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ppanel_new()

struct MuttWindow* ppanel_new ( bool  status_on_top,
struct IndexSharedData shared 
)

Create the Windows for the Pager panel.

Parameters
status_on_toptrue, if the Pager bar should be on top
sharedShared Index data
Return values
ptrNew Pager Panel

Definition at line 119 of file ppanel.c.

120 {
124  panel_pager->state.visible = false; // The Pager and Pager Bar are initially hidden
125 
126  struct PagerPrivateData *priv = pager_private_data_new();
127  panel_pager->wdata = priv;
128  panel_pager->wdata_free = pager_private_data_free;
129 
130  struct MuttWindow *win_pager = pager_window_new(shared, priv);
131  panel_pager->focus = win_pager;
132 
133  struct MuttWindow *win_pbar = pbar_new(shared, priv);
134  if (status_on_top)
135  {
136  mutt_window_add_child(panel_pager, win_pbar);
137  mutt_window_add_child(panel_pager, win_pager);
138  }
139  else
140  {
141  mutt_window_add_child(panel_pager, win_pager);
142  mutt_window_add_child(panel_pager, win_pbar);
143  }
144 
146  notify_observer_add(panel_pager->notify, NT_WINDOW, ppanel_window_observer, panel_pager);
147 
148  return panel_pager;
149 }
static int ppanel_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: ppanel.c:73
static int ppanel_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: ppanel.c:93
@ WT_PAGER
A panel containing the Pager Window.
Definition: mutt_window.h:100
struct MuttWindow * pager_window_new(struct IndexSharedData *shared, struct PagerPrivateData *priv)
Create a new Pager Window (list of Emails)
Definition: pager.c:420
struct PagerPrivateData * pager_private_data_new(void)
Create new Pager Data.
Definition: private_data.c:59
void pager_private_data_free(struct MuttWindow *win, void **ptr)
Free Pager Data.
Definition: private_data.c:39
struct MuttWindow * pbar_new(struct IndexSharedData *shared, struct PagerPrivateData *priv)
Create the Pager Bar.
Definition: pbar.c:322
bool visible
Window is visible.
Definition: mutt_window.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pager_window_new()

struct MuttWindow* pager_window_new ( struct IndexSharedData shared,
struct PagerPrivateData priv 
)

Create a new Pager Window (list of Emails)

Parameters
sharedShared Index Data
privPrivate Pager Data
Return values
ptrNew Window

Definition at line 420 of file pager.c.

422 {
426  win->wdata = priv;
427  win->recalc = pager_recalc;
428  win->repaint = pager_repaint;
429 
436 
437  return win;
438 }
static int pager_pager_observer(struct NotifyCallback *nc)
Notification that the Pager has changed - Implements observer_t -.
Definition: pager.c:371
static int pager_color_observer(struct NotifyCallback *nc)
Notification that a Color has changed - Implements observer_t -.
Definition: pager.c:241
static int pager_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: pager.c:284
static int pager_index_observer(struct NotifyCallback *nc)
Notification that the Index has changed - Implements observer_t -.
Definition: pager.c:330
static int pager_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: pager.c:383
static int pager_global_observer(struct NotifyCallback *nc)
Notification that a Global Event occurred - Implements observer_t -.
Definition: pager.c:304
static int pager_recalc(struct MuttWindow *win)
Recalculate the Pager display - Implements MuttWindow::recalc() -.
Definition: pager.c:123
static int pager_repaint(struct MuttWindow *win)
Repaint the Pager display - Implements MuttWindow::repaint() -.
Definition: pager.c:133
@ NT_COLOR
Colour has changed, NotifyColor, EventColor.
Definition: notify_type.h:41
@ NT_ALL
Register for all notifications.
Definition: notify_type.h:35
@ NT_GLOBAL
Not object-related, NotifyGlobal.
Definition: notify_type.h:46
int(* repaint)(struct MuttWindow *win)
Definition: mutt_window.h:182
int(* recalc)(struct MuttWindow *win)
Definition: mutt_window.h:171
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_display_message()

int mutt_display_message ( struct MuttWindow win_index,
struct IndexSharedData shared 
)

Display a message in the pager.

Parameters
win_indexIndex Window
sharedShared Index data
Return values
0Success
-1Error

Definition at line 449 of file message.c.

450 {
451  struct MuttWindow *dlg = dialog_find(win_index);
452  struct MuttWindow *win_pager = window_find_child(dlg, WT_CUSTOM);
453  struct MuttWindow *win_pbar = window_find_child(dlg, WT_STATUS_BAR);
454  struct Buffer *tempfile = mutt_buffer_pool_get();
455  struct Message *msg = NULL;
456 
457  squash_index_panel(shared->mailbox, win_index, win_pager);
458 
459  int rc = PAGER_LOOP_QUIT;
460  do
461  {
462  msg = mx_msg_open(shared->mailbox, shared->email->msgno);
463  if (!msg)
464  break;
465 
467 
468  mutt_buffer_reset(tempfile);
469  // win_pager might not be visible and have a size yet, so use win_index
470  rc = email_to_file(msg, tempfile, shared->mailbox, shared->email, NULL,
471  win_index->state.cols, &cmflags);
472  if (rc < 0)
473  break;
474 
475  notify_crypto(shared->email, msg, cmflags);
476 
477  /* Invoke the builtin pager */
478  struct PagerData pdata = { 0 };
479  struct PagerView pview = { &pdata };
480 
481  pdata.fp = msg->fp;
482  pdata.fname = mutt_buffer_string(tempfile);
483 
484  pview.mode = PAGER_MODE_EMAIL;
485  pview.banner = NULL;
486  pview.flags = MUTT_PAGER_MESSAGE |
487  (shared->email->body->nowrap ? MUTT_PAGER_NOWRAP : 0);
488  pview.win_index = win_index;
489  pview.win_pbar = win_pbar;
490  pview.win_pager = win_pager;
491 
492  rc = mutt_pager(&pview);
493  mx_msg_close(shared->mailbox, &msg);
494  } while (rc == PAGER_LOOP_RELOAD);
495 
497 
498  mx_msg_close(shared->mailbox, &msg);
499  mutt_buffer_pool_release(&tempfile);
500  return rc;
501 }
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:38
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:42
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:32
#define MUTT_CM_DISPLAY
Output is displayed to the user.
Definition: copy.h:39
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1193
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
Return a stream pointer for a message.
Definition: mx.c:1147
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: lib.h:71
#define MUTT_PAGER_MESSAGE
Definition: lib.h:74
static int email_to_file(struct Message *msg, struct Buffer *tempfile, struct Mailbox *m, struct Email *e, const char *header, int wrap_len, CopyMessageFlags *cmflags)
Decrypt, decode and weed an Email into a file.
Definition: message.c:174
static void expand_index_panel(struct MuttWindow *win_index, struct MuttWindow *win_pager)
Restore the Index Panel.
Definition: message.c:428
static void notify_crypto(struct Email *e, struct Message *msg, CopyMessageFlags cmflags)
Notify the user about the crypto status of the Email.
Definition: message.c:365
static void squash_index_panel(struct Mailbox *m, struct MuttWindow *win_index, struct MuttWindow *win_pager)
Shrink or hide the Index Panel.
Definition: message.c:399
bool nowrap
Do not wrap the output in the pager.
Definition: body.h:88
struct Body * body
List of MIME parts.
Definition: email.h:67
A local copy of an email.
Definition: mxapi.h:43
FILE * fp
pointer to the message data
Definition: mxapi.h:44
Data to be displayed by PagerView.
Definition: lib.h:158
Paged view into some data.
Definition: lib.h:169
const char * banner
Title to display in status bar.
Definition: lib.h:173
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ external_pager()

int external_pager ( struct Mailbox m,
struct Email e,
const char *  command 
)

Display a message in an external program.

Parameters
mMailbox
eEmail to display
commandExternal command to run
Return values
0Success
-1Error

Definition at line 311 of file message.c.

312 {
313  struct Message *msg = mx_msg_open(m, e->msgno);
314  if (!msg)
315  return -1;
316 
317  char buf[1024] = { 0 };
318  const char *const c_pager_format = cs_subset_string(NeoMutt->sub, "pager_format");
319  const int screen_width = RootWindow->state.cols;
320  mutt_make_string(buf, sizeof(buf), screen_width, NONULL(c_pager_format), m,
322 
323  struct Buffer *tempfile = mutt_buffer_pool_get();
324 
326  int rc = email_to_file(msg, tempfile, m, e, buf, screen_width, &cmflags);
327  if (rc < 0)
328  goto cleanup;
329 
330  mutt_endwin();
331 
332  struct Buffer *cmd = mutt_buffer_pool_get();
333  mutt_buffer_printf(cmd, "%s %s", command, mutt_buffer_string(tempfile));
334  int r = mutt_system(mutt_buffer_string(cmd));
335  if (r == -1)
336  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
337  unlink(mutt_buffer_string(tempfile));
339 
340  if (!OptNoCurses)
341  keypad(stdscr, true);
342  if (r != -1)
343  mutt_set_flag(m, e, MUTT_READ, true);
344  const bool c_prompt_after = cs_subset_bool(NeoMutt->sub, "prompt_after");
345  if ((r != -1) && c_prompt_after)
346  {
348  rc = km_dokey(MENU_PAGER);
349  }
350  else
351  rc = 0;
352 
353 cleanup:
354  mx_msg_close(m, &msg);
355  mutt_buffer_pool_release(&tempfile);
356  return rc;
357 }
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:158
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:388
void mutt_unget_ch(int ch)
Return a keystroke to the input buffer.
Definition: curs_lib.c:522
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
void mutt_make_string(char *buf, size_t buflen, int cols, const char *s, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags, const char *progress)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1405
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:53
static const char * ExtPagerProgress
Definition: message.c:59
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: rootwin.c:104
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pager_queue_redraw()

void pager_queue_redraw ( struct PagerPrivateData priv,
PagerRedrawFlags  redraw 
)

Queue a request for a redraw.

Parameters
privPrivate Pager data
redrawItem to redraw, e.g. PAGER_REDRAW_PAGER

Definition at line 143 of file dlg_pager.c.

144 {
145  priv->redraw |= redraw;
146  priv->pview->win_pager->actions |= WA_RECALC;
147 }
#define WA_RECALC
Recalculate the contents of the Window.
Definition: mutt_window.h:110
WindowActionFlags actions
Actions to be performed, e.g. WA_RECALC.
Definition: mutt_window.h:132
PagerRedrawFlags redraw
When to redraw the screen.
Definition: private_data.h:69
+ Here is the caller graph for this function:

◆ mutt_is_quote_line()

int mutt_is_quote_line ( char *  line,
regmatch_t *  pmatch 
)

Is a line of message text a quote?

Parameters
[in]lineLine to test
[out]pmatchRegex sub-matches
Return values
trueLine is quoted

Checks if line matches the $quote_regex and doesn't match $smileys. This is used by the pager for calling qstyle_classify.

Definition at line 303 of file display.c.

304 {
305  bool is_quote = false;
306  const struct Regex *c_smileys = cs_subset_regex(NeoMutt->sub, "smileys");
307  regmatch_t pmatch_internal[1], smatch[1];
308 
309  if (!pmatch)
310  pmatch = pmatch_internal;
311 
312  const struct Regex *c_quote_regex = cs_subset_regex(NeoMutt->sub, "quote_regex");
313  if (mutt_regex_capture(c_quote_regex, line, 1, pmatch))
314  {
315  if (mutt_regex_capture(c_smileys, line, 1, smatch))
316  {
317  if (smatch[0].rm_so > 0)
318  {
319  char c = line[smatch[0].rm_so];
320  line[smatch[0].rm_so] = 0;
321 
322  if (mutt_regex_capture(c_quote_regex, line, 1, pmatch))
323  is_quote = true;
324 
325  line[smatch[0].rm_so] = c;
326  }
327  }
328  else
329  is_quote = true;
330  }
331 
332  return is_quote;
333 }
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition: helpers.c:243
bool mutt_regex_capture(const struct Regex *regex, const char *str, size_t nmatch, regmatch_t matches[])
Match a regex against a string, with provided options.
Definition: regex.c:614
Cached regular expression.
Definition: regex3.h:89
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_clear_pager_position()

void mutt_clear_pager_position ( void  )

◆ dump_text_syntax()

void dump_text_syntax ( struct TextSyntax ts,
int  num 
)

Definition at line 37 of file pager.c.

38 {
39  if (!ts || (num == 0))
40  return;
41 
42  for (int i = 0; i < num; i++)
43  {
44  int index = -1;
45  const char *swatch = "";
46  if (!ts[i].attr_color)
47  continue;
48  struct CursesColor *cc = ts[i].attr_color->curses_color;
49  if (cc)
50  {
51  index = cc->index;
52  swatch = color_debug_log_color(cc->fg, cc->bg);
53  }
54  mutt_debug(LL_DEBUG1, "\t\t%3d %4d %4d %s\n", index, ts[i].first, ts[i].last, swatch);
55  }
56 }
const char * color_debug_log_color(int fg, int bg)
Get a colourful string to represent a colour in the log.
Definition: debug.c:103
struct CursesColor * curses_color
Underlying Curses colour.
Definition: attr.h:36
Colour in the ncurses palette.
Definition: curses2.h:38
short index
Index number.
Definition: curses2.h:43
uint32_t fg
Foreground colour.
Definition: curses2.h:41
uint32_t bg
Background colour.
Definition: curses2.h:42
struct AttrColor * attr_color
Curses colour of text.
Definition: display.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_line()

void dump_line ( int  i,
struct Line line 
)

Definition at line 58 of file pager.c.

59 {
60  mutt_debug(LL_DEBUG1, "Line: %d (offset: %ld)\n", i, line->offset);
61  // mutt_debug(LL_DEBUG1, "\toffset: %ld\n", line->offset);
62  if ((line->cid > 0) && (line->cid != MT_COLOR_NORMAL))
63  {
64  struct Buffer *buf = mutt_buffer_pool_get();
65  get_colorid_name(line->cid, buf);
66 
67  const char *swatch = "";
68  struct AttrColor *ac = simple_color_get(line->cid);
69  if (ac && ac->curses_color)
70  {
71  struct CursesColor *cc = ac->curses_color;
72  swatch = color_debug_log_color(cc->fg, cc->bg);
73  }
74 
75  mutt_debug(LL_DEBUG1, "\tcolor: %d %s (%s)\n", line->cid, swatch,
76  mutt_buffer_string(buf));
78  }
79  if (line->cont_line)
80  {
81  mutt_debug(LL_DEBUG1, "\tcont_line: %s\n",
82  line->cont_line ? "\033[1;32myes\033[0m" : "\033[31mno\033[0m");
83  }
84  if (line->cont_header)
85  {
86  mutt_debug(LL_DEBUG1, "\tcont_header: %s\n",
87  line->cont_header ? "\033[1;32myes\033[0m" : "\033[31mno\033[0m");
88  }
89 
90  if (line->syntax_arr_size > 0)
91  {
92  mutt_debug(LL_DEBUG1, "\tsyntax: %d\n", line->syntax_arr_size);
94  }
95  if (line->search_arr_size > 0)
96  {
97  mutt_debug(LL_DEBUG1, "\t\033[1;36msearch\033[0m: %d\n", line->search_arr_size);
99  }
100 }
void get_colorid_name(unsigned int cid, struct Buffer *buf)
Get the name of a color id.
Definition: command.c:321
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
Definition: simple.c:74
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:53
void dump_text_syntax(struct TextSyntax *ts, int num)
Definition: pager.c:37
LOFF_T offset
Offset into Email file (PagerPrivateData->fp)
Definition: display.h:52
bool cont_header
Continuation of a header line (wrapped by MTA)
Definition: display.h:55
short syntax_arr_size
Number of items in syntax array.
Definition: display.h:57
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_pager()

void dump_pager ( struct PagerPrivateData priv)

Definition at line 102 of file pager.c.

103 {
104  if (!priv)
105  return;
106 
107  mutt_debug(LL_DEBUG1, "----------------------------------------------\n");
108  mutt_debug(LL_DEBUG1, "Pager: %d lines (fd %d)\n", priv->lines_used, fileno(priv->fp));
109  for (int i = 0; i < priv->lines_used; i++)
110  {
111  dump_line(i, &priv->lines[i]);
112  }
113 }
void dump_line(int i, struct Line *line)
Definition: pager.c:58
int lines_used
Size of lines array (used entries)
Definition: private_data.h:49
+ Here is the caller graph for this function:

Variable Documentation

◆ braille_row

int braille_row
extern

Definition at line 80 of file dlg_pager.c.

◆ braille_col

int braille_col
extern

Definition at line 81 of file dlg_pager.c.