NeoMutt  2023-05-17-56-ga67199
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 buf_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 MailboxView *mv, 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...
 
bool mutt_is_quote_line (char *buf, regmatch_t *pmatch)
 Is a line of message text a quote? More...
 
const char * pager_get_pager (struct ConfigSubset *sub)
 Get the value of $pager. 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 BrailleRow
 Braille display: row to leave the cursor. More...
 
int BrailleCol
 Braille display: column to leave the cursor. 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 lib.h.

Macro Definition Documentation

◆ MUTT_PAGER_NO_FLAGS

#define MUTT_PAGER_NO_FLAGS   0

No flags are set.

Definition at line 59 of file lib.h.

◆ MUTT_SHOWFLAT

#define MUTT_SHOWFLAT   (1 << 0)

Show characters (used for displaying help)

Definition at line 60 of file lib.h.

◆ MUTT_SHOWCOLOR

#define MUTT_SHOWCOLOR   (1 << 1)

Show characters in color otherwise don't show characters.

Definition at line 61 of file lib.h.

◆ MUTT_HIDE

#define MUTT_HIDE   (1 << 2)

Don't show quoted text.

Definition at line 62 of file lib.h.

◆ MUTT_SEARCH

#define MUTT_SEARCH   (1 << 3)

Resolve search patterns.

Definition at line 63 of file lib.h.

◆ MUTT_TYPES

#define MUTT_TYPES   (1 << 4)

Compute line's type.

Definition at line 64 of file lib.h.

◆ MUTT_SHOW

#define MUTT_SHOW   (MUTT_SHOWCOLOR | MUTT_SHOWFLAT)

Definition at line 65 of file lib.h.

◆ MUTT_PAGER_NSKIP

#define MUTT_PAGER_NSKIP   (1 << 5)

Preserve whitespace with smartwrap.

Definition at line 68 of file lib.h.

◆ MUTT_PAGER_MARKER

#define MUTT_PAGER_MARKER   (1 << 6)

Use markers if option is set.

Definition at line 69 of file lib.h.

◆ MUTT_PAGER_RETWINCH

#define MUTT_PAGER_RETWINCH   (1 << 7)

Need reformatting on SIGWINCH.

Definition at line 70 of file lib.h.

◆ MUTT_PAGER_ATTACHMENT

#define MUTT_PAGER_ATTACHMENT   (1 << 8)

Attachments may exist.

Definition at line 71 of file lib.h.

◆ MUTT_PAGER_NOWRAP

#define MUTT_PAGER_NOWRAP   (1 << 9)

Format for term width, ignore $wrap.

Definition at line 72 of file lib.h.

◆ MUTT_PAGER_LOGS

#define MUTT_PAGER_LOGS   (1 << 10)

Logview mode.

Definition at line 73 of file lib.h.

◆ MUTT_PAGER_BOTTOM

#define MUTT_PAGER_BOTTOM   (1 << 11)

Start at the bottom.

Definition at line 74 of file lib.h.

◆ MUTT_PAGER_MESSAGE

#define MUTT_PAGER_MESSAGE   (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER)

Definition at line 75 of file lib.h.

◆ MUTT_DISPLAYFLAGS

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

Definition at line 77 of file lib.h.

◆ NT_PAGER_NO_FLAGS

#define NT_PAGER_NO_FLAGS   0

No flags are set.

Definition at line 183 of file lib.h.

◆ NT_PAGER_DELETE

#define NT_PAGER_DELETE   (1 << 0)

Pager Private Data is about to be freed.

Definition at line 184 of file lib.h.

◆ NT_PAGER_VIEW

#define NT_PAGER_VIEW   (1 << 1)

Pager View has changed.

Definition at line 185 of file lib.h.

◆ PAGER_REDRAW_NO_FLAGS

#define PAGER_REDRAW_NO_FLAGS   0

No flags are set.

Definition at line 188 of file lib.h.

◆ PAGER_REDRAW_PAGER

#define PAGER_REDRAW_PAGER   (1 << 1)

Redraw the pager.

Definition at line 189 of file lib.h.

◆ PAGER_REDRAW_FLOW

#define PAGER_REDRAW_FLOW   (1 << 2)

Reflow the pager.

Definition at line 190 of file lib.h.

Typedef Documentation

◆ PagerFlags

typedef uint16_t PagerFlags

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

Definition at line 58 of file lib.h.

◆ NotifyPager

typedef uint8_t NotifyPager

