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:
parent
a28528d260
commit
cdf6544c94
98
degesch.c
98
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);
|
||||
|
Loading…
Reference in New Issue
Block a user