From 5605eb90405f732019043990cd39f1fd96e72182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 22 May 2021 16:42:43 +0200 Subject: [PATCH 1/2] url-mode: remove overlapping URLs, not just duplicates echo -e '\e]8;;https://www.foo.bar\e\\https://www.foo\e]8;;\e\\.bar' will produce an OSC-8 URL (https://www.foo) that is slightly shorter than the auto-detected one (https://www.foo.bar). This produces strange results in URL mode. For example, if url.osc8-underline=always, the OSC8 underline will be removed when url-mode is exited. This patch changes the behavior so that auto-detected URLs that overlap OSC-8 URLs are removed. Note that OSC-8 URLs cannot overlap with each other, and that auto-detected URLs also cannot overlap with each other. --- CHANGELOG.md | 1 + terminal.h | 1 + url-mode.c | 46 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0474fe3d..e5e4bbf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,7 @@ (https://codeberg.org/dnkl/foot/issues/478). * `ctrl + w` (_extend-to-word-boundary_) can now be used across lines (https://codeberg.org/dnkl/foot/issues/421). +* Ignore auto-detected URLs that overlap with OSC-8 URLs. ### Deprecated diff --git a/terminal.h b/terminal.h index 472b4938..1721a4c1 100644 --- a/terminal.h +++ b/terminal.h @@ -258,6 +258,7 @@ struct url { struct coord end; enum url_action action; bool url_mode_dont_change_url_attr; /* Entering/exiting URL mode doesn’t touch the cells’ attr.url */ + bool osc8; }; typedef tll(struct url) url_list_t; diff --git a/url-mode.c b/url-mode.c index dc63ebbe..e036b1f2 100644 --- a/url-mode.c +++ b/url-mode.c @@ -370,7 +370,8 @@ auto_detected(const struct terminal *term, enum url_action action, .url = url_utf8, .start = start, .end = end, - .action = action})); + .action = action, + .osc8 = false})); } state = STATE_PROTOCOL; @@ -424,26 +425,51 @@ osc8_uris(const struct terminal *term, enum url_action action, url_list_t *urls) .start = start, .end = end, .action = action, - .url_mode_dont_change_url_attr = dont_touch_url_attr})); + .url_mode_dont_change_url_attr = dont_touch_url_attr, + .osc8 = true})); } } } static void -remove_duplicates(url_list_t *urls) +remove_overlapping(url_list_t *urls, int cols) { tll_foreach(*urls, outer) { tll_foreach(*urls, inner) { if (outer == inner) continue; - if (outer->item.start.row == inner->item.start.row && - outer->item.start.col == inner->item.start.col && - outer->item.end.row == inner->item.end.row && - outer->item.end.col == inner->item.end.col) + const struct url *out = &outer->item; + const struct url *in = &inner->item; + + uint64_t in_start = in->start.row * cols + in->start.col; + uint64_t in_end = in->end.row * cols + in->end.col; + + uint64_t out_start = out->start.row * cols + out->start.col; + uint64_t out_end = out->end.row * cols + out->end.col; + + if ((in_start <= out_start && in_end >= out_start) || + (in_start <= out_end && in_end >= out_end) || + (in_start >= out_start && in_end <= out_end)) { - url_destroy(&inner->item); - tll_remove(*urls, inner); + /* + * OSC-8 URLs can’t overlap with each + * other. + * + * Similarily, auto-detected URLs cannot overlap with + * each other. + * + * But OSC-8 URLs can overlap with auto-detected ones. + */ + xassert(in->osc8 || out->osc8); + + if (in->osc8) { + url_destroy(&outer->item); + tll_remove(*urls, outer); + } else { + url_destroy(&inner->item); + tll_remove(*urls, inner); + } } } } @@ -455,7 +481,7 @@ urls_collect(const struct terminal *term, enum url_action action, url_list_t *ur xassert(tll_length(term->urls) == 0); osc8_uris(term, action, urls); auto_detected(term, action, urls); - remove_duplicates(urls); + remove_overlapping(urls, term->grid->num_cols); } static int From a9e8ba09322d563e2de6fb48993727b509442c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 22 May 2021 17:08:14 +0200 Subject: [PATCH 2/2] url-mode: codespell --- url-mode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/url-mode.c b/url-mode.c index e036b1f2..9473dc14 100644 --- a/url-mode.c +++ b/url-mode.c @@ -456,7 +456,7 @@ remove_overlapping(url_list_t *urls, int cols) * OSC-8 URLs can’t overlap with each * other. * - * Similarily, auto-detected URLs cannot overlap with + * Similarly, auto-detected URLs cannot overlap with * each other. * * But OSC-8 URLs can overlap with auto-detected ones.