summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2016-10-13 22:48:51 +0000
committernicm <nicm>2016-10-13 22:48:51 +0000
commit4289a1ebfa7479413ec5ac543b88c4ea039d00a0 (patch)
treed17862b06b8822aa1b8ab91d83e51a47e25e60e3
parent7a1a01feeff7b2ab17e2caef2d6b2180a8c1e70e (diff)
Trying to do hooks generically is way too complicated and unreliable and
confusing, particularly trying to automatically figure out what target hooks should be using. So simplify it: - drop before hooks entirely, they don't seem to be very useful; - commands with special requirements now fire their own after hook (for example, if they change session or window, or if they have -t and -s and need to choose which one the hook uses as current target); - commands with no special requirements can have the CMD_AFTERHOOK flag added and they will use the -t state. At the moment new-session, new-window, split-window fire their own hook, and display-message uses the flag. The remaining commands still need to be looked at.
-rw-r--r--cmd-display-message.c2
-rw-r--r--cmd-if-shell.c1
-rw-r--r--cmd-join-pane.c7
-rw-r--r--cmd-new-session.c7
-rw-r--r--cmd-new-window.c7
-rw-r--r--cmd-queue.c88
-rw-r--r--cmd-source-file.c1
-rw-r--r--cmd-split-window.c17
-rw-r--r--cmd-swap-pane.c7
-rw-r--r--cmd-swap-window.c7
-rw-r--r--hooks.c3
-rw-r--r--tmux.119
-rw-r--r--tmux.h4
13 files changed, 57 insertions, 113 deletions
diff --git a/cmd-display-message.c b/cmd-display-message.c
index 05e84561..74fa7804 100644
--- a/cmd-display-message.c
+++ b/cmd-display-message.c
@@ -45,7 +45,7 @@ const struct cmd_entry cmd_display_message_entry = {
.cflag = CMD_CLIENT_CANFAIL,
.tflag = CMD_PANE,
- .flags = 0,
+ .flags = CMD_AFTERHOOK,
.exec = cmd_display_message_exec
};
diff --git a/cmd-if-shell.c b/cmd-if-shell.c
index 615da2b6..2a8cbff2 100644
--- a/cmd-if-shell.c
+++ b/cmd-if-shell.c
@@ -165,7 +165,6 @@ 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/cmd-join-pane.c b/cmd-join-pane.c
index a337e728..3ff8f08e 100644
--- a/cmd-join-pane.c
+++ b/cmd-join-pane.c
@@ -156,12 +156,5 @@ cmd_join_pane_exec(struct cmd *self, struct cmd_q *cmdq)
notify_window_layout_changed(src_w);
notify_window_layout_changed(dst_w);
- cmd_find_clear_state(&cmdq->current, NULL, 0);
- cmdq->current.s = dst_s;
- cmdq->current.wl = dst_wl;
- cmdq->current.w = dst_w;
- cmdq->current.wp = dst_wp;
- cmd_find_log_state(__func__, &cmdq->current);
-
return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-new-session.c b/cmd-new-session.c
index 5292efcc..5924b793 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -80,6 +80,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
u_int sx, sy;
struct format_tree *ft;
struct environ_entry *envent;
+ struct cmd_find_state fs;
if (self->entry == &cmd_has_session_entry) {
/*
@@ -310,13 +311,15 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
format_free(ft);
}
- cmd_find_from_session(&cmdq->current, s);
-
if (!detached)
cmdq->client_exit = 0;
if (to_free != NULL)
free((void *)to_free);
+
+ cmd_find_from_session(&fs, s);
+ if (hooks_wait(s->hooks, cmdq, &fs, "after-new-session") == 0)
+ return (CMD_RETURN_WAIT);
return (CMD_RETURN_NORMAL);
error:
diff --git a/cmd-new-window.c b/cmd-new-window.c
index a8725ee1..4d0e0057 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -61,6 +61,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
int argc, detached;
struct format_tree *ft;
struct environ_entry *envent;
+ struct cmd_find_state fs;
if (args_has(args, 'a')) {
if ((idx = winlink_shuffle_up(s, wl)) == -1) {
@@ -152,10 +153,12 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
format_free(ft);
}
- cmd_find_from_winlink(&cmdq->current, s, wl);
-
if (to_free != NULL)
free((void *)to_free);
+
+ cmd_find_from_winlink(&fs, s, wl);
+ if (hooks_wait(s->hooks, cmdq, &fs, "after-new-window") == 0)
+ return (CMD_RETURN_WAIT);
return (CMD_RETURN_NORMAL);
error:
diff --git a/cmd-queue.c b/cmd-queue.c
index 2464eb17..8b28dd65 100644
--- a/cmd-queue.c
+++ b/cmd-queue.c
@@ -182,34 +182,16 @@ cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist, struct mouse_event *m)
item->mouse.valid = 0;
}
-/* Find hooks list. */
-static struct hooks *
-cmdq_get_hooks(struct cmd_q *cmdq)
-{
- struct session *s;
-
- 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)
- return (s->hooks);
- return (global_hooks);
-}
-
/* Process one command. */
static enum cmd_retval
cmdq_continue_one(struct cmd_q *cmdq)
{
- struct cmd *cmd = cmdq->cmd;
- const char *name = cmd->entry->name;
- struct hooks *hooks;
- enum cmd_retval retval;
- char *tmp;
- int flags = !!(cmd->flags & CMD_CONTROL);
+ struct cmd *cmd = cmdq->cmd;
+ enum cmd_retval retval;
+ char *tmp;
+ int flags = !!(cmd->flags & CMD_CONTROL);
+ const char *name;
+ struct cmd_find_state *fsp, fs;
tmp = cmd_print(cmd);
log_debug("cmdq %p: %s", cmdq, tmp);
@@ -218,44 +200,35 @@ cmdq_continue_one(struct cmd_q *cmdq)
cmdq->time = time(NULL);
cmdq->number++;
- if (~cmdq->flags & CMD_Q_REENTRY)
- cmdq_guard(cmdq, "begin", flags);
+ cmdq_guard(cmdq, "begin", flags);
if (cmd_prepare_state(cmd, cmdq, cmdq->parent) != 0)
goto error;
- if (~cmdq->flags & CMD_Q_NOHOOKS) {
- hooks = cmdq_get_hooks(cmdq);
- 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) {
- if (cmd_prepare_state(cmd, cmdq, cmdq->parent) != 0)
- goto error;
- hooks = cmdq_get_hooks(cmdq);
- if (hooks_wait(hooks, cmdq, NULL, "after-%s", name) == 0)
- retval = CMD_RETURN_WAIT;
+ if (~cmd->entry->flags & CMD_AFTERHOOK)
+ goto end;
+
+ if (cmd_find_valid_state(&cmdq->state.tflag))
+ fsp = &cmdq->state.tflag;
+ else {
+ if (cmd_find_current(&fs, cmdq, CMD_FIND_QUIET) != 0)
+ goto end;
+ fsp = &fs;
}
- cmdq_guard(cmdq, "end", flags);
+ name = cmd->entry->name;
+ if (hooks_wait(fsp->s->hooks, cmdq, fsp, "after-%s", name) == 0)
+ retval = CMD_RETURN_WAIT;
+end:
+ cmdq_guard(cmdq, "end", flags);
return (retval);
error:
cmdq_guard(cmdq, "error", flags);
- cmdq->flags &= ~CMD_Q_REENTRY;
return (CMD_RETURN_ERROR);
}
@@ -271,8 +244,6 @@ cmdq_continue(struct cmd_q *cmdq)
cmdq->references++;
notify_disable();
- cmd_find_clear_state(&cmdq->current, NULL, 0);
-
log_debug("continuing cmdq %p: flags %#x, client %p", cmdq, cmdq->flags,
c);
@@ -280,18 +251,11 @@ cmdq_continue(struct cmd_q *cmdq)
if (empty)
goto empty;
- /*
- * 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);
- }
+ 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/cmd-source-file.c b/cmd-source-file.c
index ef3ac7ac..0f299ddf 100644
--- a/cmd-source-file.c
+++ b/cmd-source-file.c
@@ -49,7 +49,6 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq)
int quiet;
cmdq1 = cmdq_new(cmdq->client);
- cmdq1->flags |= cmdq->flags & CMD_Q_NOHOOKS;
cmdq1->emptyfn = cmd_source_file_done;
cmdq1->data = cmdq;
diff --git a/cmd-split-window.c b/cmd-split-window.c
index b09a5109..41a53c63 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -66,6 +66,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct layout_cell *lc;
struct format_tree *ft;
struct environ_entry *envent;
+ struct cmd_find_state fs;
server_unzoom_window(w);
@@ -178,15 +179,17 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
notify_window_layout_changed(w);
- cmd_find_clear_state(&cmdq->current, NULL, 0);
- cmdq->current.s = s;
- cmdq->current.wl = wl;
- cmdq->current.w = wl->window;
- cmdq->current.wp = new_wp;
- cmd_find_log_state(__func__, &cmdq->current);
-
if (to_free != NULL)
free((void *)to_free);
+
+ cmd_find_clear_state(&fs, NULL, 0);
+ fs.s = s;
+ fs.wl = wl;
+ fs.w = w;
+ fs.wp = new_wp;
+ cmd_find_log_state(__func__, &fs);
+ if (hooks_wait(s->hooks, cmdq, &fs, "after-split-window") == 0)
+ return (CMD_RETURN_WAIT);
return (CMD_RETURN_NORMAL);
error:
diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c
index 2568ac01..e5f5c810 100644
--- a/cmd-swap-pane.c
+++ b/cmd-swap-pane.c
@@ -124,12 +124,5 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
server_redraw_window(src_w);
server_redraw_window(dst_w);
- cmd_find_clear_state(&cmdq->current, NULL, 0);
- cmdq->current.s = cmdq->state.tflag.s;
- cmdq->current.wl = cmdq->state.tflag.wl;
- cmdq->current.w = dst_w;
- cmdq->current.wp = src_wp;
- cmd_find_log_state(__func__, &cmdq->current);
-
return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-swap-window.c b/cmd-swap-window.c
index 2d2767c4..904a974d 100644
--- a/cmd-swap-window.c
+++ b/cmd-swap-window.c
@@ -84,12 +84,5 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
recalculate_sizes();
- cmd_find_clear_state(&cmdq->current, NULL, 0);
- cmdq->current.s = dst;
- cmdq->current.wl = wl_dst;
- cmdq->current.w = wl_dst->window;
- cmdq->current.wp = cmdq->state.sflag.wp;
- cmd_find_log_state(__func__, &cmdq->current);
-
return (CMD_RETURN_NORMAL);
}
diff --git a/hooks.c b/hooks.c
index 62ea05d1..2e0126b7 100644
--- a/hooks.c
+++ b/hooks.c
@@ -196,6 +196,9 @@ hooks_wait(struct hooks *hooks, struct cmd_q *cmdq, struct cmd_find_state *fs,
va_list ap;
char *name;
+ if (cmdq->flags & CMD_Q_NOHOOKS)
+ return (-1);
+
va_start(ap, fmt);
xvasprintf(&name, fmt, ap);
va_end(ap);
diff --git a/tmux.1 b/tmux.1
index f3e7e26d..bb90bc9f 100644
--- a/tmux.1
+++ b/tmux.1
@@ -3204,20 +3204,16 @@ shows only the option value, not the name.
.Nm
allows commands to run on various triggers, called
.Em hooks .
-Each
+Most
.Nm
-command has a
-.Em before
-hook and an
+commands have 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
+A command's after
+hook is run after it completes, 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
+They are named with an
.Ql after-
prefix.
For example, the following command adds a hook to select the even-vertical
@@ -3227,11 +3223,6 @@ layout after every
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
diff --git a/tmux.h b/tmux.h
index 2a271ec5..3f29f07f 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1339,8 +1339,7 @@ struct cmd_q {
int references;
int flags;
#define CMD_Q_DEAD 0x1
-#define CMD_Q_REENTRY 0x2
-#define CMD_Q_NOHOOKS 0x4
+#define CMD_Q_NOHOOKS 0x2
struct client *client;
int client_exit;
@@ -1404,6 +1403,7 @@ struct cmd_entry {
#define CMD_STARTSERVER 0x1
#define CMD_READONLY 0x2
+#define CMD_AFTERHOOK 0x4
int flags;
enum cmd_retval (*exec)(struct cmd *, struct cmd_q *);