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

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

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

Go to the source code of this file.

Data Structures

struct  PagerData
 Data to be displayed by PagerView. More...
 
struct  PagerView
 Paged view into some data. More...
 

Macros

#define MUTT_PAGER_NO_FLAGS   0
 No flags are set. More...
 
#define MUTT_SHOWFLAT   (1 << 0)
 Show characters (used for displaying help) More...
 
#define MUTT_SHOWCOLOR   (1 << 1)
 Show characters in color otherwise don't show characters. More...
 
#define MUTT_HIDE   (1 << 2)
 Don't show quoted text. More...
 
#define MUTT_SEARCH   (1 << 3)
 Resolve search patterns. More...
 
#define MUTT_TYPES   (1 << 4)
 Compute line's type. More...
 
#define MUTT_SHOW   (MUTT_SHOWCOLOR | MUTT_SHOWFLAT)
 
#define MUTT_PAGER_NSKIP   (1 << 5)
 Preserve whitespace with smartwrap. More...
 
#define MUTT_PAGER_MARKER   (1 << 6)
 Use markers if option is set. More...
 
#define MUTT_PAGER_RETWINCH   (1 << 7)
 Need reformatting on SIGWINCH. More...
 
#define MUTT_PAGER_ATTACHMENT   (1 << 8)
 Attachments may exist. More...
 
#define MUTT_PAGER_NOWRAP   (1 << 9)
 Format for term width, ignore $wrap. More...
 
#define MUTT_PAGER_LOGS   (1 << 10)
 Logview mode. More...
 
#define MUTT_PAGER_BOTTOM   (1 << 11)
 Start at the bottom. More...
 
#define MUTT_PAGER_MESSAGE   (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER)
 
#define MUTT_DISPLAYFLAGS   (MUTT_SHOW | MUTT_PAGER_NSKIP | MUTT_PAGER_MARKER | MUTT_PAGER_LOGS)
 
#define NT_PAGER_NO_FLAGS   0
 No flags are set. More...
 
#define NT_PAGER_DELETE   (1 << 0)
 Pager Private Data is about to be freed. More...
 
#define NT_PAGER_VIEW   (1 << 1)
 Pager View has changed. More...
 
#define PAGER_REDRAW_NO_FLAGS   0
 No flags are set. More...
 
#define PAGER_REDRAW_PAGER   (1 << 1)
 Redraw the pager. More...
 
#define PAGER_REDRAW_FLOW   (1 << 2)
 Reflow the pager. More...
 

Typedefs

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

Enumerations

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

Functions

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

Variables

int braille_row
 
int braille_col
 

Detailed Description

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

Authors
  • Michael R. Elkins

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file lib.h.

Macro Definition Documentation

◆ MUTT_PAGER_NO_FLAGS

#define MUTT_PAGER_NO_FLAGS   0

No flags are set.

Definition at line 58 of file lib.h.

◆ MUTT_SHOWFLAT

#define MUTT_SHOWFLAT   (1 << 0)

Show characters (used for displaying help)

Definition at line 59 of file lib.h.

◆ MUTT_SHOWCOLOR

#define MUTT_SHOWCOLOR   (1 << 1)

Show characters in color otherwise don't show characters.

Definition at line 60 of file lib.h.

◆ MUTT_HIDE

#define MUTT_HIDE   (1 << 2)

Don't show quoted text.

Definition at line 61 of file lib.h.

◆ MUTT_SEARCH

#define MUTT_SEARCH   (1 << 3)

Resolve search patterns.

Definition at line 62 of file lib.h.

◆ MUTT_TYPES

#define MUTT_TYPES   (1 << 4)

Compute line's type.

Definition at line 63 of file lib.h.

◆ MUTT_SHOW

#define MUTT_SHOW   (MUTT_SHOWCOLOR | MUTT_SHOWFLAT)

Definition at line 64 of file lib.h.

◆ MUTT_PAGER_NSKIP

#define MUTT_PAGER_NSKIP   (1 << 5)

Preserve whitespace with smartwrap.

Definition at line 67 of file lib.h.

◆ MUTT_PAGER_MARKER

#define MUTT_PAGER_MARKER   (1 << 6)

Use markers if option is set.

Definition at line 68 of file lib.h.

◆ MUTT_PAGER_RETWINCH

#define MUTT_PAGER_RETWINCH   (1 << 7)

Need reformatting on SIGWINCH.

Definition at line 69 of file lib.h.

◆ MUTT_PAGER_ATTACHMENT

#define MUTT_PAGER_ATTACHMENT   (1 << 8)

Attachments may exist.

Definition at line 70 of file lib.h.

◆ MUTT_PAGER_NOWRAP

#define MUTT_PAGER_NOWRAP   (1 << 9)

Format for term width, ignore $wrap.

Definition at line 71 of file lib.h.

◆ MUTT_PAGER_LOGS

#define MUTT_PAGER_LOGS   (1 << 10)

Logview mode.

Definition at line 72 of file lib.h.

◆ MUTT_PAGER_BOTTOM

#define MUTT_PAGER_BOTTOM   (1 << 11)

Start at the bottom.

