From cdf6544c943e95bc63b4cdbaa4e8bb8231c3d099 Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Sat, 8 Aug 2015 20:29:31 +0200
Subject: 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);
--
cgit v1.2.3-70-g09d2