Flags, e.g. NT_PAGER_DELETE.

Definition at line 182 of file lib.h.

◆ PagerRedrawFlags

typedef uint8_t PagerRedrawFlags

Flags, e.g. PAGER_REDRAW_PAGER.

Definition at line 187 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 132 of file lib.h.

133{
135
141
143};
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition: lib.h:140
@ PAGER_MODE_HELP
Pager is invoked via 3rd path to show help.
Definition: lib.h:139
@ 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:137
@ PAGER_MODE_EMAIL
Pager is invoked via 1st path. The mime part is selected automatically.
Definition: lib.h:136
@ PAGER_MODE_ATTACH_E
A special case of PAGER_MODE_ATTACH - attachment is a full-blown email message.
Definition: lib.h:138
@ PAGER_MODE_UNKNOWN
A default and invalid mode, should never be used.
Definition: lib.h:134
@ PAGER_MODE_MAX
Another invalid mode, should never be used.
Definition: lib.h:142

◆ 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 148 of file lib.h.

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

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 225 of file dlg_pager.c.

226{
227 //===========================================================================
228 // ACT 1 - Ensure sanity of the caller and determine the mode
229 //===========================================================================
230 assert(pview);
231 assert((pview->mode > PAGER_MODE_UNKNOWN) && (pview->mode < PAGER_MODE_MAX));
232 assert(pview->pdata); // view can't exist in a vacuum
233 assert(pview->win_pager);
234 assert(pview->win_pbar);
235
236 struct MuttWindow *dlg = dialog_find(pview->win_pager);
237 struct IndexSharedData *shared = dlg->wdata;
238 struct MuttWindow *win_sidebar = window_find_child(dlg, WT_SIDEBAR);
239
240 switch (pview->mode)
241 {
242 case PAGER_MODE_EMAIL:
243 // This case was previously identified by IsEmail macro
244 // we expect data to contain email and not contain body
245 // We also expect email to always belong to some mailbox
246 assert(shared->mailbox_view);
247 assert(shared->mailbox);
248 assert(shared->email);
249 assert(!pview->pdata->body);
250 break;
251
253 // this case was previously identified by IsAttach and IsMsgAttach
254 // macros, we expect data to contain:
255 // - body (viewing regular attachment)
256 // - fp and body->email in special case of viewing an attached email.
257 assert(pview->pdata->body);
258 if (pview->pdata->fp && pview->pdata->body->email)
259 {
260 // Special case: attachment is a full-blown email message.
261 // Yes, emails can contain other emails.
262 pview->mode = PAGER_MODE_ATTACH_E;
263 }
264 break;
265
266 case PAGER_MODE_HELP:
267 case PAGER_MODE_OTHER:
268 assert(!shared->mailbox_view);
269 assert(!shared->email);
270 assert(!pview->pdata->body);
271 break;
272
274 case PAGER_MODE_MAX:
275 default:
276 // Unexpected mode. Catch fire and explode.
277 // This *should* happen if mode is PAGER_MODE_ATTACH_E, since
278 // we do not expect any caller to pass it to us.
279 assert(false);
280 break;
281 }
282
283 //===========================================================================
284 // ACT 2 - Declare, initialize local variables, read config, etc.
285 //===========================================================================
286
287 //---------- local variables ------------------------------------------------
288 int op = 0;
289 enum MailboxType mailbox_type = shared->mailbox ? shared->mailbox->type : MUTT_UNKNOWN;
290 struct PagerPrivateData *priv = pview->win_pager->parent->wdata;
291 priv->rc = -1;
292 priv->searchctx = 0;
293 priv->first = true;
294 priv->wrapped = false;
295 priv->delay_read_timestamp = 0;
296 priv->pager_redraw = false;
297
298 // Wipe any previous state info
299 struct Notify *notify = priv->notify;
300 int prc = priv->rc;
301 memset(priv, 0, sizeof(*priv));
302 priv->rc = prc;
303 priv->notify = notify;
304 TAILQ_INIT(&priv->ansi_list);
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->mailbox_view)
313 shared->mailbox_view->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, true);
318 }
319 else
320 {
321 priv->delay_read_timestamp = mutt_date_now_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);
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);
366
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
385 do
386 {
389 window_redraw(NULL);
390
391 const bool c_braille_friendly = cs_subset_bool(NeoMutt->sub, "braille_friendly");
392 if (c_braille_friendly)
393 {
394 if (BrailleRow != -1)
395 {
397 BrailleRow = -1;
398 }
399 }
400 else
401 {
402 mutt_window_move(priv->pview->win_pbar, priv->pview->win_pager->state.cols - 1, 0);
403 }
404
405 // force redraw of the screen at every iteration of the event loop
406 mutt_refresh();
407
408 //-------------------------------------------------------------------------
409 // Check if information in the status bar needs an update
410 // This is done because pager is a single-threaded application, which
411 // tries to emulate concurrency.
412 //-------------------------------------------------------------------------
413 bool do_new_mail = false;
414 if (shared->mailbox && !OptAttachMsg)
415 {
416 int oldcount = shared->mailbox->msg_count;
417 /* check for new mail */
418 enum MxStatus check = mx_mbox_check(shared->mailbox);
419 if (check == MX_STATUS_ERROR)
420 {
421 if (!shared->mailbox || buf_is_empty(&shared->mailbox->pathbuf))
422 {
423 /* fatal error occurred */
425 break;
426 }
427 }
428 else if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED) ||
429 (check == MX_STATUS_FLAGS))
430 {
431 /* notify user of newly arrived mail */
432 if (check == MX_STATUS_NEW_MAIL)
433 {
434 for (size_t i = oldcount; i < shared->mailbox->msg_count; i++)
435 {
436 struct Email *e = shared->mailbox->emails[i];
437
438 if (e && !e->read)
439 {
440 mutt_message(_("New mail in this mailbox"));
441 do_new_mail = true;
442 break;
443 }
444 }
445 }
446
447 if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED))
448 {
450 OptSearchInvalid = true;
451 }
452 }
453
454 if (mutt_mailbox_notify(shared->mailbox) || do_new_mail)
455 {
456 const bool c_beep_new = cs_subset_bool(NeoMutt->sub, "beep_new");
457 if (c_beep_new)
458 mutt_beep(true);
459 const char *const c_new_mail_command = cs_subset_string(NeoMutt->sub, "new_mail_command");
460 if (c_new_mail_command)
461 {
462 char cmd[1024] = { 0 };
463 menu_status_line(cmd, sizeof(cmd), shared, NULL, sizeof(cmd),
464 NONULL(c_new_mail_command));
465 if (mutt_system(cmd) != 0)
466 mutt_error(_("Error running \"%s\""), cmd);
467 }
468 }
469 }
470 //-------------------------------------------------------------------------
471
472 if (priv->pager_redraw)
473 {
474 priv->pager_redraw = false;
476 clearok(stdscr, true); /* force complete redraw */
478
480 if (pview->flags & MUTT_PAGER_RETWINCH)
481 {
482 /* Store current position. */
483 priv->win_height = -1;
484 for (size_t i = 0; i <= priv->top_line; i++)
485 if (!priv->lines[i].cont_line)
486 priv->win_height++;
487
488 Resize = mutt_mem_malloc(sizeof(struct Resize));
489
490 Resize->line = priv->win_height;
493
494 op = OP_ABORT;
495 priv->rc = OP_REFORMAT_WINCH;
496 break;
497 }
498 else
499 {
500 /* note: mutt_resize_screen() -> mutt_window_reflow() sets
501 * PAGER_REDRAW_PAGER and PAGER_REDRAW_FLOW */
502 op = OP_NULL;
503 }
504 continue;
505 }
506
507#ifdef USE_DEBUG_COLOR
508 dump_pager(priv);
509#endif
510
511 //-------------------------------------------------------------------------
512 // Finally, read user's key press
513 //-------------------------------------------------------------------------
514 // km_dokey() reads not only user's key strokes, but also a MacroBuffer
515 // MacroBuffer may contain OP codes of the operations.
516 // MacroBuffer is global
517 // OP codes inserted into the MacroBuffer by various functions.
518 // One of such functions is `mutt_enter_command()`
519 // Some OP codes are not handled by pager, they cause pager to quit returning
520 // OP code to index. Index handles the operation and then restarts pager
521 op = km_dokey(MENU_PAGER);
522
523 // km_dokey() can block, so recheck the timer.
524 // Note: This check must occur before handling the operations of the index
525 // as those can change the currently selected message/entry yielding to
526 // marking the wrong message as read.
528 {
529 mutt_set_flag(shared->mailbox, shared->email, MUTT_READ, true, true);
530 }
531
532 if (SigWinch)
533 priv->pager_redraw = true;
534
535 if (op >= OP_NULL)
537
538 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
539
540 if (op < OP_NULL)
541 {
542 op = OP_NULL;
544 continue;
545 }
546
547 if (op == OP_NULL)
548 {
550 continue;
551 }
552
553 int rc = pager_function_dispatcher(priv->pview->win_pager, op);
554
555 if (pview->mode == PAGER_MODE_EMAIL)
556 {
557 if ((rc == FR_UNKNOWN) && priv->pview->win_index)
559#ifdef USE_SIDEBAR
560 if (rc == FR_UNKNOWN)
561 rc = sb_function_dispatcher(win_sidebar, op);
562#endif
563 }
564 if (rc == FR_UNKNOWN)
565 rc = global_function_dispatcher(NULL, op);
566
567 if ((rc == FR_UNKNOWN) &&
568 ((pview->mode == PAGER_MODE_ATTACH) || (pview->mode == PAGER_MODE_ATTACH_E)))
569 {
570 // Some attachment functions still need to be delegated
571 priv->rc = op;
572 break;
573 }
574
575 if ((pview->mode != PAGER_MODE_EMAIL) && (rc == FR_UNKNOWN))
577
578 } while (priv->loop == PAGER_LOOP_CONTINUE);
579
580 //-------------------------------------------------------------------------
581 // END OF ACT 3: Read user input loop - while (op != OP_ABORT)
582 //-------------------------------------------------------------------------
583
584 mutt_file_fclose(&priv->fp);
585 if (pview->mode == PAGER_MODE_EMAIL)
586 {
587 if (shared->mailbox_view)
588 shared->mailbox_view->msg_in_pager = -1;
589 }
590
592
593 for (size_t i = 0; i < priv->lines_max; i++)
594 {
595 FREE(&(priv->lines[i].syntax));
596 if (priv->search_compiled && priv->lines[i].search)
597 FREE(&(priv->lines[i].search));
598 }
599 if (priv->search_compiled)
600 {
601 regfree(&priv->search_re);
602 priv->search_compiled = false;
603 }
604 FREE(&priv->lines);
606 {
607 struct AttrColor *ac = NULL;
608 int count = 0;
609 TAILQ_FOREACH(ac, &priv->ansi_list, entries)
610 {
611 count++;
612 }
613 color_debug(LL_DEBUG5, "AnsiColors %d\n", count);
614 }
615
616 priv->pview = NULL;
617
618 if (priv->loop == PAGER_LOOP_RELOAD)
619 return PAGER_LOOP_RELOAD;
620
621 return (priv->rc != -1) ? priv->rc : 0;
622}
void attr_color_list_clear(struct AttrColorList *acl)
Free the contents of an AttrColorList.
Definition: attr.c:97
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:303
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:593
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:141
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:131
void dump_pager(struct PagerPrivateData *priv)
Definition: pager.c:101
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
int BrailleRow
Braille display: row to leave the cursor.
Definition: dlg_pager.c:80
int BrailleCol
Braille display: column to leave the cursor.
Definition: dlg_pager.c:82
static bool check_read_delay(uint64_t *timestamp)
Is it time to mark the message read?
Definition: dlg_pager.c:194
void pager_queue_redraw(struct PagerPrivateData *priv, PagerRedrawFlags redraw)
Queue a request for a redraw.
Definition: dlg_pager.c:145
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:157
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
void mutt_set_flag(struct Mailbox *m, struct Email *e, enum MessageType flag, bool bf, bool upd_mbox)
Set a flag on an email.
Definition: flags.c:52
bool OptAttachMsg
(pseudo) used by attach-message
Definition: globals.c:66
bool OptSearchInvalid
(pseudo) used to invalidate the search pattern
Definition: globals.c:86
SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.c:60
int pager_function_dispatcher(struct MuttWindow *win, int op)
Perform a Pager function - Implements function_dispatcher_t -.
Definition: functions.c:795
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:3017
#define mutt_error(...)
Definition: logging2.h:90
#define mutt_message(...)
Definition: logging2.h:89
#define mutt_debug(LEVEL,...)
Definition: logging2.h:87
#define mutt_perror(...)
Definition: logging2.h:91
void mutt_timeout_hook(void)
Execute any timeout hooks.
Definition: hook.c:892
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:803
void km_error_key(enum MenuType mtype)
Handle an unbound key sequence.
Definition: keymap.c:1077
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
MailboxType
Supported mailbox formats.
Definition: mailbox.h:41
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:44
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define FREE(x)
Definition: memory.h:43
void msgwin_clear_text(void)
Clear the text in the Message Window.
Definition: msgwin.c:250
uint64_t mutt_date_now_ms(void)
Return the number of milliseconds since the Unix epoch.
Definition: date.c:455
#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:81
void mutt_resize_screen(void)
Update NeoMutt's opinion about the window size (CURSES)
Definition: resize.c:72
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:73
bool mutt_mailbox_notify(struct Mailbox *m_cur)
Notify the user if there's new mail.
Definition: mutt_mailbox.c:227
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:605
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:341
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:294
struct MuttWindow * window_set_focus(struct MuttWindow *win)
Set the Window focus.
Definition: mutt_window.c:660
void window_set_visible(struct MuttWindow *win, bool visible)
Set a Window visible or hidden.
Definition: mutt_window.c:163
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:523
void window_invalidate_all(void)
Mark all windows as in need of repaint.
Definition: mutt_window.c:743
@ 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:1143
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:48
#define OP_ABORT
Definition: opcodes.h:33
bool jump_to_bottom(struct PagerPrivateData *priv, struct PagerView *pview)
Make sure the bottom line is displayed.
Definition: functions.c:103
#define MUTT_PAGER_RETWINCH
Need reformatting on SIGWINCH.
Definition: lib.h:70
#define NT_PAGER_VIEW
Pager View has changed.
Definition: lib.h:185
#define MUTT_TYPES
Compute line's type.
Definition: lib.h:64
#define MUTT_SHOWCOLOR
Show characters in color otherwise don't show characters.
Definition: lib.h:61
#define PAGER_REDRAW_FLOW
Reflow the pager.
Definition: lib.h:190
#define MUTT_PAGER_BOTTOM
Start at the bottom.
Definition: lib.h:74
#define PAGER_REDRAW_PAGER
Redraw the pager.
Definition: lib.h:189
#define MUTT_SHOWFLAT
Show characters (used for displaying help)
Definition: lib.h:60
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:52
#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:479
#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:110
Data shared between Index, Pager and Sidebar.
Definition: shared_data.h:37
struct Email * email
Currently selected Email.
Definition: shared_data.h:42
struct Mailbox * mailbox
Current Mailbox.
Definition: shared_data.h:41
struct MailboxView * mailbox_view
Current Mailbox view.
Definition: shared_data.h:40
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:44
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:163
FILE * fp
Source stream.
Definition: lib.h:161
struct Body * body
Current attachment.
Definition: lib.h:160
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:176
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:171
enum PagerMode mode
Pager mode.
Definition: lib.h:172
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:173
struct MuttWindow * win_pbar
Pager Bar Window.
Definition: lib.h:177
struct MuttWindow * win_pager
Pager Window.
Definition: lib.h:178
Keep track of screen resizing.
Definition: dlg_pager.c:73
bool search_compiled
Definition: dlg_pager.c:75
bool search_back
Definition: dlg_pager.c:76
int line
Definition: dlg_pager.c:74
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 123 of file do_pager.c.

124{
125 assert(pview);
126 assert(pview->pdata);
127 assert(pview->pdata->fname);
128 assert((pview->mode == PAGER_MODE_ATTACH) ||
129 (pview->mode == PAGER_MODE_HELP) || (pview->mode == PAGER_MODE_OTHER));
130
134
135 struct IndexSharedData *shared = index_shared_data_new();
136 shared->email = e;
137
138 notify_set_parent(shared->notify, dlg->notify);
139
140 dlg->wdata = shared;
142
143 const bool c_status_on_top = cs_subset_bool(NeoMutt->sub, "status_on_top");
144 struct MuttWindow *panel_pager = ppanel_new(c_status_on_top, shared);
145 dlg->focus = panel_pager;
146 mutt_window_add_child(dlg, panel_pager);
147
150 dialog_push(dlg);
151
152 pview->win_index = NULL;
153 pview->win_pbar = window_find_child(panel_pager, WT_STATUS_BAR);
154 pview->win_pager = window_find_child(panel_pager, WT_CUSTOM);
155
156 int rc;
157
158 const char *const c_pager = pager_get_pager(NeoMutt->sub);
159 if (c_pager)
160 {
161 struct Buffer *cmd = buf_pool_get();
162
163 mutt_endwin();
164 buf_file_expand_fmt_quote(cmd, c_pager, pview->pdata->fname);
165 if (mutt_system(buf_string(cmd)) == -1)
166 {
167 mutt_error(_("Error running \"%s\""), buf_string(cmd));
168 rc = -1;
169 }
170 else
171 {
172 rc = 0;
173 }
175 buf_pool_release(&cmd);
176 }
177 else
178 {
179 rc = mutt_pager(pview);
180 }
181
182 dialog_pop();
183 mutt_window_free(&dlg);
184 return rc;
185}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:90
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:225
void buf_file_expand_fmt_quote(struct Buffer *dest, const char *fmt, const char *src)
Replace s in a string with a filename.
Definition: file.c:1475
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:194
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:95
void index_shared_data_free(struct MuttWindow *win, void **ptr)
Free Shared Index Data - Implements MuttWindow::wdata_free() -.
Definition: shared_data.c:134
struct IndexSharedData * index_shared_data_new(void)
Create new Index Data.
Definition: shared_data.c:152
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
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:200
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:440
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:180
@ 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
const char * pager_get_pager(struct ConfigSubset *sub)
Get the value of $pager.
Definition: config.c:103
struct MuttWindow * ppanel_new(bool status_on_top, struct IndexSharedData *shared)
Create the Windows for the Pager panel.
Definition: ppanel.c:122
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
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:159
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:

◆ buf_strip_formatting()

void buf_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 688 of file display.c.

689{
690 const char *s = src;
691
692 buf_reset(dest);
693
694 if (!s)
695 return;
696
697 while (s[0] != '\0')
698 {
699 if ((s[0] == '\010') && (s > src))
700 {
701 if (s[1] == '_') /* underline */
702 {
703 s += 2;
704 }
705 else if (s[1] && buf_len(dest)) /* bold or overstrike */
706 {
707 dest->dptr--;
708 buf_addch(dest, s[1]);
709 s += 2;
710 }
711 else /* ^H */
712 {
713 buf_addch(dest, *s++);
714 }
715 continue;
716 }
717
718 int len = ansi_color_seq_length(s);
719 if (len > 0)
720 {
721 s += len;
722 }
723 else if (strip_markers && (s[0] == '\033') && (s[1] == ']') &&
725 {
726 mutt_debug(LL_DEBUG2, "Seen attachment marker\n");
727 while (*s++ != '\a')
728 ; /* skip pseudo-ANSI sequence */
729 }
730 else
731 {
732 buf_addch(dest, *s++);
733 }
734 }
735}
int ansi_color_seq_length(const char *str)
Is this an ANSI escape sequence?
Definition: ansi.c:78
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:460
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:88
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:253
static int check_protected_header_marker(const char *p)
Check that the unique marker is present.
Definition: display.c:298
static int check_attachment_marker(const char *p)
Check that the unique marker is present.
Definition: display.c:288
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
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 122 of file ppanel.c.

123{
127 panel_pager->state.visible = false; // The Pager and Pager Bar are initially hidden
128
130 panel_pager->wdata = priv;
131 panel_pager->wdata_free = pager_private_data_free;
132
133 struct MuttWindow *win_pager = pager_window_new(shared, priv);
134 panel_pager->focus = win_pager;
135
136 struct MuttWindow *win_pbar = pbar_new(shared, priv);
137 if (status_on_top)
138 {
139 mutt_window_add_child(panel_pager, win_pbar);
140 mutt_window_add_child(panel_pager, win_pager);
141 }
142 else
143 {
144 mutt_window_add_child(panel_pager, win_pager);
145 mutt_window_add_child(panel_pager, win_pbar);
146 }
147
149 notify_observer_add(panel_pager->notify, NT_WINDOW, ppanel_window_observer, panel_pager);
150
151 return panel_pager;
152}
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:95
@ 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:414
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:330
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 414 of file pager.c.

416{
420 win->wdata = priv;
421 win->recalc = pager_recalc;
422 win->repaint = pager_repaint;
423
430
431 return win;
432}
static int pager_pager_observer(struct NotifyCallback *nc)
Notification that the Pager has changed - Implements observer_t -.
Definition: pager.c:362
static int pager_color_observer(struct NotifyCallback *nc)
Notification that a Color has changed - Implements observer_t -.
Definition: pager.c:237
static int pager_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: pager.c:273
static int pager_index_observer(struct NotifyCallback *nc)
Notification that the Index has changed - Implements observer_t -.
Definition: pager.c:319
static int pager_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: pager.c:376
static int pager_global_observer(struct NotifyCallback *nc)
Notification that a Global Event occurred - Implements observer_t -.
Definition: pager.c:295
static int pager_recalc(struct MuttWindow *win)
Recalculate the Pager display - Implements MuttWindow::recalc() -.
Definition: pager.c:121
static int pager_repaint(struct MuttWindow *win)
Repaint the Pager display - Implements MuttWindow::repaint() -.
Definition: pager.c:131
@ 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:181
int(* recalc)(struct MuttWindow *win)
Definition: mutt_window.h:170
+ 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 458 of file message.c.

459{
460 struct MuttWindow *dlg = dialog_find(win_index);
461 struct MuttWindow *win_pager = window_find_child(dlg, WT_CUSTOM);
462 struct MuttWindow *win_pbar = window_find_child(dlg, WT_STATUS_BAR);
463 struct Buffer *tempfile = buf_pool_get();
464 struct Message *msg = NULL;
465
466 squash_index_panel(shared->mailbox, win_index, win_pager);
467
468 int rc = PAGER_LOOP_QUIT;
469 do
470 {
471 msg = mx_msg_open(shared->mailbox, shared->email);
472 if (!msg)
473 break;
474
476
477 buf_reset(tempfile);
478 // win_pager might not be visible and have a size yet, so use win_index
479 rc = email_to_file(msg, tempfile, shared->mailbox, shared->email, NULL,
480 win_index->state.cols, &cmflags);
481 if (rc < 0)
482 break;
483
484 notify_crypto(shared->email, msg, cmflags);
485
486 /* Invoke the builtin pager */
487 struct PagerData pdata = { 0 };
488 struct PagerView pview = { &pdata };
489
490 pdata.fp = msg->fp;
491 pdata.fname = buf_string(tempfile);
492
493 pview.mode = PAGER_MODE_EMAIL;
494 pview.banner = NULL;
495 pview.flags = MUTT_PAGER_MESSAGE |
496 (shared->email->body->nowrap ? MUTT_PAGER_NOWRAP : 0);
497 pview.win_index = win_index;
498 pview.win_pbar = win_pbar;
499 pview.win_pager = win_pager;
500
501 rc = mutt_pager(&pview);
502 mx_msg_close(shared->mailbox, &msg);
503 } while (rc == PAGER_LOOP_RELOAD);
504
506
507 mx_msg_close(shared->mailbox, &msg);
508 buf_pool_release(&tempfile);
509 return rc;
510}
#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:34
#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:1210
struct Message * mx_msg_open(struct Mailbox *m, struct Email *e)
Return a stream pointer for a message.
Definition: mx.c:1164
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: lib.h:72
#define MUTT_PAGER_MESSAGE
Definition: lib.h:75
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:175
static void expand_index_panel(struct MuttWindow *win_index, struct MuttWindow *win_pager)
Restore the Index Panel.
Definition: message.c:437
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:372
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:410
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:159
Paged view into some data.
Definition: lib.h:170
const char * banner
Title to display in status bar.
Definition: lib.h:174
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ external_pager()

int external_pager ( struct MailboxView mv,
struct Email e,
const char *  command 
)

Display a message in an external program.

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

Definition at line 312 of file message.c.

313{
314 if (!mv || !mv->mailbox)
315 return -1;
316
317 struct Mailbox *m = mv->mailbox;
318 struct Message *msg = mx_msg_open(m, e);
319 if (!msg)
320 return -1;
321
322 char buf[1024] = { 0 };
323 const char *const c_pager_format = cs_subset_string(NeoMutt->sub, "pager_format");
324 const int screen_width = RootWindow->state.cols;
325 mutt_make_string(buf, sizeof(buf), screen_width, NONULL(c_pager_format), m,
327
328 struct Buffer *tempfile = buf_pool_get();
329
331 int rc = email_to_file(msg, tempfile, m, e, buf, screen_width, &cmflags);
332 if (rc < 0)
333 goto cleanup;
334
335 mutt_endwin();
336
337 struct Buffer *cmd = buf_pool_get();
338 buf_printf(cmd, "%s %s", command, buf_string(tempfile));
339 int r = mutt_system(buf_string(cmd));
340 if (r == -1)
341 mutt_error(_("Error running \"%s\""), buf_string(cmd));
342 unlink(buf_string(tempfile));
343 buf_pool_release(&cmd);
344
345 if (!OptNoCurses)
346 keypad(stdscr, true);
347 if (r != -1)
348 mutt_set_flag(m, e, MUTT_READ, true, true);
349 const bool c_prompt_after = cs_subset_bool(NeoMutt->sub, "prompt_after");
350 if ((r != -1) && c_prompt_after)
351 {
353 rc = km_dokey(MENU_PAGER);
354 }
355 else
356 {
357 rc = 0;
358 }
359
360cleanup:
361 mx_msg_close(m, &msg);
362 buf_pool_release(&tempfile);
363 return rc;
364}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:173
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
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: globals.c:82
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:1489
static const char * ExtPagerProgress
Status bar message when entire message is visible in the Pager.
Definition: message.c:60
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: rootwin.c:104
struct Mailbox * mailbox
Current Mailbox.
Definition: mview.h:50
A mailbox.
Definition: mailbox.h:79
+ 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 145 of file dlg_pager.c.

146{
147 priv->redraw |= redraw;
148 priv->pview->win_pager->actions |= WA_RECALC;
149}
#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()

bool 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 312 of file display.c.

313{
314 bool is_quote = false;
315 const struct Regex *c_smileys = cs_subset_regex(NeoMutt->sub, "smileys");
316 regmatch_t pmatch_internal[1];
317
318 if (!pmatch)
319 pmatch = pmatch_internal;
320
321 const struct Regex *c_quote_regex = cs_subset_regex(NeoMutt->sub, "quote_regex");
322 if (mutt_regex_capture(c_quote_regex, line, 1, pmatch))
323 {
324 regmatch_t smatch[1];
325 if (mutt_regex_capture(c_smileys, line, 1, smatch))
326 {
327 if (smatch[0].rm_so > 0)
328 {
329 char c = line[smatch[0].rm_so];
330 line[smatch[0].rm_so] = 0;
331
332 if (mutt_regex_capture(c_quote_regex, line, 1, pmatch))
333 is_quote = true;
334
335 line[smatch[0].rm_so] = c;
336 }
337 }
338 else
339 {
340 is_quote = true;
341 }
342 }
343
344 return is_quote;
345}
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:618
Cached regular expression.
Definition: regex3.h:89
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pager_get_pager()

const char * pager_get_pager ( struct ConfigSubset sub)

Get the value of $pager.

Parameters
subConfig Subset
Return values
strExternal command to use
NULLThe internal pager will be used
Note
If $pager has the magic value of "builtin", NULL will be returned

Definition at line 103 of file config.c.

104{
105 const char *c_pager = cs_subset_string(sub, "pager");
106 if (!c_pager || mutt_str_equal(c_pager, "builtin"))
107 return NULL;
108
109 return c_pager;
110}
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:798
+ 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 = buf_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, buf_string(buf));
76 buf_pool_release(&buf);
77 }
78 if (line->cont_line)
79 {
80 mutt_debug(LL_DEBUG1, "\tcont_line: %s\n",
81 line->cont_line ? "\033[1;32myes\033[0m" : "\033[31mno\033[0m");
82 }
83 if (line->cont_header)
84 {
85 mutt_debug(LL_DEBUG1, "\tcont_header: %s\n",
86 line->cont_header ? "\033[1;32myes\033[0m" : "\033[31mno\033[0m");
87 }
88
89 if (line->syntax_arr_size > 0)
90 {
91 mutt_debug(LL_DEBUG1, "\tsyntax: %d\n", line->syntax_arr_size);
93 }
94 if (line->search_arr_size > 0)
95 {
96 mutt_debug(LL_DEBUG1, "\t\033[1;36msearch\033[0m: %d\n", line->search_arr_size);
98 }
99}
void get_colorid_name(unsigned int cid, struct Buffer *buf)
Get the name of a color id.
Definition: command.c:667
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:57
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 101 of file pager.c.

102{
103 if (!priv)
104 return;
105
106 mutt_debug(LL_DEBUG1, "----------------------------------------------\n");
107 mutt_debug(LL_DEBUG1, "Pager: %d lines (fd %d)\n", priv->lines_used, fileno(priv->fp));
108 for (int i = 0; i < priv->lines_used; i++)
109 {
110 dump_line(i, &priv->lines[i]);
111 }
112}
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

◆ BrailleRow

int BrailleRow
extern

Braille display: row to leave the cursor.

Definition at line 80 of file dlg_pager.c.

◆ BrailleCol

int BrailleCol
extern

Braille display: column to leave the cursor.

Definition at line 82 of file dlg_pager.c.