From cdf6544c943e95bc63b4cdbaa4e8bb8231c3d099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Sat, 8 Aug 2015 20:29:31 +0200 Subject: [PATCH] degesch: use formatting in the backlog It's a rather crude solution to just pipe the raw terminfo strings to less but hey, it works. --- degesch.c | 98 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 30 deletions(-) diff --git a/degesch.c b/degesch.c index b7c9434..83bafae 100644 --- a/degesch.c +++ b/degesch.c @@ -1642,10 +1642,6 @@ static struct config_schema g_config_behaviour[] = .type = CONFIG_ITEM_BOOLEAN, .default_ = "off", .on_change = on_config_logging_change }, - { .name = "backlog_helper", - .comment = "Shell command to display a buffer's history", - .type = CONFIG_ITEM_STRING, - .default_ = "\"LESSSECURE=1 less -M -R +G\"" }, { .name = "save_on_quit", .comment = "Save configuration before quitting", .type = CONFIG_ITEM_BOOLEAN, @@ -1656,6 +1652,18 @@ static struct config_schema g_config_behaviour[] = .default_ = "off", .on_change = on_config_debug_mode_change }, + // We use -r here rather than -R because of GNU screen, + // which has an ^O in its string to reset formatting attributes + + { .name = "backlog_helper", + .comment = "Shell command to display a buffer's history", + .type = CONFIG_ITEM_STRING, + .default_ = "\"LESSSECURE=1 less -M -r +G\"" }, + { .name = "backlog_helper_strip_formatting", + .comment = "Strip formatting from backlog helper input", + .type = CONFIG_ITEM_BOOLEAN, + .default_ = "off" }, + { .name = "reconnect_delay_growing", .comment = "Growing factor for reconnect delay", .type = CONFIG_ITEM_INTEGER, @@ -2068,7 +2076,7 @@ enum struct attribute_printer { struct app_context *ctx; ///< Application context - terminal_printer_fn printer; ///< Terminal printer + FILE *stream; ///< Output stream bool dirty; ///< Attributes are set int want; ///< Desired attributes @@ -2076,21 +2084,33 @@ struct attribute_printer int want_background; ///< Desired background color }; +static void +attribute_printer_tputs (struct attribute_printer *self, const char *attr) +{ + terminal_printer_fn printer = get_attribute_printer (self->stream); + if (printer) + tputs (attr, 1, printer); + else + // We shouldn't really do this but we need it to + // output formatting to the backlog + fputs (attr, self->stream); +} + static void attribute_printer_reset (struct attribute_printer *self) { if (self->dirty) - tputs (self->ctx->attrs[ATTR_RESET], 1, self->printer); + attribute_printer_tputs (self, self->ctx->attrs[ATTR_RESET]); self->dirty = false; } static void attribute_printer_init (struct attribute_printer *self, - struct app_context *ctx, terminal_printer_fn printer) + struct app_context *ctx, FILE *stream) { self->ctx = ctx; - self->printer = printer; + self->stream = stream; self->dirty = true; self->want = 0; @@ -2104,7 +2124,7 @@ attribute_printer_apply (struct attribute_printer *self, int attribute) attribute_printer_reset (self); if (attribute != ATTR_RESET) { - tputs (self->ctx->attrs[attribute], 1, self->printer); + attribute_printer_tputs (self, self->ctx->attrs[attribute]); self->dirty = true; } } @@ -2192,24 +2212,23 @@ attribute_printer_update (struct attribute_printer *self) attribute_printer_reset (self); if (attributes) - tputs (tparm (set_attributes, - 0, // standout + attribute_printer_tputs (self, tparm (set_attributes, + 0, // standout attributes & ATTRIBUTE_UNDERLINE, attributes & ATTRIBUTE_INVERSE, attributes & ATTRIBUTE_BLINK, - 0, // dim + 0, // dim attributes & ATTRIBUTE_BOLD, - 0, // blank - 0, // protect - 0) // acs - , 1, self->printer); + 0, // blank + 0, // protect + 0)); // acs if (enter_italics_mode && (attributes & ATTRIBUTE_ITALIC)) - tputs (enter_italics_mode, 1, self->printer); + attribute_printer_tputs (self, enter_italics_mode); if (fg >= 0) - tputs (g_terminal.color_set_fg[fg], 1, self->printer); + attribute_printer_tputs (self, g_terminal.color_set_fg[fg]); if (bg >= 0) - tputs (g_terminal.color_set_bg[bg], 1, self->printer); + attribute_printer_tputs (self, g_terminal.color_set_bg[bg]); self->dirty = true; } @@ -2677,10 +2696,9 @@ formatter_flush_text (struct app_context *ctx, const char *text, FILE *stream) } static void -formatter_flush (struct formatter *self, FILE *stream) +formatter_flush (struct formatter *self, FILE *stream, bool raw_attributes) { - terminal_printer_fn printer = get_attribute_printer (stream); - if (!printer) + if (!raw_attributes && !get_attribute_printer (stream)) { LIST_FOR_EACH (struct formatter_item, iter, self->items) if (iter->type == FORMATTER_ITEM_TEXT) @@ -2689,7 +2707,7 @@ formatter_flush (struct formatter *self, FILE *stream) } struct attribute_printer state; - attribute_printer_init (&state, self->ctx, printer); + attribute_printer_init (&state, self->ctx, stream); attribute_printer_reset (&state); int attribute_ignore = 0; @@ -2733,7 +2751,8 @@ buffer_update_time (struct app_context *ctx, time_t now) } static void -buffer_line_flush (struct buffer_line *line, struct formatter *f, FILE *output) +buffer_line_flush (struct buffer_line *line, struct formatter *f, FILE *output, + bool raw_attributes) { int flags = line->flags; if (flags & BUFFER_LINE_INDENT) formatter_add (f, " "); @@ -2742,7 +2761,7 @@ buffer_line_flush (struct buffer_line *line, struct formatter *f, FILE *output) formatter_add_from (f, line->formatter); formatter_add (f, "\n"); - formatter_flush (f, output); + formatter_flush (f, output, raw_attributes); formatter_free (f); } @@ -2775,12 +2794,32 @@ buffer_line_display (struct app_context *ctx, } input_hide (&ctx->input); - buffer_line_flush (line, &f, stdout); + buffer_line_flush (line, &f, stdout, false); // Flush the trailing formatting reset item fflush (stdout); input_show (&ctx->input); } +static void +buffer_line_write_to_backlog (struct app_context *ctx, + struct buffer_line *line, FILE *log_file) +{ + struct formatter f; + formatter_init (&f, ctx, NULL); + + struct tm current; + char buf[20]; + if (!localtime_r (&line->when, ¤t)) + print_error ("%s: %s", "localtime_r", strerror (errno)); + else if (!strftime (buf, sizeof buf, "%F %T", ¤t)) + print_error ("%s: %s", "strftime", "buffer too small"); + else + formatter_add (&f, "#a#s#r ", ATTR_TIMESTAMP, buf); + + buffer_line_flush (line, &f, log_file, !get_config_boolean + (ctx->config.root, "behaviour.backlog_helper_strip_formatting")); +} + static void buffer_line_write_to_log (struct app_context *ctx, struct buffer_line *line, FILE *log_file) @@ -2800,7 +2839,7 @@ buffer_line_write_to_log (struct app_context *ctx, else formatter_add (&f, "#s ", buf); - buffer_line_flush (line, &f, log_file); + buffer_line_flush (line, &f, log_file, false); } static void @@ -3052,7 +3091,7 @@ buffer_print_read_marker (struct app_context *ctx) struct formatter f; formatter_init (&f, ctx, NULL); formatter_add (&f, "#a-- -- -- ---\n", ATTR_READ_MARKER); - formatter_flush (&f, stdout); + formatter_flush (&f, stdout, false); formatter_free (&f); } @@ -8918,10 +8957,9 @@ display_backlog (struct app_context *ctx) FILE *backlog = tmpfile (); set_cloexec (fileno (backlog)); - // TODO: retrieve the lines with formatting for (struct buffer_line *line = ctx->current_buffer->lines; line; line = line->next) - buffer_line_write_to_log (ctx, line, backlog); + buffer_line_write_to_backlog (ctx, line, backlog); rewind (backlog); suspend_terminal (ctx);