config+url: add support for user-defined regex patterns

Users can now define their own regex patterns, and use them via key
bindings:

    [regex:foo]
    regex=foo(bar)?
    launch=path-to-script-or-application {match}

    [key-bindings]
    regex-launch=[foo] Control+Shift+q
    regex-copy=[foo] Control+Mod1+Shift+q

That is, add a section called 'regex:', followed by an
identifier. Define a regex and a launcher command line.

Add a key-binding, regex-launch and/or regex-copy (similar to
show-urls-launch and show-urls-copy), and connect them to the regex
with the "[regex-name]" syntax (similar to how the pipe-* bindings
work).
This commit is contained in:
Daniel Eklöf 2025-02-03 08:55:47 +01:00
parent f718cb3fb0
commit 051cd6ecfc
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
8 changed files with 310 additions and 48 deletions

40
input.c
View file

@ -349,9 +349,9 @@ execute_binding(struct seat *seat, struct terminal *term,
action == BIND_ACTION_SHOW_URLS_LAUNCH ? URL_ACTION_LAUNCH :
URL_ACTION_PERSISTENT;
urls_collect(term, url_action, &term->urls);
urls_collect(term, url_action, &term->conf->url.preg, true, &term->urls);
urls_assign_key_combos(term->conf, &term->urls);
urls_render(term);
urls_render(term, &term->conf->url.launch);
return true;
}
@ -448,6 +448,42 @@ execute_binding(struct seat *seat, struct terminal *term,
term_shutdown(term);
return true;
case BIND_ACTION_REGEX_LAUNCH:
case BIND_ACTION_REGEX_COPY:
if (binding->aux->type != BINDING_AUX_REGEX)
return true;
tll_foreach(term->conf->custom_regexes, it) {
const struct custom_regex *regex = &it->item;
if (streq(regex->name, binding->aux->regex_name)) {
xassert(!urls_mode_is_active(term));
enum url_action url_action = action == BIND_ACTION_REGEX_LAUNCH
? URL_ACTION_LAUNCH : URL_ACTION_COPY;
if (regex->regex == NULL) {
LOG_ERR("regex:%s has no regex defined", regex->name);
return true;
}
if (url_action == URL_ACTION_LAUNCH && regex->launch.argv.args == NULL) {
LOG_ERR("regex:%s has no launch command defined", regex->name);
return true;
}
urls_collect(term, url_action, &regex->preg, false, &term->urls);
urls_assign_key_combos(term->conf, &term->urls);
urls_render(term, &regex->launch);
return true;
}
}
LOG_ERR(
"no regex section named '%s' defined in the configuration",
binding->aux->regex_name);
return true;
case BIND_ACTION_SELECT_BEGIN:
selection_start(
term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE, false);