This adds an implementation hooks using a RB tree to store the name of the hook and the command-list it uses. These will be accessed via commands to add/remove hooks. --- hooks.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ session.c | 2 ++ tmux.c | 2 ++ tmux.h | 23 +++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 hooks.c
diff --git a/hooks.c b/hooks.c new file mode 100644 index 0000000..dfc4088 --- /dev/null +++ b/hooks.c @@ -0,0 +1,114 @@ +/* $Id$ */ + +/* + * Copyright (c) 2012 Thomas Adam <tho...@xteddy.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> + +#include <ctype.h> +#include <stdlib.h> + +#include <string.h> + +#include "tmux.h" + +RB_GENERATE(hooks, hook, entry, hooks_cmp); + +int +hooks_cmp(struct hook *hook1, struct hook *hook2) +{ + return (strcmp(hook1->name, hook2->name)); +} + +void +hooks_init(struct hooks *hooks, struct hooks *copy) +{ + RB_INIT(hooks); + + if (copy != NULL) + hooks_copy(copy, hooks); +} + +void +hooks_copy(struct hooks *src, struct hooks *dst) +{ + struct hook *h; + + RB_FOREACH(h, hooks, src) + hooks_add(dst, h->name, h->cmdlist); +} + +void +hooks_free(struct hooks *hooks) +{ + struct hook *h, *h2; + + RB_FOREACH_SAFE(h, hooks, hooks, h2) + hooks_remove(hooks, h); +} + +void +hooks_add(struct hooks *hooks, const char *name, struct cmd_list *cmdlist) +{ + struct hook *h; + + if ((h = hooks_find(hooks, (char *)name)) != NULL) + hooks_remove(hooks, h); + + h = xcalloc(1, sizeof *h); + h->name = xstrdup(name); + h->cmdlist = cmdlist; + h->cmdlist->references++; + + RB_INSERT(hooks, hooks, h); +} + +void +hooks_remove(struct hooks *hooks, struct hook *h) +{ + if (h == NULL) + return; + + RB_REMOVE(hooks, hooks, h); + cmd_list_free(h->cmdlist); + free(h->name); + free(h); +} + +struct hook * +hooks_find(struct hooks *hooks, const char *name) +{ + struct hook h; + + if (name == NULL) + return (NULL); + + h.name = (char *)name; + + return (RB_FIND(hooks, hooks, &h)); +} + +void +hooks_run(struct hook *hook, struct cmd_q *cmdq) +{ + struct cmd *cmd; + + if (hook == NULL) + return; + + TAILQ_FOREACH(cmd, &hook->cmdlist->list, qentry) + cmd->entry->exec(cmd, cmdq); +} diff --git a/session.c b/session.c index 74eb06a..b75d459 100644 --- a/session.c +++ b/session.c @@ -104,6 +104,7 @@ session_create(const char *name, const char *cmd, const char *cwd, TAILQ_INIT(&s->lastw); RB_INIT(&s->windows); + hooks_init(&s->hooks, &global_hooks); options_init(&s->options, &global_s_options); environ_init(&s->environ); if (env != NULL) @@ -160,6 +161,7 @@ session_destroy(struct session *s) session_group_remove(s); environ_free(&s->environ); options_free(&s->options); + hooks_free(&s->hooks); while (!TAILQ_EMPTY(&s->lastw)) winlink_stack_remove(&s->lastw, TAILQ_FIRST(&s->lastw)); diff --git a/tmux.c b/tmux.c index 8ea91eb..662867d 100644 --- a/tmux.c +++ b/tmux.c @@ -37,6 +37,7 @@ struct options global_options; /* server options */ struct options global_s_options; /* session options */ struct options global_w_options; /* window options */ struct environ global_environ; +struct hooks global_hooks; struct event_base *ev_base; @@ -321,6 +322,7 @@ main(int argc, char **argv) flags |= IDENTIFY_UTF8; } + hooks_init(&global_hooks, NULL); environ_init(&global_environ); for (var = environ; *var != NULL; var++) environ_put(&global_environ, *var); diff --git a/tmux.h b/tmux.h index 9c91d6a..096b8ce 100644 --- a/tmux.h +++ b/tmux.h @@ -1075,6 +1075,14 @@ struct environ_entry { }; RB_HEAD(environ, environ_entry); +/* Hooks. */ +struct hook { + char *name; + struct cmd_list *cmdlist; + RB_ENTRY(hook) entry; +}; +RB_HEAD(hooks, hook); + /* Client session. */ struct session_group { TAILQ_HEAD(, session) sessions; @@ -1100,6 +1108,7 @@ struct session { struct winlink_stack lastw; struct winlinks windows; + struct hooks hooks; struct options options; #define SESSION_UNATTACHED 0x1 /* not attached to any clients */ @@ -1501,6 +1510,7 @@ RB_HEAD(format_tree, format_entry); #define CMD_BUFFER_USAGE "[-b buffer-index]" /* tmux.c */ +extern struct hooks global_hooks; extern struct options global_options; extern struct options global_s_options; extern struct options global_w_options; @@ -1548,6 +1558,17 @@ void format_winlink( void format_window_pane(struct format_tree *, struct window_pane *); void format_paste_buffer(struct format_tree *, struct paste_buffer *); +/* hooks.c */ +int hooks_cmp(struct hook *, struct hook *); +RB_PROTOTYPE(hooks, hook, entry, hooks_cmp); +void hooks_init(struct hooks *, struct hooks *); +void hooks_free(struct hooks *); +void hooks_add(struct hooks *, const char *, struct cmd_list *); +void hooks_copy(struct hooks *, struct hooks *); +void hooks_remove(struct hooks *, struct hook *); +void hooks_run(struct hook *, struct cmd_q *); +struct hook *hooks_find(struct hooks *, const char *); + /* mode-key.c */ extern const struct mode_key_table mode_key_tables[]; extern struct mode_key_tree mode_key_tree_vi_edit; @@ -1821,10 +1842,12 @@ extern const struct cmd_entry cmd_send_prefix_entry; extern const struct cmd_entry cmd_server_info_entry; extern const struct cmd_entry cmd_set_buffer_entry; extern const struct cmd_entry cmd_set_environment_entry; +extern const struct cmd_entry cmd_set_hook_entry; extern const struct cmd_entry cmd_set_option_entry; extern const struct cmd_entry cmd_set_window_option_entry; extern const struct cmd_entry cmd_show_buffer_entry; extern const struct cmd_entry cmd_show_environment_entry; +extern const struct cmd_entry cmd_show_hooks_entry; extern const struct cmd_entry cmd_show_messages_entry; extern const struct cmd_entry cmd_show_options_entry; extern const struct cmd_entry cmd_show_window_options_entry; -- 1.7.10.4 ------------------------------------------------------------------------------ Minimize network downtime and maximize team effectiveness. Reduce network management and security costs.Learn how to hire the most talented Cisco Certified professionals. Visit the Employer Resources Portal http://www.cisco.com/web/learning/employer_resources/index.html _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users