diff --git a/curs_main.c b/curs_main.c index 197a58ed6c1..e8221b65048 100644 --- a/curs_main.c +++ b/curs_main.c @@ -47,6 +47,7 @@ #include "ncrypt/ncrypt.h" #include "opcodes.h" #include "options.h" +#include "pager.h" #include "pattern.h" #include "protos.h" #include "sort.h" @@ -1489,6 +1490,25 @@ int mutt_index_menu(void) break; #endif /* USE_POP */ + case OP_SHOW_MESSAGES: + { + char tempfile[PATH_MAX]; + mutt_mktemp(tempfile, sizeof(tempfile)); + + FILE *fp = mutt_file_fopen(tempfile, "a+"); + if (!fp) + { + mutt_perror("fopen"); + break; + } + + log_queue_save(fp); + mutt_file_fclose(&fp); + + mutt_do_pager("messages", tempfile, MUTT_PAGER_LOGS, NULL); + break; + } + case OP_HELP: mutt_help(MENU_MAIN); diff --git a/functions.h b/functions.h index b96e24e0aa5..49b49023bbf 100644 --- a/functions.h +++ b/functions.h @@ -92,6 +92,7 @@ const struct Binding OpGeneric[] = { /* map: generic */ }; const struct Binding OpMain[] = { /* map: index */ + { "show-messages", OP_SHOW_MESSAGES, "M" }, { "create-alias", OP_CREATE_ALIAS, "a" }, { "bounce-message", OP_BOUNCE_MESSAGE, "b" }, { "break-thread", OP_MAIN_BREAK_THREAD, "#" }, diff --git a/mutt/logging.c b/mutt/logging.c index e1705567ea4..611eda11f2e 100644 --- a/mutt/logging.c +++ b/mutt/logging.c @@ -342,6 +342,36 @@ void log_queue_flush(log_dispatcher_t disp) log_queue_empty(); } +/** + * log_queue_save - Save the contents of the queue to a temporary file + * @param fp Open file handle + * @retval num Number of lines written to the file + * + * The queue is written to a temporary file. The format is: + * * `[HH:MM:SS] FORMATTED-MESSAGE` + * + * @note The caller should free the returned string and delete the file. + */ +int log_queue_save(FILE *fp) +{ + if (!fp) + return 0; + + char buf[32]; + int count = 0; + struct LogLine *ll = NULL; + STAILQ_FOREACH(ll, &LogQueue, entries) + { + strftime(buf, sizeof(buf), "%H:%M:%S", localtime(&ll->time)); + fprintf(fp, "[%s]<%c> %s", buf, LevelAbbr[ll->level + 3], ll->message); + if (ll->level <= 0) + fputs("\n", fp); + count++; + } + + return count; +} + /** * log_disp_queue - Save a log line to an internal queue * @param stamp Unix time diff --git a/mutt/logging.h b/mutt/logging.h index cf99d0709c7..24393980880 100644 --- a/mutt/logging.h +++ b/mutt/logging.h @@ -83,6 +83,7 @@ int log_disp_terminal(time_t stamp, const char *file, int line, const char *func int log_queue_add(struct LogLine *ll); void log_queue_empty(void); void log_queue_flush(log_dispatcher_t disp); +int log_queue_save(FILE *fp); void log_queue_set_max_size(int size); void log_file_close(bool verbose); diff --git a/mutt_curses.h b/mutt_curses.h index 4556b4f725c..9c8fbcd129b 100644 --- a/mutt_curses.h +++ b/mutt_curses.h @@ -163,6 +163,7 @@ enum ColorId MT_COLOR_SB_INDICATOR, MT_COLOR_SB_SPOOLFILE, #endif + MT_COLOR_MESSAGE_LOG, /* please no non-MT_COLOR_INDEX objects after this point */ MT_COLOR_INDEX, MT_COLOR_INDEX_AUTHOR, diff --git a/mutt_logging.c b/mutt_logging.c index b52318333f8..188ec07d0a5 100644 --- a/mutt_logging.c +++ b/mutt_logging.c @@ -171,6 +171,8 @@ int log_disp_curses(time_t stamp, const char *file, int line, } log_disp_file(stamp, file, line, function, level, "%s", buf); + if (stamp == 0) + log_disp_queue(stamp, file, line, function, level, "%s", buf); /* Don't display debugging message on screen */ if (level > LL_MESSAGE) diff --git a/opcodes.h b/opcodes.h index e1bc9cfb863..bc29684ce8c 100644 --- a/opcodes.h +++ b/opcodes.h @@ -27,6 +27,7 @@ #define OPS_CORE(_fmt) \ _fmt(OP_NULL, N_("null operation")) \ + _fmt(OP_SHOW_MESSAGES, N_("show messages")) \ _fmt(OP_END_COND, N_("end of conditional execution (noop)")) \ _fmt(OP_ATTACH_VIEW_MAILCAP, N_("force viewing of attachment using mailcap")) \ _fmt(OP_ATTACH_VIEW_TEXT, N_("view attachment as text")) \ diff --git a/pager.c b/pager.c index 024b564d599..65c067811d0 100644 --- a/pager.c +++ b/pager.c @@ -236,7 +236,11 @@ static void resolve_color(struct Line *line_info, int n, int cnt, int flags, } else m = n; - if (!(flags & MUTT_SHOWCOLOR)) + if (flags & MUTT_PAGER_LOGS) + { + def_color = ColorDefs[(line_info[n].syntax)[0].color]; + } + else if (!(flags & MUTT_SHOWCOLOR)) def_color = ColorDefs[MT_COLOR_NORMAL]; else if (line_info[m].type == MT_COLOR_HEADER) def_color = (line_info[m].syntax)[0].color; @@ -1015,6 +1019,16 @@ static void resolve_types(char *buf, char *raw, struct Line *line_info, int n, if (nl > 0) buf[nl] = '\n'; } + + if (line_info[n].type == MT_COLOR_MESSAGE_LOG) + { + line_info[n].chunks = 1; + line_info[n].syntax = mutt_mem_calloc(1, sizeof(struct Syntax)); + + (line_info[n].syntax)[i].color = MT_COLOR_ERROR; + (line_info[n].syntax)[i].first = 5; + (line_info[n].syntax)[i].last = 10; + } } static int is_ansi(unsigned char *buf) @@ -1446,6 +1460,25 @@ static int display_line(FILE *f, LOFF_T *last_pos, struct Line **line_info, } } + if (flags & MUTT_PAGER_LOGS) + { + /* determine the line class */ + if (fill_buffer(f, last_pos, (*line_info)[n].offset, &buf, &fmt, &buflen, &buf_ready) < 0) + { + if (change_last) + (*last)--; + goto out; + } + + (*line_info)[n].type = MT_COLOR_MESSAGE_LOG; + if (buf[11] == 'M') + (*line_info)[n].syntax[0].color = MT_COLOR_MESSAGE; + else if (buf[11] == 'E') + (*line_info)[n].syntax[0].color = MT_COLOR_ERROR; + else + (*line_info)[n].syntax[0].color = MT_COLOR_NORMAL; + } + /* only do color highlighting if we are viewing a message */ if (flags & (MUTT_SHOWCOLOR | MUTT_TYPES)) { diff --git a/pager.h b/pager.h index 94e6cc0f94a..0cdc0e74198 100644 --- a/pager.h +++ b/pager.h @@ -43,8 +43,9 @@ struct Menu; #define MUTT_PAGER_MESSAGE (MUTT_SHOWCOLOR | MUTT_PAGER_MARKER) #define MUTT_PAGER_ATTACHMENT (1 << 8) #define MUTT_PAGER_NOWRAP (1 << 9) /**< format for term width, ignore $wrap */ +#define MUTT_PAGER_LOGS (1 << 10) /**< Logview mode */ -#define MUTT_DISPLAYFLAGS (MUTT_SHOW | MUTT_PAGER_NSKIP | MUTT_PAGER_MARKER) +#define MUTT_DISPLAYFLAGS (MUTT_SHOW | MUTT_PAGER_NSKIP | MUTT_PAGER_MARKER | MUTT_PAGER_LOGS) /** * struct Pager - An email being displayed