summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2020-10-04 12:04:24 +0200
committerPřemysl Eric Janouch <p@janouch.name>2020-10-04 12:04:24 +0200
commitf665f147ffb542024a754f227186950e222927b4 (patch)
treed9c1f10520ba9c7fcdd4b8771fa1761654353f66
parent9819b75b643d60e931ae2a7758b35000e806a925 (diff)
downloadxK-f665f147ffb542024a754f227186950e222927b4.tar.gz
xK-f665f147ffb542024a754f227186950e222927b4.tar.xz
xK-f665f147ffb542024a754f227186950e222927b4.zip
degesch: resolve the issue with less(1) and SO/SI
Now that I've learnt what exactly these characters are and how they ended up in attribute strings, we can just eliminate them and disable `backlog_helper_strip_formatting`. Saner defaults, again. I've also added skipping of terminfo delay sequences, so now it's less of an issue to pipe raw attribute sequences into backlog helpers.
-rw-r--r--degesch.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/degesch.c b/degesch.c
index 5c172f5..4639da7 100644
--- a/degesch.c
+++ b/degesch.c
@@ -2445,11 +2445,6 @@ static struct config_schema g_config_behaviour[] =
.default_ = "off",
.on_change = on_config_debug_mode_change },
- // GNU screen has an ^O in its formatting attributes reset string,
- // therefore we can't just pipe raw formatting to `less -R`.
- // You can use the -r switch, however that makes `less` very confused
- // about line wrapping, and the result is suboptimal.
-
{ .name = "backlog_limit",
.comment = "Maximum number of lines stored in the backlog",
.type = CONFIG_ITEM_INTEGER,
@@ -2463,7 +2458,7 @@ static struct config_schema g_config_behaviour[] =
{ .name = "backlog_helper_strip_formatting",
.comment = "Strip formatting from backlog helper input",
.type = CONFIG_ITEM_BOOLEAN,
- .default_ = "on" },
+ .default_ = "off" },
{ .name = "reconnect_delay_growing",
.comment = "Growing factor for reconnect delay",
@@ -2785,15 +2780,35 @@ struct attr_printer
#define ATTR_PRINTER_INIT(ctx, stream) { ctx->attrs, stream, true }
static void
+attr_printer_filtered_puts (FILE *stream, const char *attr)
+{
+ for (; *attr; attr++)
+ {
+ // sgr/set_attributes and sgr0/exit_attribute_mode like to enable or
+ // disable the ACS with SO/SI (e.g. for TERM=screen), however `less -R`
+ // does not skip over these characters and it screws up word wrapping
+ if (*attr == 14 /* SO */ || *attr == 15 /* SI */)
+ continue;
+
+ // Trivially skip delay sequences intended to be processed by tputs()
+ const char *end = NULL;
+ if (attr[0] == '$' && attr[1] == '<' && (end = strchr (attr, '>')))
+ attr = end;
+ else
+ fputc (*attr, stream);
+ }
+}
+
+static void
attr_printer_tputs (struct attr_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);
+ // We shouldn't really do this but we need it to output formatting
+ // to the backlog helper--it should be SGR-only
+ attr_printer_filtered_puts (self->stream, attr);
}
static void
@@ -3604,7 +3619,7 @@ explode_text (struct exploder *self, const char *text)
// Throw away any potentially harmful control characters first
struct str filtered = str_make ();
for (const char *p = text; *p; p++)
- if (!strchr ("\a\b\x1b", *p))
+ if (!strchr ("\a\b\x0e\x0f\x1b" /* BEL BS SO SI ESC */, *p))
str_append_c (&filtered, *p);
size_t term_len = 0;