From 5b18d37032bec29baa94581fb9ef88aa7424dc8b Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 13 Oct 2016 22:48:52 +0000 Subject: 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. --- usr.bin/tmux/cmd-display-message.c | 4 +- usr.bin/tmux/cmd-if-shell.c | 3 +- usr.bin/tmux/cmd-join-pane.c | 9 +--- usr.bin/tmux/cmd-new-session.c | 9 ++-- usr.bin/tmux/cmd-new-window.c | 9 ++-- usr.bin/tmux/cmd-queue.c | 90 ++++++++++++-------------------------- usr.bin/tmux/cmd-source-file.c | 3 +- usr.bin/tmux/cmd-split-window.c | 19 ++++---- usr.bin/tmux/cmd-swap-pane.c | 9 +--- usr.bin/tmux/cmd-swap-window.c | 9 +--- usr.bin/tmux/hooks.c | 5 ++- usr.bin/tmux/tmux.1 | 21 +++------ usr.bin/tmux/tmux.h | 6 +-- 13 files changed, 70 insertions(+), 126 deletions(-) (limited to 'usr.bin') diff --git a/usr.bin/tmux/cmd-display-message.c b/usr.bin/tmux/cmd-display-message.c index f19bf5548d7..9704f251130 100644 --- a/usr.bin/tmux/cmd-display-message.c +++ b/usr.bin/tmux/cmd-display-message.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-display-message.c,v 1.37 2016/10/10 21:51:39 nicm Exp $ */ +/* $OpenBSD: cmd-display-message.c,v 1.38 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha @@ -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/usr.bin/tmux/cmd-if-shell.c b/usr.bin/tmux/cmd-if-shell.c index e3ac8d0b825..b29f045a1ed 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.45 2016/10/10 21:51:39 nicm Exp $ */ +/* $OpenBSD: cmd-if-shell.c,v 1.46 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha @@ -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/usr.bin/tmux/cmd-join-pane.c b/usr.bin/tmux/cmd-join-pane.c index 30ff89dcb82..0d3e114cfbd 100644 --- a/usr.bin/tmux/cmd-join-pane.c +++ b/usr.bin/tmux/cmd-join-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-join-pane.c,v 1.27 2016/10/13 10:01:49 nicm Exp $ */ +/* $OpenBSD: cmd-join-pane.c,v 1.28 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2011 George Nachman @@ -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/usr.bin/tmux/cmd-new-session.c b/usr.bin/tmux/cmd-new-session.c index bc5b21b226b..3a6608b0c2b 100644 --- a/usr.bin/tmux/cmd-new-session.c +++ b/usr.bin/tmux/cmd-new-session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-new-session.c,v 1.89 2016/10/13 10:01:49 nicm Exp $ */ +/* $OpenBSD: cmd-new-session.c,v 1.90 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -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/usr.bin/tmux/cmd-new-window.c b/usr.bin/tmux/cmd-new-window.c index 6c5b2ae8cbe..73f62d01743 100644 --- a/usr.bin/tmux/cmd-new-window.c +++ b/usr.bin/tmux/cmd-new-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-new-window.c,v 1.61 2016/10/13 10:01:49 nicm Exp $ */ +/* $OpenBSD: cmd-new-window.c,v 1.62 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -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/usr.bin/tmux/cmd-queue.c b/usr.bin/tmux/cmd-queue.c index b976e984546..aefc1a3ddd5 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.39 2016/10/13 10:01:49 nicm Exp $ */ +/* $OpenBSD: cmd-queue.c,v 1.40 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2013 Nicholas Marriott @@ -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/usr.bin/tmux/cmd-source-file.c b/usr.bin/tmux/cmd-source-file.c index 233bb30ec57..ec95314f2aa 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.26 2016/10/10 21:51:39 nicm Exp $ */ +/* $OpenBSD: cmd-source-file.c,v 1.27 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2008 Tiago Cunha @@ -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/usr.bin/tmux/cmd-split-window.c b/usr.bin/tmux/cmd-split-window.c index f34586fcdbb..f42e6428ead 100644 --- a/usr.bin/tmux/cmd-split-window.c +++ b/usr.bin/tmux/cmd-split-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-split-window.c,v 1.72 2016/10/13 10:01:49 nicm Exp $ */ +/* $OpenBSD: cmd-split-window.c,v 1.73 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -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/usr.bin/tmux/cmd-swap-pane.c b/usr.bin/tmux/cmd-swap-pane.c index 56404a91700..4702d7312b9 100644 --- a/usr.bin/tmux/cmd-swap-pane.c +++ b/usr.bin/tmux/cmd-swap-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-swap-pane.c,v 1.28 2016/10/13 10:01:49 nicm Exp $ */ +/* $OpenBSD: cmd-swap-pane.c,v 1.29 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -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/usr.bin/tmux/cmd-swap-window.c b/usr.bin/tmux/cmd-swap-window.c index 255a5684914..adc94b07aa9 100644 --- a/usr.bin/tmux/cmd-swap-window.c +++ b/usr.bin/tmux/cmd-swap-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-swap-window.c,v 1.18 2016/10/13 10:01:49 nicm Exp $ */ +/* $OpenBSD: cmd-swap-window.c,v 1.19 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -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/usr.bin/tmux/hooks.c b/usr.bin/tmux/hooks.c index ca45395acdd..5b51a0065c9 100644 --- a/usr.bin/tmux/hooks.c +++ b/usr.bin/tmux/hooks.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hooks.c,v 1.5 2016/10/10 21:29:23 nicm Exp $ */ +/* $OpenBSD: hooks.c,v 1.6 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2012 Thomas Adam @@ -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/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 87d4a016b4c..c2915f99743 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.504 2016/10/13 21:37:03 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.505 2016/10/13 22:48:51 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -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/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index f3b2d3878c4..86a2f6036d6 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.661 2016/10/13 20:27:27 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.662 2016/10/13 22:48:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -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 *); -- cgit v1.2.3