summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2016-04-29 14:05:25 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2016-04-29 14:05:25 +0000
commit3e2a80372cf7ab1ece40b6e7efb0ce2b7ccb409f (patch)
treea040483d38d88a7aad45baf53bd227ef5b1a9248
parent42d33530005d1927ae1c51720d9655ebf1ebd3de (diff)
Final parts of command hooks, add before- and after- hooks to each command.
-rw-r--r--usr.bin/tmux/cmd-if-shell.c3
-rw-r--r--usr.bin/tmux/cmd-queue.c58
-rw-r--r--usr.bin/tmux/cmd-source-file.c3
-rw-r--r--usr.bin/tmux/format.c7
-rw-r--r--usr.bin/tmux/tmux.137
5 files changed, 92 insertions, 16 deletions
diff --git a/usr.bin/tmux/cmd-if-shell.c b/usr.bin/tmux/cmd-if-shell.c
index 902264c2415..5c9185774f6 100644
--- a/usr.bin/tmux/cmd-if-shell.c
+++ b/usr.bin/tmux/cmd-if-shell.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-if-shell.c,v 1.41 2016/03/01 12:06:07 nicm Exp $ */
+/* $OpenBSD: cmd-if-shell.c,v 1.42 2016/04/29 14:05:24 nicm Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -157,6 +157,7 @@ cmd_if_shell_callback(struct job *job)
}
cmdq1 = cmdq_new(cmdq->client);
+ cmdq1->flags |= cmdq->flags & CMD_Q_NOHOOKS;
cmdq1->emptyfn = cmd_if_shell_done;
cmdq1->data = cdata;
diff --git a/usr.bin/tmux/cmd-queue.c b/usr.bin/tmux/cmd-queue.c
index daf71ea8844..691ac376f1e 100644
--- a/usr.bin/tmux/cmd-queue.c
+++ b/usr.bin/tmux/cmd-queue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-queue.c,v 1.35 2016/01/19 16:01:30 nicm Exp $ */
+/* $OpenBSD: cmd-queue.c,v 1.36 2016/04/29 14:05:24 nicm Exp $ */
/*
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -186,6 +186,9 @@ static enum cmd_retval
cmdq_continue_one(struct cmd_q *cmdq)
{
struct cmd *cmd = cmdq->cmd;
+ const char *name = cmd->entry->name;
+ struct session *s;
+ struct hooks *hooks;
enum cmd_retval retval;
char *tmp;
int flags = !!(cmd->flags & CMD_CONTROL);
@@ -197,19 +200,51 @@ cmdq_continue_one(struct cmd_q *cmdq)
cmdq->time = time(NULL);
cmdq->number++;
- cmdq_guard(cmdq, "begin", flags);
+ if (~cmdq->flags & CMD_Q_REENTRY)
+ cmdq_guard(cmdq, "begin", flags);
- if (cmd_prepare_state(cmd, cmdq, NULL) != 0)
+ if (cmd_prepare_state(cmd, cmdq, cmdq->parent) != 0)
goto error;
+
+ if (~cmdq->flags & CMD_Q_NOHOOKS) {
+ s = NULL;
+ if (cmdq->state.tflag.s != NULL)
+ s = cmdq->state.tflag.s;
+ else if (cmdq->state.sflag.s != NULL)
+ s = cmdq->state.sflag.s;
+ else if (cmdq->state.c != NULL)
+ s = cmdq->state.c->session;
+ if (s != NULL)
+ hooks = s->hooks;
+ else
+ hooks = global_hooks;
+
+ if (~cmdq->flags & CMD_Q_REENTRY) {
+ cmdq->flags |= CMD_Q_REENTRY;
+ if (hooks_wait(hooks, cmdq, NULL,
+ "before-%s", name) == 0)
+ return (CMD_RETURN_WAIT);
+ if (cmd_prepare_state(cmd, cmdq, cmdq->parent) != 0)
+ goto error;
+ }
+ } else
+ hooks = NULL;
+ cmdq->flags &= ~CMD_Q_REENTRY;
+
retval = cmd->entry->exec(cmd, cmdq);
if (retval == CMD_RETURN_ERROR)
goto error;
+ if (hooks != NULL && hooks_wait(hooks, cmdq, NULL,
+ "after-%s", name) == 0)
+ retval = CMD_RETURN_WAIT;
cmdq_guard(cmdq, "end", flags);
+
return (retval);
error:
cmdq_guard(cmdq, "error", flags);
+ cmdq->flags &= ~CMD_Q_REENTRY;
return (CMD_RETURN_ERROR);
}
@@ -232,11 +267,18 @@ cmdq_continue(struct cmd_q *cmdq)
if (empty)
goto empty;
- if (cmdq->item == NULL) {
- cmdq->item = TAILQ_FIRST(&cmdq->queue);
- cmdq->cmd = TAILQ_FIRST(&cmdq->item->cmdlist->list);
- } else
- cmdq->cmd = TAILQ_NEXT(cmdq->cmd, qentry);
+ /*
+ * If the command isn't in the middle of running hooks (due to
+ * CMD_RETURN_WAIT), move onto the next command; otherwise, leave the
+ * state of the queue as it is.
+ */
+ if (~cmdq->flags & CMD_Q_REENTRY) {
+ if (cmdq->item == NULL) {
+ cmdq->item = TAILQ_FIRST(&cmdq->queue);
+ cmdq->cmd = TAILQ_FIRST(&cmdq->item->cmdlist->list);
+ } else
+ cmdq->cmd = TAILQ_NEXT(cmdq->cmd, qentry);
+ }
do {
while (cmdq->cmd != NULL) {
diff --git a/usr.bin/tmux/cmd-source-file.c b/usr.bin/tmux/cmd-source-file.c
index 9255b5537df..31a1eaca606 100644
--- a/usr.bin/tmux/cmd-source-file.c
+++ b/usr.bin/tmux/cmd-source-file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-source-file.c,v 1.23 2015/12/13 21:53:57 nicm Exp $ */
+/* $OpenBSD: cmd-source-file.c,v 1.24 2016/04/29 14:05:24 nicm Exp $ */
/*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@@ -49,6 +49,7 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq)
char *cause;
cmdq1 = cmdq_new(cmdq->client);
+ cmdq1->flags |= cmdq->flags & CMD_Q_NOHOOKS;
cmdq1->emptyfn = cmd_source_file_done;
cmdq1->data = cmdq;
diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c
index 0e83446a345..241b3cb3be0 100644
--- a/usr.bin/tmux/format.c
+++ b/usr.bin/tmux/format.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: format.c,v 1.105 2016/01/31 09:54:46 nicm Exp $ */
+/* $OpenBSD: format.c,v 1.106 2016/04/29 14:05:24 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -468,6 +468,7 @@ struct format_tree *
format_create(struct cmd_q *cmdq, int flags)
{
struct format_tree *ft;
+ struct cmd *cmd;
if (!event_initialized(&format_job_event)) {
evtimer_set(&format_job_event, format_job_timer, NULL);
@@ -486,6 +487,10 @@ format_create(struct cmd_q *cmdq, int flags)
if (cmdq != NULL && cmdq->cmd != NULL)
format_add(ft, "command_name", "%s", cmdq->cmd->entry->name);
+ if (cmdq != NULL && cmdq->parent != NULL) {
+ cmd = cmdq->parent->cmd;
+ format_add(ft, "command_hooked", "%s", cmd->entry->name);
+ }
return (ft);
}
diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1
index 446eae31045..bd3cadc9ee7 100644
--- a/usr.bin/tmux/tmux.1
+++ b/usr.bin/tmux/tmux.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.482 2016/04/27 09:39:09 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.483 2016/04/29 14:05:24 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: April 27 2016 $
+.Dd $Mdocdate: April 29 2016 $
.Dt TMUX 1
.Os
.Sh NAME
@@ -3221,9 +3221,35 @@ shows only the option value, not the name.
.Nm
allows commands to run on various triggers, called
.Em hooks .
-Each hook has a
-.Em name .
-The following hooks are available:
+Each
+.Nm
+command has a
+.Em before
+hook and an
+.Em after
+hook and there are a number of hooks not associated with commands.
+.Pp
+A command's before hook is run before the command is executed and its after
+hook is run afterwards, except when the command is run as part of a hook
+itself.
+Before hooks are named using the
+.Ql before-
+prefix and after hooks the
+.Ql after-
+prefix.
+For example, the following command adds a hook to select the even-vertical
+layout after every
+.Ic split-window :
+.Bd -literal -offset indent
+set-hook after-split-window "selectl even-vertical"
+.Ed
+.Pp
+Or to write when each new window is created to a file:
+.Bd -literal -offset indent
+set-hook before-new-window 'run "date >>/tmp/log"'
+.Ed
+.Pp
+In addition, the following hooks are available:
.Bl -tag -width "XXXXXXXXXXXXXXXX"
.It alert-activity
Run when a window has activity.
@@ -3450,6 +3476,7 @@ The following variables are available, where appropriate:
.It Li "client_tty" Ta "" Ta "Pseudo terminal of client"
.It Li "client_utf8" Ta "" Ta "1 if client supports utf8"
.It Li "client_width" Ta "" Ta "Width of client"
+.It Li "command_hooked" Ta "" Ta "Name of command hooked, if any"
.It Li "command_name" Ta "" Ta "Name of command in use, if any"
.It Li "cursor_flag" Ta "" Ta "Pane cursor flag"
.It Li "cursor_x" Ta "" Ta "Cursor X position in pane"