urls: OSC-8 URLs can now optionally be underlined outside of url-mode

This patch adds a new configuration option,
‘osc8-underline=url-mode|always’.

When set to ‘url-mode’, OSC-8 URLs are only
highlighted (i.e. underlined) in url-mode, just like auto-detected
URLs.

When set to ‘always’, they are always underlined, regardless of mode,
and regardless of their other attributes.

This is implemented by tagging collected URLs with a boolean,
instructing urls_render() and urls_reset() whether they should update
the cells’ ‘url’ attribute or not.

The OSC-8 collecter sets this based on the value of ‘osc8-underline’.

Finally, when closing an OSC-8 URL, the cells are immediately tagged
with the ‘url’ attribute if ‘osc8-underline’ is set to ‘always’.
This commit is contained in:
Daniel Eklöf 2021-02-14 21:29:22 +01:00
parent a0b977fcee
commit 2074f8b656
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
7 changed files with 65 additions and 3 deletions

View file

@ -791,6 +791,19 @@ parse_section_main(const char *key, const char *value, struct config *conf,
return false;
}
else if (strcmp(key, "osc8-underline") == 0) {
if (strcmp(value, "url-mode") == 0)
conf->osc8_underline = OSC8_UNDERLINE_URL_MODE;
else if (strcmp(value, "always") == 0)
conf->osc8_underline = OSC8_UNDERLINE_URL_MODE;
else {
LOG_AND_NOTIFY_ERR(
"%s:%u: [default]: %s: invalid 'osc8-underline'; "
"must be one of 'url-mode', or 'always'", path, lineno, value);
return false;
}
}
else {
LOG_AND_NOTIFY_ERR("%s:%u: [default]: %s: invalid key", path, lineno, key);
return false;
@ -2243,6 +2256,8 @@ config_load(struct config *conf, const char *conf_path,
.argv = NULL,
},
.osc8_underline = OSC8_UNDERLINE_ALWAYS,
.tweak = {
.fcft_filter = FCFT_SCALING_FILTER_LANCZOS3,
.allow_overflowing_double_width_glyphs = true,

View file

@ -205,6 +205,11 @@ struct config {
struct config_spawn_template notify;
struct config_spawn_template url_launch;
enum {
OSC8_UNDERLINE_URL_MODE,
OSC8_UNDERLINE_ALWAYS,
} osc8_underline;
struct {
enum fcft_scaling_filter fcft_filter;
bool allow_overflowing_double_width_glyphs;

View file

@ -241,13 +241,25 @@ in this order:
Clipboard target to automatically copy selected text to. One of
*none*, *primary*, *clipboard* or *both*. Default: _primary_.
*workers*
Number of threads to use for rendering. Set to 0 to disable
multithreading. Default: the number of available logical CPUs
(including SMT). Note that this is not always the best value. In
some cases, the number of physical _cores_ is better.
*osc8-underline*
When to underline OSC-8 URLs. Possible values are *url-mode* and
*always*.
When set to *url-mode*, OSC-8 URLs are only highlighted in URL
mode, just like auto-detected URLs.
When set to *always*, OSC-8 URLs are always highlighted,
regardless of their other attributes (bold, italic etc). Note that
this does _not_ make them clickable.
Default: _url-mode_
# SECTION: scrollback

View file

@ -29,6 +29,7 @@
# jump-label-letters=sadfjklewcmpgh
# selection-target=primary
# workers=<number of logical CPUs>
# osc8-underline=url-mode
[scrollback]
# lines=1000

View file

@ -3049,13 +3049,25 @@ term_osc8_close(struct terminal *term)
do {
int end_col = r == end.row ? end.col : term->cols - 1;
struct row *row = term->grid->rows[r];
switch (term->conf->osc8_underline) {
case OSC8_UNDERLINE_ALWAYS:
for (int c = start_col; c <= end_col; c++)
row->cells[c].attrs.url = true;
break;
case OSC8_UNDERLINE_URL_MODE:
break;
}
struct row_uri_range range = {
.start = start_col,
.end = end_col,
.id = term->vt.osc8.id,
.uri = xstrdup(term->vt.osc8.uri),
};
grid_row_add_uri_range(term->grid->rows[r], range);
grid_row_add_uri_range(row, range);
start_col = 0;
} while (r++ != end.row);

View file

@ -256,6 +256,7 @@ struct url {
struct coord start;
struct coord end;
enum url_action action;
bool url_mode_dont_change_url_attr; /* Entering/exiting URL mode doesnt touch the cells attr.url */
};
typedef tll(struct url) url_list_t;

View file

@ -374,6 +374,18 @@ UNIGNORE_WARNINGS
static void
osc8_uris(const struct terminal *term, enum url_action action, url_list_t *urls)
{
bool dont_touch_url_attr = false;
switch (term->conf->osc8_underline) {
case OSC8_UNDERLINE_URL_MODE:
dont_touch_url_attr = false;
break;
case OSC8_UNDERLINE_ALWAYS:
dont_touch_url_attr = true;
break;
}
for (int r = 0; r < term->rows; r++) {
const struct row *row = grid_row_in_view(term->grid, r);
@ -396,7 +408,8 @@ osc8_uris(const struct terminal *term, enum url_action action, url_list_t *urls)
.url = xstrdup(it->item.uri),
.start = start,
.end = end,
.action = action}));
.action = action,
.url_mode_dont_change_url_attr = dont_touch_url_attr}));
}
}
}
@ -542,6 +555,9 @@ urls_assign_key_combos(const struct config *conf, url_list_t *urls)
static void
tag_cells_for_url(struct terminal *term, const struct url *url, bool value)
{
if (url->url_mode_dont_change_url_attr)
return;
const struct coord *start = &url->start;
const struct coord *end = &url->end;