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.
This commit is contained in:
Přemysl Eric Janouch 2015-08-08 20:29:31 +02:00
parent a28528d260
commit cdf6544c94
1 changed files with 68 additions and 30 deletions

View File

@ -1642,10 +1642,6 @@ static struct config_schema g_config_behaviour[] =
.type = CONFIG_ITEM_BOOLEAN, .type = CONFIG_ITEM_BOOLEAN,
.default_ = "off", .default_ = "off",
.on_change = on_config_logging_change }, .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", { .name = "save_on_quit",
.comment = "Save configuration before quitting", .comment = "Save configuration before quitting",
.type = CONFIG_ITEM_BOOLEAN, .type = CONFIG_ITEM_BOOLEAN,
@ -1656,6 +1652,18 @@ static struct config_schema g_config_behaviour[] =
.default_ = "off", .default_ = "off",
.on_change = on_config_debug_mode_change }, .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", { .name = "reconnect_delay_growing",
.comment = "Growing factor for reconnect delay", .comment = "Growing factor for reconnect delay",
.type = CONFIG_ITEM_INTEGER, .type = CONFIG_ITEM_INTEGER,
@ -2068,7 +2076,7 @@ enum
struct attribute_printer struct attribute_printer
{ {
struct app_context *ctx; ///< Application context struct app_context *ctx; ///< Application context
terminal_printer_fn printer; ///< Terminal printer FILE *stream; ///< Output stream
bool dirty; ///< Attributes are set bool dirty; ///< Attributes are set
int want; ///< Desired attributes int want; ///< Desired attributes
@ -2076,21 +2084,33 @@ struct attribute_printer
int want_background; ///< Desired background color 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 static void
attribute_printer_reset (struct attribute_printer *self) attribute_printer_reset (struct attribute_printer *self)
{ {
if (self->dirty) if (self->dirty)
tputs (self->ctx->attrs[ATTR_RESET], 1, self->printer); attribute_printer_tputs (self, self->ctx->attrs[ATTR_RESET]);
self->dirty = false; self->dirty = false;
} }
static void static void
attribute_printer_init (struct attribute_printer *self, 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->ctx = ctx;
self->printer = printer; self->stream = stream;
self->dirty = true; self->dirty = true;
self->want = 0; self->want = 0;
@ -2104,7 +2124,7 @@ attribute_printer_apply (struct attribute_printer *self, int attribute)
attribute_printer_reset (self); attribute_printer_reset (self);
if (attribute != ATTR_RESET) if (attribute != ATTR_RESET)
{ {
tputs (self->ctx->attrs[attribute], 1, self->printer); attribute_printer_tputs (self, self->ctx->attrs[attribute]);
self->dirty = true; self->dirty = true;
} }
} }
@ -2192,24 +2212,23 @@ attribute_printer_update (struct attribute_printer *self)
attribute_printer_reset (self); attribute_printer_reset (self);
if (attributes) if (attributes)
tputs (tparm (set_attributes, attribute_printer_tputs (self, tparm (set_attributes,
0, // standout 0, // standout
attributes & ATTRIBUTE_UNDERLINE, attributes & ATTRIBUTE_UNDERLINE,
attributes & ATTRIBUTE_INVERSE, attributes & ATTRIBUTE_INVERSE,
attributes & ATTRIBUTE_BLINK, attributes & ATTRIBUTE_BLINK,
0, // dim 0, // dim
attributes & ATTRIBUTE_BOLD, attributes & ATTRIBUTE_BOLD,
0, // blank 0, // blank
0, // protect 0, // protect
0) // acs 0)); // acs
, 1, self->printer);
if (enter_italics_mode && (attributes & ATTRIBUTE_ITALIC)) if (enter_italics_mode && (attributes & ATTRIBUTE_ITALIC))
tputs (enter_italics_mode, 1, self->printer); attribute_printer_tputs (self, enter_italics_mode);
if (fg >= 0) 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) 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; self->dirty = true;
} }
@ -2677,10 +2696,9 @@ formatter_flush_text (struct app_context *ctx, const char *text, FILE *stream)
} }
static void 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 (!raw_attributes && !get_attribute_printer (stream))
if (!printer)
{ {
LIST_FOR_EACH (struct formatter_item, iter, self->items) LIST_FOR_EACH (struct formatter_item, iter, self->items)
if (iter->type == FORMATTER_ITEM_TEXT) if (iter->type == FORMATTER_ITEM_TEXT)
@ -2689,7 +2707,7 @@ formatter_flush (struct formatter *self, FILE *stream)
} }
struct attribute_printer state; struct attribute_printer state;
attribute_printer_init (&state, self->ctx, printer); attribute_printer_init (&state, self->ctx, stream);
attribute_printer_reset (&state); attribute_printer_reset (&state);
int attribute_ignore = 0; int attribute_ignore = 0;
@ -2733,7 +2751,8 @@ buffer_update_time (struct app_context *ctx, time_t now)
} }
static void 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; int flags = line->flags;
if (flags & BUFFER_LINE_INDENT) formatter_add (f, " "); 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_from (f, line->formatter);
formatter_add (f, "\n"); formatter_add (f, "\n");
formatter_flush (f, output); formatter_flush (f, output, raw_attributes);
formatter_free (f); formatter_free (f);
} }
@ -2775,12 +2794,32 @@ buffer_line_display (struct app_context *ctx,
} }
input_hide (&ctx->input); input_hide (&ctx->input);
buffer_line_flush (line, &f, stdout); buffer_line_flush (line, &f, stdout, false);
// Flush the trailing formatting reset item // Flush the trailing formatting reset item
fflush (stdout); fflush (stdout);
input_show (&ctx->input); 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, &current))
print_error ("%s: %s", "localtime_r", strerror (errno));
else if (!strftime (buf, sizeof buf, "%F %T", &current))
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 static void
buffer_line_write_to_log (struct app_context *ctx, buffer_line_write_to_log (struct app_context *ctx,
struct buffer_line *line, FILE *log_file) struct buffer_line *line, FILE *log_file)
@ -2800,7 +2839,7 @@ buffer_line_write_to_log (struct app_context *ctx,
else else
formatter_add (&f, "#s ", buf); formatter_add (&f, "#s ", buf);
buffer_line_flush (line, &f, log_file); buffer_line_flush (line, &f, log_file, false);
} }
static void static void
@ -3052,7 +3091,7 @@ buffer_print_read_marker (struct app_context *ctx)
struct formatter f; struct formatter f;
formatter_init (&f, ctx, NULL); formatter_init (&f, ctx, NULL);
formatter_add (&f, "#a-- -- -- ---\n", ATTR_READ_MARKER); formatter_add (&f, "#a-- -- -- ---\n", ATTR_READ_MARKER);
formatter_flush (&f, stdout); formatter_flush (&f, stdout, false);
formatter_free (&f); formatter_free (&f);
} }
@ -8918,10 +8957,9 @@ display_backlog (struct app_context *ctx)
FILE *backlog = tmpfile (); FILE *backlog = tmpfile ();
set_cloexec (fileno (backlog)); set_cloexec (fileno (backlog));
// TODO: retrieve the lines with formatting
for (struct buffer_line *line = ctx->current_buffer->lines; for (struct buffer_line *line = ctx->current_buffer->lines;
line; line = line->next) line; line = line->next)
buffer_line_write_to_log (ctx, line, backlog); buffer_line_write_to_backlog (ctx, line, backlog);
rewind (backlog); rewind (backlog);
suspend_terminal (ctx); suspend_terminal (ctx);