diff --git a/CHANGELOG.md b/CHANGELOG.md index a14b0fab..8b750f3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,12 +72,19 @@ * Do not try to set a zero width, or height, if the compositor sends a _configure_ event with only one dimension being zero ([#1925][1925]). +* Auto-detection of URLs (i.e. not OSC-8 based URLs) are now regex + based. [1925]: https://codeberg.org/dnkl/foot/issues/1925 ### Deprecated ### Removed + +* `url.uri-characters` and `url.protocols`. Both options have been + replaced by `url.regex`. + + ### Fixed * Kitty keyboard protocol: alternate key reporting failing to report diff --git a/config.c b/config.c index a9db87d5..c96e7168 100644 --- a/config.c +++ b/config.c @@ -420,14 +420,6 @@ done: return ret; } -static int -c32cmp_single(const void *_a, const void *_b) -{ - const char32_t *a = _a; - const char32_t *b = _b; - return *a - *b; -} - static bool str_has_prefix(const char *str, const char *prefix) { @@ -1225,7 +1217,6 @@ parse_section_url(struct context *ctx) { struct config *conf = ctx->conf; const char *key = ctx->key; - const char *value = ctx->value; if (streq(key, "launch")) return value_to_spawn_template(ctx, &conf->url.launch); @@ -1243,70 +1234,6 @@ parse_section_url(struct context *ctx) (int *)&conf->url.osc8_underline); } - else if (streq(key, "protocols")) { - for (size_t i = 0; i < conf->url.prot_count; i++) - free(conf->url.protocols[i]); - free(conf->url.protocols); - - conf->url.max_prot_len = 0; - conf->url.prot_count = 0; - conf->url.protocols = NULL; - - char *copy = xstrdup(value); - - for (char *prot = strtok(copy, ","); - prot != NULL; - prot = strtok(NULL, ",")) - { - - /* Strip leading whitespace */ - while (isspace(prot[0])) - prot++; - - /* Strip trailing whitespace */ - size_t len = strlen(prot); - while (isspace(prot[len - 1])) - len--; - prot[len] = '\0'; - - size_t chars = mbsntoc32(NULL, prot, len, 0); - if (chars == (size_t)-1) { - ctx->value = prot; - LOG_CONTEXTUAL_ERRNO("invalid protocol"); - return false; - } - - conf->url.prot_count++; - conf->url.protocols = xrealloc( - conf->url.protocols, - conf->url.prot_count * sizeof(conf->url.protocols[0])); - - size_t idx = conf->url.prot_count - 1; - conf->url.protocols[idx] = xmalloc((chars + 1 + 3) * sizeof(char32_t)); - mbsntoc32(conf->url.protocols[idx], prot, len, chars + 1); - c32cpy(&conf->url.protocols[idx][chars], U"://"); - - chars += 3; /* Include the "://" */ - if (chars > conf->url.max_prot_len) - conf->url.max_prot_len = chars; - } - - free(copy); - return true; - } - - else if (streq(key, "uri-characters")) { - if (!value_to_wchars(ctx, &conf->url.uri_characters)) - return false; - - qsort( - conf->url.uri_characters, - c32len(conf->url.uri_characters), - sizeof(conf->url.uri_characters[0]), - &c32cmp_single); - return true; - } - else { LOG_CONTEXTUAL_ERR("not a valid option: %s", key); return false; @@ -3196,7 +3123,6 @@ config_load(struct config *conf, const char *conf_path, }, .url = { .label_letters = xc32dup(U"sadfjklewcmpgh"), - .uri_characters = xc32dup(U"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.,~:;/?#@!$&%*+=\"'()[]"), .osc8_underline = OSC8_UNDERLINE_URL_MODE, }, .can_shape_grapheme = fcft_caps & FCFT_CAPABILITY_GRAPHEME_SHAPING, @@ -3315,34 +3241,6 @@ config_load(struct config *conf, const char *conf_path, tokenize_cmdline("--action ${action-name}=${action-label}", &conf->desktop_notifications.command_action_arg.argv.args); tokenize_cmdline("xdg-open ${url}", &conf->url.launch.argv.args); - static const char32_t *url_protocols[] = { - U"http://", - U"https://", - U"ftp://", - U"ftps://", - U"file://", - U"gemini://", - U"gopher://", - U"irc://", - U"ircs://", - }; - conf->url.protocols = xmalloc( - ALEN(url_protocols) * sizeof(conf->url.protocols[0])); - conf->url.prot_count = ALEN(url_protocols); - conf->url.max_prot_len = 0; - - for (size_t i = 0; i < ALEN(url_protocols); i++) { - size_t len = c32len(url_protocols[i]); - if (len > conf->url.max_prot_len) - conf->url.max_prot_len = len; - conf->url.protocols[i] = xc32dup(url_protocols[i]); - } - - qsort( - conf->url.uri_characters, - c32len(conf->url.uri_characters), - sizeof(conf->url.uri_characters[0]), - &c32cmp_single); tll_foreach(*initial_user_notifications, it) { tll_push_back(conf->notifications, it->item); @@ -3577,12 +3475,7 @@ config_clone(const struct config *old) config_font_list_clone(&conf->csd.font, &old->csd.font); conf->url.label_letters = xc32dup(old->url.label_letters); - conf->url.uri_characters = xc32dup(old->url.uri_characters); spawn_template_clone(&conf->url.launch, &old->url.launch); - conf->url.protocols = xmalloc( - old->url.prot_count * sizeof(conf->url.protocols[0])); - for (size_t i = 0; i < old->url.prot_count; i++) - conf->url.protocols[i] = xc32dup(old->url.protocols[i]); key_binding_list_clone(&conf->bindings.key, &old->bindings.key); key_binding_list_clone(&conf->bindings.search, &old->bindings.search); @@ -3663,10 +3556,6 @@ config_free(struct config *conf) free(conf->url.label_letters); spawn_template_free(&conf->url.launch); - for (size_t i = 0; i < conf->url.prot_count; i++) - free(conf->url.protocols[i]); - free(conf->url.protocols); - free(conf->url.uri_characters); free_key_binding_list(&conf->bindings.key); free_key_binding_list(&conf->bindings.search); diff --git a/config.h b/config.h index 7d9f88c3..a7947d9d 100644 --- a/config.h +++ b/config.h @@ -219,11 +219,6 @@ struct config { OSC8_UNDERLINE_URL_MODE, OSC8_UNDERLINE_ALWAYS, } osc8_underline; - - char32_t **protocols; - char32_t *uri_characters; - size_t prot_count; - size_t max_prot_len; } url; struct { diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 903d3375..813348c9 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -782,19 +782,6 @@ xdgtoken=95ebdfe56e4f47ddb5bba9d7dc3a2c35 Default: _sadfjklewcmpgh_. -*protocols* - Comma separated list of protocols (schemes) that should be - recognized in URL mode. Note that only auto-detected URLs are - affected by this option. OSC-8 URLs are always enabled, regardless - of protocol. Default: _http, https, ftp, ftps, file, gemini, - gopher, irc, ircs_. - -*uri-characters* - Set of characters allowed in auto-detected URLs. Any character not - included in this set constitutes a URL delimiter. - - Default: - _abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-\_.,~:;/?#@!$&%\*+="'()[]_ # SECTION: cursor diff --git a/foot.ini b/foot.ini index 17fabd3d..864c990c 100644 --- a/foot.ini +++ b/foot.ini @@ -69,8 +69,6 @@ # launch=xdg-open ${url} # label-letters=sadfjklewcmpgh # osc8-underline=url-mode -# protocols=http, https, ftp, ftps, file, gemini, gopher -# uri-characters=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.,~:;/?#@!$&%*+="'()[] [cursor] # style=block diff --git a/tests/test-config.c b/tests/test-config.c index 303ddd6f..37cf4f22 100644 --- a/tests/test-config.c +++ b/tests/test-config.c @@ -106,50 +106,6 @@ test_c32string(struct context *ctx, bool (*parse_fun)(struct context *ctx), } } -static void -test_protocols(struct context *ctx, bool (*parse_fun)(struct context *ctx), - const char *key, char32_t **const *ptr) -{ - ctx->key = key; - - static const struct { - const char *option_string; - int count; - const char32_t *value[2]; - bool invalid; - } input[] = { - {""}, - {"http", 1, {U"http://"}}, - {" http", 1, {U"http://"}}, - {"http, https", 2, {U"http://", U"https://"}}, - {"longprotocolislong", 1, {U"longprotocolislong://"}}, - }; - - for (size_t i = 0; i < ALEN(input); i++) { - ctx->value = input[i].option_string; - - if (input[i].invalid) { - if (parse_fun(ctx)) { - BUG("[%s].%s=%s: did not fail to parse as expected", - ctx->section, ctx->key, &ctx->value[0]); - } - } else { - if (!parse_fun(ctx)) { - BUG("[%s].%s=%s: failed to parse", - ctx->section, ctx->key, &ctx->value[0]); - } - for (int c = 0; c < input[i].count; c++) { - if (c32cmp((*ptr)[c], input[i].value[c]) != 0) { - BUG("[%s].%s=%s: set value[%d] (%ls) not the expected one (%ls)", - ctx->section, ctx->key, &ctx->value[c], c, - (const wchar_t *)(*ptr)[c], - (const wchar_t *)input[i].value[c]); - } - } - } - } -} - static void test_boolean(struct context *ctx, bool (*parse_fun)(struct context *ctx), const char *key, const bool *ptr) @@ -647,9 +603,6 @@ test_section_url(void) (int []){OSC8_UNDERLINE_URL_MODE, OSC8_UNDERLINE_ALWAYS}, (int *)&conf.url.osc8_underline); test_c32string(&ctx, &parse_section_url, "label-letters", &conf.url.label_letters); - test_protocols(&ctx, &parse_section_url, "protocols", &conf.url.protocols); - - /* TODO: uri-characters (wchar string, but sorted) */ config_free(&conf); }