Merge hooks into options and make each one an array option. This allows

multiple commands to be easily bound to one hook. set-hook and
show-hooks remain but they are now variants of set-option and
show-options. show-options now has a -H flag to show hooks (by default
they are not shown).
This commit is contained in:
nicm
2019-04-26 11:38:51 +00:00
parent f1e14f86c4
commit dfb7bb6830
20 changed files with 356 additions and 414 deletions

View File

@ -36,13 +36,34 @@ struct notify_entry {
};
static void
notify_hook1(struct cmdq_item *item, struct notify_entry *ne)
notify_hook_formats(struct cmdq_item *item, struct session *s, struct window *w,
int pane)
{
struct cmd_find_state fs;
struct hook *hook;
struct cmdq_item *new_item;
struct session *s = ne->session;
struct window *w = ne->window;
if (s != NULL) {
cmdq_format(item, "hook_session", "$%u", s->id);
cmdq_format(item, "hook_session_name", "%s", s->name);
}
if (w != NULL) {
cmdq_format(item, "hook_window", "@%u", w->id);
cmdq_format(item, "hook_window_name", "%s", w->name);
}
if (pane != -1)
cmdq_format(item, "hook_pane", "%%%d", pane);
}
static void
notify_insert_hook(struct cmdq_item *item, struct notify_entry *ne)
{
struct cmd_find_state fs;
struct options *oo;
struct cmdq_item *new_item;
struct session *s = ne->session;
struct window *w = ne->window;
struct options_entry *o;
struct options_array_item *a;
struct cmd_list *cmdlist;
log_debug("%s: %s", __func__, ne->name);
cmd_find_clear_state(&fs, 0);
if (cmd_find_empty_state(&ne->fs) || !cmd_find_valid_state(&ne->fs))
@ -50,26 +71,31 @@ notify_hook1(struct cmdq_item *item, struct notify_entry *ne)
else
cmd_find_copy_state(&fs, &ne->fs);
hook = hooks_find(hooks_get(fs.s), ne->name);
if (hook == NULL)
if (fs.s == NULL)
oo = global_s_options;
else
oo = fs.s->options;
o = options_get(oo, ne->name);
if (o == NULL)
return;
log_debug("notify hook %s", ne->name);
new_item = cmdq_get_command(hook->cmdlist, &fs, NULL, CMDQ_NOHOOKS);
cmdq_format(new_item, "hook", "%s", ne->name);
a = options_array_first(o);
while (a != NULL) {
cmdlist = options_array_item_value(a)->cmdlist;
if (cmdlist == NULL) {
a = options_array_next(a);
continue;
}
if (s != NULL) {
cmdq_format(new_item, "hook_session", "$%u", s->id);
cmdq_format(new_item, "hook_session_name", "%s", s->name);
new_item = cmdq_get_command(cmdlist, &fs, NULL, CMDQ_NOHOOKS);
cmdq_format(new_item, "hook", "%s", ne->name);
notify_hook_formats(new_item, s, w, ne->pane);
cmdq_insert_after(item, new_item);
item = new_item;
a = options_array_next(a);
}
if (w != NULL) {
cmdq_format(new_item, "hook_window", "@%u", w->id);
cmdq_format(new_item, "hook_window_name", "%s", w->name);
}
if (ne->pane != -1)
cmdq_format(new_item, "hook_pane", "%%%d", ne->pane);
cmdq_insert_after(item, new_item);
}
static enum cmd_retval
@ -102,7 +128,7 @@ notify_callback(struct cmdq_item *item, void *data)
if (strcmp(ne->name, "session-window-changed") == 0)
control_notify_session_window_changed(ne->session);
notify_hook1(item, ne);
notify_insert_hook(item, ne);
if (ne->client != NULL)
server_client_unref(ne->client);
@ -169,7 +195,7 @@ notify_hook(struct cmdq_item *item, const char *name)
ne.window = item->target.w;
ne.pane = item->target.wp->id;
notify_hook1(item, &ne);
notify_insert_hook(item, &ne);
}
void