From 3f35b5299fb2c08637aa12757185e5b82eeb3fc1 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 16 Oct 2016 19:36:37 +0000 Subject: Provide a way for hooks to tag formats onto the commands they fire so that the user can get at additional information - now used for the "hook" format, more to come. --- cmd-queue.c | 25 ++++++++++++++++++++++++- format.c | 17 +++++++++++++++-- hooks.c | 18 +++++++----------- notify.c | 7 ++----- tmux.h | 5 ++++- 5 files changed, 52 insertions(+), 20 deletions(-) diff --git a/cmd-queue.c b/cmd-queue.c index 61cf0188..5056fffc 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -102,7 +102,8 @@ cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item) static void cmdq_remove(struct cmdq_item *item) { - free((void *)item->hook); + if (item->formats != NULL) + format_free(item->formats); if (item->client != NULL) server_client_unref(item->client); @@ -241,6 +242,28 @@ cmdq_fire_callback(struct cmdq_item *item) return (item->cb(item, item->data)); } +/* Add a format to command queue. */ +void +cmdq_format(struct cmdq_item *item, const char *key, const char *fmt, ...) +{ + va_list ap; + struct cmdq_item *loop; + char *value; + + va_start(ap, fmt); + xvasprintf(&value, fmt, ap); + va_end(ap); + + for (loop = item; loop != NULL; loop = item->next) { + if (loop->formats == NULL) + loop->formats = format_create(NULL, 0); + format_add(loop->formats, key, "%s", value); + } + + free(value); +} + + /* Process next item on command queue. */ u_int cmdq_next(struct client *c) diff --git a/format.c b/format.c index a8c5fa51..1b933275 100644 --- a/format.c +++ b/format.c @@ -468,6 +468,19 @@ format_cb_pane_tabs(struct format_tree *ft, struct format_entry *fe) evbuffer_free(buffer); } +/* Merge a format tree. */ +static void +format_merge(struct format_tree *ft, struct format_tree *from) +{ + struct format_entry *fe; + + RB_FOREACH(fe, format_entry_tree, &from->tree) { + if (fe->value != NULL) + format_add(ft, fe->key, "%s", fe->value); + } + +} + /* Create a new tree. */ struct format_tree * format_create(struct cmdq_item *item, int flags) @@ -491,8 +504,8 @@ format_create(struct cmdq_item *item, int flags) if (item != NULL && item->cmd != NULL) format_add(ft, "command", "%s", item->cmd->entry->name); - if (item != NULL && item->hook != NULL) - format_add(ft, "hook", "%s", item->hook); + if (item != NULL && item->formats != NULL) + format_merge(ft, item->formats); return (ft); } diff --git a/hooks.c b/hooks.c index 3fa79e49..832e6f84 100644 --- a/hooks.c +++ b/hooks.c @@ -146,7 +146,7 @@ hooks_run(struct hooks *hooks, struct client *c, struct cmd_find_state *fs, struct hook *hook; va_list ap; char *name; - struct cmdq_item *new_item, *loop; + struct cmdq_item *new_item; va_start(ap, fmt); xvasprintf(&name, fmt, ap); @@ -160,12 +160,10 @@ hooks_run(struct hooks *hooks, struct client *c, struct cmd_find_state *fs, log_debug("running hook %s", name); new_item = cmdq_get_command(hook->cmdlist, fs, NULL, CMDQ_NOHOOKS); + cmdq_format(new_item, "hook", "%s", name); + cmdq_append(c, new_item); - for (loop = new_item; loop != NULL; loop = loop->next) - loop->hook = xstrdup(name); free(name); - - cmdq_append(c, new_item); } void @@ -175,7 +173,7 @@ hooks_insert(struct hooks *hooks, struct cmdq_item *item, struct hook *hook; va_list ap; char *name; - struct cmdq_item *new_item, *loop; + struct cmdq_item *new_item; if (item->flags & CMDQ_NOHOOKS) return; @@ -192,13 +190,11 @@ hooks_insert(struct hooks *hooks, struct cmdq_item *item, log_debug("running hook %s (parent %p)", name, item); new_item = cmdq_get_command(hook->cmdlist, fs, NULL, CMDQ_NOHOOKS); - - for (loop = new_item; loop != NULL; loop = loop->next) - loop->hook = xstrdup(name); - free(name); - + cmdq_format(new_item, "hook", "%s", name); if (item != NULL) cmdq_insert_after(item, new_item); else cmdq_append(NULL, new_item); + + free(name); } diff --git a/notify.c b/notify.c index 392797ba..20709e53 100644 --- a/notify.c +++ b/notify.c @@ -59,7 +59,7 @@ notify_hook(struct cmdq_item *item, struct notify_entry *ne) const char *name; struct cmd_find_state fs; struct hook *hook; - struct cmdq_item *new_item, *loop; + struct cmdq_item *new_item; name = notify_hooks[ne->type]; if (name == NULL) @@ -83,10 +83,7 @@ notify_hook(struct cmdq_item *item, struct notify_entry *ne) log_debug("notify hook %s", name); new_item = cmdq_get_command(hook->cmdlist, &fs, NULL, CMDQ_NOHOOKS); - - for (loop = new_item; loop != NULL; loop = loop->next) - loop->hook = xstrdup(name); - + cmdq_format(new_item, "hook", "%s", name); cmdq_insert_after(item, new_item); } diff --git a/tmux.h b/tmux.h index 1ce6e692..0f2cda51 100644 --- a/tmux.h +++ b/tmux.h @@ -1250,7 +1250,8 @@ struct cmdq_item { u_int number; time_t time; - const char *hook; + struct format_tree *formats; + int flags; #define CMDQ_FIRED 0x1 #define CMDQ_WAITING 0x2 @@ -1783,6 +1784,8 @@ struct cmdq_item *cmdq_get_command(struct cmd_list *, struct cmd_find_state *, struct cmdq_item *cmdq_get_callback(cmdq_cb, void *); void cmdq_insert_after(struct cmdq_item *, struct cmdq_item *); void cmdq_append(struct client *, struct cmdq_item *); +void printflike(3, 4) cmdq_format(struct cmdq_item *, const char *, + const char *, ...); u_int cmdq_next(struct client *); void cmdq_guard(struct cmdq_item *, const char *, int); void printflike(2, 3) cmdq_print(struct cmdq_item *, const char *, ...); -- cgit v1.2.3