Definition at line 73 of file lib.h.

◆ MUTT_PAGER_MESSAGE

#define MUTT_PAGER_MESSAGE   (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER)

Definition at line 74 of file lib.h.

◆ MUTT_DISPLAYFLAGS

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

Definition at line 76 of file lib.h.

◆ NT_PAGER_NO_FLAGS

#define NT_PAGER_NO_FLAGS   0

No flags are set.

Definition at line 182 of file lib.h.

◆ NT_PAGER_DELETE

#define NT_PAGER_DELETE   (1 << 0)

Pager Private Data is about to be freed.

Definition at line 183 of file lib.h.

◆ NT_PAGER_VIEW

#define NT_PAGER_VIEW   (1 << 1)

Pager View has changed.

Definition at line 184 of file lib.h.

◆ PAGER_REDRAW_NO_FLAGS

#define PAGER_REDRAW_NO_FLAGS   0

No flags are set.

Definition at line 187 of file lib.h.

◆ PAGER_REDRAW_PAGER

#define PAGER_REDRAW_PAGER   (1 << 1)

Redraw the pager.

Definition at line 188 of file lib.h.

◆ PAGER_REDRAW_FLOW

#define PAGER_REDRAW_FLOW   (1 << 2)

Reflow the pager.

Definition at line 189 of file lib.h.

Typedef Documentation

◆ PagerFlags

typedef uint16_t PagerFlags

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

Definition at line 57 of file lib.h.

◆ NotifyPager

typedef uint8_t NotifyPager

Flags, e.g. NT_PAGER_DELETE.

Definition at line 181 of file lib.h.

◆ PagerRedrawFlags

typedef uint8_t PagerRedrawFlags

Flags, e.g. PAGER_REDRAW_PAGER.

Definition at line 186 of file lib.h.

Enumeration Type Documentation

◆ PagerMode

enum PagerMode

Determine the behaviour of the Pager.

Enumerator
PAGER_MODE_UNKNOWN 

A default and invalid mode, should never be used.

PAGER_MODE_EMAIL 

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

PAGER_MODE_ATTACH 

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

PAGER_MODE_ATTACH_E 

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

PAGER_MODE_HELP 

Pager is invoked via 3rd path to show help.

PAGER_MODE_OTHER 

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

PAGER_MODE_MAX 

Another invalid mode, should never be used.

Definition at line 131 of file lib.h.

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

◆ PagerLoopMode

What the Pager Event Loop should do next.

Enumerator
PAGER_LOOP_CONTINUE 

Stay in the Pager Event Loop.

PAGER_LOOP_QUIT 

Quit the Pager.

PAGER_LOOP_RELOAD 

Reload the Pager from scratch.

Definition at line 147 of file lib.h.

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

Function Documentation

◆ mutt_pager()

int mutt_pager ( struct PagerView pview)

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

Parameters
pviewPager view settings
Return values
0Success
-1Error

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

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

Definition at line 223 of file dlg_pager.c.

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

◆ mutt_do_pager()

int mutt_do_pager ( struct PagerView pview,
struct Email e 
)

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

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

Definition at line 123 of file do_pager.c.

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

◆ mutt_buffer_strip_formatting()

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

Removes ANSI and backspace formatting.

Parameters
destBuffer for the result
srcString to strip
strip_markersRemove

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

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

Definition at line 674 of file display.c.

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

◆ ppanel_new()

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

Create the Windows for the Pager panel.

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

Definition at line 122 of file ppanel.c.

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

◆ pager_window_new()

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

Create a new Pager Window (list of Emails)

Parameters
sharedShared Index Data
privPrivate Pager Data
Return values
ptrNew Window

Definition at line 429 of file pager.c.

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

◆ mutt_display_message()

int mutt_display_message ( struct MuttWindow win_index,
struct IndexSharedData shared 
)

Display a message in the pager.

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

Definition at line 449 of file message.c.

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

◆ external_pager()

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

Display a message in an external program.

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

Definition at line 311 of file message.c.

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

◆ pager_queue_redraw()

void pager_queue_redraw ( struct PagerPrivateData priv,
PagerRedrawFlags  redraw 
)

Queue a request for a redraw.

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

Definition at line 143 of file dlg_pager.c.

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

◆ mutt_is_quote_line()

bool mutt_is_quote_line ( char *  line,
regmatch_t *  pmatch 
)

Is a line of message text a quote?

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

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

Definition at line 310 of file display.c.

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

◆ mutt_clear_pager_position()

void mutt_clear_pager_position ( void  )

◆ dump_text_syntax()

void dump_text_syntax ( struct TextSyntax ts,
int  num 
)

Definition at line 37 of file pager.c.

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

◆ dump_line()

void dump_line ( int  i,
struct Line line 
)

Definition at line 58 of file pager.c.

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

◆ dump_pager()

void dump_pager ( struct PagerPrivateData priv)

Definition at line 102 of file pager.c.

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

Variable Documentation

◆ braille_row

int braille_row
extern

Definition at line 80 of file dlg_pager.c.

◆ braille_col

int braille_col
extern

Definition at line 81 of file dlg_pager.c.