diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2020-10-04 12:04:24 +0200 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2020-10-04 12:04:24 +0200 |
commit | f665f147ffb542024a754f227186950e222927b4 (patch) | |
tree | d9c1f10520ba9c7fcdd4b8771fa1761654353f66 | |
parent | 9819b75b643d60e931ae2a7758b35000e806a925 (diff) | |
download | xK-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.c | 35 |
1 files changed, 25 insertions, 10 deletions
@@ -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; |