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; 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 { else {
LOG_AND_NOTIFY_ERR("%s:%u: [default]: %s: invalid key", path, lineno, key); LOG_AND_NOTIFY_ERR("%s:%u: [default]: %s: invalid key", path, lineno, key);
return false; return false;
@ -2243,6 +2256,8 @@ config_load(struct config *conf, const char *conf_path,
.argv = NULL, .argv = NULL,
}, },
.osc8_underline = OSC8_UNDERLINE_ALWAYS,
.tweak = { .tweak = {
.fcft_filter = FCFT_SCALING_FILTER_LANCZOS3, .fcft_filter = FCFT_SCALING_FILTER_LANCZOS3,
.allow_overflowing_double_width_glyphs = true, .allow_overflowing_double_width_glyphs = true,

View file

@ -205,6 +205,11 @@ struct config {
struct config_spawn_template notify; struct config_spawn_template notify;
struct config_spawn_template url_launch; struct config_spawn_template url_launch;
enum {
OSC8_UNDERLINE_URL_MODE,
OSC8_UNDERLINE_ALWAYS,
} osc8_underline;
struct { struct {
enum fcft_scaling_filter fcft_filter; enum fcft_scaling_filter fcft_filter;
bool allow_overflowing_double_width_glyphs; 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 Clipboard target to automatically copy selected text to. One of
*none*, *primary*, *clipboard* or *both*. Default: _primary_. *none*, *primary*, *clipboard* or *both*. Default: _primary_.
*workers* *workers*
Number of threads to use for rendering. Set to 0 to disable Number of threads to use for rendering. Set to 0 to disable
multithreading. Default: the number of available logical CPUs multithreading. Default: the number of available logical CPUs
(including SMT). Note that this is not always the best value. In (including SMT). Note that this is not always the best value. In
some cases, the number of physical _cores_ is better. 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 # SECTION: scrollback

View file

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

View file

@ -3049,13 +3049,25 @@ term_osc8_close(struct terminal *term)
do { do {
int end_col = r == end.row ? end.col : term->cols - 1; 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 = { struct row_uri_range range = {
.start = start_col, .start = start_col,
.end = end_col, .end = end_col,
.id = term->vt.osc8.id, .id = term->vt.osc8.id,
.uri = xstrdup(term->vt.osc8.uri), .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; start_col = 0;
} while (r++ != end.row); } while (r++ != end.row);

View file

@ -256,6 +256,7 @@ struct url {
struct coord start; struct coord start;
struct coord end; struct coord end;
enum url_action action; 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; typedef tll(struct url) url_list_t;

View file

@ -374,6 +374,18 @@ UNIGNORE_WARNINGS
static void static void
osc8_uris(const struct terminal *term, enum url_action action, url_list_t *urls) 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++) { for (int r = 0; r < term->rows; r++) {
const struct row *row = grid_row_in_view(term->grid, 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), .url = xstrdup(it->item.uri),
.start = start, .start = start,
.end = end, .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 static void
tag_cells_for_url(struct terminal *term, const struct url *url, bool value) 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 *start = &url->start;
const struct coord *end = &url->end; const struct coord *end = &url->end;