The branch, hooks has been updated
via 0ad7514ec8301d6291b00d2288b440ea2556617c (commit)
from 2c08a3a55922651b2d5100ba5778cce74da906b2 (commit)
- Log -----------------------------------------------------------------
commit 0ad7514ec8301d6291b00d2288b440ea2556617c
Author: Nicholas Marriott <[email protected]>
Commit: Nicholas Marriott <[email protected]>
Infrastructure for hooks - structures and the set-hook and show-hook
commands.
---
Makefile.am | 3 +
cmd-set-hook.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++
cmd-show-hooks.c | 63 +++++++++++++++++++++++++++++++
cmd.c | 2 +
hooks.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
options.c | 4 +-
session.c | 2 +
tmux.c | 2 +
tmux.h | 27 +++++++++++++
9 files changed, 303 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 690e466..8a38068 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -125,8 +125,10 @@ dist_tmux_SOURCES = \
cmd-server-info.c \
cmd-set-buffer.c \
cmd-set-environment.c \
+ cmd-set-hook.c \
cmd-set-option.c \
cmd-show-environment.c \
+ cmd-show-hooks.c \
cmd-show-messages.c \
cmd-show-options.c \
cmd-source-file.c \
@@ -149,6 +151,7 @@ dist_tmux_SOURCES = \
grid-cell.c \
grid-view.c \
grid.c \
+ hooks.c \
input-keys.c \
input.c \
job.c \
diff --git a/cmd-set-hook.c b/cmd-set-hook.c
new file mode 100644
index 0000000..b602933
--- /dev/null
+++ b/cmd-set-hook.c
@@ -0,0 +1,93 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2012 Thomas Adam <[email protected]>
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include "tmux.h"
+
+/*
+ * Set a global or session hook.
+ */
+
+enum cmd_retval cmd_set_hook_exec(struct cmd *, struct cmd_q *);
+void cmd_set_hook_prepare(struct cmd *, struct cmd_q *);
+
+const struct cmd_entry cmd_set_hook_entry = {
+ "set-hook", NULL,
+ "gt:u", 1, 2,
+ "[-gu]" CMD_TARGET_SESSION_USAGE " hook-name [command]",
+ 0,
+ NULL,
+ cmd_set_hook_exec,
+};
+
+enum cmd_retval
+cmd_set_hook_exec(struct cmd *self, struct cmd_q *cmdq)
+{
+ struct args *args = self->args;
+ struct session *s;
+ struct cmd_list *cmdlist;
+ struct hooks *hooks;
+ struct hook *hook;
+ char *cause;
+ const char *name, *cmd;
+
+ if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+ hooks = args_has(args, 'g') ? &global_hooks : &s->hooks;
+
+ name = args->argv[0];
+ if (*name == '\0') {
+ cmdq_error(cmdq, "invalid hook name");
+ return (CMD_RETURN_ERROR);
+ }
+ if (args->argc < 2)
+ cmd = NULL;
+ else
+ cmd = args->argv[1];
+
+ if (args_has(args, 'u')) {
+ if (cmd != NULL) {
+ cmdq_error(cmdq, "command passed to unset hook: %s",
+ name);
+ return (CMD_RETURN_ERROR);
+ }
+ if ((hook = hooks_find(hooks, name)) != NULL)
+ hooks_remove(hooks, hook);
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (cmd == NULL) {
+ cmdq_error(cmdq, "no command to set hook: %s", name);
+ return (CMD_RETURN_ERROR);
+ }
+ if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) {
+ if (cause != NULL) {
+ cmdq_error(cmdq, "%s", cause);
+ free(cause);
+ }
+ return (CMD_RETURN_ERROR);
+ }
+ hooks_add(hooks, name, cmdlist);
+ cmd_list_free(cmdlist);
+
+ return (CMD_RETURN_NORMAL);
+}
diff --git a/cmd-show-hooks.c b/cmd-show-hooks.c
new file mode 100644
index 0000000..384e664
--- /dev/null
+++ b/cmd-show-hooks.c
@@ -0,0 +1,63 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2012 Thomas Adam <[email protected]>
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include "tmux.h"
+
+/*
+ * Show global or session hooks.
+ */
+
+enum cmd_retval cmd_show_hooks_exec(struct cmd *, struct cmd_q *);
+void cmd_show_hooks_prepare(struct cmd *, struct cmd_q *);
+
+const struct cmd_entry cmd_show_hooks_entry = {
+ "show-hooks", NULL,
+ "gt:", 0, 1,
+ "[-g] " CMD_TARGET_SESSION_USAGE,
+ 0,
+ NULL,
+ cmd_show_hooks_exec
+};
+
+enum cmd_retval
+cmd_show_hooks_exec(struct cmd *self, struct cmd_q *cmdq)
+{
+ struct args *args = self->args;
+ struct session *s;
+ struct hooks *hooks;
+ struct hook *hook;
+ char tmp[BUFSIZ];
+ size_t used;
+
+ if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+ hooks = args_has(args, 'g') ? &global_hooks : &s->hooks;
+
+ RB_FOREACH(hook, hooks_tree, &hooks->tree) {
+ used = xsnprintf(tmp, sizeof tmp, "%s -> ", hook->name);
+ cmd_list_print(hook->cmdlist, tmp + used, (sizeof tmp) - used);
+ cmdq_print(cmdq, "%s", tmp);
+ }
+
+ return (CMD_RETURN_NORMAL);
+}
diff --git a/cmd.c b/cmd.c
index 414c906..72c336a 100644
--- a/cmd.c
+++ b/cmd.c
@@ -95,11 +95,13 @@ const struct cmd_entry *cmd_table[] = {
&cmd_send_prefix_entry,
&cmd_server_info_entry,
&cmd_set_buffer_entry,
+ &cmd_set_hook_entry,
&cmd_set_environment_entry,
&cmd_set_option_entry,
&cmd_set_window_option_entry,
&cmd_show_buffer_entry,
&cmd_show_environment_entry,
+ &cmd_show_hooks_entry,
&cmd_show_messages_entry,
&cmd_show_options_entry,
&cmd_show_window_options_entry,
diff --git a/hooks.c b/hooks.c
new file mode 100644
index 0000000..7157eef
--- /dev/null
+++ b/hooks.c
@@ -0,0 +1,109 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2012 Thomas Adam <[email protected]>
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include "tmux.h"
+
+RB_GENERATE(hooks_tree, hook, entry, hooks_cmp);
+
+struct hook *hooks_find1(struct hooks *, const char *);
+
+int
+hooks_cmp(struct hook *hook1, struct hook *hook2)
+{
+ return (strcmp(hook1->name, hook2->name));
+}
+
+void
+hooks_init(struct hooks *hooks, struct hooks *parent)
+{
+ RB_INIT(&hooks->tree);
+ hooks->parent = parent;
+}
+
+void
+hooks_free(struct hooks *hooks)
+{
+ struct hook *hook, *hook1;
+
+ RB_FOREACH_SAFE(hook, hooks_tree, &hooks->tree, hook1)
+ hooks_remove(hooks, hook);
+}
+
+void
+hooks_add(struct hooks *hooks, const char *name, struct cmd_list *cmdlist)
+{
+ struct hook *hook;
+
+ if ((hook = hooks_find1(hooks, name)) != NULL)
+ hooks_remove(hooks, hook);
+
+ hook = xcalloc(1, sizeof *hook);
+ hook->name = xstrdup(name);
+ hook->cmdlist = cmdlist;
+ hook->cmdlist->references++;
+
+ RB_INSERT(hooks_tree, &hooks->tree, hook);
+}
+
+void
+hooks_remove(struct hooks *hooks, struct hook *hook)
+{
+ RB_REMOVE(hooks_tree, &hooks->tree, hook);
+ cmd_list_free(hook->cmdlist);
+ free((char *) hook->name);
+ free(hook);
+}
+
+struct hook *
+hooks_find1(struct hooks *hooks, const char *name)
+{
+ struct hook hook;
+
+ hook.name = name;
+ return (RB_FIND(hooks_tree, &hooks->tree, &hook));
+}
+
+struct hook *
+hooks_find(struct hooks *hooks, const char *name)
+{
+ struct hook hook0, *hook;
+
+ hook0.name = name;
+ hook = RB_FIND(hooks_tree, &hooks->tree, &hook0);
+ while (hook == NULL) {
+ hooks = hooks->parent;
+ if (hooks == NULL)
+ break;
+ hook = RB_FIND(hooks_tree, &hooks->tree, &hook0);
+ }
+ return (hook);
+}
+
+void
+hooks_run(struct hook *hook, struct cmd_q *cmdq)
+{
+ struct cmd *cmd;
+
+ TAILQ_FOREACH(cmd, &hook->cmdlist->list, qentry)
+ cmd->entry->exec(cmd, cmdq);
+}
diff --git a/options.c b/options.c
index 7360906..776f250 100644
--- a/options.c
+++ b/options.c
@@ -25,8 +25,8 @@
#include "tmux.h"
/*
- * Option handling; each option has a name, type and value and is stored in
- * a splay tree.
+ * Option handling; each option has a name, type and value and is stored in a
+ * tree.
*/
RB_GENERATE(options_tree, options_entry, entry, options_cmp);
diff --git a/session.c b/session.c
index 66a52bc..a27c8aa 100644
--- a/session.c
+++ b/session.c
@@ -103,6 +103,7 @@ session_create(const char *name, const char *cmd, int cwd,
struct environ *env,
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 1e6edd9..47b3dee 100644
--- a/tmux.c
+++ b/tmux.c
@@ -38,6 +38,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;
@@ -288,6 +289,7 @@ main(int argc, char **argv)
flags |= CLIENT_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 84ad164..5d16dac 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1041,6 +1041,18 @@ struct environ_entry {
};
RB_HEAD(environ, environ_entry);
+/* Hooks. */
+struct hook {
+ const char *name;
+ struct cmd_list *cmdlist;
+ RB_ENTRY(hook) entry;
+};
+
+struct hooks {
+ RB_HEAD(hooks_tree, hook) tree;
+ struct hooks *parent;
+};
+
/* Client session. */
struct session_group {
TAILQ_HEAD(, session) sessions;
@@ -1066,6 +1078,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 */
@@ -1479,6 +1492,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;
@@ -1526,6 +1540,17 @@ void format_window_pane(struct format_tree
*,
void format_paste_buffer(struct format_tree *,
struct paste_buffer *);
+/* hooks.c */
+int hooks_cmp(struct hook *, struct hook *);
+RB_PROTOTYPE(hooks_tree, 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;
@@ -1800,10 +1825,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;
-----------------------------------------------------------------------
Summary of changes:
Makefile.am | 3 +
cmd-set-hook.c | 93 +++++++++++++++++++++++++++
cmd-kill-session.c => cmd-show-hooks.c | 47 +++++++-------
cmd.c | 2 +
hooks.c | 109 ++++++++++++++++++++++++++++++++
options.c | 4 +-
session.c | 2 +
tmux.c | 2 +
tmux.h | 27 ++++++++
9 files changed, 264 insertions(+), 25 deletions(-)
create mode 100644 cmd-set-hook.c
copy cmd-kill-session.c => cmd-show-hooks.c (55%)
create mode 100644 hooks.c
hooks/post-receive
--
tmux
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60135031&iu=/4140/ostg.clktrk
_______________________________________________
tmux-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs