NeoMutt  2025-12-11-980-ge38c27
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_first_entry (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Move to the first entry - Implements pager_function_t -.
 
static int op_last_entry (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Move to the last entry - Implements pager_function_t -.
 
static int op_pager_half_down (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Scroll down 1/2 page - Implements pager_function_t -.
 
static int op_pager_half_up (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Scroll up 1/2 page - Implements pager_function_t -.
 
static int op_pager_hide_quoted (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Toggle display of quoted text - Implements pager_function_t -.
 
static int op_pager_next_line (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Scroll down one line - Implements pager_function_t -.
 
static int op_pager_next_page (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Move to the next page - Implements pager_function_t -.
 
static int op_pager_prev_line (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Scroll up one line - Implements pager_function_t -.
 
static int op_pager_prev_page (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Move to the previous page - Implements pager_function_t -.
 
static int op_pager_search (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Search for a regular expression - Implements pager_function_t -.
 
static int op_pager_search_next (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Search for next match - Implements pager_function_t -.
 
static int op_pager_skip_headers (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Jump to first line after headers - Implements pager_function_t -.
 
static int op_pager_skip_quoted (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Skip beyond quoted text - Implements pager_function_t -.
 
static int op_exit (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Exit this menu - Implements pager_function_t -.
 
static int op_quit (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Save changes to mailbox and quit - Implements pager_function_t -.
 
static int op_help (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Help screen - Implements pager_function_t -.
 
static int op_save (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Save the Pager text - Implements pager_function_t -.
 
static int op_search_toggle (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Toggle search pattern coloring - Implements pager_function_t -.
 
static int op_view_attachments (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Show MIME attachments - Implements pager_function_t -.
 
static int op_ignore (struct PagerFunctionData *fdata, const struct KeyEvent *event)
 Ignore this function - Implements pager_function_t -.
 

Detailed Description

Prototype for a Pager Function.

Parameters
fdataPager Function context data
eventEvent to process
Return values
enumFunctionRetval
Precondition
fdata is not NULL
event is not NULL

Function Documentation

◆ op_first_entry()

static int op_first_entry ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Move to the first entry - Implements pager_function_t -.

Definition at line 225 of file functions.c.

226{
227 struct PagerPrivateData *priv = fdata->priv;
228 if (priv->top_line == 0)
229 {
230 mutt_message(_("Top of message is shown"));
231 return FR_ERROR;
232 }
233 else
234 {
235 priv->top_line = 0;
237 }
238
239 return FR_SUCCESS;
240}
@ FR_SUCCESS
Valid function - successfully performed.
Definition dispatcher.h:40
@ FR_ERROR
Valid function - error occurred.
Definition dispatcher.h:39
#define mutt_message(...)
Definition logging2.h:93
#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:173
@ NT_PAGER
Pager data has changed, NotifyPager, PagerPrivateData.
Definition notify_type.h:54
@ NT_PAGER_VIEW
Pager View has changed.
Definition lib.h:192
struct PagerPrivateData * priv
Private Pager data.
Definition functions.h:41
Private state data for the Pager.
struct Notify * notify
Notifications: NotifyPager, PagerPrivateData.
int top_line
First visible line on screen.
+ Here is the call graph for this function:

◆ op_last_entry()

static int op_last_entry ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Move to the last entry - Implements pager_function_t -.

Definition at line 245 of file functions.c.

246{
247 struct PagerPrivateData *priv = fdata->priv;
248 if (!jump_to_bottom(priv, priv->pview))
249 {
250 mutt_message(_("Bottom of message is shown"));
251 return FR_ERROR;
252 }
253
254 return FR_SUCCESS;
255}
bool jump_to_bottom(struct PagerPrivateData *priv, struct PagerView *pview)
Make sure the bottom line is displayed.
Definition functions.c:197
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 PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Scroll down 1/2 page - Implements pager_function_t -.

Definition at line 260 of file functions.c.

261{
262 struct PagerPrivateData *priv = fdata->priv;
263 const bool c_pager_stop = cs_subset_bool(fdata->n->sub, "pager_stop");
264 if (priv->lines[priv->cur_line].offset < (priv->st.st_size - 1))
265 {
266 int rows = priv->pview->win_pager->state.rows;
267 if (event->count > 0)
268 {
269 int advance = event->count * (rows / 2);
270 priv->top_line = down_n_lines(advance, priv->lines, priv->top_line,
271 priv->lines_used, priv->hide_quoted);
272 }
273 else
274 {
275 priv->top_line = up_n_lines(rows / 2, priv->lines, priv->cur_line, priv->hide_quoted);
276 }
278 }
279 else if (c_pager_stop)
280 {
281 /* emulate "less -q" and don't go on to the next message. */
282 if (event->count == 0)
283 {
284 mutt_message(_("Bottom of message is shown"));
285 return FR_ERROR;
286 }
287 }
288 else
289 {
290 /* end of the current message, so display the next message. */
292 }
293 return FR_SUCCESS;
294}
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:439
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:154
static int down_n_lines(int nlines, struct Line *info, int cur, int max, bool hiding)
Reposition the pager's view down by n lines.
Definition functions.c:175
int count
Optional count prefix, e.g. 3 for 3j
Definition get.h:78
LOFF_T offset
Offset into Email file (PagerPrivateData->fp)
Definition display.h:51
struct WindowState state
Current state of the Window.
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
struct NeoMutt * n
NeoMutt application data.
Definition functions.h:38
PagerFlags hide_quoted
Set to MUTT_HIDE when quoted email is hidden <toggle-quoted>
int cur_line
Current line (last line visible on screen)
int lines_used
Size of lines array (used entries)
struct Line * lines
Array of text lines in pager.
struct stat st
Stats about Email file.
struct MuttWindow * win_index
Index Window.
Definition lib.h:179
struct MuttWindow * win_pager
Pager Window.
Definition lib.h:181
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 PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Scroll up 1/2 page - Implements pager_function_t -.

Definition at line 299 of file functions.c.

300{
301 struct PagerPrivateData *priv = fdata->priv;
302 const int old_top_line = priv->top_line;
303 if (priv->top_line)
304 {
305 int rows = priv->pview->win_pager->state.rows;
306 int n = MAX(event->count, 1) * (rows / 2 + rows % 2);
307 priv->top_line = up_n_lines(n, priv->lines, priv->top_line, priv->hide_quoted);
309 }
310 else if (event->count == 0)
311 {
312 mutt_message(_("Top of message is shown"));
313 }
314 return (old_top_line == 0) ? FR_ERROR : FR_SUCCESS;
315}
#define MAX(a, b)
Return the maximum of two values.
Definition memory.h:38
int old_top_line
Old top line, used for repainting.
+ Here is the call graph for this function:

◆ op_pager_hide_quoted()

static int op_pager_hide_quoted ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Toggle display of quoted text - Implements pager_function_t -.

Definition at line 320 of file functions.c.

321{
322 struct PagerPrivateData *priv = fdata->priv;
323 if (!priv->has_types)
324 return FR_NO_ACTION;
325
326 priv->hide_quoted ^= MUTT_HIDE;
327 if (priv->hide_quoted && COLOR_QUOTED(priv->lines[priv->top_line].cid))
328 {
329 priv->top_line = up_n_lines(1, priv->lines, priv->top_line, priv->hide_quoted);
330 }
331 else
332 {
334 }
336 return FR_SUCCESS;
337}
@ 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:121
@ PAGER_REDRAW_PAGER
Redraw the pager.
Definition lib.h:202
#define MUTT_HIDE
Don't show quoted text.
Definition lib.h:66
#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 PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Scroll down one line - Implements pager_function_t -.

Definition at line 342 of file functions.c.

343{
344 struct PagerPrivateData *priv = fdata->priv;
345 if (priv->lines[priv->cur_line].offset < (priv->st.st_size - 1))
346 {
347 int n = MAX(event->count, 1);
348 priv->top_line = down_n_lines(n, priv->lines, priv->top_line,
349 priv->lines_used, priv->hide_quoted);
351 }
352 else if (event->count == 0)
353 {
354 mutt_message(_("Bottom of message is shown"));
355 return FR_ERROR;
356 }
357 return FR_SUCCESS;
358}
+ Here is the call graph for this function:

◆ op_pager_next_page()

static int op_pager_next_page ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Move to the next page - Implements pager_function_t -.

Definition at line 363 of file functions.c.

364{
365 struct PagerPrivateData *priv = fdata->priv;
366 const bool c_pager_stop = cs_subset_bool(fdata->n->sub, "pager_stop");
367 if (priv->lines[priv->cur_line].offset < (priv->st.st_size - 1))
368 {
369 const short c_pager_context = cs_subset_number(fdata->n->sub, "pager_context");
370 if (event->count > 0)
371 {
372 int advance = event->count * (priv->pview->win_pager->state.rows - c_pager_context);
373 priv->top_line = down_n_lines(advance, priv->lines, priv->top_line,
374 priv->lines_used, priv->hide_quoted);
375 }
376 else
377 {
378 priv->top_line = up_n_lines(c_pager_context, priv->lines, priv->cur_line,
379 priv->hide_quoted);
380 }
382 }
383 else if (c_pager_stop)
384 {
385 /* emulate "less -q" and don't go on to the next message. */
386 if (event->count == 0)
387 {
388 mutt_message(_("Bottom of message is shown"));
389 return FR_ERROR;
390 }
391 }
392 else
393 {
394 /* end of the current message, so display the next message. */
396 }
397 return FR_SUCCESS;
398}
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 PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Scroll up one line - Implements pager_function_t -.

Definition at line 403 of file functions.c.

404{
405 struct PagerPrivateData *priv = fdata->priv;
406 if (priv->top_line)
407 {
408 int n = MAX(event->count, 1);
409 priv->top_line = up_n_lines(n, priv->lines, priv->top_line, priv->hide_quoted);
411 }
412 else if (event->count == 0)
413 {
414 mutt_message(_("Top of message is shown"));
415 return FR_ERROR;
416 }
417 return FR_SUCCESS;
418}
+ Here is the call graph for this function:

◆ op_pager_prev_page()

static int op_pager_prev_page ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Move to the previous page - Implements pager_function_t -.

Definition at line 423 of file functions.c.

424{
425 struct PagerPrivateData *priv = fdata->priv;
426 if (priv->top_line == 0)
427 {
428 if (event->count == 0)
429 {
430 mutt_message(_("Top of message is shown"));
431 return FR_ERROR;
432 }
433 }
434 else
435 {
436 const short c_pager_context = cs_subset_number(fdata->n->sub, "pager_context");
437 int n = MAX(event->count, 1) * (priv->pview->win_pager->state.rows - c_pager_context);
438 priv->top_line = up_n_lines(n, priv->lines, priv->top_line, priv->hide_quoted);
440 }
441 return FR_SUCCESS;
442}
+ Here is the call graph for this function:

◆ op_pager_search()

static int op_pager_search ( struct PagerFunctionData * fdata,
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 451 of file functions.c.

452{
453 struct PagerPrivateData *priv = fdata->priv;
454 struct PagerView *pview = priv->pview;
455
456 int rc = FR_NO_ACTION;
457 struct Buffer *buf = buf_pool_get();
458
459 buf_strcpy(buf, priv->search_str);
460 const int op = event->op;
461 if (mw_get_field(((op == OP_SEARCH) || (op == OP_SEARCH_NEXT)) ? _("Search for: ") : _("Reverse search for: "),
463 {
464 goto done;
465 }
466
467 if (mutt_str_equal(buf_string(buf), priv->search_str))
468 {
469 if (priv->search_compiled)
470 {
471 struct KeyEvent event_s = { 0, OP_NULL };
472
473 /* do an implicit search-next */
474 if (op == OP_SEARCH)
475 event_s.op = OP_SEARCH_NEXT;
476 else
477 event_s.op = OP_SEARCH_OPPOSITE;
478
479 priv->wrapped = false;
480 op_pager_search_next(fdata, &event_s);
481 }
482 }
483
484 if (buf_is_empty(buf))
485 goto done;
486
487 mutt_str_copy(priv->search_str, buf_string(buf), sizeof(priv->search_str));
488
489 /* leave search_back alone if op == OP_SEARCH_NEXT */
490 if (op == OP_SEARCH)
491 priv->search_back = false;
492 else if (op == OP_SEARCH_REVERSE)
493 priv->search_back = true;
494
495 if (priv->search_compiled)
496 {
497 regfree(&priv->search_re);
498 for (size_t i = 0; i < priv->lines_used; i++)
499 {
500 FREE(&(priv->lines[i].search));
501 priv->lines[i].search_arr_size = -1;
502 }
503 }
504
505 uint16_t rflags = mutt_mb_is_lower(priv->search_str) ? REG_ICASE : 0;
506 int err = REG_COMP(&priv->search_re, priv->search_str, REG_NEWLINE | rflags);
507 if (err != 0)
508 {
509 regerror(err, &priv->search_re, buf->data, buf->dsize);
510 mutt_error("%s", buf_string(buf));
511 for (size_t i = 0; i < priv->lines_max; i++)
512 {
513 /* cleanup */
514 FREE(&(priv->lines[i].search));
515 priv->lines[i].search_arr_size = -1;
516 }
517 priv->search_flag = 0;
518 priv->search_compiled = false;
519 rc = FR_ERROR;
520 }
521 else
522 {
523 priv->search_compiled = true;
524 /* update the search pointers */
525 int line_num = 0;
526 while (display_line(priv->fp, &priv->bytes_read, &priv->lines, line_num,
527 &priv->lines_used, &priv->lines_max,
528 MUTT_SEARCH | (pview->flags & MUTT_PAGER_NOWRAP) | priv->has_types,
529 &priv->quote_list, &priv->q_level, &priv->force_redraw,
530 &priv->search_re, priv->pview->win_pager, &priv->ansi_list) == 0)
531 {
532 line_num++;
533 }
534
535 if (priv->search_back)
536 {
537 /* searching backward */
538 int i;
539 for (i = priv->top_line; i >= 0; i--)
540 {
541 if ((!priv->hide_quoted || !COLOR_QUOTED(priv->lines[i].cid)) &&
542 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
543 {
544 break;
545 }
546 }
547
548 if (i >= 0)
549 priv->top_line = i;
550 }
551 else
552 {
553 /* searching forward */
554 int i;
555 for (i = priv->top_line; i < priv->lines_used; i++)
556 {
557 if ((!priv->hide_quoted || !COLOR_QUOTED(priv->lines[i].cid)) &&
558 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
559 {
560 break;
561 }
562 }
563
564 if (i < priv->lines_used)
565 priv->top_line = i;
566 }
567
568 if (priv->lines[priv->top_line].search_arr_size == 0)
569 {
570 priv->search_flag = 0;
571 mutt_error(_("Not found"));
572 rc = FR_ERROR;
573 }
574 else
575 {
576 const short c_search_context = cs_subset_number(fdata->n->sub, "search_context");
577 priv->search_flag = MUTT_SEARCH;
578 /* give some context for search results */
579 if (c_search_context < priv->pview->win_pager->state.rows)
580 priv->searchctx = c_search_context;
581 else
582 priv->searchctx = 0;
583 if (priv->top_line - priv->searchctx > 0)
584 priv->top_line -= priv->searchctx;
585 rc = FR_SUCCESS;
586 }
587 }
590
591done:
592 buf_pool_release(&buf);
593 return rc;
594}
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:298
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
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:1063
@ MUTT_COMP_CLEAR
Clear input if printable character is pressed.
Definition wdata.h:47
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:502
#define mutt_error(...)
Definition logging2.h:94
static int op_pager_search_next(struct PagerFunctionData *fdata, const struct KeyEvent *event)
Search for next match - Implements pager_function_t -.
Definition functions.c:603
@ HC_PATTERN
Patterns.
Definition lib.h:60
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:666
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:587
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition lib.h:74
#define MUTT_SEARCH
Resolve search patterns.
Definition lib.h:67
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:75
int op
Function opcode, e.g. OP_HELP.
Definition get.h:77
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:173
PagerFlags flags
Additional settings to tweak pager's function.
Definition lib.h:176
+ 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 PagerFunctionData * fdata,
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 603 of file functions.c.

604{
605 struct PagerPrivateData *priv = fdata->priv;
606 if (priv->search_compiled)
607 {
608 const short c_search_context = cs_subset_number(fdata->n->sub, "search_context");
609 bool found = false;
610 priv->wrapped = false;
611
612 if (c_search_context < priv->pview->win_pager->state.rows)
613 priv->searchctx = c_search_context;
614 else
615 priv->searchctx = 0;
616
617 const int op = event->op;
618
619 search_next:
620 if ((!priv->search_back && (op == OP_SEARCH_NEXT)) ||
621 (priv->search_back && (op == OP_SEARCH_OPPOSITE)))
622 {
623 /* searching forward */
624 int i;
625 for (i = priv->wrapped ? 0 : priv->top_line + priv->searchctx + 1;
626 i < priv->lines_used; i++)
627 {
628 if ((!priv->hide_quoted || !COLOR_QUOTED(priv->lines[i].cid)) &&
629 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
630 {
631 break;
632 }
633 }
634
635 const bool c_wrap_search = cs_subset_bool(fdata->n->sub, "wrap_search");
636 if (i < priv->lines_used)
637 {
638 priv->top_line = i;
639 found = true;
640 }
641 else if (priv->wrapped || !c_wrap_search)
642 {
643 mutt_error(_("Not found"));
644 }
645 else
646 {
647 mutt_message(_("Search wrapped to top"));
648 priv->wrapped = true;
649 goto search_next;
650 }
651 }
652 else
653 {
654 /* searching backward */
655 int i;
656 for (i = priv->wrapped ? priv->lines_used : priv->top_line + priv->searchctx - 1;
657 i >= 0; i--)
658 {
659 if ((!priv->hide_quoted ||
660 (priv->has_types && !COLOR_QUOTED(priv->lines[i].cid))) &&
661 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
662 {
663 break;
664 }
665 }
666
667 const bool c_wrap_search = cs_subset_bool(fdata->n->sub, "wrap_search");
668 if (i >= 0)
669 {
670 priv->top_line = i;
671 found = true;
672 }
673 else if (priv->wrapped || !c_wrap_search)
674 {
675 mutt_error(_("Not found"));
676 }
677 else
678 {
679 mutt_message(_("Search wrapped to bottom"));
680 priv->wrapped = true;
681 goto search_next;
682 }
683 }
684
685 if (!found)
686 return FR_ERROR;
687
688 if (priv->lines[priv->top_line].search_arr_size > 0)
689 {
690 priv->search_flag = MUTT_SEARCH;
691 /* give some context for search results */
692 if (priv->top_line - priv->searchctx > 0)
693 priv->top_line -= priv->searchctx;
694 }
695
697 return FR_SUCCESS;
698 }
699
700 /* no previous search pattern */
701 return op_pager_search(fdata, event);
702}
static int op_pager_search(struct PagerFunctionData *fdata, const struct KeyEvent *event)
Search for a regular expression - Implements pager_function_t -.
Definition functions.c:451
+ 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 PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Jump to first line after headers - Implements pager_function_t -.

Definition at line 707 of file functions.c.

708{
709 struct PagerPrivateData *priv = fdata->priv;
710 struct PagerView *pview = priv->pview;
711
712 if (!priv->has_types)
713 return FR_NO_ACTION;
714
715 int rc = 0;
716 int new_topline = 0;
717
718 while (((new_topline < priv->lines_used) ||
719 (0 == (rc = display_line(priv->fp, &priv->bytes_read, &priv->lines,
720 new_topline, &priv->lines_used, &priv->lines_max,
721 MUTT_TYPES | (pview->flags & MUTT_PAGER_NOWRAP), &priv->quote_list,
722 &priv->q_level, &priv->force_redraw, &priv->search_re,
723 priv->pview->win_pager, &priv->ansi_list)))) &&
724 color_is_header(priv->lines[new_topline].cid))
725 {
726 new_topline++;
727 }
728
729 if (rc < 0)
730 {
731 /* L10N: Displayed if <skip-headers> is invoked in the pager, but
732 there is no text past the headers.
733 (I don't think this is actually possible in Mutt's code, but
734 display some kind of message in case it somehow occurs.) */
735 mutt_warning(_("No text past headers"));
736 return FR_ERROR;
737 }
738 priv->top_line = new_topline;
740 return FR_SUCCESS;
741}
bool color_is_header(enum ColorId cid)
Colour is for an Email header.
Definition display.c:488
#define mutt_warning(...)
Definition logging2.h:92
#define MUTT_TYPES
Compute line's type.
Definition lib.h:68
+ Here is the call graph for this function:

◆ op_pager_skip_quoted()

static int op_pager_skip_quoted ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Skip beyond quoted text - Implements pager_function_t -.

With a count prefix, skip N quoted blocks instead of 1.

Definition at line 838 of file functions.c.

839{
840 struct PagerPrivateData *priv = fdata->priv;
841
842 if (!priv->has_types)
843 return FR_NO_ACTION;
844
845 const int count = MAX(event->count, 1);
846
847 for (int i = 0; i < count; i++)
848 {
849 if (pager_skip_quoted_once(priv, fdata) < 0)
850 return FR_NO_ACTION;
851 }
852
853 return FR_SUCCESS;
854}
static int pager_skip_quoted_once(struct PagerPrivateData *priv, struct PagerFunctionData *fdata)
Skip to next unquoted block.
Definition functions.c:750
+ Here is the call graph for this function:

◆ op_exit()

static int op_exit ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Exit this menu - Implements pager_function_t -.

Definition at line 861 of file functions.c.

862{
863 struct PagerPrivateData *priv = fdata->priv;
864 priv->rc = -1;
865 priv->loop = PAGER_LOOP_QUIT;
866 return FR_DONE;
867}
@ FR_DONE
Exit the Dialog.
Definition dispatcher.h:36
@ PAGER_LOOP_QUIT
Quit the Pager.
Definition lib.h:154
int rc
Return code from functions.
enum PagerLoopMode loop
What the Event Loop should do next, e.g. PAGER_LOOP_CONTINUE.

◆ op_quit()

static int op_quit ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Save changes to mailbox and quit - Implements pager_function_t -.

Close the Pager and ask the Index to quit NeoMutt. The Index will save any changes to the Mailbox and close it.

Definition at line 875 of file functions.c.

876{
877 struct PagerPrivateData *priv = fdata->priv;
878 if (priv->pview->mode != PAGER_MODE_EMAIL)
879 return FR_UNKNOWN;
880
881 priv->rc = -1;
882 priv->loop = PAGER_LOOP_QUIT;
883
884 // Close the Pager, then let the Index handle the quit
885 mutt_push_macro_event(0, OP_QUIT);
886
887 return FR_DONE;
888}
@ FR_UNKNOWN
Unknown function.
Definition dispatcher.h:34
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition get.c:173
@ PAGER_MODE_EMAIL
Pager is invoked via 1st path. The mime part is selected automatically.
Definition lib.h:139
enum PagerMode mode
Pager mode.
Definition lib.h:175
+ Here is the call graph for this function:

◆ op_help()

static int op_help ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Help screen - Implements pager_function_t -.

Definition at line 893 of file functions.c.

894{
895 struct PagerPrivateData *priv = fdata->priv;
896 if (priv->pview->mode == PAGER_MODE_HELP)
897 {
898 /* don't let the user enter the help-menu from the help screen! */
899 mutt_error(_("Help is currently being shown"));
900 return FR_ERROR;
901 }
902 mutt_help(fdata->mod_data->md_pager);
904 return FR_SUCCESS;
905}
void mutt_help(const struct MenuDefinition *md)
Display the Help Page.
Definition help.c:147
@ PAGER_MODE_HELP
Pager is invoked via 3rd path to show help.
Definition lib.h:142
struct PagerModuleData * mod_data
Pager module data.
Definition functions.h:39
struct MenuDefinition * md_pager
Pager menu definition.
Definition module_data.h:32
+ Here is the call graph for this function:

◆ op_save()

static int op_save ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Save the Pager text - Implements pager_function_t -.

Definition at line 910 of file functions.c.

911{
912 struct PagerPrivateData *priv = fdata->priv;
913 struct PagerView *pview = priv->pview;
914 if (pview->mode != PAGER_MODE_OTHER)
915 return FR_UNKNOWN;
916
917 if (!priv->fp)
918 return FR_UNKNOWN;
919
920 int rc = FR_ERROR;
921 FILE *fp_save = NULL;
922 struct Buffer *buf = buf_pool_get();
923
924 // Save the current read position
925 long pos = ftell(priv->fp);
926 rewind(priv->fp);
927
928 struct FileCompletionData cdata = { false, NULL, NULL, NULL, NULL };
929 if ((mw_get_field(_("Save to file: "), buf, MUTT_COMP_CLEAR, HC_FILE,
930 &CompleteFileOps, &cdata) != 0) ||
931 buf_is_empty(buf))
932 {
933 rc = FR_SUCCESS;
934 goto done;
935 }
936
937 expand_path(buf, false);
938 fp_save = mutt_file_fopen(buf_string(buf), "a+");
939 if (!fp_save)
940 {
941 mutt_perror("%s", buf_string(buf));
942 goto done;
943 }
944
945 int bytes = mutt_file_copy_stream(priv->fp, fp_save);
946 if (bytes == -1)
947 {
948 mutt_perror("%s", buf_string(buf));
949 goto done;
950 }
951
952 mutt_message(_("Saved to: %s"), buf_string(buf));
953 rc = FR_SUCCESS;
954
955done:
956 // Restore the read position (rewound at start of function)
957 if (pos >= 0)
958 (void) mutt_file_seek(priv->fp, pos, SEEK_SET);
959
960 mutt_file_fclose(&fp_save);
961 buf_pool_release(&buf);
962
963 return rc;
964}
const struct CompleteOps CompleteFileOps
Auto-Completion of Files.
Definition complete.c:152
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition file.c:224
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:648
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
#define mutt_perror(...)
Definition logging2.h:95
@ HC_FILE
Files.
Definition lib.h:59
void expand_path(struct Buffer *buf, bool regex)
Create the canonical path.
Definition muttlib.c:122
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition lib.h:143
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 PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Toggle search pattern coloring - Implements pager_function_t -.

Definition at line 969 of file functions.c.

970{
971 struct PagerPrivateData *priv = fdata->priv;
972 if (priv->search_compiled)
973 {
974 priv->search_flag ^= MUTT_SEARCH;
976 }
977 return FR_SUCCESS;
978}
+ Here is the call graph for this function:

◆ op_view_attachments()

static int op_view_attachments ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Show MIME attachments - Implements pager_function_t -.

Definition at line 983 of file functions.c.

984{
985 struct IndexSharedData *shared = fdata->shared;
986 struct PagerPrivateData *priv = fdata->priv;
987 struct PagerView *pview = priv->pview;
988
989 // This needs to be delegated
990 if (pview->flags & MUTT_PAGER_ATTACHMENT)
991 return FR_UNKNOWN;
992
994 return FR_NOT_IMPL;
995 dlg_attach(fdata->n->sub, shared->mailbox_view, shared->email,
996 pview->pdata->fp, shared->attach_msg);
997 if (shared->email->attach_del)
998 shared->mailbox->changed = true;
1000 return FR_SUCCESS;
1001}
@ FR_NOT_IMPL
Invalid function - feature not enabled.
Definition dispatcher.h:37
void dlg_attach(struct ConfigSubset *sub, struct MailboxView *mv, struct Email *e, FILE *fp, bool attach_msg)
Show the attachments in a Menu -.
Definition dlg_attach.c:208
static bool assert_pager_mode(bool test)
Check that pager is in correct mode.
Definition functions.c:136
#define MUTT_PAGER_ATTACHMENT
Attachments may exist.
Definition lib.h:73
bool attach_del
Has an attachment marked for deletion.
Definition email.h:99
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
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:112
FILE * fp
Source stream.
Definition lib.h:164
struct IndexSharedData * shared
Shared Index data.
Definition functions.h:40
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition lib.h:174
+ Here is the call graph for this function:

◆ op_ignore()

static int op_ignore ( struct PagerFunctionData * fdata,
const struct KeyEvent * event )
static

Ignore this function - Implements pager_function_t -.

Definition at line 1006 of file functions.c.

1007{
1008 return FR_NO_ACTION;
1009}