mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
config: add url.protocols
This makes the protocols recognized by auto-detected URLs configurable. Closes #531
This commit is contained in:
parent
0f483d65ce
commit
53516aceec
6 changed files with 85 additions and 19 deletions
|
|
@ -44,6 +44,8 @@
|
|||
and a new `command` action to run an arbitrary command.
|
||||
(https://codeberg.org/dnkl/foot/pulls/483)
|
||||
* Dedicated `[url]` section to config.
|
||||
* `[url].protocols` option to `foot.ini`
|
||||
(https://codeberg.org/dnkl/foot/issues/531).
|
||||
* Support for setting the full 256 color palette in foot.ini
|
||||
(https://codeberg.org/dnkl/foot/issues/489)
|
||||
* XDG activation support, will be used by `[bell].urgent` when
|
||||
|
|
|
|||
66
config.c
66
config.c
|
|
@ -1001,6 +1001,47 @@ parse_section_url(const char *key, const char *value, struct config *conf,
|
|||
}
|
||||
}
|
||||
|
||||
else if (strcmp(key, "protocols") == 0) {
|
||||
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, " "))
|
||||
{
|
||||
size_t chars = mbstowcs(NULL, prot, 0);
|
||||
if (chars == (size_t)-1) {
|
||||
LOG_AND_NOTIFY_ERRNO(
|
||||
"%s:%u: [url]: protocols: invalid protocol name: %s",
|
||||
path, lineno, prot);
|
||||
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(wchar_t));
|
||||
mbstowcs(conf->url.protocols[idx], prot, chars + 1);
|
||||
wcscpy(&conf->url.protocols[idx][chars], L"://");
|
||||
|
||||
size_t len = chars + 3; /* Include the "://" */
|
||||
if (len > conf->url.max_prot_len)
|
||||
conf->url.max_prot_len = len;
|
||||
}
|
||||
|
||||
free(copy);
|
||||
}
|
||||
|
||||
else {
|
||||
LOG_AND_NOTIFY_ERR("%s:%d: [url]: %s: invalid key", path, lineno, key);
|
||||
return false;
|
||||
|
|
@ -2527,6 +2568,27 @@ config_load(struct config *conf, const char *conf_path,
|
|||
conf->url.launch.raw_cmd = xstrdup("xdg-open ${url}");
|
||||
tokenize_cmdline(conf->url.launch.raw_cmd, &conf->url.launch.argv);
|
||||
|
||||
static const wchar_t *url_protocols[] = {
|
||||
L"http://",
|
||||
L"https://",
|
||||
L"ftp://",
|
||||
L"ftps://",
|
||||
L"file://",
|
||||
L"gemini://",
|
||||
L"gopher://",
|
||||
};
|
||||
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 = wcslen(url_protocols[i]);
|
||||
if (len > conf->url.max_prot_len)
|
||||
conf->url.max_prot_len = len;
|
||||
conf->url.protocols[i] = xwcsdup(url_protocols[i]);
|
||||
}
|
||||
|
||||
tll_foreach(*initial_user_notifications, it) {
|
||||
tll_push_back(conf->notifications, it->item);
|
||||
tll_remove(*initial_user_notifications, it);
|
||||
|
|
@ -2644,6 +2706,10 @@ config_free(struct config conf)
|
|||
|
||||
free(conf.url.label_letters);
|
||||
free_spawn_template(&conf.url.launch);
|
||||
for (size_t i = 0; i < conf.url.prot_count; i++)
|
||||
free(conf.url.protocols[i]);
|
||||
free(conf.url.protocols);
|
||||
|
||||
key_binding_list_free(&conf.bindings.key);
|
||||
key_binding_list_free(&conf.bindings.search);
|
||||
key_binding_list_free(&conf.bindings.url);
|
||||
|
|
|
|||
3
config.h
3
config.h
|
|
@ -135,6 +135,9 @@ struct config {
|
|||
OSC8_UNDERLINE_ALWAYS,
|
||||
} osc8_underline;
|
||||
|
||||
wchar_t **protocols;
|
||||
size_t prot_count;
|
||||
size_t max_prot_len;
|
||||
} url;
|
||||
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -323,6 +323,13 @@ in this order:
|
|||
String of characters to use when generating key sequences for URL
|
||||
jump labels. Default: _sadfjklewcmpgh_.
|
||||
|
||||
*protocols*
|
||||
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_.
|
||||
|
||||
|
||||
# SECTION: cursor
|
||||
|
||||
This section controls the cursor style and color. Note that
|
||||
|
|
|
|||
2
foot.ini
2
foot.ini
|
|
@ -45,6 +45,8 @@
|
|||
# launch=xdg-open ${url}
|
||||
# label-letters=sadfjklewcmpgh
|
||||
# osc8-underline=url-mode
|
||||
# protocols = http https ftp ftps file gemini gopher
|
||||
|
||||
[cursor]
|
||||
# style=block
|
||||
# color=111111 dcdccc
|
||||
|
|
|
|||
24
url-mode.c
24
url-mode.c
|
|
@ -212,23 +212,9 @@ static void
|
|||
auto_detected(const struct terminal *term, enum url_action action,
|
||||
url_list_t *urls)
|
||||
{
|
||||
static const wchar_t *const prots[] = {
|
||||
L"http://",
|
||||
L"https://",
|
||||
L"ftp://",
|
||||
L"ftps://",
|
||||
L"file://",
|
||||
L"gemini://",
|
||||
L"gopher://",
|
||||
};
|
||||
|
||||
size_t max_prot_len = 0;
|
||||
for (size_t i = 0; i < ALEN(prots); i++) {
|
||||
size_t len = wcslen(prots[i]);
|
||||
if (len > max_prot_len)
|
||||
max_prot_len = len;
|
||||
}
|
||||
const struct config *conf = term->conf;
|
||||
|
||||
size_t max_prot_len = conf->url.max_prot_len;
|
||||
wchar_t proto_chars[max_prot_len];
|
||||
struct coord proto_start[max_prot_len];
|
||||
size_t proto_char_count = 0;
|
||||
|
|
@ -266,15 +252,15 @@ auto_detected(const struct terminal *term, enum url_action action,
|
|||
proto_start[max_prot_len - 1] = (struct coord){c, r};
|
||||
proto_char_count++;
|
||||
|
||||
for (size_t i = 0; i < ALEN(prots); i++) {
|
||||
size_t prot_len = wcslen(prots[i]);
|
||||
for (size_t i = 0; i < conf->url.prot_count; i++) {
|
||||
size_t prot_len = wcslen(conf->url.protocols[i]);
|
||||
|
||||
if (proto_char_count < prot_len)
|
||||
continue;
|
||||
|
||||
const wchar_t *proto = &proto_chars[max_prot_len - prot_len];
|
||||
|
||||
if (wcsncasecmp(prots[i], proto, prot_len) == 0) {
|
||||
if (wcsncasecmp(conf->url.protocols[i], proto, prot_len) == 0) {
|
||||
state = STATE_URL;
|
||||
start = proto_start[max_prot_len - prot_len];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue