NeoMutt  2022-04-29-247-gc6aae8
Teaching an old dog new tricks
DOXYGEN
functions.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <stddef.h>
31#include <inttypes.h> // IWYU pragma: keep
32#include <stdbool.h>
33#include <sys/stat.h>
34#include "mutt/lib.h"
35#include "config/lib.h"
36#include "email/lib.h"
37#include "core/lib.h"
38#include "gui/lib.h"
39#include "mutt.h"
40#include "functions.h"
41#include "lib.h"
42#include "attach/lib.h"
43#include "color/lib.h"
44#include "enter/lib.h"
45#include "index/lib.h"
46#include "menu/lib.h"
47#include "display.h"
48#include "opcodes.h"
49#include "private_data.h"
50#include "protos.h"
51#ifdef ENABLE_NLS
52#include <libintl.h>
53#endif
54
55static const char *Not_available_in_this_menu = N_("Not available in this menu");
56
57static int op_pager_search_next(struct IndexSharedData *shared,
58 struct PagerPrivateData *priv, int op);
59
68static inline bool assert_pager_mode(bool test)
69{
70 if (test)
71 return true;
72
75 return false;
76}
77
86static int up_n_lines(int nlines, struct Line *info, int cur, bool hiding)
87{
88 while ((cur > 0) && (nlines > 0))
89 {
90 cur--;
91 if (!hiding || (info[cur].cid != MT_COLOR_QUOTED))
92 nlines--;
93 }
94
95 return cur;
96}
97
105bool jump_to_bottom(struct PagerPrivateData *priv, struct PagerView *pview)
106{
107 if (!(priv->lines[priv->cur_line].offset < (priv->st.st_size - 1)))
108 {
109 return false;
110 }
111
112 int line_num = priv->cur_line;
113 /* make sure the types are defined to the end of file */
114 while (display_line(priv->fp, &priv->bytes_read, &priv->lines, line_num,
115 &priv->lines_used, &priv->lines_max,
116 priv->has_types | (pview->flags & MUTT_PAGER_NOWRAP),
117 &priv->quote_list, &priv->q_level, &priv->force_redraw,
118 &priv->search_re, priv->pview->win_pager, &priv->ansi_list) == 0)
119 {
120 line_num++;
121 }
122 priv->top_line = up_n_lines(priv->pview->win_pager->state.rows, priv->lines,
123 priv->lines_used, priv->hide_quoted);
125 return true;
126}
127
128// -----------------------------------------------------------------------------
129
133static int op_pager_bottom(struct IndexSharedData *shared,
134 struct PagerPrivateData *priv, int op)
135{
136 if (!jump_to_bottom(priv, priv->pview))
137 mutt_message(_("Bottom of message is shown"));
138
139 return FR_SUCCESS;
140}
141
145static int op_pager_half_down(struct IndexSharedData *shared,
146 struct PagerPrivateData *priv, int op)
147{
148 const bool c_pager_stop = cs_subset_bool(NeoMutt->sub, "pager_stop");
149 if (priv->lines[priv->cur_line].offset < (priv->st.st_size - 1))
150 {
151 priv->top_line = up_n_lines(priv->pview->win_pager->state.rows / 2,
152 priv->lines, priv->cur_line, priv->hide_quoted);
154 }
155 else if (c_pager_stop)
156 {
157 /* emulate "less -q" and don't go on to the next message. */
158 mutt_message(_("Bottom of message is shown"));
159 }
160 else
161 {
162 /* end of the current message, so display the next message. */
164 }
165 return FR_SUCCESS;
166}
167
171static int op_pager_half_up(struct IndexSharedData *shared,
172 struct PagerPrivateData *priv, int op)
173{
174 if (priv->top_line)
175 {
176 priv->top_line = up_n_lines(priv->pview->win_pager->state.rows / 2 +
177 (priv->pview->win_pager->state.rows % 2),
178 priv->lines, priv->top_line, priv->hide_quoted);
180 }
181 else
182 mutt_message(_("Top of message is shown"));
183 return FR_SUCCESS;
184}
185
189static int op_pager_hide_quoted(struct IndexSharedData *shared,
190 struct PagerPrivateData *priv, int op)
191{
192 if (!priv->has_types)
193 return FR_NO_ACTION;
194
195 priv->hide_quoted ^= MUTT_HIDE;
196 if (priv->hide_quoted && (priv->lines[priv->top_line].cid == MT_COLOR_QUOTED))
197 {
198 priv->top_line = up_n_lines(1, priv->lines, priv->top_line, priv->hide_quoted);
199 }
200 else
201 {
203 }
205 return FR_SUCCESS;
206}
207
211static int op_pager_next_line(struct IndexSharedData *shared,
212 struct PagerPrivateData *priv, int op)
213{
214 if (priv->lines[priv->cur_line].offset < (priv->st.st_size - 1))
215 {
216 priv->top_line++;
217 if (priv->hide_quoted)
218 {
219 while ((priv->lines[priv->top_line].cid == MT_COLOR_QUOTED) &&
220 (priv->top_line < priv->lines_used))
221 {
222 priv->top_line++;
223 }
224 }
226 }
227 else
228 {
229 mutt_message(_("Bottom of message is shown"));
230 }
231 return FR_SUCCESS;
232}
233
237static int op_pager_next_page(struct IndexSharedData *shared,
238 struct PagerPrivateData *priv, int op)
239{
240 const bool c_pager_stop = cs_subset_bool(NeoMutt->sub, "pager_stop");
241 if (priv->lines[priv->cur_line].offset < (priv->st.st_size - 1))
242 {
243 const short c_pager_context = cs_subset_number(NeoMutt->sub, "pager_context");
244 priv->top_line = up_n_lines(c_pager_context, priv->lines, priv->cur_line, priv->hide_quoted);
246 }
247 else if (c_pager_stop)
248 {
249 /* emulate "less -q" and don't go on to the next message. */
250 mutt_message(_("Bottom of message is shown"));
251 }
252 else
253 {
254 /* end of the current message, so display the next message. */
256 }
257 return FR_SUCCESS;
258}
259
263static int op_pager_prev_line(struct IndexSharedData *shared,
264 struct PagerPrivateData *priv, int op)
265{
266 if (priv->top_line)
267 {
268 priv->top_line = up_n_lines(1, priv->lines, priv->top_line, priv->hide_quoted);
270 }
271 else
272 {
273 mutt_message(_("Top of message is shown"));
274 }
275 return FR_SUCCESS;
276}
277
281static int op_pager_prev_page(struct IndexSharedData *shared,
282 struct PagerPrivateData *priv, int op)
283{
284 if (priv->top_line == 0)
285 {
286 mutt_message(_("Top of message is shown"));
287 }
288 else
289 {
290 const short c_pager_context = cs_subset_number(NeoMutt->sub, "pager_context");
291 priv->top_line = up_n_lines(priv->pview->win_pager->state.rows - c_pager_context,
292 priv->lines, priv->top_line, priv->hide_quoted);
294 }
295 return FR_SUCCESS;
296}
297
305static int op_pager_search(struct IndexSharedData *shared,
306 struct PagerPrivateData *priv, int op)
307{
308 struct PagerView *pview = priv->pview;
309
310 int rc = FR_NO_ACTION;
311 struct Buffer *buf = mutt_buffer_pool_get();
312
313 mutt_buffer_strcpy(buf, priv->search_str);
314 if (mutt_buffer_get_field(((op == OP_SEARCH) || (op == OP_SEARCH_NEXT)) ?
315 _("Search for: ") :
316 _("Reverse search for: "),
318 NULL, NULL, NULL) != 0)
319 {
320 goto done;
321 }
322
324 {
325 if (priv->search_compiled)
326 {
327 /* do an implicit search-next */
328 if (op == OP_SEARCH)
329 op = OP_SEARCH_NEXT;
330 else
331 op = OP_SEARCH_OPPOSITE;
332
333 priv->wrapped = false;
334 op_pager_search_next(shared, priv, op);
335 }
336 }
337
338 if (mutt_buffer_is_empty(buf))
339 goto done;
340
341 mutt_str_copy(priv->search_str, mutt_buffer_string(buf), sizeof(priv->search_str));
342
343 /* leave search_back alone if op == OP_SEARCH_NEXT */
344 if (op == OP_SEARCH)
345 priv->search_back = false;
346 else if (op == OP_SEARCH_REVERSE)
347 priv->search_back = true;
348
349 if (priv->search_compiled)
350 {
351 regfree(&priv->search_re);
352 for (size_t i = 0; i < priv->lines_used; i++)
353 {
354 FREE(&(priv->lines[i].search));
355 priv->lines[i].search_arr_size = -1;
356 }
357 }
358
359 uint16_t rflags = mutt_mb_is_lower(priv->search_str) ? REG_ICASE : 0;
360 int err = REG_COMP(&priv->search_re, priv->search_str, REG_NEWLINE | rflags);
361 if (err != 0)
362 {
363 regerror(err, &priv->search_re, buf->data, buf->dsize);
364 mutt_error("%s", mutt_buffer_string(buf));
365 for (size_t i = 0; i < priv->lines_max; i++)
366 {
367 /* cleanup */
368 FREE(&(priv->lines[i].search));
369 priv->lines[i].search_arr_size = -1;
370 }
371 priv->search_flag = 0;
372 priv->search_compiled = false;
373 }
374 else
375 {
376 priv->search_compiled = true;
377 /* update the search pointers */
378 int line_num = 0;
379 while (display_line(priv->fp, &priv->bytes_read, &priv->lines, line_num,
380 &priv->lines_used, &priv->lines_max,
381 MUTT_SEARCH | (pview->flags & MUTT_PAGER_NSKIP) |
382 (pview->flags & MUTT_PAGER_NOWRAP) | priv->has_types,
383 &priv->quote_list, &priv->q_level, &priv->force_redraw,
384 &priv->search_re, priv->pview->win_pager, &priv->ansi_list) == 0)
385 {
386 line_num++;
387 }
388
389 if (!priv->search_back)
390 {
391 /* searching forward */
392 int i;
393 for (i = priv->top_line; i < priv->lines_used; i++)
394 {
395 if ((!priv->hide_quoted || (priv->lines[i].cid != MT_COLOR_QUOTED)) &&
396 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
397 {
398 break;
399 }
400 }
401
402 if (i < priv->lines_used)
403 priv->top_line = i;
404 }
405 else
406 {
407 /* searching backward */
408 int i;
409 for (i = priv->top_line; i >= 0; i--)
410 {
411 if ((!priv->hide_quoted || (priv->lines[i].cid != MT_COLOR_QUOTED)) &&
412 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
413 {
414 break;
415 }
416 }
417
418 if (i >= 0)
419 priv->top_line = i;
420 }
421
422 if (priv->lines[priv->top_line].search_arr_size == 0)
423 {
424 priv->search_flag = 0;
425 mutt_error(_("Not found"));
426 }
427 else
428 {
429 const short c_search_context = cs_subset_number(NeoMutt->sub, "search_context");
430 priv->search_flag = MUTT_SEARCH;
431 /* give some context for search results */
432 if (c_search_context < priv->pview->win_pager->state.rows)
433 priv->searchctx = c_search_context;
434 else
435 priv->searchctx = 0;
436 if (priv->top_line - priv->searchctx > 0)
437 priv->top_line -= priv->searchctx;
438 }
439 }
442 rc = FR_SUCCESS;
443
444done:
446 return rc;
447}
448
456static int op_pager_search_next(struct IndexSharedData *shared,
457 struct PagerPrivateData *priv, int op)
458{
459 if (priv->search_compiled)
460 {
461 const short c_search_context = cs_subset_number(NeoMutt->sub, "search_context");
462 priv->wrapped = false;
463
464 if (c_search_context < priv->pview->win_pager->state.rows)
465 priv->searchctx = c_search_context;
466 else
467 priv->searchctx = 0;
468
469 search_next:
470 if ((!priv->search_back && (op == OP_SEARCH_NEXT)) ||
471 (priv->search_back && (op == OP_SEARCH_OPPOSITE)))
472 {
473 /* searching forward */
474 int i;
475 for (i = priv->wrapped ? 0 : priv->top_line + priv->searchctx + 1;
476 i < priv->lines_used; i++)
477 {
478 if ((!priv->hide_quoted || (priv->lines[i].cid != MT_COLOR_QUOTED)) &&
479 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
480 {
481 break;
482 }
483 }
484
485 const bool c_wrap_search = cs_subset_bool(NeoMutt->sub, "wrap_search");
486 if (i < priv->lines_used)
487 priv->top_line = i;
488 else if (priv->wrapped || !c_wrap_search)
489 mutt_error(_("Not found"));
490 else
491 {
492 mutt_message(_("Search wrapped to top"));
493 priv->wrapped = true;
494 goto search_next;
495 }
496 }
497 else
498 {
499 /* searching backward */
500 int i;
501 for (i = priv->wrapped ? priv->lines_used : priv->top_line + priv->searchctx - 1;
502 i >= 0; i--)
503 {
504 if ((!priv->hide_quoted || (priv->has_types && (priv->lines[i].cid != MT_COLOR_QUOTED))) &&
505 !priv->lines[i].cont_line && (priv->lines[i].search_arr_size > 0))
506 {
507 break;
508 }
509 }
510
511 const bool c_wrap_search = cs_subset_bool(NeoMutt->sub, "wrap_search");
512 if (i >= 0)
513 priv->top_line = i;
514 else if (priv->wrapped || !c_wrap_search)
515 mutt_error(_("Not found"));
516 else
517 {
518 mutt_message(_("Search wrapped to bottom"));
519 priv->wrapped = true;
520 goto search_next;
521 }
522 }
523
524 if (priv->lines[priv->top_line].search_arr_size > 0)
525 {
526 priv->search_flag = MUTT_SEARCH;
527 /* give some context for search results */
528 if (priv->top_line - priv->searchctx > 0)
529 priv->top_line -= priv->searchctx;
530 }
531
533 return FR_SUCCESS;
534 }
535
536 /* no previous search pattern */
537 return op_pager_search(shared, priv, op);
538}
539
543static int op_pager_skip_headers(struct IndexSharedData *shared,
544 struct PagerPrivateData *priv, int op)
545{
546 struct PagerView *pview = priv->pview;
547
548 if (!priv->has_types)
549 return FR_NO_ACTION;
550
551 int dretval = 0;
552 int new_topline = 0;
553
554 while (((new_topline < priv->lines_used) ||
555 (0 == (dretval = display_line(priv->fp, &priv->bytes_read, &priv->lines,
556 new_topline, &priv->lines_used, &priv->lines_max,
558 &priv->quote_list, &priv->q_level,
559 &priv->force_redraw, &priv->search_re,
560 priv->pview->win_pager, &priv->ansi_list)))) &&
561 simple_color_is_header(priv->lines[new_topline].cid))
562 {
563 new_topline++;
564 }
565
566 if (dretval < 0)
567 {
568 /* L10N: Displayed if <skip-headers> is invoked in the pager, but
569 there is no text past the headers.
570 (I don't think this is actually possible in Mutt's code, but
571 display some kind of message in case it somehow occurs.) */
572 mutt_warning(_("No text past headers"));
573 return FR_NO_ACTION;
574 }
575 priv->top_line = new_topline;
577 return FR_SUCCESS;
578}
579
583static int op_pager_skip_quoted(struct IndexSharedData *shared,
584 struct PagerPrivateData *priv, int op)
585{
586 struct PagerView *pview = priv->pview;
587
588 if (!priv->has_types)
589 return FR_NO_ACTION;
590
591 const short c_skip_quoted_context = cs_subset_number(NeoMutt->sub, "pager_skip_quoted_context");
592 int dretval = 0;
593 int new_topline = priv->top_line;
594 int num_quoted = 0;
595
596 /* In a header? Skip all the email headers, and done */
597 if (simple_color_is_header(priv->lines[new_topline].cid))
598 {
599 while (((new_topline < priv->lines_used) ||
600 (0 == (dretval = display_line(
601 priv->fp, &priv->bytes_read, &priv->lines, new_topline, &priv->lines_used,
602 &priv->lines_max, MUTT_TYPES | (pview->flags & MUTT_PAGER_NOWRAP),
603 &priv->quote_list, &priv->q_level, &priv->force_redraw,
604 &priv->search_re, priv->pview->win_pager, &priv->ansi_list)))) &&
605 simple_color_is_header(priv->lines[new_topline].cid))
606 {
607 new_topline++;
608 }
609 priv->top_line = new_topline;
611 return FR_SUCCESS;
612 }
613
614 /* Already in the body? Skip past previous "context" quoted lines */
615 if (c_skip_quoted_context > 0)
616 {
617 while (((new_topline < priv->lines_used) ||
618 (0 == (dretval = display_line(
619 priv->fp, &priv->bytes_read, &priv->lines, new_topline, &priv->lines_used,
620 &priv->lines_max, MUTT_TYPES | (pview->flags & MUTT_PAGER_NOWRAP),
621 &priv->quote_list, &priv->q_level, &priv->force_redraw,
622 &priv->search_re, priv->pview->win_pager, &priv->ansi_list)))) &&
623 (priv->lines[new_topline].cid == MT_COLOR_QUOTED))
624 {
625 new_topline++;
626 num_quoted++;
627 }
628
629 if (dretval < 0)
630 {
631 mutt_error(_("No more unquoted text after quoted text"));
632 return FR_NO_ACTION;
633 }
634 }
635
636 if (num_quoted <= c_skip_quoted_context)
637 {
638 num_quoted = 0;
639
640 while (((new_topline < priv->lines_used) ||
641 (0 == (dretval = display_line(
642 priv->fp, &priv->bytes_read, &priv->lines, new_topline, &priv->lines_used,
643 &priv->lines_max, MUTT_TYPES | (pview->flags & MUTT_PAGER_NOWRAP),
644 &priv->quote_list, &priv->q_level, &priv->force_redraw,
645 &priv->search_re, priv->pview->win_pager, &priv->ansi_list)))) &&
646 (priv->lines[new_topline].cid != MT_COLOR_QUOTED))
647 {
648 new_topline++;
649 }
650
651 if (dretval < 0)
652 {
653 mutt_error(_("No more quoted text"));
654 return FR_NO_ACTION;
655 }
656
657 while (((new_topline < priv->lines_used) ||
658 (0 == (dretval = display_line(
659 priv->fp, &priv->bytes_read, &priv->lines, new_topline, &priv->lines_used,
660 &priv->lines_max, MUTT_TYPES | (pview->flags & MUTT_PAGER_NOWRAP),
661 &priv->quote_list, &priv->q_level, &priv->force_redraw,
662 &priv->search_re, priv->pview->win_pager, &priv->ansi_list)))) &&
663 (priv->lines[new_topline].cid == MT_COLOR_QUOTED))
664 {
665 new_topline++;
666 num_quoted++;
667 }
668
669 if (dretval < 0)
670 {
671 mutt_error(_("No more unquoted text after quoted text"));
672 return FR_NO_ACTION;
673 }
674 }
675 priv->top_line = new_topline - MIN(c_skip_quoted_context, num_quoted);
677 return FR_SUCCESS;
678}
679
683static int op_pager_top(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
684{
685 if (priv->top_line)
686 priv->top_line = 0;
687 else
688 mutt_message(_("Top of message is shown"));
689 return FR_SUCCESS;
690}
691
692// -----------------------------------------------------------------------------
693
697static int op_exit(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
698{
699 priv->rc = -1;
700 priv->loop = PAGER_LOOP_QUIT;
701 return FR_DONE;
702}
703
707static int op_help(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
708{
709 if (priv->pview->mode == PAGER_MODE_HELP)
710 {
711 /* don't let the user enter the help-menu from the help screen! */
712 mutt_error(_("Help is currently being shown"));
713 return FR_ERROR;
714 }
717 return FR_SUCCESS;
718}
719
723static int op_search_toggle(struct IndexSharedData *shared,
724 struct PagerPrivateData *priv, int op)
725{
726 if (priv->search_compiled)
727 {
728 priv->search_flag ^= MUTT_SEARCH;
730 }
731 return FR_SUCCESS;
732}
733
737static int op_view_attachments(struct IndexSharedData *shared,
738 struct PagerPrivateData *priv, int op)
739{
740 struct PagerView *pview = priv->pview;
741
742 // This needs to be delegated
743 if (pview->flags & MUTT_PAGER_ATTACHMENT)
744 return FR_UNKNOWN;
745
747 return FR_NOT_IMPL;
748 dlg_select_attachment(NeoMutt->sub, shared->mailbox, shared->email,
749 pview->pdata->fp);
750 if (shared->email->attach_del)
751 shared->mailbox->changed = true;
753 return FR_SUCCESS;
754}
755
756// -----------------------------------------------------------------------------
757
762 // clang-format off
763 { OP_EXIT, op_exit },
764 { OP_HALF_DOWN, op_pager_half_down },
765 { OP_HALF_UP, op_pager_half_up },
766 { OP_HELP, op_help },
767 { OP_NEXT_LINE, op_pager_next_line },
768 { OP_NEXT_PAGE, op_pager_next_page },
769 { OP_PAGER_BOTTOM, op_pager_bottom },
770 { OP_PAGER_HIDE_QUOTED, op_pager_hide_quoted },
771 { OP_PAGER_SKIP_HEADERS, op_pager_skip_headers },
772 { OP_PAGER_SKIP_QUOTED, op_pager_skip_quoted },
773 { OP_PAGER_TOP, op_pager_top },
774 { OP_PREV_LINE, op_pager_prev_line },
775 { OP_PREV_PAGE, op_pager_prev_page },
776 { OP_SEARCH, op_pager_search },
777 { OP_SEARCH_REVERSE, op_pager_search },
778 { OP_SEARCH_NEXT, op_pager_search_next },
779 { OP_SEARCH_OPPOSITE, op_pager_search_next },
780 { OP_SEARCH_TOGGLE, op_search_toggle },
781 { OP_VIEW_ATTACHMENTS, op_view_attachments },
782 { 0, NULL },
783 // clang-format on
784};
785
790{
791 if (!win)
792 {
794 return FR_ERROR;
795 }
796
797 struct PagerPrivateData *priv = win->parent->wdata;
798 if (!priv)
799 return FR_ERROR;
800
801 struct MuttWindow *dlg = dialog_find(win);
802 if (!dlg || !dlg->wdata)
803 return FR_ERROR;
804
805 int rc = FR_UNKNOWN;
806 for (size_t i = 0; PagerFunctions[i].op != OP_NULL; i++)
807 {
808 const struct PagerFunction *fn = &PagerFunctions[i];
809 if (fn->op == op)
810 {
811 struct IndexSharedData *shared = dlg->wdata;
812 rc = fn->function(shared, priv, op);
813 break;
814 }
815 }
816
817 if (rc == FR_UNKNOWN) // Not our function
818 return rc;
819
820 const char *result = dispacher_get_retval_name(rc);
821 mutt_debug(LL_DEBUG1, "Handled %s (%d) -> %s\n", opcodes_get_name(op), op, NONULL(result));
822
823 return rc;
824}
GUI display the mailboxes in a side panel.
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:260
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:327
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
Color and attribute parsing.
bool simple_color_is_header(enum ColorId cid)
Colour is for an Email header.
Definition: simple.c:105
@ MT_COLOR_QUOTED
Pager: quoted text.
Definition: color.h:58
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
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:592
struct MuttWindow * dialog_find(struct MuttWindow *win)
Find the parent Dialog of a Window.
Definition: dialog.c:83
const char * dispacher_get_retval_name(int rv)
Get the name of a return value.
Definition: dispatcher.c:54
@ FR_SUCCESS
Valid function - successfully performed.
Definition: dispatcher.h:39
@ FR_DONE
Exit the Dialog.
Definition: dispatcher.h:35
@ FR_UNKNOWN
Unknown function.
Definition: dispatcher.h:33
@ FR_ERROR
Valid function - error occurred.
Definition: dispatcher.h:38
@ FR_NOT_IMPL
Invalid function - feature not enabled.
Definition: dispatcher.h:36
@ FR_NO_ACTION
Valid function - no action performed.
Definition: dispatcher.h:37
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:980
Pager Display.
void dlg_select_attachment(struct ConfigSubset *sub, struct Mailbox *m, struct Email *e, FILE *fp)
Show the attachments in a Menu.
Definition: dlg_attach.c:449
void pager_queue_redraw(struct PagerPrivateData *priv, PagerRedrawFlags redraw)
Queue a request for a redraw.
Definition: dlg_pager.c:143
Structs that make up an email.
Enter a string.
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: window.c:180
int pager_function_dispatcher(struct MuttWindow *win, int op)
Perform a Pager function - Implements function_dispatcher_t -.
Definition: functions.c:789
#define mutt_warning(...)
Definition: logging.h:85
#define mutt_error(...)
Definition: logging.h:87
#define mutt_message(...)
Definition: logging.h:86
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
static int op_exit(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Exit this menu - Implements pager_function_t -.
Definition: functions.c:697
static int op_pager_skip_quoted(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Skip beyond quoted text - Implements pager_function_t -.
Definition: functions.c:583
static int op_pager_skip_headers(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Jump to first line after headers - Implements pager_function_t -.
Definition: functions.c:543
static int op_pager_half_up(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Scroll up 1/2 page - Implements pager_function_t -.
Definition: functions.c:171
static int op_pager_next_line(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Scroll down one line - Implements pager_function_t -.
Definition: functions.c:211
static int op_search_toggle(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Toggle search pattern coloring - Implements pager_function_t -.
Definition: functions.c:723
static int op_pager_top(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Jump to the top of the message - Implements pager_function_t -.
Definition: functions.c:683
static int op_view_attachments(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Show MIME attachments - Implements pager_function_t -.
Definition: functions.c:737
static int op_pager_hide_quoted(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Toggle display of quoted text - Implements pager_function_t -.
Definition: functions.c:189
static int op_pager_next_page(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Move to the next page - Implements pager_function_t -.
Definition: functions.c:237
static int op_pager_prev_page(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Move to the previous page - Implements pager_function_t -.
Definition: functions.c:281
static int op_pager_bottom(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Jump to the bottom of the message - Implements pager_function_t -.
Definition: functions.c:133
static int op_help(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
This screen - Implements pager_function_t -.
Definition: functions.c:707
static int op_pager_half_down(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Scroll down 1/2 page - Implements pager_function_t -.
Definition: functions.c:145
static int op_pager_search(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Search for a regular expression - Implements pager_function_t -.
Definition: functions.c:305
static int op_pager_search_next(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Search for next match - Implements pager_function_t -.
Definition: functions.c:456
static int op_pager_prev_line(struct IndexSharedData *shared, struct PagerPrivateData *priv, int op)
Scroll up one line - Implements pager_function_t -.
Definition: functions.c:263
Convenience wrapper for the gui headers.
void mutt_help(enum MenuType menu)
Display the help menu.
Definition: help.c:386
bool index_next_undeleted(struct MuttWindow *win_index)
Select the next undeleted Email (if possible)
Definition: functions.c:157
GUI manage the main index (list of emails)
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
bool mutt_mb_is_lower(const char *s)
Does a multi-byte string contain only lowercase characters?
Definition: mbyte.c:355
#define FREE(x)
Definition: memory.h:43
#define MIN(a, b)
Definition: memory.h:31
GUI present the user with a selectable list.
Convenience wrapper for the library headers.
#define N_(a)
Definition: message.h:32
#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
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
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:652
Many unsorted constants and some structs.
#define MUTT_COMP_PATTERN
Pattern mode (in pattern dialog)
Definition: mutt.h:61
#define MUTT_COMP_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:62
@ NT_PAGER
Pager data has changed, NotifyPager, PagerPrivateData.
Definition: notify_type.h:52
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition: opcodes.c:46
All user-callable functions.
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:86
static const char * Not_available_in_this_menu
Definition: functions.c:55
bool jump_to_bottom(struct PagerPrivateData *priv, struct PagerView *pview)
Make sure the bottom line is displayed.
Definition: functions.c:105
struct PagerFunction PagerFunctions[]
All the NeoMutt functions that the Pager supports.
Definition: functions.c:761
static bool assert_pager_mode(bool test)
Check that pager is in correct mode.
Definition: functions.c:68
@ PAGER_LOOP_QUIT
Quit the Pager.
Definition: lib.h:150
#define NT_PAGER_VIEW
Pager View has changed.
Definition: lib.h:184
#define MUTT_PAGER_NSKIP
Preserve whitespace with smartwrap.
Definition: lib.h:67
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: lib.h:71
#define MUTT_HIDE
Don't show quoted text.
Definition: lib.h:61
#define MUTT_TYPES
Compute line's type.
Definition: lib.h:63
#define MUTT_SEARCH
Resolve search patterns.
Definition: lib.h:62
@ PAGER_MODE_HELP
Pager is invoked via 3rd path to show help.
Definition: lib.h:138
@ PAGER_MODE_EMAIL
Pager is invoked via 1st path. The mime part is selected automatically.
Definition: lib.h:135
#define PAGER_REDRAW_PAGER
Redraw the pager.
Definition: lib.h:188
#define MUTT_PAGER_ATTACHMENT
Attachments may exist.
Definition: lib.h:70
Private state data for the Pager.
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
Prototypes for many functions.
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:53
Sidebar functions.
Key value store.
#define NONULL(x)
Definition: string2.h:37
String manipulation buffer.
Definition: buffer.h:34
size_t dsize
Length of data.
Definition: buffer.h:37
char * data
Pointer to data.
Definition: buffer.h:35
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
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
LOFF_T offset
Offset into Email file (PagerPrivateData->fp)
Definition: display.h:52
bool changed
Mailbox has been modified.
Definition: mailbox.h:110
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
void * wdata
Private data.
Definition: mutt_window.h:145
struct MuttWindow * parent
Parent Window.
Definition: mutt_window.h:135
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
FILE * fp
Source stream.
Definition: lib.h:160
A NeoMutt function.
Definition: functions.h:50
pager_function_t function
Function to call.
Definition: functions.h:52
int op
Op code, e.g. OP_MAIN_LIMIT.
Definition: functions.h:51
Private state data for the Pager.
Definition: private_data.h:41
PagerFlags hide_quoted
Set to MUTT_HIDE when quoted email is hidden <toggle-quoted>
Definition: private_data.h:60
int rc
Return code from functions.
Definition: private_data.h:73
int q_level
Number of unique quoting levels.
Definition: private_data.h:59
int cur_line
Current line (last line visible on screen)
Definition: private_data.h:51
bool wrapped
Has the search/next wrapped around?
Definition: private_data.h:76
int lines_used
Size of lines array (used entries)
Definition: private_data.h:49
char search_str[256]
Current search string.
Definition: private_data.h:63
int lines_max
Capacity of lines array (total entries)
Definition: private_data.h:50
bool force_redraw
Repaint is needed.
Definition: private_data.h:68
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
LOFF_T bytes_read
Number of bytes read from file.
Definition: private_data.h:46
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 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
FILE * fp
File containing decrypted/decoded/weeded Email.
Definition: private_data.h:44
PagerFlags search_flag
Set to MUTT_SEARCH when search results are visible <search-toggle>
Definition: private_data.h:62
bool search_compiled
Search regex is in use.
Definition: private_data.h:64
Paged view into some data.
Definition: lib.h:169
struct MuttWindow * win_index
Index Window.
Definition: lib.h:175
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:170
enum PagerMode mode
Pager mode.
Definition: lib.h:171
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:172
struct MuttWindow * win_pager
Pager Window.
Definition: lib.h:177
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:61
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:54