NeoMutt  2025-12-11-435-g4ac674
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
Pager Function API

Prototype for a Pager Function. More...

+ Collaboration diagram for Pager Function API:

Functions

static int op_pager_bottom (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Jump to the bottom of the message - Implements pager_function_t -.
 
static int op_pager_half_down (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Scroll down 1/2 page - Implements pager_function_t -.
 
static int op_pager_half_up (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Scroll up 1/2 page - Implements pager_function_t -.
 
static int op_pager_hide_quoted (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Toggle display of quoted text - Implements pager_function_t -.
 
static int op_pager_next_line (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Scroll down one line - Implements pager_function_t -.
 
static int op_pager_next_page (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Move to the next page - Implements pager_function_t -.
 
static int op_pager_prev_line (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Scroll up one line - Implements pager_function_t -.
 
static int op_pager_prev_page (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Move to the previous page - Implements pager_function_t -.
 
static int op_pager_search (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Search for a regular expression - Implements pager_function_t -.
 
static int op_pager_search_next (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Search for next match - Implements pager_function_t -.
 
static int op_pager_skip_headers (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Jump to first line after headers - Implements pager_function_t -.
 
static int op_pager_skip_quoted (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Skip beyond quoted text - Implements pager_function_t -.
 
static int op_pager_top (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Jump to the top of the message - Implements pager_function_t -.
 
static int op_exit (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Exit this menu - Implements pager_function_t -.
 
static int op_help (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Help screen - Implements pager_function_t -.
 
static int op_save (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Save the Pager text - Implements pager_function_t -.
 
static int op_search_toggle (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Toggle search pattern coloring - Implements pager_function_t -.
 
static int op_view_attachments (struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
 Show MIME attachments - Implements pager_function_t -.
 

Detailed Description

Prototype for a Pager Function.

Parameters
sharedShared Index data
privPrivate Index data
eventEvent to process
Return values
enumFunctionRetval
Precondition
shared is not NULL
priv is not NULL
event is not NULL

Function Documentation

◆ op_pager_bottom()

static int op_pager_bottom ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Jump to the bottom of the message - Implements pager_function_t -.

Definition at line 409 of file functions.c.

411{
412 if (!jump_to_bottom(priv, priv->pview))
413 mutt_message(_("Bottom of message is shown"));
414
415 return FR_SUCCESS;
416}
@ FR_SUCCESS
Valid function - successfully performed.
Definition dispatcher.h:40
#define mutt_message(...)
Definition logging2.h:93
#define _(a)
Definition message.h:28
bool jump_to_bottom(struct PagerPrivateData *priv, struct PagerView *pview)
Make sure the bottom line is displayed.
Definition functions.c:381
struct PagerView * pview
Object to view in the pager.
+ Here is the call graph for this function:

◆ op_pager_half_down()

static int op_pager_half_down ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Scroll down 1/2 page - Implements pager_function_t -.

Definition at line 421 of file functions.c.

423{
424 const bool c_pager_stop = cs_subset_bool(NeoMutt->sub, "pager_stop");
425 if (priv->lines[priv->cur_line].offset < (priv->st.st_size - 1))
426 {
427 priv->top_line = up_n_lines(priv->pview->win_pager->state.rows / 2,
428 priv->lines, priv->cur_line, priv->hide_quoted);
430 }
431 else if (c_pager_stop)
432 {
433 /* emulate "less -q" and don't go on to the next message. */
434 mutt_message(_("Bottom of message is shown"));
435 }
436 else
437 {
438 /* end of the current message, so display the next message. */
440 }
441 return FR_SUCCESS;
442}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
bool index_next_undeleted(struct MuttWindow *win_index)
Select the next undeleted Email (if possible)
Definition functions.c:394
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition notify.c:173
@ NT_PAGER
Pager data has changed, NotifyPager, PagerPrivateData.
Definition notify_type.h:53
static int up_n_lines(int nlines, struct Line *info, int cur, bool hiding)
Reposition the pager's view up by n lines.
Definition functions.c:362
#define NT_PAGER_VIEW
Pager View has changed.
Definition lib.h:187
LOFF_T offset
Offset into Email file (PagerPrivateData->fp)
Definition display.h:51
struct WindowState state
Current state of the Window.
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
PagerFlags hide_quoted
Set to MUTT_HIDE when quoted email is hidden <toggle-quoted>
int cur_line
Current line (last line visible on screen)
struct Line * lines
Array of text lines in pager.
struct Notify * notify
Notifications: NotifyPager, PagerPrivateData.
int top_line
First visible line on screen.
struct stat st
Stats about Email file.
struct MuttWindow * win_index
Index Window.
Definition lib.h:178
struct MuttWindow * win_pager
Pager Window.
Definition lib.h:180
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition mutt_window.h:61
+ Here is the call graph for this function:

◆ op_pager_half_up()

static int op_pager_half_up ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Scroll up 1/2 page - Implements pager_function_t -.

Definition at line 447 of file functions.c.

449{
450 if (priv->top_line)
451 {
452 priv->top_line = up_n_lines(priv->pview->win_pager->state.rows / 2 +
453 (priv->pview->win_pager->state.rows % 2),
454 priv->lines, priv->top_line, priv->hide_quoted);
456 }
457 else
458 {
459 mutt_message(_("Top of message is shown"));
460 }
461 return FR_SUCCESS;
462}
+ Here is the call graph for this function:

◆ op_pager_hide_quoted()

static int op_pager_hide_quoted ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Toggle display of quoted text - Implements pager_function_t -.

Definition at line 467 of file functions.c.

469{
470 if (!priv->has_types)
471 return FR_NO_ACTION;
472
473 priv->hide_quoted ^= MUTT_HIDE;
474 if (priv->hide_quoted && COLOR_QUOTED(priv->lines[priv->top_line].cid))
475 {
476 priv->top_line = up_n_lines(1, priv->lines, priv->top_line, priv->hide_quoted);
477 }
478 else
479 {
481 }
483 return FR_SUCCESS;
484}
@ FR_NO_ACTION
Valid function - no action performed.
Definition dispatcher.h:38
void pager_queue_redraw(struct PagerPrivateData *priv, PagerRedrawFlags redraw)
Queue a request for a redraw.
Definition dlg_pager.c:125
#define MUTT_HIDE
Don't show quoted text.
Definition lib.h:65
#define PAGER_REDRAW_PAGER
Redraw the pager.
Definition lib.h:191
#define COLOR_QUOTED(cid)
Definition quoted.h:28
short cid
Default line colour, e.g. MT_COLOR_SIGNATURE.
Definition display.h:52
int has_types
Set to MUTT_TYPES for PAGER_MODE_EMAIL or MUTT_SHOWCOLOR.
+ Here is the call graph for this function:

◆ op_pager_next_line()

static int op_pager_next_line ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Scroll down one line - Implements pager_function_t -.

Definition at line 489 of file functions.c.

491{
492 if (priv->lines[priv->cur_line].offset < (priv->st.st_size - 1))
493 {
494 priv->top_line++;
495 if (priv->hide_quoted)
496 {
497 while ((priv->top_line < priv->lines_used) &&
498 COLOR_QUOTED(priv->lines[priv->top_line].cid))
499 {
500 priv->top_line++;
501 }
502 }
504 }
505 else
506 {
507 mutt_message(_("Bottom of message is shown"));
508 }
509 return FR_SUCCESS;
510}
int lines_used
Size of lines array (used entries)
+ Here is the call graph for this function:

◆ op_pager_next_page()

static int op_pager_next_page ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Move to the next page - Implements pager_function_t -.

Definition at line 515 of file functions.c.

517{
518 const bool c_pager_stop = cs_subset_bool(NeoMutt->sub, "pager_stop");
519 if (priv->lines[priv->cur_line].offset < (priv->st.st_size - 1))
520 {
521 const short c_pager_context = cs_subset_number(NeoMutt->sub, "pager_context");
522 priv->top_line = up_n_lines(c_pager_context, priv->lines, priv->cur_line, priv->hide_quoted);
524 }
525 else if (c_pager_stop)
526 {
527 /* emulate "less -q" and don't go on to the next message. */
528 mutt_message(_("Bottom of message is shown"));
529 }
530 else
531 {
532 /* end of the current message, so display the next message. */
534 }
535 return FR_SUCCESS;
536}
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition helpers.c:143
+ Here is the call graph for this function:

◆ op_pager_prev_line()

static int op_pager_prev_line ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Scroll up one line - Implements pager_function_t -.

Definition at line 541 of file functions.c.

543{
544 if (priv->top_line)
545 {
546 priv->top_line = up_n_lines(1, priv->lines, priv->top_line, priv->hide_quoted);
548 }
549 else
550 {
551 mutt_message(_("Top of message is shown"));
552 }
553 return FR_SUCCESS;
554}
+ Here is the call graph for this function:

◆ op_pager_prev_page()

static int op_pager_prev_page ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Move to the previous page - Implements pager_function_t -.

Definition at line 559 of file functions.c.

561{
562 if (priv->top_line == 0)
563 {
564 mutt_message(_("Top of message is shown"));
565 }
566 else
567 {
568 const short c_pager_context = cs_subset_number(NeoMutt->sub, "pager_context");
569 priv->top_line = up_n_lines(priv->pview->win_pager->state.rows - c_pager_context,
570 priv->lines, priv->top_line, priv->hide_quoted);
572 }
573 return FR_SUCCESS;
574}
+ Here is the call graph for this function:

◆ op_pager_search()

static int op_pager_search ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Search for a regular expression - Implements pager_function_t -.

This function handles:

  • OP_SEARCH
  • OP_SEARCH_REVERSE

Definition at line 583 of file functions.c.

585{
586 struct PagerView *pview = priv->pview;
587
588 int rc = FR_NO_ACTION;
589 struct Buffer *buf = buf_pool_get();
590
591 buf_strcpy(buf, priv->search_str);
592 const int op = event->op;
593 if (mw_get_field(((op == OP_SEARCH) || (op == OP_SEARCH_NEXT)) ? _("Search for: ") : _("Reverse search for: "),
595 {
596 goto done;
597 }
598
599 if (mutt_str_equal(buf_string(buf), priv->search_str))
600 {
601 if (priv->search_compiled)
602 {
603 struct KeyEvent event_s = { 0, OP_NULL };
604
605 /* do an implicit search-next */
606 if (op == OP_SEARCH)
607 event_s.op = OP_SEARCH_NEXT;
608 else
609 event_s.op = OP_SEARCH_OPPOSITE;
610
611 priv->wrapped = false;
612 op_pager_search_next(shared, priv, &event_s);
613 }
614 }
615
616 if (buf_is_empty(buf))
617 goto done;
618
619 mutt_str_copy(priv->search_str, buf_string(buf), sizeof(priv->search_str));
620
621 /* leave search_back alone if op == OP_SEARCH_NEXT */
622 if (op == OP_SEARCH)
623 priv->search_back = false;
624 else if (op == OP_SEARCH_REVERSE)
625 priv->search_back = true;
626
627 if (priv->search_compiled)
628 {
629 regfree(&priv->search_re);
630 for (size_t i = 0; i < priv->lines_used; i++)
631 {
632 FREE(&(priv->lines[i].search));
633 priv->lines[i].search_arr_size = -1;
634 }
635 }
636
637 uint16_t rflags = mutt_mb_is_lower(priv->search_str) ? REG_ICASE : 0;
638 int err = REG_COMP(&priv->search_re, priv->search_str, REG_NEWLINE | rflags);
639 if (err != 0)
640 {
641 regerror(err, &priv->search_re, buf->data, buf->dsize);
642 mutt_error("%s", buf_string(buf));
643 for (size_t i = 0; i < priv->lines_max; i++)
644 {
645 /* cleanup */
646 FREE(&(priv->lines[i].search));
647 priv->lines[i].search_arr_size = -1;
648 }
649 priv->search_flag = 0;
650 priv->search_compiled = false;
651 }
652 else
653 {
654 priv->search_compiled = true;
655 /* update the search pointers */
656 int line_num = 0;
657 while (display_line(priv->fp, &priv->bytes_read, &priv->lines, line_num,
658 &priv->lines_used, &priv->lines_max,
659 MUTT_SEARCH | (pview->flags & MUTT_PAGER_NOWRAP) | priv->has_types,
660 &priv->quote_list, &priv->q_level, &priv->force_redraw,
661 &priv->search_re, priv->pview->win_pager, &priv->ansi_list) == 0)
662 {
663 line_num++;
664 }
665
666 if (priv->search_back)
667 {
668 /* searching backward */
669 int i;
670 for (i = priv->top_line; i >= 0; i--)
671 {
672 if ((!priv->hide_quoted || !COLOR_QUOTED(priv->lines[i].cid)) &&
673 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
674 {
675 break;
676 }
677 }
678
679 if (i >= 0)
680 priv->top_line = i;
681 }
682 else
683 {
684 /* searching forward */
685 int i;
686 for (i = priv->top_line; i < priv->lines_used; i++)
687 {
688 if ((!priv->hide_quoted || !COLOR_QUOTED(priv->lines[i].cid)) &&
689 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
690 {
691 break;
692 }
693 }
694
695 if (i < priv->lines_used)
696 priv->top_line = i;
697 }
698
699 if (priv->lines[priv->top_line].search_arr_size == 0)
700 {
701 priv->search_flag = 0;
702 mutt_error(_("Not found"));
703 }
704 else
705 {
706 const short c_search_context = cs_subset_number(NeoMutt->sub, "search_context");
707 priv->search_flag = MUTT_SEARCH;
708 /* give some context for search results */
709 if (c_search_context < priv->pview->win_pager->state.rows)
710 priv->searchctx = c_search_context;
711 else
712 priv->searchctx = 0;
713 if (priv->top_line - priv->searchctx > 0)
714 priv->top_line -= priv->searchctx;
715 }
716 }
719 rc = FR_SUCCESS;
720
721done:
722 buf_pool_release(&buf);
723 return rc;
724}
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:291
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
int display_line(FILE *fp, LOFF_T *bytes_read, struct Line **lines, int line_num, int *lines_used, int *lines_max, PagerFlags flags, struct QuoteStyle **quote_list, int *q_level, bool *force_redraw, regex_t *search_re, struct MuttWindow *win_pager, struct AttrColorList *ansi_list)
Print a line on screen.
Definition display.c:1053
#define MUTT_COMP_CLEAR
Clear input if printable character is pressed.
Definition wdata.h:43
int mw_get_field(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
Ask the user for a string -.
Definition window.c:270
#define mutt_error(...)
Definition logging2.h:94
static int op_pager_search_next(struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
Search for next match - Implements pager_function_t -.
Definition functions.c:733
@ HC_PATTERN
Patterns.
Definition lib.h:59
bool mutt_mb_is_lower(const char *s)
Does a multi-byte string contain only lowercase characters?
Definition mbyte.c:355
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:662
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition string.c:583
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition lib.h:73
#define MUTT_SEARCH
Resolve search patterns.
Definition lib.h:66
const struct CompleteOps CompletePatternOps
Auto-Completion of Patterns.
Definition complete.c:98
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition regex3.h:49
String manipulation buffer.
Definition buffer.h:36
size_t dsize
Length of data.
Definition buffer.h:39
char * data
Pointer to data.
Definition buffer.h:37
An event such as a keypress.
Definition get.h:50
int op
Function opcode, e.g. OP_HELP.
Definition get.h:52
short search_arr_size
Number of items in search array.
Definition display.h:59
struct TextSyntax * search
Array of search text in the line.
Definition display.h:60
bool cont_line
Continuation of a previous line (wrapped by NeoMutt)
Definition display.h:53
int q_level
Number of unique quoting levels.
bool wrapped
Has the search/next wrapped around?
char search_str[256]
Current search string.
int lines_max
Capacity of lines array (total entries)
bool force_redraw
Repaint is needed.
LOFF_T bytes_read
Number of bytes read from file.
bool search_back
Search backwards.
struct QuoteStyle * quote_list
Tree of quoting levels.
struct AttrColorList ansi_list
List of ANSI colours used in the Pager.
int searchctx
Space to show around search matches.
regex_t search_re
Compiled search string.
FILE * fp
File containing decrypted/decoded/weeded Email.
PagerFlags search_flag
Set to MUTT_SEARCH when search results are visible <search-toggle>
bool search_compiled
Search regex is in use.
Paged view into some data.
Definition lib.h:172
PagerFlags flags
Additional settings to tweak pager's function.
Definition lib.h:175
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ op_pager_search_next()

static int op_pager_search_next ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Search for next match - Implements pager_function_t -.

This function handles:

  • OP_SEARCH_NEXT
  • OP_SEARCH_OPPOSITE

Definition at line 733 of file functions.c.

735{
736 if (priv->search_compiled)
737 {
738 const short c_search_context = cs_subset_number(NeoMutt->sub, "search_context");
739 priv->wrapped = false;
740
741 if (c_search_context < priv->pview->win_pager->state.rows)
742 priv->searchctx = c_search_context;
743 else
744 priv->searchctx = 0;
745
746 const int op = event->op;
747
748 search_next:
749 if ((!priv->search_back && (op == OP_SEARCH_NEXT)) ||
750 (priv->search_back && (op == OP_SEARCH_OPPOSITE)))
751 {
752 /* searching forward */
753 int i;
754 for (i = priv->wrapped ? 0 : priv->top_line + priv->searchctx + 1;
755 i < priv->lines_used; i++)
756 {
757 if ((!priv->hide_quoted || !COLOR_QUOTED(priv->lines[i].cid)) &&
758 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
759 {
760 break;
761 }
762 }
763
764 const bool c_wrap_search = cs_subset_bool(NeoMutt->sub, "wrap_search");
765 if (i < priv->lines_used)
766 {
767 priv->top_line = i;
768 }
769 else if (priv->wrapped || !c_wrap_search)
770 {
771 mutt_error(_("Not found"));
772 }
773 else
774 {
775 mutt_message(_("Search wrapped to top"));
776 priv->wrapped = true;
777 goto search_next;
778 }
779 }
780 else
781 {
782 /* searching backward */
783 int i;
784 for (i = priv->wrapped ? priv->lines_used : priv->top_line + priv->searchctx - 1;
785 i >= 0; i--)
786 {
787 if ((!priv->hide_quoted ||
788 (priv->has_types && !COLOR_QUOTED(priv->lines[i].cid))) &&
789 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
790 {
791 break;
792 }
793 }
794
795 const bool c_wrap_search = cs_subset_bool(NeoMutt->sub, "wrap_search");
796 if (i >= 0)
797 {
798 priv->top_line = i;
799 }
800 else if (priv->wrapped || !c_wrap_search)
801 {
802 mutt_error(_("Not found"));
803 }
804 else
805 {
806 mutt_message(_("Search wrapped to bottom"));
807 priv->wrapped = true;
808 goto search_next;
809 }
810 }
811
812 if (priv->lines[priv->top_line].search_arr_size > 0)
813 {
814 priv->search_flag = MUTT_SEARCH;
815 /* give some context for search results */
816 if (priv->top_line - priv->searchctx > 0)
817 priv->top_line -= priv->searchctx;
818 }
819
821 return FR_SUCCESS;
822 }
823
824 /* no previous search pattern */
825 return op_pager_search(shared, priv, event);
826}
static int op_pager_search(struct IndexSharedData *shared, struct PagerPrivateData *priv, const struct KeyEvent *event)
Search for a regular expression - Implements pager_function_t -.
Definition functions.c:583
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ op_pager_skip_headers()

static int op_pager_skip_headers ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Jump to first line after headers - Implements pager_function_t -.

Definition at line 831 of file functions.c.

833{
834 struct PagerView *pview = priv->pview;
835
836 if (!priv->has_types)
837 return FR_NO_ACTION;
838
839 int rc = 0;
840 int new_topline = 0;
841
842 while (((new_topline < priv->lines_used) ||
843 (0 == (rc = display_line(priv->fp, &priv->bytes_read, &priv->lines,
844 new_topline, &priv->lines_used, &priv->lines_max,
845 MUTT_TYPES | (pview->flags & MUTT_PAGER_NOWRAP), &priv->quote_list,
846 &priv->q_level, &priv->force_redraw, &priv->search_re,
847 priv->pview->win_pager, &priv->ansi_list)))) &&
848 color_is_header(priv->lines[new_topline].cid))
849 {
850 new_topline++;
851 }
852
853 if (rc < 0)
854 {
855 /* L10N: Displayed if <skip-headers> is invoked in the pager, but
856 there is no text past the headers.
857 (I don't think this is actually possible in Mutt's code, but
858 display some kind of message in case it somehow occurs.) */
859 mutt_warning(_("No text past headers"));
860 return FR_NO_ACTION;
861 }
862 priv->top_line = new_topline;
864 return FR_SUCCESS;
865}
bool color_is_header(enum ColorId cid)
Colour is for an Email header.
Definition display.c:487
#define mutt_warning(...)
Definition logging2.h:92
#define MUTT_TYPES
Compute line's type.
Definition lib.h:67
+ Here is the call graph for this function:

◆ op_pager_skip_quoted()

static int op_pager_skip_quoted ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Skip beyond quoted text - Implements pager_function_t -.

Definition at line 870 of file functions.c.

872{
873 struct PagerView *pview = priv->pview;
874
875 if (!priv->has_types)
876 return FR_NO_ACTION;
877
878 const short c_pager_skip_quoted_context = cs_subset_number(NeoMutt->sub, "pager_skip_quoted_context");
879 int rc = 0;
880 int new_topline = priv->top_line;
881 int num_quoted = 0;
882
883 /* In a header? Skip all the email headers, and done */
884 if (color_is_header(priv->lines[new_topline].cid))
885 {
886 while (((new_topline < priv->lines_used) ||
887 (0 == (rc = display_line(priv->fp, &priv->bytes_read, &priv->lines,
888 new_topline, &priv->lines_used, &priv->lines_max,
889 MUTT_TYPES | (pview->flags & MUTT_PAGER_NOWRAP), &priv->quote_list,
890 &priv->q_level, &priv->force_redraw, &priv->search_re,
891 priv->pview->win_pager, &priv->ansi_list)))) &&
892 color_is_header(priv->lines[new_topline].cid))
893 {
894 new_topline++;
895 }
896 priv->top_line = new_topline;
898 return FR_SUCCESS;
899 }
900
901 /* Already in the body? Skip past previous "context" quoted lines */
902 if (c_pager_skip_quoted_context > 0)
903 {
904 while (((new_topline < priv->lines_used) ||
905 (0 == (rc = display_line(priv->fp, &priv->bytes_read, &priv->lines,
906 new_topline, &priv->lines_used, &priv->lines_max,
907 MUTT_TYPES | (pview->flags & MUTT_PAGER_NOWRAP), &priv->quote_list,
908 &priv->q_level, &priv->force_redraw, &priv->search_re,
909 priv->pview->win_pager, &priv->ansi_list)))) &&
910 COLOR_QUOTED(priv->lines[new_topline].cid))
911 {
912 new_topline++;
913 num_quoted++;
914 }
915
916 if (rc < 0)
917 {
918 mutt_error(_("No more unquoted text after quoted text"));
919 return FR_NO_ACTION;
920 }
921 }
922
923 if (num_quoted <= c_pager_skip_quoted_context)
924 {
925 num_quoted = 0;
926
927 while (((new_topline < priv->lines_used) ||
928 (0 == (rc = display_line(priv->fp, &priv->bytes_read, &priv->lines,
929 new_topline, &priv->lines_used, &priv->lines_max,
930 MUTT_TYPES | (pview->flags & MUTT_PAGER_NOWRAP), &priv->quote_list,
931 &priv->q_level, &priv->force_redraw, &priv->search_re,
932 priv->pview->win_pager, &priv->ansi_list)))) &&
933 !COLOR_QUOTED(priv->lines[new_topline].cid))
934 {
935 new_topline++;
936 }
937
938 if (rc < 0)
939 {
940 mutt_error(_("No more quoted text"));
941 return FR_NO_ACTION;
942 }
943
944 while (((new_topline < priv->lines_used) ||
945 (0 == (rc = display_line(priv->fp, &priv->bytes_read, &priv->lines,
946 new_topline, &priv->lines_used, &priv->lines_max,
947 MUTT_TYPES | (pview->flags & MUTT_PAGER_NOWRAP), &priv->quote_list,
948 &priv->q_level, &priv->force_redraw, &priv->search_re,
949 priv->pview->win_pager, &priv->ansi_list)))) &&
950 COLOR_QUOTED(priv->lines[new_topline].cid))
951 {
952 new_topline++;
953 num_quoted++;
954 }
955
956 if (rc < 0)
957 {
958 mutt_error(_("No more unquoted text after quoted text"));
959 return FR_NO_ACTION;
960 }
961 }
962 priv->top_line = new_topline - MIN(c_pager_skip_quoted_context, num_quoted);
964 return FR_SUCCESS;
965}
#define MIN(a, b)
Return the minimum of two values.
Definition memory.h:40
+ Here is the call graph for this function:

◆ op_pager_top()

static int op_pager_top ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Jump to the top of the message - Implements pager_function_t -.

Definition at line 970 of file functions.c.

972{
973 if (priv->top_line == 0)
974 {
975 mutt_message(_("Top of message is shown"));
976 }
977 else
978 {
979 priv->top_line = 0;
981 }
982
983 return FR_SUCCESS;
984}
+ Here is the call graph for this function:

◆ op_exit()

static int op_exit ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Exit this menu - Implements pager_function_t -.

Definition at line 991 of file functions.c.

993{
994 priv->rc = -1;
995 priv->loop = PAGER_LOOP_QUIT;
996 return FR_DONE;
997}
@ FR_DONE
Exit the Dialog.
Definition dispatcher.h:36
@ PAGER_LOOP_QUIT
Quit the Pager.
Definition lib.h:153
int rc
Return code from functions.
enum PagerLoopMode loop
What the Event Loop should do next, e.g. PAGER_LOOP_CONTINUE.

◆ op_help()

static int op_help ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Help screen - Implements pager_function_t -.

Definition at line 1002 of file functions.c.

1004{
1005 if (priv->pview->mode == PAGER_MODE_HELP)
1006 {
1007 /* don't let the user enter the help-menu from the help screen! */
1008 mutt_error(_("Help is currently being shown"));
1009 return FR_ERROR;
1010 }
1013 return FR_SUCCESS;
1014}
@ FR_ERROR
Valid function - error occurred.
Definition dispatcher.h:39
void mutt_help(const struct MenuDefinition *md)
Display the Help Page.
Definition help.c:147
struct MenuDefinition * MdPager
Pager Menu Definition.
Definition functions.c:64
@ PAGER_MODE_HELP
Pager is invoked via 3rd path to show help.
Definition lib.h:141
enum PagerMode mode
Pager mode.
Definition lib.h:174
+ Here is the call graph for this function:

◆ op_save()

static int op_save ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Save the Pager text - Implements pager_function_t -.

Definition at line 1019 of file functions.c.

1021{
1022 struct PagerView *pview = priv->pview;
1023 if (pview->mode != PAGER_MODE_OTHER)
1024 return FR_UNKNOWN;
1025
1026 if (!priv->fp)
1027 return FR_UNKNOWN;
1028
1029 int rc = FR_ERROR;
1030 FILE *fp_save = NULL;
1031 struct Buffer *buf = buf_pool_get();
1032
1033 // Save the current read position
1034 long pos = ftell(priv->fp);
1035 rewind(priv->fp);
1036
1037 struct FileCompletionData cdata = { false, NULL, NULL, NULL, NULL };
1038 if ((mw_get_field(_("Save to file: "), buf, MUTT_COMP_CLEAR, HC_FILE,
1039 &CompleteFileOps, &cdata) != 0) ||
1040 buf_is_empty(buf))
1041 {
1042 rc = FR_SUCCESS;
1043 goto done;
1044 }
1045
1046 expand_path(buf, false);
1047 fp_save = mutt_file_fopen(buf_string(buf), "a+");
1048 if (!fp_save)
1049 {
1050 mutt_perror("%s", buf_string(buf));
1051 goto done;
1052 }
1053
1054 int bytes = mutt_file_copy_stream(priv->fp, fp_save);
1055 if (bytes == -1)
1056 {
1057 mutt_perror("%s", buf_string(buf));
1058 goto done;
1059 }
1060
1061 mutt_message(_("Saved to: %s"), buf_string(buf));
1062 rc = FR_SUCCESS;
1063
1064done:
1065 // Restore the read position (rewound at start of function)
1066 if (pos >= 0)
1067 mutt_file_seek(priv->fp, pos, SEEK_SET);
1068
1069 mutt_file_fclose(&fp_save);
1070 buf_pool_release(&buf);
1071
1072 return rc;
1073}
const struct CompleteOps CompleteFileOps
Auto-Completion of Files.
Definition complete.c:152
@ FR_UNKNOWN
Unknown function.
Definition dispatcher.h:34
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition file.c:222
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:652
#define mutt_file_fclose(FP)
Definition file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
#define mutt_perror(...)
Definition logging2.h:95
@ HC_FILE
Files.
Definition lib.h:58
void expand_path(struct Buffer *buf, bool regex)
Create the canonical path.
Definition muttlib.c:121
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition lib.h:142
Input for the file completion function.
Definition curs_lib.h:39
+ Here is the call graph for this function:

◆ op_search_toggle()

static int op_search_toggle ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Toggle search pattern coloring - Implements pager_function_t -.

Definition at line 1078 of file functions.c.

1080{
1081 if (priv->search_compiled)
1082 {
1083 priv->search_flag ^= MUTT_SEARCH;
1085 }
1086 return FR_SUCCESS;
1087}
+ Here is the call graph for this function:

◆ op_view_attachments()

static int op_view_attachments ( struct IndexSharedData * shared,
struct PagerPrivateData * priv,
const struct KeyEvent * event )
static

Show MIME attachments - Implements pager_function_t -.

Definition at line 1092 of file functions.c.

1094{
1095 struct PagerView *pview = priv->pview;
1096
1097 // This needs to be delegated
1098 if (pview->flags & MUTT_PAGER_ATTACHMENT)
1099 return FR_UNKNOWN;
1100
1101 if (!assert_pager_mode(pview->mode == PAGER_MODE_EMAIL))
1102 return FR_NOT_IMPL;
1103 dlg_attachment(NeoMutt->sub, shared->mailbox_view, shared->email,
1104 pview->pdata->fp, shared->attach_msg);
1105 if (shared->email->attach_del)
1106 shared->mailbox->changed = true;
1108 return FR_SUCCESS;
1109}
@ FR_NOT_IMPL
Invalid function - feature not enabled.
Definition dispatcher.h:37
void dlg_attachment(struct ConfigSubset *sub, struct MailboxView *mv, struct Email *e, FILE *fp, bool attach_msg)
Show the attachments in a Menu -.
Definition dlg_attach.c:207
static bool assert_pager_mode(bool test)
Check that pager is in correct mode.
Definition functions.c:344
@ PAGER_MODE_EMAIL
Pager is invoked via 1st path. The mime part is selected automatically.
Definition lib.h:138
#define MUTT_PAGER_ATTACHMENT
Attachments may exist.
Definition lib.h:72
bool attach_del
Has an attachment marked for deletion.
Definition email.h:99
struct Email * email
Currently selected Email.
Definition shared_data.h:42
struct Mailbox * mailbox
Current Mailbox.
Definition shared_data.h:41
bool attach_msg
Are we in "attach message" mode?
Definition shared_data.h:46
struct MailboxView * mailbox_view
Current Mailbox view.
Definition shared_data.h:40
bool changed
Mailbox has been modified.
Definition mailbox.h:109
FILE * fp
Source stream.
Definition lib.h:163
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition lib.h:173
+ Here is the call graph for this function: