The branch, hooks has been updated
  discards  8e2cab16cbca65ccb25a79068f32e24436a7aae5 (commit)
  discards  aefdd9c368013008a566257bc99d4bdde4c65f65 (commit)
  discards  9178a39f431d89d8c30307f9a5843986fa743fa4 (commit)
  discards  d9bec8233a3f3dd44795efb2d8a93255a0856a56 (commit)
  discards  1bb3aa6f7ea481412adcde41ba228b564a245123 (commit)
  discards  5c2831bcf2f265065d3e0bb18ad51f7e754e5060 (commit)
  discards  2103ae2e24a53668f9ca003d2b28f6f3c1eaa02f (commit)
       via  91e9eefdf5beb53fd39c15253039e2d196c557a8 (commit)
       via  9b8982f472a55c3cd44c3f5b00522ccfc995abce (commit)
       via  574c60e83f44f85782b464b8e935df88aa762b3b (commit)
       via  51233d8b2a8509405856439f11e7a60d08da8335 (commit)
       via  68429cd0d3ebfa0a721814b097f03d95d532580c (commit)
       via  df6488a47088ec8bcddc6a1cfa85fec1a462c789 (commit)
       via  776eef49d8e13b227d25e5d56d4c379b89c4aacb (commit)
       via  6e764fb53e7665d723d0ac58ec32c5b608f9c713 (commit)
       via  86207ee676af4fc64f6e289d824460800f43194e (commit)
       via  66e8811c64a833b759511b3f7309e834155a8442 (commit)
       via  a9644c1f8bf28b7c27edca1d8c85275ae6f89509 (commit)
       via  8a8e2eb04aa03bd1b8f4a515fc1d7e50a35acb44 (commit)
       via  da72a0b7a8b1f893fd25cfdacef9be7dffa61989 (commit)
       via  aae2b7aa89b80ec6b07a8036f923dc6c8882cfae (commit)
       via  fee096a40680dff40557f016b5904b3dfbf9072c (commit)
       via  be0ad01b7c4d9d7948d9c9595ff2a4af3af68793 (commit)
       via  daea0e4fff77e63ea05392b67d96606c5e7b3ecc (commit)
       via  cc1bc9717c19091e3a89a0cf28b902a23d85b84f (commit)
       via  9cb5afe114c035a7412b58d65dc39c16f3b72ff5 (commit)
       via  2a9a75a569f6932afeb00d7506f370c4044d5eea (commit)
       via  5f8138faf551c3678de3c92c5764e2e7edfc4602 (commit)
       via  160e3e2be3543377925551146403933a7c631f51 (commit)
       via  d88c381ce912dfc48fc2d53ed020bf2016f4b509 (commit)
       via  f495b150fa06cf0556159fe15e0dd2e0a09bb445 (commit)
       via  3771ab7c67ed002faa980b353bcc858669131b58 (commit)
       via  7a0c94b28ab96d32dcbd98cfad54662f67875332 (commit)
       via  32f1ceddc9d2e58655daf42e952989eb8561c8a3 (commit)

This update added new revisions after undoing existing revisions.  That is
to say, the old revision is not a strict subset of the new revision.  This
situation occurs when you --force push a change and generate a repository
containing something like this:

 * -- * -- B -- O -- O -- O (8e2cab16cbca65ccb25a79068f32e24436a7aae5)
            \
             N -- N -- N (91e9eefdf5beb53fd39c15253039e2d196c557a8)

When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.

- Log -----------------------------------------------------------------
commit 91e9eefdf5beb53fd39c15253039e2d196c557a8
Author: Thomas Adam <tho...@xteddy.org>
Commit: Thomas Adam <tho...@xteddy.org>

    Commands: Make use of prepare
    
    Switch over all tmux commands to make use of prepare.
---
 cmd-attach-session.c   |   11 ++++++--
 cmd-bind-key.c         |    3 +-
 cmd-break-pane.c       |    9 +++++--
 cmd-capture-pane.c     |    7 +++--
 cmd-choose-buffer.c    |    9 ++++---
 cmd-choose-client.c    |   10 +++++---
 cmd-choose-tree.c      |   22 +++++++++++------
 cmd-clear-history.c    |   11 +++++----
 cmd-clock-mode.c       |   10 ++++----
 cmd-command-prompt.c   |    7 +++--
 cmd-confirm-before.c   |    7 +++--
 cmd-copy-mode.c        |    8 +++---
 cmd-delete-buffer.c    |    3 +-
 cmd-detach-client.c    |   28 ++++++++++++++++------
 cmd-display-message.c  |   42 +++++++++++++++++++++++----------
 cmd-display-panes.c    |   10 ++++----
 cmd-find-window.c      |    9 ++++---
 cmd-has-session.c      |   11 ++++-----
 cmd-if-shell.c         |   34 +++++++++++++++++++--------
 cmd-join-pane.c        |   31 ++++++++++++++++++------
 cmd-kill-pane.c        |   10 +++++---
 cmd-kill-server.c      |    6 +++-
 cmd-kill-session.c     |    8 ++++--
 cmd-kill-window.c      |   12 +++++----
 cmd-list-buffers.c     |    3 +-
 cmd-list-clients.c     |   14 +++++------
 cmd-list-keys.c        |    6 +++-
 cmd-list-panes.c       |   25 ++++++++++++++++----
 cmd-list-sessions.c    |    3 +-
 cmd-list-windows.c     |   18 +++++++++++---
 cmd-load-buffer.c      |    3 +-
 cmd-lock-server.c      |   28 ++++++++++++++++------
 cmd-move-window.c      |   33 +++++++++++++++++++++-----
 cmd-new-session.c      |    6 +++-
 cmd-new-window.c       |   25 +++++++++++++++-----
 cmd-paste-buffer.c     |   10 +++++---
 cmd-pipe-pane.c        |    8 ++++--
 cmd-queue.c            |   59 ++++++++++++++++++++++++++++++++++++++++++++++++
 cmd-refresh-client.c   |    7 +++--
 cmd-rename-session.c   |    8 ++++--
 cmd-rename-window.c    |    9 ++++---
 cmd-resize-pane.c      |    8 ++++--
 cmd-respawn-pane.c     |    9 +++++--
 cmd-respawn-window.c   |    8 ++++--
 cmd-rotate-window.c    |    8 +++---
 cmd-run-shell.c        |   17 +++++--------
 cmd-save-buffer.c      |    6 +++-
 cmd-select-layout.c    |   17 ++++++++-----
 cmd-select-pane.c      |   31 +++++++++++++++++++-----
 cmd-select-window.c    |   52 +++++++++++++++++++++++++++++++----------
 cmd-send-keys.c        |   15 ++++++++----
 cmd-set-buffer.c       |    3 +-
 cmd-set-environment.c  |    8 ++++--
 cmd-set-option.c       |    6 +++-
 cmd-show-environment.c |    8 ++++--
 cmd-show-messages.c    |   12 +++++----
 cmd-show-options.c     |   28 +++++++++++++++++-----
 cmd-source-file.c      |    3 +-
 cmd-split-window.c     |   13 +++++++---
 cmd-swap-pane.c        |    9 ++++---
 cmd-swap-window.c      |   27 +++++++++++++++------
 cmd-switch-client.c    |   20 +++++++++++++--
 cmd-unbind-key.c       |    3 +-
 cmd-wait-for.c         |    3 +-
 64 files changed, 620 insertions(+), 277 deletions(-)

diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index 160f2a8..6a469a9 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -31,13 +31,15 @@
  */
 
 enum cmd_retval        cmd_attach_session_exec(struct cmd *, struct cmd_q *);
+void           cmd_attach_session_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_attach_session_entry = {
        "attach-session", "attach",
        "c:drt:", 0, 0,
        "[-dr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
-       CMD_CANTNEST|CMD_STARTSERVER,
-       cmd_attach_session_exec
+       CMD_CANTNEST|CMD_STARTSERVER|CMD_PREPARESESSION,
+       cmd_attach_session_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -76,6 +78,9 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int 
dflag, int rflag,
                if (w != NULL)
                        wl = winlink_find_by_window(&s->windows, w);
        }
+       /* TA:  Likely broken! */
+       if ((s = cmdq->state.s) == NULL)
+               return (CMD_RETURN_ERROR);
 
        if (cmdq->client == NULL)
                return (CMD_RETURN_NORMAL);
@@ -190,5 +195,5 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_q 
*cmdq)
        struct args     *args = self->args;
 
        return (cmd_attach_session(cmdq, args_get(args, 't'),
-           args_has(args, 'd'), args_has(args, 'r'), args_get(args, 'c')));
+               args_has(args, 'd'), args_has(args, 'r'), args_get(args, 'c')));
 }
diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index 5d68d48..6eda84d 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -36,7 +36,8 @@ const struct cmd_entry cmd_bind_key_entry = {
        "cnrt:", 1, -1,
        "[-cnr] [-t mode-table] key command [arguments]",
        0,
-       cmd_bind_key_exec
+       cmd_bind_key_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-break-pane.c b/cmd-break-pane.c
index 0025167..c2f2ea1 100644
--- a/cmd-break-pane.c
+++ b/cmd-break-pane.c
@@ -34,8 +34,9 @@ const struct cmd_entry cmd_break_pane_entry = {
        "break-pane", "breakp",
        "dPF:t:", 0, 0,
        "[-dP] [-F format] " CMD_TARGET_PANE_USAGE,
-       0,
-       cmd_break_pane_exec
+       CMD_PREPAREPANE,
+       cmd_break_pane_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -54,8 +55,10 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
        const char              *template;
        char                    *cp;
 
-       if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
+       wp = cmdq->state.wp;
+       s = cmdq->state.s;
 
        if (window_count_panes(wl->window) == 1) {
                cmdq_error(cmdq, "can't break with only one pane");
diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c
index ce60b4c..74a2dc1 100644
--- a/cmd-capture-pane.c
+++ b/cmd-capture-pane.c
@@ -40,8 +40,9 @@ const struct cmd_entry cmd_capture_pane_entry = {
        "ab:CeE:JpPqS:t:", 0, 0,
        "[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] [-S start-line]"
        CMD_TARGET_PANE_USAGE,
-       0,
-       cmd_capture_pane_exec
+       CMD_PREPAREPANE,
+       cmd_capture_pane_exec,
+       NULL
 };
 
 char *
@@ -178,7 +179,7 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
        const char              *bufname;
        size_t                   len;
 
-       if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
+       if ((wp = cmdq->state.wp) == NULL)
                return (CMD_RETURN_ERROR);
 
        len = 0;
diff --git a/cmd-choose-buffer.c b/cmd-choose-buffer.c
index 19f5fba..674ad82 100644
--- a/cmd-choose-buffer.c
+++ b/cmd-choose-buffer.c
@@ -36,8 +36,9 @@ const struct cmd_entry cmd_choose_buffer_entry = {
        "choose-buffer", NULL,
        "F:t:", 0, 1,
        CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
-       0,
-       cmd_choose_buffer_exec
+       CMD_PREPAREWINDOW,
+       cmd_choose_buffer_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -53,7 +54,7 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
        u_int                            idx;
        int                              utf8flag;
 
-       if ((c = cmd_current_client(cmdq)) == NULL) {
+       if ((c = cmdq->state.c) == NULL) {
                cmdq_error(cmdq, "no client available");
                return (CMD_RETURN_ERROR);
        }
@@ -61,7 +62,7 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
        if ((template = args_get(args, 'F')) == NULL)
                template = CHOOSE_BUFFER_TEMPLATE;
 
-       if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
        utf8flag = options_get_number(&wl->window->options, "utf8");
 
diff --git a/cmd-choose-client.c b/cmd-choose-client.c
index 5a1892f..f3237b2 100644
--- a/cmd-choose-client.c
+++ b/cmd-choose-client.c
@@ -34,6 +34,7 @@
        "(last used #{client_activity_string})"
 
 enum cmd_retval         cmd_choose_client_exec(struct cmd *, struct cmd_q *);
+void            cmd_choose_client_prepare(struct cmd *, struct cmd_q *);
 
 void   cmd_choose_client_callback(struct window_choose_data *);
 
@@ -41,8 +42,9 @@ const struct cmd_entry cmd_choose_client_entry = {
        "choose-client", NULL,
        "F:t:", 0, 1,
        CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
-       0,
-       cmd_choose_client_exec
+       CMD_PREPAREWINDOW,
+       cmd_choose_client_exec,
+       NULL
 };
 
 struct cmd_choose_client_data {
@@ -61,12 +63,12 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
        char                            *action;
        u_int                            i, idx, cur;
 
-       if ((c = cmd_current_client(cmdq)) == NULL) {
+       if ((c = cmdq->state.c) == NULL) {
                cmdq_error(cmdq, "no client available");
                return (CMD_RETURN_ERROR);
        }
 
-       if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
 
        if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c
index 823d042..4be9f6c 100644
--- a/cmd-choose-tree.c
+++ b/cmd-choose-tree.c
@@ -48,24 +48,27 @@ const struct cmd_entry cmd_choose_tree_entry = {
        "S:W:swub:c:t:", 0, 1,
        "[-suw] [-b session-template] [-c window template] [-S format] " \
        "[-W format] " CMD_TARGET_WINDOW_USAGE,
-       0,
-       cmd_choose_tree_exec
+       CMD_PREPAREWINDOW,
+       cmd_choose_tree_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_choose_session_entry = {
        "choose-session", NULL,
        "F:t:", 0, 1,
        CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
-       0,
-       cmd_choose_tree_exec
+       CMD_PREPAREWINDOW,
+       cmd_choose_tree_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_choose_window_entry = {
        "choose-window", NULL,
        "F:t:", 0, 1,
        CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
-       0,
-       cmd_choose_tree_exec
+       CMD_PREPAREWINDOW,
+       cmd_choose_tree_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -87,12 +90,15 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_q *cmdq)
        ses_template = win_template = NULL;
        ses_action = win_action = NULL;
 
-       if ((c = cmd_current_client(cmdq)) == NULL) {
+       if ((c = cmdq->state.c) == NULL) {
                cmdq_error(cmdq, "no client available");
                return (CMD_RETURN_ERROR);
        }
 
-       if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
+       if ((s = cmdq->state.c->session) == NULL)
+               return (CMD_RETURN_ERROR);
+
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
 
        if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
diff --git a/cmd-clear-history.c b/cmd-clear-history.c
index e134288..e345238 100644
--- a/cmd-clear-history.c
+++ b/cmd-clear-history.c
@@ -25,23 +25,24 @@
  */
 
 enum cmd_retval         cmd_clear_history_exec(struct cmd *, struct cmd_q *);
+void            cmd_clear_history_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_clear_history_entry = {
        "clear-history", "clearhist",
        "t:", 0, 0,
        CMD_TARGET_PANE_USAGE,
-       0,
-       cmd_clear_history_exec
+       CMD_PREPAREPANE,
+       cmd_clear_history_exec,
+       NULL
 };
 
 enum cmd_retval
-cmd_clear_history_exec(struct cmd *self, struct cmd_q *cmdq)
+cmd_clear_history_exec(unused struct cmd *self, struct cmd_q *cmdq)
 {
-       struct args             *args = self->args;
        struct window_pane      *wp;
        struct grid             *gd;
 
-       if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
+       if ((wp = cmdq->state.wp) == NULL)
                return (CMD_RETURN_ERROR);
        gd = wp->base.grid;
 
diff --git a/cmd-clock-mode.c b/cmd-clock-mode.c
index 8083581..32e8d47 100644
--- a/cmd-clock-mode.c
+++ b/cmd-clock-mode.c
@@ -30,17 +30,17 @@ const struct cmd_entry cmd_clock_mode_entry = {
        "clock-mode", NULL,
        "t:", 0, 0,
        CMD_TARGET_PANE_USAGE,
-       0,
-       cmd_clock_mode_exec
+       CMD_PREPAREPANE,
+       cmd_clock_mode_exec,
+       NULL
 };
 
 enum cmd_retval
-cmd_clock_mode_exec(struct cmd *self, struct cmd_q *cmdq)
+cmd_clock_mode_exec(unused struct cmd *self, struct cmd_q *cmdq)
 {
-       struct args             *args = self->args;
        struct window_pane      *wp;
 
-       if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
+       if ((wp = cmdq->state.wp) == NULL)
                return (CMD_RETURN_ERROR);
 
        window_pane_set_mode(wp, &window_clock_mode);
diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c
index 22b1d84..7f66fc4 100644
--- a/cmd-command-prompt.c
+++ b/cmd-command-prompt.c
@@ -38,8 +38,9 @@ const struct cmd_entry cmd_command_prompt_entry = {
        "command-prompt", NULL,
        "I:p:t:", 0, 1,
        "[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " [template]",
-       0,
-       cmd_command_prompt_exec
+       CMD_PREPARECLIENT,
+       cmd_command_prompt_exec,
+       NULL
 };
 
 struct cmd_command_prompt_cdata {
@@ -62,7 +63,7 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_q *cmdq)
        char                            *prompt, *ptr, *input = NULL;
        size_t                           n;
 
-       if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+       if ((c = cmdq->state.c) == NULL)
                return (CMD_RETURN_ERROR);
 
        if (c->prompt_string != NULL)
diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c
index 0bf5844..d5ecd8b 100644
--- a/cmd-confirm-before.c
+++ b/cmd-confirm-before.c
@@ -37,8 +37,9 @@ const struct cmd_entry cmd_confirm_before_entry = {
        "confirm-before", "confirm",
        "p:t:", 1, 1,
        "[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
-       0,
-       cmd_confirm_before_exec
+       CMD_PREPARECLIENT,
+       cmd_confirm_before_exec,
+       NULL
 };
 
 struct cmd_confirm_before_data {
@@ -55,7 +56,7 @@ cmd_confirm_before_exec(struct cmd *self, struct cmd_q *cmdq)
        char                            *cmd, *copy, *new_prompt, *ptr;
        const char                      *prompt;
 
-       if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+       if ((c = cmdq->state.c) == NULL)
                return (CMD_RETURN_ERROR);
 
        if ((prompt = args_get(args, 'p')) != NULL)
diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c
index 8933529..c06967d 100644
--- a/cmd-copy-mode.c
+++ b/cmd-copy-mode.c
@@ -30,17 +30,17 @@ const struct cmd_entry cmd_copy_mode_entry = {
        "copy-mode", NULL,
        "t:u", 0, 0,
        "[-u] " CMD_TARGET_PANE_USAGE,
-       0,
-       cmd_copy_mode_exec
+       CMD_PREPAREPANE,
+       cmd_copy_mode_exec,
+       NULL
 };
 
 enum cmd_retval
 cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq)
 {
-       struct args             *args = self->args;
        struct window_pane      *wp;
 
-       if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
+       if ((wp = cmdq->state.wp) == NULL)
                return (CMD_RETURN_ERROR);
 
        if (wp->mode != &window_copy_mode) {
diff --git a/cmd-delete-buffer.c b/cmd-delete-buffer.c
index 42268b7..a7a6dc7 100644
--- a/cmd-delete-buffer.c
+++ b/cmd-delete-buffer.c
@@ -33,7 +33,8 @@ const struct cmd_entry cmd_delete_buffer_entry = {
        "b:", 0, 0,
        CMD_BUFFER_USAGE,
        0,
-       cmd_delete_buffer_exec
+       cmd_delete_buffer_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-detach-client.c b/cmd-detach-client.c
index 600554a..cd11542 100644
--- a/cmd-detach-client.c
+++ b/cmd-detach-client.c
@@ -27,23 +27,37 @@
  */
 
 enum cmd_retval         cmd_detach_client_exec(struct cmd *, struct cmd_q *);
+void            cmd_detach_client_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_detach_client_entry = {
        "detach-client", "detach",
        "as:t:P", 0, 0,
        "[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE,
-       CMD_READONLY,
-       cmd_detach_client_exec
+       CMD_READONLY|CMD_PREPARECLIENT|CMD_PREPARESESSION,
+       cmd_detach_client_exec,
+       cmd_detach_client_prepare
 };
 
 const struct cmd_entry cmd_suspend_client_entry = {
        "suspend-client", "suspendc",
        "t:", 0, 0,
        CMD_TARGET_CLIENT_USAGE,
-       0,
-       cmd_detach_client_exec
+       CMD_PREPARECLIENT,
+       cmd_detach_client_exec,
+       cmd_detach_client_prepare
 };
 
+void
+cmd_detach_client_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       if (args_has(args, 's'))
+               cmdq->state.s = cmd_find_session(cmdq, args_get(args, 's'), 0);
+       else
+               cmdq->state.c = cmd_find_client(cmdq, args_get(args, 't'), 0);
+}
+
 enum cmd_retval
 cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
 {
@@ -68,8 +82,7 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
                msgtype = MSG_DETACH;
 
        if (args_has(args, 's')) {
-               s = cmd_find_session(cmdq, args_get(args, 's'), 0);
-               if (s == NULL)
+               if ((s = cmdq->state.s) == NULL)
                        return (CMD_RETURN_ERROR);
 
                for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -80,8 +93,7 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
                            strlen(c->session->name) + 1);
                }
        } else {
-               c = cmd_find_client(cmdq, args_get(args, 't'), 0);
-               if (c == NULL)
+               if ((c = cmdq->state.c) == NULL)
                        return (CMD_RETURN_ERROR);
 
                if (args_has(args, 'a')) {
diff --git a/cmd-display-message.c b/cmd-display-message.c
index f3547b0..226d159 100644
--- a/cmd-display-message.c
+++ b/cmd-display-message.c
@@ -33,16 +33,37 @@
        "- (%H:%M %d-%b-%y)"
 
 enum cmd_retval         cmd_display_message_exec(struct cmd *, struct cmd_q *);
+void            cmd_display_message_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_display_message_entry = {
        "display-message", "display",
        "c:pt:F:", 0, 1,
        "[-p] [-c target-client] [-F format] " CMD_TARGET_PANE_USAGE
        " [message]",
-       0,
-       cmd_display_message_exec
+       CMD_PREPAREWINDOW|CMD_PREPARECLIENT,
+       cmd_display_message_exec,
+       cmd_display_message_prepare
 };
 
+void
+cmd_display_message_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       if (args_has(args, 't')) {
+               cmdq->state.wl = cmd_find_pane(cmdq, args_get(args, 't'),
+                   &cmdq->state.s, &cmdq->state.wp);
+       } else {
+               cmdq->state.wl = cmd_find_pane(cmdq, NULL, &cmdq->state.s,
+                   &cmdq->state.wp);
+       }
+
+       if (args_has(args, 'c'))
+               cmdq->state.c = cmd_find_client(cmdq, args_get(args, 'c'), 0);
+       else
+               cmdq->state.c = cmd_current_client(cmdq);
+}
+
 enum cmd_retval
 cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq)
 {
@@ -58,27 +79,22 @@ cmd_display_message_exec(struct cmd *self, struct cmd_q 
*cmdq)
        time_t                   t;
        size_t                   len;
 
-       if (args_has(args, 't')) {
-               wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
-               if (wl == NULL)
-                       return (CMD_RETURN_ERROR);
-       } else {
-               wl = cmd_find_pane(cmdq, NULL, &s, &wp);
-               if (wl == NULL)
-                       return (CMD_RETURN_ERROR);
-       }
+       if ((wl = cmdq->state.wl) == NULL)
+               return (CMD_RETURN_ERROR);
+
+       wp = cmdq->state.wp;
+       s = cmdq->state.s;
 
        if (args_has(args, 'F') && args->argc != 0) {
                cmdq_error(cmdq, "only one of -F or argument must be given");
                return (CMD_RETURN_ERROR);
        }
 
+       c = cmdq->state.c;
        if (args_has(args, 'c')) {
-               c = cmd_find_client(cmdq, args_get(args, 'c'), 0);
                if (c == NULL)
                        return (CMD_RETURN_ERROR);
        } else {
-               c = cmd_current_client(cmdq);
                if (c == NULL && !args_has(self->args, 'p')) {
                        cmdq_error(cmdq, "no client available");
                        return (CMD_RETURN_ERROR);
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 9ce8971..8b9cf58 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -30,17 +30,17 @@ const struct cmd_entry cmd_display_panes_entry = {
        "display-panes", "displayp",
        "t:", 0, 0,
        CMD_TARGET_CLIENT_USAGE,
-       0,
-       cmd_display_panes_exec
+       CMD_PREPARECLIENT,
+       cmd_display_panes_exec,
+       NULL
 };
 
 enum cmd_retval
-cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
+cmd_display_panes_exec(unused struct cmd *self, struct cmd_q *cmdq)
 {
-       struct args     *args = self->args;
        struct client   *c;
 
-       if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+       if ((c = cmdq->state.c) == NULL)
                return (CMD_RETURN_ERROR);
 
        server_set_identify(c);
diff --git a/cmd-find-window.c b/cmd-find-window.c
index 88e4879..7273633 100644
--- a/cmd-find-window.c
+++ b/cmd-find-window.c
@@ -51,8 +51,9 @@ const struct cmd_entry cmd_find_window_entry = {
        "find-window", "findw",
        "F:CNt:T", 1, 4,
        "[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string",
-       0,
-       cmd_find_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_find_window_exec,
+       NULL
 };
 
 struct cmd_find_window_data {
@@ -143,13 +144,13 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
        const char                      *template;
        u_int                            i, match_flags;
 
-       if ((c = cmd_current_client(cmdq)) == NULL) {
+       if ((c = cmdq->state.c) == NULL) {
                cmdq_error(cmdq, "no client available");
                return (CMD_RETURN_ERROR);
        }
        s = c->session;
 
-       if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
 
        if ((template = args_get(args, 'F')) == NULL)
diff --git a/cmd-has-session.c b/cmd-has-session.c
index a873b20..78a62f7 100644
--- a/cmd-has-session.c
+++ b/cmd-has-session.c
@@ -30,16 +30,15 @@ const struct cmd_entry cmd_has_session_entry = {
        "has-session", "has",
        "t:", 0, 0,
        CMD_TARGET_SESSION_USAGE,
-       0,
-       cmd_has_session_exec
+       CMD_PREPAREWINDOW,
+       cmd_has_session_exec,
+       NULL
 };
 
 enum cmd_retval
-cmd_has_session_exec(struct cmd *self, struct cmd_q *cmdq)
+cmd_has_session_exec(unused struct cmd *self, struct cmd_q *cmdq)
 {
-       struct args     *args = self->args;
-
-       if (cmd_find_session(cmdq, args_get(args, 't'), 0) == NULL)
+       if (cmdq->state.s == NULL)
                return (CMD_RETURN_ERROR);
 
        return (CMD_RETURN_NORMAL);
diff --git a/cmd-if-shell.c b/cmd-if-shell.c
index 1543291..29783a8 100644
--- a/cmd-if-shell.c
+++ b/cmd-if-shell.c
@@ -30,6 +30,7 @@
  */
 
 enum cmd_retval         cmd_if_shell_exec(struct cmd *, struct cmd_q *);
+void            cmd_if_shell_prepare(struct cmd *, struct cmd_q *);
 
 void   cmd_if_shell_callback(struct job *);
 void   cmd_if_shell_done(struct cmd_q *);
@@ -40,7 +41,8 @@ const struct cmd_entry cmd_if_shell_entry = {
        "bFt:", 2, 3,
        "[-bF] " CMD_TARGET_PANE_USAGE " shell-command command [command]",
        0,
-       cmd_if_shell_exec
+       cmd_if_shell_exec,
+       NULL
 };
 
 struct cmd_if_shell_data {
@@ -51,6 +53,18 @@ struct cmd_if_shell_data {
        int              started;
 };
 
+void
+cmd_if_shell_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       if (args_has(args, 't')) {
+               cmdq->state.wl = cmd_find_pane(cmdq, args_get(args, 't'),
+                   &cmdq->state.s, &cmdq->state.wp);
+       } else
+               cmdq->state.c = cmd_find_client(cmdq, NULL, 1);
+}
+
 enum cmd_retval
 cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
 {
@@ -64,15 +78,15 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
        struct window_pane              *wp = NULL;
        struct format_tree              *ft;
 
-       if (args_has(args, 't'))
-               wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
-       else {
-               c = cmd_find_client(cmdq, NULL, 1);
-               if (c != NULL && c->session != NULL) {
-                       s = c->session;
-                       wl = s->curw;
-                       wp = wl->window->active;
-               }
+       wl = cmdq->state.wl;
+       s = cmdq->state.s;
+       wp = cmdq->state.wp;
+       c = cmdq->state.c;
+
+       if (!args_has(args, 't') && c != NULL && c->session != NULL) {
+               s = c->session;
+               wl = s->curw;
+               wp = wl->window->active;
        }
 
        ft = format_create();
diff --git a/cmd-join-pane.c b/cmd-join-pane.c
index 5603541..a6be1bf 100644
--- a/cmd-join-pane.c
+++ b/cmd-join-pane.c
@@ -29,6 +29,7 @@
  */
 
 enum cmd_retval         cmd_join_pane_exec(struct cmd *, struct cmd_q *);
+void            cmd_join_pane_prepare(struct cmd *, struct cmd_q *);
 
 enum cmd_retval         join_pane(struct cmd *, struct cmd_q *, int);
 
@@ -36,18 +37,31 @@ const struct cmd_entry cmd_join_pane_entry = {
        "join-pane", "joinp",
        "bdhvp:l:s:t:", 0, 0,
        "[-bdhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
-       0,
-       cmd_join_pane_exec
+       CMD_PREPAREPANE,
+       cmd_join_pane_exec,
+       cmd_join_pane_prepare
 };
 
 const struct cmd_entry cmd_move_pane_entry = {
        "move-pane", "movep",
        "bdhvp:l:s:t:", 0, 0,
        "[-bdhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
-       0,
-       cmd_join_pane_exec
+       CMD_PREPAREWINDOW,
+       cmd_join_pane_exec,
+       cmd_join_pane_prepare
 };
 
+
+void
+cmd_join_pane_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       cmdq->state.wl = cmd_find_pane(cmdq, args_get(args, 't'),
+           &cmdq->state.s, &cmdq->state.wp);
+       cmdq->state.wl2 = cmd_find_pane(cmdq, args_get(args, 's'), NULL,
+           &cmdq->state.wp2);
+}
 enum cmd_retval
 cmd_join_pane_exec(struct cmd *self, struct cmd_q *cmdq)
 {
@@ -67,16 +81,17 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int 
not_same_window)
        enum layout_type         type;
        struct layout_cell      *lc;
 
-       dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), &dst_s, &dst_wp);
-       if (dst_wl == NULL)
+       if ((dst_wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
+       dst_s =  cmdq->state.s;
+       dst_wp = cmdq->state.wp;
        dst_w = dst_wl->window;
        dst_idx = dst_wl->idx;
        server_unzoom_window(dst_w);
 
-       src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
-       if (src_wl == NULL)
+       if ((src_wl = cmdq->state.wl2) == NULL)
                return (CMD_RETURN_ERROR);
+       src_wp = cmdq->state.wp2;
        src_w = src_wl->window;
        server_unzoom_window(src_w);
 
diff --git a/cmd-kill-pane.c b/cmd-kill-pane.c
index f4735fd..26f0e0c 100644
--- a/cmd-kill-pane.c
+++ b/cmd-kill-pane.c
@@ -27,24 +27,26 @@
  */
 
 enum cmd_retval         cmd_kill_pane_exec(struct cmd *, struct cmd_q *);
+void            cmd_kill_pane_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_kill_pane_entry = {
        "kill-pane", "killp",
        "at:", 0, 0,
        "[-a] " CMD_TARGET_PANE_USAGE,
-       0,
-       cmd_kill_pane_exec
+       CMD_PREPAREPANE,
+       cmd_kill_pane_exec,
+       NULL
 };
 
 enum cmd_retval
 cmd_kill_pane_exec(struct cmd *self, struct cmd_q *cmdq)
 {
-       struct args             *args = self->args;
        struct winlink          *wl;
        struct window_pane      *loopwp, *tmpwp, *wp;
 
-       if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
+       wp = cmdq->state.wp;
        server_unzoom_window(wl->window);
 
        if (window_count_panes(wl->window) == 1) {
diff --git a/cmd-kill-server.c b/cmd-kill-server.c
index 07d9430..930bef5 100644
--- a/cmd-kill-server.c
+++ b/cmd-kill-server.c
@@ -34,7 +34,8 @@ const struct cmd_entry cmd_kill_server_entry = {
        "", 0, 0,
        "",
        0,
-       cmd_kill_server_exec
+       cmd_kill_server_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_start_server_entry = {
@@ -42,7 +43,8 @@ const struct cmd_entry cmd_start_server_entry = {
        "", 0, 0,
        "",
        CMD_STARTSERVER,
-       cmd_kill_server_exec
+       cmd_kill_server_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-kill-session.c b/cmd-kill-session.c
index d7e2a21..3515a67 100644
--- a/cmd-kill-session.c
+++ b/cmd-kill-session.c
@@ -28,13 +28,15 @@
  */
 
 enum cmd_retval         cmd_kill_session_exec(struct cmd *, struct cmd_q *);
+void            cmd_kill_session_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_kill_session_entry = {
        "kill-session", NULL,
        "at:", 0, 0,
        "[-a] " CMD_TARGET_SESSION_USAGE,
-       0,
-       cmd_kill_session_exec
+       CMD_PREPARESESSION,
+       cmd_kill_session_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -43,7 +45,7 @@ cmd_kill_session_exec(struct cmd *self, struct cmd_q *cmdq)
        struct args     *args = self->args;
        struct session  *s, *s2, *s3;
 
-       if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
+       if ((s = cmdq->state.s) == NULL)
                return (CMD_RETURN_ERROR);
 
        if (args_has(args, 'a')) {
diff --git a/cmd-kill-window.c b/cmd-kill-window.c
index d402acc..3689440 100644
--- a/cmd-kill-window.c
+++ b/cmd-kill-window.c
@@ -30,8 +30,9 @@ const struct cmd_entry cmd_kill_window_entry = {
        "kill-window", "killw",
        "at:", 0, 0,
        "[-a] " CMD_TARGET_WINDOW_USAGE,
-       0,
-       cmd_kill_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_kill_window_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_unlink_window_entry = {
@@ -39,7 +40,8 @@ const struct cmd_entry cmd_unlink_window_entry = {
        "kt:", 0, 0,
        "[-k] " CMD_TARGET_WINDOW_USAGE,
        0,
-       cmd_kill_window_exec
+       cmd_kill_window_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -52,9 +54,10 @@ cmd_kill_window_exec(struct cmd *self, struct cmd_q *cmdq)
        struct session_group    *sg;
        u_int                    references;
 
-       if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
        w = wl->window;
+       s = cmdq->state.s;
 
        if (self->entry == &cmd_unlink_window_entry) {
                sg = session_group_find(s);
@@ -66,7 +69,6 @@ cmd_kill_window_exec(struct cmd *self, struct cmd_q *cmdq)
                        cmdq_error(cmdq, "window only linked to one session");
                        return (CMD_RETURN_ERROR);
                }
-               server_unlink_window(s, wl);
        } else {
                if (args_has(args, 'a')) {
                        RB_FOREACH_SAFE(wl2, winlinks, &s->windows, wl3) {
diff --git a/cmd-list-buffers.c b/cmd-list-buffers.c
index 8eb1610..6c5db2c 100644
--- a/cmd-list-buffers.c
+++ b/cmd-list-buffers.c
@@ -37,7 +37,8 @@ const struct cmd_entry cmd_list_buffers_entry = {
        "F:", 0, 0,
        "[-F format]",
        0,
-       cmd_list_buffers_exec
+       cmd_list_buffers_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-list-clients.c b/cmd-list-clients.c
index 292be72..9b51e05 100644
--- a/cmd-list-clients.c
+++ b/cmd-list-clients.c
@@ -39,8 +39,9 @@ const struct cmd_entry cmd_list_clients_entry = {
        "list-clients", "lsc",
        "F:t:", 0, 0,
        "[-F format] " CMD_TARGET_SESSION_USAGE,
-       CMD_READONLY,
-       cmd_list_clients_exec
+       CMD_READONLY|CMD_PREPARESESSION,
+       cmd_list_clients_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -54,12 +55,9 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
        u_int                    i;
        char                    *line;
 
-       if (args_has(args, 't')) {
-               s = cmd_find_session(cmdq, args_get(args, 't'), 0);
-               if (s == NULL)
-                       return (CMD_RETURN_ERROR);
-       } else
-               s = NULL;
+       s = cmdq->state.s;
+       if (args_has(args, 't') && s == NULL)
+               return (CMD_RETURN_ERROR);
 
        if ((template = args_get(args, 'F')) == NULL)
                template = LIST_CLIENTS_TEMPLATE;
diff --git a/cmd-list-keys.c b/cmd-list-keys.c
index 0733ee2..de8310e 100644
--- a/cmd-list-keys.c
+++ b/cmd-list-keys.c
@@ -36,7 +36,8 @@ const struct cmd_entry cmd_list_keys_entry = {
        "t:", 0, 0,
        "[-t key-table]",
        0,
-       cmd_list_keys_exec
+       cmd_list_keys_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_list_commands_entry = {
@@ -44,7 +45,8 @@ const struct cmd_entry cmd_list_commands_entry = {
        "", 0, 0,
        "",
        0,
-       cmd_list_keys_exec
+       cmd_list_keys_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-list-panes.c b/cmd-list-panes.c
index 7f62177..caeb48e 100644
--- a/cmd-list-panes.c
+++ b/cmd-list-panes.c
@@ -28,6 +28,7 @@
  */
 
 enum cmd_retval         cmd_list_panes_exec(struct cmd *, struct cmd_q *);
+void            cmd_list_panes_prepare(struct cmd *, struct cmd_q *);
 
 void   cmd_list_panes_server(struct cmd *, struct cmd_q *);
 void   cmd_list_panes_session(
@@ -39,10 +40,24 @@ const struct cmd_entry cmd_list_panes_entry = {
        "list-panes", "lsp",
        "asF:t:", 0, 0,
        "[-as] [-F format] " CMD_TARGET_WINDOW_USAGE,
-       0,
-       cmd_list_panes_exec
+       CMD_PREPARESESSION|CMD_PREPAREWINDOW,
+       cmd_list_panes_exec,
+       cmd_list_panes_prepare
 };
 
+void
+cmd_list_panes_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       if (args_has(args, 's'))
+               cmdq->state.s = cmd_find_session(cmdq, args_get(args, 't'), 0);
+       else if (args_has(args, 't')) {
+               cmdq->state.wl = cmd_find_window(cmdq, args_get(args, 't'),
+                   &cmdq->state.s);
+       }
+}
+
 enum cmd_retval
 cmd_list_panes_exec(struct cmd *self, struct cmd_q *cmdq)
 {
@@ -50,16 +65,16 @@ cmd_list_panes_exec(struct cmd *self, struct cmd_q *cmdq)
        struct session  *s;
        struct winlink  *wl;
 
+       s = cmdq->state.s;
+
        if (args_has(args, 'a'))
                cmd_list_panes_server(self, cmdq);
        else if (args_has(args, 's')) {
-               s = cmd_find_session(cmdq, args_get(args, 't'), 0);
                if (s == NULL)
                        return (CMD_RETURN_ERROR);
                cmd_list_panes_session(self, s, cmdq, 1);
        } else {
-               wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
-               if (wl == NULL)
+               if ((wl = cmdq->state.wl) == NULL)
                        return (CMD_RETURN_ERROR);
                cmd_list_panes_window(self, s, wl, cmdq, 0);
        }
diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c
index ea8f3e3..5b4472f 100644
--- a/cmd-list-sessions.c
+++ b/cmd-list-sessions.c
@@ -43,7 +43,8 @@ const struct cmd_entry cmd_list_sessions_entry = {
        "F:", 0, 0,
        "[-F format]",
        0,
-       cmd_list_sessions_exec
+       cmd_list_sessions_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-list-windows.c b/cmd-list-windows.c
index 5f73e8d..3cd980c 100644
--- a/cmd-list-windows.c
+++ b/cmd-list-windows.c
@@ -40,6 +40,7 @@
        "[#{window_width}x#{window_height}] "
 
 enum cmd_retval         cmd_list_windows_exec(struct cmd *, struct cmd_q *);
+void            cmd_list_windows_prepare(struct cmd *, struct cmd_q *);
 
 void   cmd_list_windows_server(struct cmd *, struct cmd_q *);
 void   cmd_list_windows_session(struct cmd *, struct session *,
@@ -49,10 +50,20 @@ const struct cmd_entry cmd_list_windows_entry = {
        "list-windows", "lsw",
        "F:at:", 0, 0,
        "[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
-       0,
-       cmd_list_windows_exec
+       CMD_PREPARESESSION,
+       cmd_list_windows_exec,
+       cmd_list_windows_prepare
 };
 
+void
+cmd_list_windows_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       if (!args_has(args, 'a'))
+               cmdq->state.s = cmd_find_session(cmdq, args_get(args, 't'), 0);
+}
+
 enum cmd_retval
 cmd_list_windows_exec(struct cmd *self, struct cmd_q *cmdq)
 {
@@ -62,8 +73,7 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_q *cmdq)
        if (args_has(args, 'a'))
                cmd_list_windows_server(self, cmdq);
        else {
-               s = cmd_find_session(cmdq, args_get(args, 't'), 0);
-               if (s == NULL)
+               if ((s = cmdq->state.s) == NULL)
                        return (CMD_RETURN_ERROR);
                cmd_list_windows_session(self, s, cmdq, 0);
        }
diff --git a/cmd-load-buffer.c b/cmd-load-buffer.c
index 785a701..fcf603d 100644
--- a/cmd-load-buffer.c
+++ b/cmd-load-buffer.c
@@ -39,7 +39,8 @@ const struct cmd_entry cmd_load_buffer_entry = {
        "b:", 1, 1,
        CMD_BUFFER_USAGE " path",
        0,
-       cmd_load_buffer_exec
+       cmd_load_buffer_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-lock-server.c b/cmd-lock-server.c
index de76475..4c4ca6e 100644
--- a/cmd-lock-server.c
+++ b/cmd-lock-server.c
@@ -25,13 +25,15 @@
  */
 
 enum cmd_retval         cmd_lock_server_exec(struct cmd *, struct cmd_q *);
+void            cmd_lock_server_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_lock_server_entry = {
        "lock-server", "lock",
        "", 0, 0,
        "",
        0,
-       cmd_lock_server_exec
+       cmd_lock_server_exec,
+       cmd_lock_server_prepare,
 };
 
 const struct cmd_entry cmd_lock_session_entry = {
@@ -39,7 +41,8 @@ const struct cmd_entry cmd_lock_session_entry = {
        "t:", 0, 0,
        CMD_TARGET_SESSION_USAGE,
        0,
-       cmd_lock_server_exec
+       cmd_lock_server_exec,
+       cmd_lock_server_prepare
 };
 
 const struct cmd_entry cmd_lock_client_entry = {
@@ -47,26 +50,35 @@ const struct cmd_entry cmd_lock_client_entry = {
        "t:", 0, 0,
        CMD_TARGET_CLIENT_USAGE,
        0,
-       cmd_lock_server_exec
+       cmd_lock_server_exec,
+       cmd_lock_server_prepare
 };
 
+void
+cmd_lock_server_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       if (self->entry == &cmd_lock_session_entry)
+               cmdq->state.s = cmd_find_session(cmdq, args_get(args, 't'), 0);
+       else if (self->entry == &cmd_lock_client_entry)
+               cmdq->state.c = cmd_find_client(cmdq, args_get(args, 't'), 0);
+}
+
 enum cmd_retval
 cmd_lock_server_exec(struct cmd *self, unused struct cmd_q *cmdq)
 {
-       struct args     *args = self->args;
        struct client   *c;
        struct session  *s;
 
        if (self->entry == &cmd_lock_server_entry)
                server_lock();
        else if (self->entry == &cmd_lock_session_entry) {
-               s = cmd_find_session(cmdq, args_get(args, 't'), 0);
-               if (s == NULL)
+               if ((s = cmdq->state.s) == NULL)
                        return (CMD_RETURN_ERROR);
                server_lock_session(s);
        } else {
-               c = cmd_find_client(cmdq, args_get(args, 't'), 0);
-               if (c == NULL)
+               if ((c = cmdq->state.c) == NULL)
                        return (CMD_RETURN_ERROR);
                server_lock_client(c);
        }
diff --git a/cmd-move-window.c b/cmd-move-window.c
index 3064cd6..c32ad64 100644
--- a/cmd-move-window.c
+++ b/cmd-move-window.c
@@ -27,23 +27,41 @@
  */
 
 enum cmd_retval         cmd_move_window_exec(struct cmd *, struct cmd_q *);
+void            cmd_move_window_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_move_window_entry = {
        "move-window", "movew",
        "dkrs:t:", 0, 0,
        "[-dkr] " CMD_SRCDST_WINDOW_USAGE,
        0,
-       cmd_move_window_exec
+       cmd_move_window_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_link_window_entry = {
        "link-window", "linkw",
        "dks:t:", 0, 0,
        "[-dk] " CMD_SRCDST_WINDOW_USAGE,
-       0,
-       cmd_move_window_exec
+       CMD_PREPARESESSION|CMD_PREPAREWINDOW,
+       cmd_move_window_exec,
+       cmd_move_window_prepare
 };
 
+void
+cmd_move_window_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       if (args_has(args, 'r'))
+               cmdq->state.s = cmd_find_session(cmdq, args_get(args, 't'), 0);
+       else {
+               cmdq->state.wl = cmd_find_window(cmdq, args_get(args, 's'),
+                   &cmdq->state.s);
+               cmdq->state.idx = cmd_find_index(cmdq, args_get(args, 't'),
+                   &cmdq->state.s2);
+       }
+}
+
 enum cmd_retval
 cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
 {
@@ -54,8 +72,7 @@ cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
        int              idx, kflag, dflag;
 
        if (args_has(args, 'r')) {
-               s = cmd_find_session(cmdq, args_get(args, 't'), 0);
-               if (s == NULL)
+               if ((s = cmdq->state.s) == NULL)
                        return (CMD_RETURN_ERROR);
 
                session_renumber_windows(s);
@@ -63,10 +80,12 @@ cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
 
                return (CMD_RETURN_NORMAL);
        }
+       src = cmdq->state.s;
+       dst = cmdq->state.s2;
 
-       if ((wl = cmd_find_window(cmdq, args_get(args, 's'), &src)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
-       if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &dst)) == -2)
+       if ((idx = cmdq->state.idx) == -2)
                return (CMD_RETURN_ERROR);
 
        kflag = args_has(self->args, 'k');
diff --git a/cmd-new-session.c b/cmd-new-session.c
index e244f88..0a05cde 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -42,7 +42,8 @@ const struct cmd_entry cmd_new_session_entry = {
        "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
        "[-y height] [command]",
        CMD_STARTSERVER|CMD_CANTNEST,
-       cmd_new_session_exec
+       cmd_new_session_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_has_session_entry = {
@@ -50,7 +51,8 @@ const struct cmd_entry cmd_has_session_entry = {
        "t:", 0, 0,
        CMD_TARGET_SESSION_USAGE,
        0,
-       cmd_new_session_exec
+       cmd_new_session_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-new-window.c b/cmd-new-window.c
index 7f14b21..4e222ba 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -32,23 +32,37 @@
 
 #define NEW_WINDOW_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
 
-enum cmd_retval        cmd_new_window_exec(struct cmd *, struct cmd_q *);
+enum cmd_retval         cmd_new_window_exec(struct cmd *, struct cmd_q *);
+void            cmd_new_window_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_new_window_entry = {
        "new-window", "neww",
        "ac:dF:kn:Pt:", 0, -1,
        "[-adkP] [-c start-directory] [-F format] [-n window-name] "
        CMD_TARGET_WINDOW_USAGE " [command]",
-       0,
-       cmd_new_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_new_window_exec,
+       cmd_new_window_prepare
 };
 
+void
+cmd_new_window_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       if (args_has(args, 'a')) {
+               cmdq->state.wl = cmd_find_window(cmdq, args_get(args, 't'),
+                   &cmdq->state.s);
+       } else
+               cmd_find_index(cmdq, args_get(args, 't'), &cmdq->state.s);
+}
+
 enum cmd_retval
 cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
 {
        struct args             *args = self->args;
-       struct session          *s;
-       struct winlink          *wl;
+       struct session          *s = cmdq->state.s;
+       struct winlink          *wl = cmdq->state.wl;
        struct client           *c;
        const char              *cmd, *path, *template;
        char                   **argv, *cause, *cp;
@@ -57,7 +71,6 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
        struct environ_entry    *envent;
 
        if (args_has(args, 'a')) {
-               wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
                if (wl == NULL)
                        return (CMD_RETURN_ERROR);
                idx = wl->idx + 1;
diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c
index 5d91aef..c99cb51 100644
--- a/cmd-paste-buffer.c
+++ b/cmd-paste-buffer.c
@@ -36,8 +36,9 @@ const struct cmd_entry cmd_paste_buffer_entry = {
        "paste-buffer", "pasteb",
        "db:prs:t:", 0, 0,
        "[-dpr] [-s separator] " CMD_BUFFER_USAGE " " CMD_TARGET_PANE_USAGE,
-       0,
-       cmd_paste_buffer_exec
+       CMD_PREPAREPANE,
+       cmd_paste_buffer_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -45,17 +46,18 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
 {
        struct args             *args = self->args;
        struct window_pane      *wp;
-       struct session          *s;
        struct paste_buffer     *pb;
        const char              *sepstr, *bufname;
 
-       if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
+       if (cmdq->state.wl == NULL)
                return (CMD_RETURN_ERROR);
 
        bufname = NULL;
        if (args_has(args, 'b'))
                bufname = args_get(args, 'b');
 
+       wp = cmdq->state.wp;
+
        if (bufname == NULL)
                pb = paste_get_top();
        else {
diff --git a/cmd-pipe-pane.c b/cmd-pipe-pane.c
index 4ab1824..facab6f 100644
--- a/cmd-pipe-pane.c
+++ b/cmd-pipe-pane.c
@@ -39,8 +39,9 @@ const struct cmd_entry cmd_pipe_pane_entry = {
        "pipe-pane", "pipep",
        "ot:", 0, 1,
        "[-o] " CMD_TARGET_PANE_USAGE " [command]",
-       0,
-       cmd_pipe_pane_exec
+       CMD_PREPAREPANE,
+       cmd_pipe_pane_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -52,8 +53,9 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
        char                    *command;
        int                      old_fd, pipe_fd[2], null_fd;
 
-       if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
+       if (cmdq->state.wl == NULL)
                return (CMD_RETURN_ERROR);
+       wp = cmdq->state.wp;
        c = cmd_find_client(cmdq, NULL, 1);
 
        /* Destroy the old pipe. */
diff --git a/cmd-queue.c b/cmd-queue.c
index a98fa9b..12a3fe2 100644
--- a/cmd-queue.c
+++ b/cmd-queue.c
@@ -21,9 +21,36 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <time.h>
+#include <string.h>
 
 #include "tmux.h"
 
+void   cmdq_set_state(struct cmd_q *);
+void   cmdq_run_hook(struct hooks *, const char *, struct cmd *,
+           struct cmd_q *);
+
+/* Fill in state members. */
+void
+cmdq_set_state(struct cmd_q *cmdq)
+{
+       memset(&cmdq->state, 0, sizeof cmdq->state);
+
+       cmdq->state.c = cmdq->client;
+
+       cmdq->state.s = cmdq->client != NULL ?
+               cmdq->client->session : NULL;
+       cmdq->state.s2 = NULL;
+       cmdq->state.w = NULL;
+       cmdq->state.wl = NULL;
+       cmdq->state.wp = NULL;
+       cmdq->state.tflag = NULL;
+       cmdq->state.sflag = NULL;
+
+       cmd_prepare(cmdq->cmd, cmdq);
+
+       cmdq->state.prior_tflag = args_get(cmdq->cmd->args, 't');
+}
+
 /* Create new command queue. */
 struct cmd_q *
 cmdq_new(struct client *c)
@@ -145,6 +172,20 @@ cmdq_run(struct cmd_q *cmdq, struct cmd_list *cmdlist)
        }
 }
 
+/* Run hooks based on the hooks prefix (before/after). */
+void
+cmdq_run_hook(struct hooks *hooks, const char *prefix, struct cmd *cmd,
+    struct cmd_q *cmdq)
+{
+       struct hook     *hook;
+       char            *s;
+
+       xasprintf(&s, "%s-%s", prefix, cmd->entry->name);
+       if ((hook = hooks_find(hooks, s)) != NULL)
+               hooks_run(hook, cmdq);
+       free(s);
+}
+
 /* Add command list to queue. */
 void
 cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist)
@@ -162,6 +203,7 @@ int
 cmdq_continue(struct cmd_q *cmdq)
 {
        struct cmd_q_item       *next;
+       struct hooks            *hooks;
        enum cmd_retval          retval;
        int                      empty, guard, flags;
        char                     s[1024];
@@ -180,6 +222,17 @@ cmdq_continue(struct cmd_q *cmdq)
 
        do {
                while (cmdq->cmd != NULL) {
+                       /*
+                        * Set the execution context for this command.  This
+                        * then allows for session hooks to be used if this
+                        * command has any.
+                        */
+                       cmdq_set_state(cmdq);
+                       if (cmdq->state.s != NULL)
+                               hooks = &cmdq->state.s->hooks;
+                       else
+                               hooks = &global_hooks;
+
                        cmd_print(cmdq->cmd, s, sizeof s);
                        log_debug("cmdq %p: %s (client %d)", cmdq, s,
                            cmdq->client != NULL ? cmdq->client->ibuf.fd : -1);
@@ -190,7 +243,13 @@ cmdq_continue(struct cmd_q *cmdq)
                        flags = !!(cmdq->cmd->flags & CMD_CONTROL);
                        guard = cmdq_guard(cmdq, "begin", flags);
 
+                       cmdq_run_hook(hooks, "before", cmdq->cmd, cmdq);
+
                        retval = cmdq->cmd->entry->exec(cmdq->cmd, cmdq);
+                       if (retval == CMD_RETURN_ERROR)
+                               break;
+
+                       cmdq_run_hook(hooks, "after", cmdq->cmd, cmdq);
 
                        if (guard) {
                                if (retval == CMD_RETURN_ERROR)
diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c
index f693872..969605b 100644
--- a/cmd-refresh-client.c
+++ b/cmd-refresh-client.c
@@ -30,8 +30,9 @@ const struct cmd_entry cmd_refresh_client_entry = {
        "refresh-client", "refresh",
        "C:St:", 0, 0,
        "[-S] [-C size] " CMD_TARGET_CLIENT_USAGE,
-       0,
-       cmd_refresh_client_exec
+       CMD_PREPARECLIENT,
+       cmd_refresh_client_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -42,7 +43,7 @@ cmd_refresh_client_exec(struct cmd *self, struct cmd_q *cmdq)
        const char      *size;
        u_int            w, h;
 
-       if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+       if ((c = cmdq->state.c) == NULL)
                return (CMD_RETURN_ERROR);
 
        if (args_has(args, 'C')) {
diff --git a/cmd-rename-session.c b/cmd-rename-session.c
index 481154c..e44c45b 100644
--- a/cmd-rename-session.c
+++ b/cmd-rename-session.c
@@ -27,13 +27,15 @@
  */
 
 enum cmd_retval         cmd_rename_session_exec(struct cmd *, struct cmd_q *);
+void            cmd_rename_session_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_rename_session_entry = {
        "rename-session", "rename",
        "t:", 1, 1,
        CMD_TARGET_SESSION_USAGE " new-name",
-       0,
-       cmd_rename_session_exec
+       CMD_PREPARESESSION,
+       cmd_rename_session_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -53,7 +55,7 @@ cmd_rename_session_exec(struct cmd *self, struct cmd_q *cmdq)
                return (CMD_RETURN_ERROR);
        }
 
-       if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
+       if ((s = cmdq->state.s) == NULL)
                return (CMD_RETURN_ERROR);
 
        RB_REMOVE(sessions, &sessions, s);
diff --git a/cmd-rename-window.c b/cmd-rename-window.c
index 2f677a4..aeee5b9 100644
--- a/cmd-rename-window.c
+++ b/cmd-rename-window.c
@@ -27,23 +27,24 @@
  */
 
 enum cmd_retval         cmd_rename_window_exec(struct cmd *, struct cmd_q *);
+void            cmd_rename_window_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_rename_window_entry = {
        "rename-window", "renamew",
        "t:", 1, 1,
        CMD_TARGET_WINDOW_USAGE " new-name",
-       0,
-       cmd_rename_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_rename_window_exec,
+       NULL
 };
 
 enum cmd_retval
 cmd_rename_window_exec(struct cmd *self, struct cmd_q *cmdq)
 {
        struct args     *args = self->args;
-       struct session  *s;
        struct winlink  *wl;
 
-       if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
 
        window_set_name(wl->window, args->argv[0]);
diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c
index 42f0f39..b55b2c3 100644
--- a/cmd-resize-pane.c
+++ b/cmd-resize-pane.c
@@ -32,8 +32,9 @@ const struct cmd_entry cmd_resize_pane_entry = {
        "resize-pane", "resizep",
        "DLRt:Ux:y:Z", 0, 1,
        "[-DLRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " 
[adjustment]",
-       0,
-       cmd_resize_pane_exec
+       CMD_PREPAREPANE,
+       cmd_resize_pane_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -48,9 +49,10 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
        u_int                    adjust;
        int                      x, y;
 
-       if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
        w = wl->window;
+       wp = cmdq->state.wp;
 
        if (args_has(args, 'Z')) {
                if (w->flags & WINDOW_ZOOMED)
diff --git a/cmd-respawn-pane.c b/cmd-respawn-pane.c
index 4703153..2aaee6b 100644
--- a/cmd-respawn-pane.c
+++ b/cmd-respawn-pane.c
@@ -34,8 +34,9 @@ const struct cmd_entry cmd_respawn_pane_entry = {
        "respawn-pane", "respawnp",
        "kt:", 0, -1,
        "[-k] " CMD_TARGET_PANE_USAGE " [command]",
-       0,
-       cmd_respawn_pane_exec
+       CMD_PREPAREPANE,
+       cmd_respawn_pane_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -52,9 +53,11 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
        u_int                    idx;
        struct environ_entry    *envent;
 
-       if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
        w = wl->window;
+       s = cmdq->state.s;
+       wp = cmdq->state.wp;
 
        if (!args_has(self->args, 'k') && wp->fd != -1) {
                if (window_pane_index(wp, &idx) != 0)
diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c
index 06102ed..af21f2f 100644
--- a/cmd-respawn-window.c
+++ b/cmd-respawn-window.c
@@ -33,8 +33,9 @@ const struct cmd_entry cmd_respawn_window_entry = {
        "respawn-window", "respawnw",
        "kt:", 0, -1,
        "[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
-       0,
-       cmd_respawn_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_respawn_window_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -50,9 +51,10 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
        char                    *cause;
        struct environ_entry    *envent;
 
-       if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
        w = wl->window;
+       s = cmdq->state.s;
 
        if (!args_has(self->args, 'k')) {
                TAILQ_FOREACH(wp, &w->panes, entry) {
diff --git a/cmd-rotate-window.c b/cmd-rotate-window.c
index 859ff04..310268c 100644
--- a/cmd-rotate-window.c
+++ b/cmd-rotate-window.c
@@ -30,21 +30,21 @@ const struct cmd_entry cmd_rotate_window_entry = {
        "rotate-window", "rotatew",
        "Dt:U", 0, 0,
        "[-DU] " CMD_TARGET_WINDOW_USAGE,
-       0,
-       cmd_rotate_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_rotate_window_exec,
+       NULL
 };
 
 enum cmd_retval
 cmd_rotate_window_exec(struct cmd *self, struct cmd_q *cmdq)
 {
-       struct args             *args = self->args;
        struct winlink          *wl;
        struct window           *w;
        struct window_pane      *wp, *wp2;
        struct layout_cell      *lc;
        u_int                    sx, sy, xoff, yoff;
 
-       if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
        w = wl->window;
 
diff --git a/cmd-run-shell.c b/cmd-run-shell.c
index b47c282..2fb50c0 100644
--- a/cmd-run-shell.c
+++ b/cmd-run-shell.c
@@ -39,8 +39,9 @@ const struct cmd_entry cmd_run_shell_entry = {
        "run-shell", "run",
        "bt:", 1, 1,
        "[-b] " CMD_TARGET_PANE_USAGE " shell-command",
-       0,
-       cmd_run_shell_exec
+       CMD_PREPAREPANE|CMD_PREPARESESSION,
+       cmd_run_shell_exec,
+       NULL
 };
 
 struct cmd_run_shell_data {
@@ -75,21 +76,17 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
        struct args                     *args = self->args;
        struct cmd_run_shell_data       *cdata;
        char                            *shellcmd;
-       struct client                   *c;
        struct session                  *s = NULL;
        struct winlink                  *wl = NULL;
        struct window_pane              *wp = NULL;
        struct format_tree              *ft;
 
        if (args_has(args, 't'))
-               wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
+               wl = cmdq->state.wl;
        else {
-               c = cmd_find_client(cmdq, NULL, 1);
-               if (c != NULL && c->session != NULL) {
-                       s = c->session;
-                       wl = s->curw;
-                       wp = wl->window->active;
-               }
+               s = cmdq->state.s;
+               wl = cmdq->state.wl;
+               wp = cmdq->state.wp;
        }
 
        ft = format_create();
diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c
index 47a263d..e3ed06b 100644
--- a/cmd-save-buffer.c
+++ b/cmd-save-buffer.c
@@ -38,7 +38,8 @@ const struct cmd_entry cmd_save_buffer_entry = {
        "ab:", 1, 1,
        "[-a] " CMD_BUFFER_USAGE " path",
        0,
-       cmd_save_buffer_exec
+       cmd_save_buffer_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_show_buffer_entry = {
@@ -46,7 +47,8 @@ const struct cmd_entry cmd_show_buffer_entry = {
        "b:", 0, 0,
        CMD_BUFFER_USAGE,
        0,
-       cmd_save_buffer_exec
+       cmd_save_buffer_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-select-layout.c b/cmd-select-layout.c
index 77137b7..4eb3719 100644
--- a/cmd-select-layout.c
+++ b/cmd-select-layout.c
@@ -30,24 +30,27 @@ const struct cmd_entry cmd_select_layout_entry = {
        "select-layout", "selectl",
        "npt:", 0, 1,
        "[-np] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
-       0,
-       cmd_select_layout_exec
+       CMD_PREPAREWINDOW,
+       cmd_select_layout_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_next_layout_entry = {
        "next-layout", "nextl",
        "t:", 0, 0,
        CMD_TARGET_WINDOW_USAGE,
-       0,
-       cmd_select_layout_exec
+       CMD_PREPAREWINDOW,
+       cmd_select_layout_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_previous_layout_entry = {
        "previous-layout", "prevl",
        "t:", 0, 0,
        CMD_TARGET_WINDOW_USAGE,
-       0,
-       cmd_select_layout_exec
+       CMD_PREPAREWINDOW,
+       cmd_select_layout_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -58,7 +61,7 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
        const char      *layoutname;
        int              next, previous, layout;
 
-       if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
        server_unzoom_window(wl->window);
 
diff --git a/cmd-select-pane.c b/cmd-select-pane.c
index 5810eea..e4bebc5 100644
--- a/cmd-select-pane.c
+++ b/cmd-select-pane.c
@@ -25,23 +25,39 @@
  */
 
 enum cmd_retval         cmd_select_pane_exec(struct cmd *, struct cmd_q *);
+void            cmd_select_pane_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_select_pane_entry = {
        "select-pane", "selectp",
        "DdeLlRt:U", 0, 0,
        "[-DdeLlRU] " CMD_TARGET_PANE_USAGE,
-       0,
-       cmd_select_pane_exec
+       CMD_PREPAREPANE,
+       cmd_select_pane_exec,
+       cmd_select_pane_prepare
 };
 
 const struct cmd_entry cmd_last_pane_entry = {
        "last-pane", "lastp",
        "det:", 0, 0,
        "[-de] " CMD_TARGET_WINDOW_USAGE,
-       0,
-       cmd_select_pane_exec
+       CMD_PREPAREPANE,
+       cmd_select_pane_exec,
+       cmd_select_pane_prepare
 };
 
+void
+cmd_select_pane_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
+               cmdq->state.wl = cmd_find_window(cmdq, args_get(args, 't'),
+                   NULL);
+       } else {
+               cmdq->state.wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL,
+                   &cmdq->state.wp);
+       }
+}
 enum cmd_retval
 cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
 {
@@ -50,8 +66,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
        struct window_pane      *wp;
 
        if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
-               wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
-               if (wl == NULL)
+               if ((wl = cmdq->state.wl) == NULL)
                        return (CMD_RETURN_ERROR);
 
                if (wl->window->last == NULL) {
@@ -73,9 +88,11 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
                return (CMD_RETURN_NORMAL);
        }
 
-       if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
 
+       wp = cmdq->state.wp;
+
        server_unzoom_window(wp->window);
        if (!window_pane_visible(wp)) {
                cmdq_error(cmdq, "pane not visible");
diff --git a/cmd-select-window.c b/cmd-select-window.c
index f530f1f..bbd7f71 100644
--- a/cmd-select-window.c
+++ b/cmd-select-window.c
@@ -27,43 +27,70 @@
  */
 
 enum cmd_retval         cmd_select_window_exec(struct cmd *, struct cmd_q *);
+void            cmd_select_window_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_select_window_entry = {
        "select-window", "selectw",
        "lnpTt:", 0, 0,
        "[-lnpT] " CMD_TARGET_WINDOW_USAGE,
-       0,
-       cmd_select_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_select_window_exec,
+       cmd_select_window_prepare
 };
 
 const struct cmd_entry cmd_next_window_entry = {
        "next-window", "next",
        "at:", 0, 0,
        "[-a] " CMD_TARGET_SESSION_USAGE,
-       0,
-       cmd_select_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_select_window_exec,
+       cmd_select_window_prepare
 };
 
 const struct cmd_entry cmd_previous_window_entry = {
        "previous-window", "prev",
        "at:", 0, 0,
        "[-a] " CMD_TARGET_SESSION_USAGE,
-       0,
-       cmd_select_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_select_window_exec,
+       cmd_select_window_prepare
 };
 
 const struct cmd_entry cmd_last_window_entry = {
        "last-window", "last",
        "t:", 0, 0,
        CMD_TARGET_SESSION_USAGE,
-       0,
-       cmd_select_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_select_window_exec,
+       cmd_select_window_prepare
 };
 
+void
+cmd_select_window_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+       int              next, previous, last;
+
+       next = self->entry == &cmd_next_window_entry;
+       if (args_has(self->args, 'n'))
+               next = 1;
+       previous = self->entry == &cmd_previous_window_entry;
+       if (args_has(self->args, 'p'))
+               previous = 1;
+       last = self->entry == &cmd_last_window_entry;
+       if (args_has(self->args, 'l'))
+               last = 1;
+
+       if (next || previous || last)
+               cmdq->state.s = cmd_find_session(cmdq, args_get(args, 't'), 0);
+       else {
+               cmdq->state.wl = cmd_find_window(cmdq, args_get(args, 't'),
+                   &cmdq->state.s);
+       }
+}
 enum cmd_retval
 cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
 {
-       struct args     *args = self->args;
        struct winlink  *wl;
        struct session  *s;
        int              next, previous, last, activity;
@@ -79,8 +106,7 @@ cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
                last = 1;
 
        if (next || previous || last) {
-               s = cmd_find_session(cmdq, args_get(args, 't'), 0);
-               if (s == NULL)
+               if ((s = cmdq->state.s) == NULL)
                        return (CMD_RETURN_ERROR);
 
                activity = args_has(self->args, 'a');
@@ -103,9 +129,9 @@ cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
 
                server_redraw_session(s);
        } else {
-               wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
-               if (wl == NULL)
+               if ((wl = cmdq->state.wl) == NULL)
                        return (CMD_RETURN_ERROR);
+               s = cmdq->state.s;
 
                /*
                 * If -T and select-window is invoked on same window as
diff --git a/cmd-send-keys.c b/cmd-send-keys.c
index 7a4d97d..fb38d00 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -28,21 +28,24 @@
  */
 
 enum cmd_retval         cmd_send_keys_exec(struct cmd *, struct cmd_q *);
+void            cmd_send_keys_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_send_keys_entry = {
        "send-keys", "send",
        "lRt:", 0, -1,
        "[-lR] " CMD_TARGET_PANE_USAGE " key ...",
-       0,
-       cmd_send_keys_exec
+       CMD_PREPAREPANE,
+       cmd_send_keys_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_send_prefix_entry = {
        "send-prefix", NULL,
        "2t:", 0, 0,
        "[-2] " CMD_TARGET_PANE_USAGE,
-       0,
-       cmd_send_keys_exec
+       CMD_PREPAREPANE,
+       cmd_send_keys_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -55,8 +58,10 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
        const u_char            *str;
        int                      i, key;
 
-       if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
+       if (cmdq->state.wl == NULL)
                return (CMD_RETURN_ERROR);
+       s = cmdq->state.s;
+       wp = cmdq->state.wp;
 
        if (self->entry == &cmd_send_prefix_entry) {
                if (args_has(args, '2'))
diff --git a/cmd-set-buffer.c b/cmd-set-buffer.c
index 0ec362b..afa7069 100644
--- a/cmd-set-buffer.c
+++ b/cmd-set-buffer.c
@@ -34,7 +34,8 @@ const struct cmd_entry cmd_set_buffer_entry = {
        "ab:n:", 0, 1,
        "[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data",
        0,
-       cmd_set_buffer_exec
+       cmd_set_buffer_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-set-environment.c b/cmd-set-environment.c
index 83e63b4..bf65a3f 100644
--- a/cmd-set-environment.c
+++ b/cmd-set-environment.c
@@ -28,13 +28,15 @@
  */
 
 enum cmd_retval         cmd_set_environment_exec(struct cmd *, struct cmd_q *);
+void            cmd_set_environment_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_set_environment_entry = {
        "set-environment", "setenv",
        "grt:u", 1, 2,
        "[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
-       0,
-       cmd_set_environment_exec
+       CMD_PREPARESESSION,
+       cmd_set_environment_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -63,7 +65,7 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq)
        if (args_has(self->args, 'g'))
                env = &global_environ;
        else {
-               if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == 
NULL)
+               if ((s = cmdq->state.s) == NULL)
                        return (CMD_RETURN_ERROR);
                env = &s->environ;
        }
diff --git a/cmd-set-option.c b/cmd-set-option.c
index 01d691d..6bc0e56 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -69,7 +69,8 @@ const struct cmd_entry cmd_set_option_entry = {
        "agoqst:uw", 1, 2,
        "[-agosquw] [-t target-session|target-window] option [value]",
        0,
-       cmd_set_option_exec
+       cmd_set_option_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_set_window_option_entry = {
@@ -77,7 +78,8 @@ const struct cmd_entry cmd_set_window_option_entry = {
        "agoqt:u", 1, 2,
        "[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
        0,
-       cmd_set_option_exec
+       cmd_set_option_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-show-environment.c b/cmd-show-environment.c
index 7737752..e5bacd6 100644
--- a/cmd-show-environment.c
+++ b/cmd-show-environment.c
@@ -28,13 +28,15 @@
  */
 
 enum cmd_retval         cmd_show_environment_exec(struct cmd *, struct cmd_q 
*);
+void            cmd_show_environment_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_show_environment_entry = {
        "show-environment", "showenv",
        "gt:", 0, 1,
        "[-g] " CMD_TARGET_SESSION_USAGE " [name]",
-       0,
-       cmd_show_environment_exec
+       CMD_PREPARESESSION,
+       cmd_show_environment_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -48,7 +50,7 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_q 
*cmdq)
        if (args_has(self->args, 'g'))
                env = &global_environ;
        else {
-               if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == 
NULL)
+               if ((s = cmdq->state.s) == NULL)
                        return (CMD_RETURN_ERROR);
                env = &s->environ;
        }
diff --git a/cmd-show-messages.c b/cmd-show-messages.c
index 308668f..aa74be4 100644
--- a/cmd-show-messages.c
+++ b/cmd-show-messages.c
@@ -34,8 +34,9 @@ const struct cmd_entry cmd_show_messages_entry = {
        "show-messages", "showmsgs",
        "IJTt:", 0, 0,
        "[-IJT] " CMD_TARGET_CLIENT_USAGE,
-       0,
-       cmd_show_messages_exec
+       CMD_PREPARECLIENT,
+       cmd_show_messages_exec,
+       NULL
 };
 
 const struct cmd_entry cmd_server_info_entry = {
@@ -43,7 +44,8 @@ const struct cmd_entry cmd_server_info_entry = {
        "", 0, 0,
        "",
        0,
-       cmd_show_messages_exec
+       cmd_show_messages_exec,
+       NULL
 };
 
 void   cmd_show_messages_server(struct cmd_q *);
@@ -123,7 +125,7 @@ cmd_show_messages_jobs(struct cmd_q *cmdq)
 }
 
 enum cmd_retval
-cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
+cmd_show_messages_exec(unused struct cmd *self, struct cmd_q *cmdq)
 {
        struct args             *args = self->args;
        struct client           *c;
@@ -152,7 +154,7 @@ cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
        if (done)
                return (CMD_RETURN_NORMAL);
 
-       if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+       if ((c = cmdq->state.c) == NULL)
                return (CMD_RETURN_ERROR);
 
        for (i = 0; i < ARRAY_LENGTH(&c->message_log); i++) {
diff --git a/cmd-show-options.c b/cmd-show-options.c
index a5011e7..dc596ca 100644
--- a/cmd-show-options.c
+++ b/cmd-show-options.c
@@ -28,6 +28,7 @@
  */
 
 enum cmd_retval         cmd_show_options_exec(struct cmd *, struct cmd_q *);
+void            cmd_show_options_prepare(struct cmd *, struct cmd_q *);
 
 enum cmd_retval        cmd_show_options_one(struct cmd *, struct cmd_q *,
                    struct options *, int);
@@ -38,8 +39,9 @@ const struct cmd_entry cmd_show_options_entry = {
        "show-options", "show",
        "gqst:vw", 0, 1,
        "[-gqsvw] [-t target-session|target-window] [option]",
-       0,
-       cmd_show_options_exec
+       CMD_PREPARESESSION|CMD_PREPAREWINDOW,
+       cmd_show_options_exec,
+       cmd_show_options_prepare
 };
 
 const struct cmd_entry cmd_show_window_options_entry = {
@@ -47,9 +49,23 @@ const struct cmd_entry cmd_show_window_options_entry = {
        "gvt:", 0, 1,
        "[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
        0,
-       cmd_show_options_exec
+       cmd_show_options_exec,
+       cmd_show_options_prepare
 };
 
+void
+cmd_show_options_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       if (args_has(args, 'g') && args_has(args, 'w') &&
+           self->entry == &cmd_show_window_options_entry) {
+               cmdq->state.wl = cmd_find_window(cmdq, args_get(args, 't'),
+                   NULL);
+       } else
+               cmdq->state.s = cmd_find_session(cmdq, args_get(args, 't'), 0);
+}
+
 enum cmd_retval
 cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq)
 {
@@ -69,8 +85,7 @@ cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq)
                if (args_has(self->args, 'g'))
                        oo = &global_w_options;
                else {
-                       wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
-                       if (wl == NULL)
+                       if ((wl = cmdq->state.wl) == NULL)
                                return (CMD_RETURN_ERROR);
                        oo = &wl->window->options;
                }
@@ -79,8 +94,7 @@ cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq)
                if (args_has(self->args, 'g'))
                        oo = &global_s_options;
                else {
-                       s = cmd_find_session(cmdq, args_get(args, 't'), 0);
-                       if (s == NULL)
+                       if ((s = cmdq->state.s) == NULL)
                                return (CMD_RETURN_ERROR);
                        oo = &s->options;
                }
diff --git a/cmd-source-file.c b/cmd-source-file.c
index e5710a0..247e72f 100644
--- a/cmd-source-file.c
+++ b/cmd-source-file.c
@@ -35,7 +35,8 @@ const struct cmd_entry cmd_source_file_entry = {
        "", 1, 1,
        "path",
        0,
-       cmd_source_file_exec
+       cmd_source_file_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-split-window.c b/cmd-split-window.c
index 6b90125..88c2635 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -39,8 +39,9 @@ const struct cmd_entry cmd_split_window_entry = {
        "bc:dF:l:hp:Pt:v", 0, -1,
        "[-bdhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
        CMD_TARGET_PANE_USAGE " [command]",
-       0,
-       cmd_split_window_exec
+       CMD_PREPAREPANE,
+       cmd_split_window_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -62,9 +63,13 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
        struct format_tree      *ft;
        struct environ_entry    *envent;
 
-       if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
+       if ((wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
-       w = wl->window;
+       else {
+               w = wl->window;
+               s = cmdq->state.s;
+               wp = cmdq->state.wp;
+       }
        server_unzoom_window(w);
 
        environ_init(&env);
diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c
index 918a2e4..75094cb 100644
--- a/cmd-swap-pane.c
+++ b/cmd-swap-pane.c
@@ -32,8 +32,9 @@ const struct cmd_entry cmd_swap_pane_entry = {
        "swap-pane", "swapp",
        "dDs:t:U", 0, 0,
        "[-dDU] " CMD_SRCDST_PANE_USAGE,
-       0,
-       cmd_swap_pane_exec
+       CMD_PREPAREPANE,
+       cmd_swap_pane_exec,
+       NULL
 };
 
 enum cmd_retval
@@ -46,10 +47,10 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
        struct layout_cell      *src_lc, *dst_lc;
        u_int                    sx, sy, xoff, yoff;
 
-       dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &dst_wp);
-       if (dst_wl == NULL)
+       if ((dst_wl = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
        dst_w = dst_wl->window;
+       dst_wp = cmdq->state.wp;
        server_unzoom_window(dst_w);
 
        if (!args_has(args, 's')) {
diff --git a/cmd-swap-window.c b/cmd-swap-window.c
index 655b910..745b2bf 100644
--- a/cmd-swap-window.c
+++ b/cmd-swap-window.c
@@ -27,31 +27,42 @@
  */
 
 enum cmd_retval        cmd_swap_window_exec(struct cmd *, struct cmd_q *);
+void           cmd_swap_window_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_swap_window_entry = {
        "swap-window", "swapw",
        "ds:t:", 0, 0,
        "[-d] " CMD_SRCDST_WINDOW_USAGE,
-       0,
-       cmd_swap_window_exec
+       CMD_PREPAREWINDOW,
+       cmd_swap_window_exec,
+       cmd_swap_window_prepare
 };
 
+void
+cmd_swap_window_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       cmdq->state.wl = cmd_find_window(cmdq, args_get(args, 's'),
+           &cmdq->state.s);
+       cmdq->state.wl2 = cmd_find_window(cmdq, args_get(args, 't'),
+           &cmdq->state.s2);
+}
+
 enum cmd_retval
 cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq)
 {
-       struct args             *args = self->args;
-       const char              *target_src, *target_dst;
        struct session          *src, *dst;
        struct session_group    *sg_src, *sg_dst;
        struct winlink          *wl_src, *wl_dst;
        struct window           *w;
 
-       target_src = args_get(args, 's');
-       if ((wl_src = cmd_find_window(cmdq, target_src, &src)) == NULL)
+       if ((wl_src = cmdq->state.wl) == NULL)
                return (CMD_RETURN_ERROR);
-       target_dst = args_get(args, 't');
-       if ((wl_dst = cmd_find_window(cmdq, target_dst, &dst)) == NULL)
+       src = cmdq->state.s;
+       if ((wl_dst = cmdq->state.wl2) == NULL)
                return (CMD_RETURN_ERROR);
+       dst = cmdq->state.s2;
 
        sg_src = session_group_find(src);
        sg_dst = session_group_find(dst);
diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index 439f593..b95f250 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -28,15 +28,26 @@
  */
 
 enum cmd_retval         cmd_switch_client_exec(struct cmd *, struct cmd_q *);
+void            cmd_switch_client_prepare(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_switch_client_entry = {
        "switch-client", "switchc",
        "lc:npt:r", 0, 0,
        "[-lnpr] [-c target-client] [-t target-session]",
-       CMD_READONLY,
-       cmd_switch_client_exec
+       CMD_READONLY|CMD_PREPARECLIENT|CMD_PREPARESESSION,
+       cmd_switch_client_exec,
+       cmd_switch_client_prepare
 };
 
+void
+cmd_switch_client_prepare(struct cmd *self, struct cmd_q *cmdq)
+{
+       struct args     *args = self->args;
+
+       cmdq->state.c = cmd_find_client(cmdq, args_get(args, 'c'), 0);
+       cmdq->state.s = cmd_find_session(cmdq, args_get(args, 't'), 0);
+}
+
 enum cmd_retval
 cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
 {
@@ -48,7 +59,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
        struct window_pane      *wp = NULL;
        const char              *tflag;
 
-       if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 0)) == NULL)
+       if ((c = cmdq->state.c) == NULL)
                return (CMD_RETURN_ERROR);
 
        if (args_has(args, 'r')) {
@@ -104,6 +115,9 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
                }
        }
 
+       if ((s = cmdq->state.s) == NULL)
+               return (CMD_RETURN_ERROR);
+
        if (c->session != NULL)
                c->last_session = c->session;
        c->session = s;
diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c
index 710210c..284c86e 100644
--- a/cmd-unbind-key.c
+++ b/cmd-unbind-key.c
@@ -34,7 +34,8 @@ const struct cmd_entry cmd_unbind_key_entry = {
        "acnt:", 0, 1,
        "[-acn] [-t mode-table] key",
        0,
-       cmd_unbind_key_exec
+       cmd_unbind_key_exec,
+       NULL
 };
 
 enum cmd_retval
diff --git a/cmd-wait-for.c b/cmd-wait-for.c
index a3e8585..c90427d 100644
--- a/cmd-wait-for.c
+++ b/cmd-wait-for.c
@@ -35,7 +35,8 @@ const struct cmd_entry cmd_wait_for_entry = {
        "LSU", 1, 1,
        "[-L|-S|-U] channel",
        0,
-       cmd_wait_for_exec
+       cmd_wait_for_exec,
+       NULL
 };
 
 struct wait_channel {


commit 9b8982f472a55c3cd44c3f5b00522ccfc995abce
Author: Thomas Adam <tho...@xteddy.org>
Commit: Thomas Adam <tho...@xteddy.org>

    Add hooks infrastructure
    
    Define a structure for holding hook information, as well as set/show hook
    commands.
---
 Makefile.am      |    3 +
 cmd-set-hook.c   |   95 +++++++++++++++++++++++++++++++++++++++++++++
 cmd-show-hooks.c |   62 ++++++++++++++++++++++++++++++
 cmd.c            |    2 +
 hooks.c          |  112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 session.c        |    2 +
 tmux.c           |    2 +
 tmux.h           |   27 +++++++++++++
 8 files changed, 305 insertions(+), 0 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 071c3a1..7739f24 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -118,8 +118,10 @@ dist_tmux_SOURCES = \
        cmd-send-keys.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 \
@@ -139,6 +141,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..75aebb9
--- /dev/null
+++ b/cmd-set-hook.c
@@ -0,0 +1,95 @@
+/* $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 <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]",
+       CMD_PREPARESESSION,
+       cmd_set_hook_exec,
+       NULL
+};
+
+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;
+
+       s = cmdq->state.s;
+       if (s == NULL || args_has(args, 'g'))
+               hooks = &global_hooks;
+       else
+               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..4babd76
--- /dev/null
+++ b/cmd-show-hooks.c
@@ -0,0 +1,62 @@
+/* $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 <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 *);
+
+const struct cmd_entry cmd_show_hooks_entry = {
+       "show-hooks", NULL,
+       "gt:", 0, 1,
+       "[-g] " CMD_TARGET_SESSION_USAGE,
+       CMD_PREPARESESSION,
+       cmd_show_hooks_exec,
+       NULL
+};
+
+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 = cmdq->state.s) == 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 66716bd..205b241 100644
--- a/cmd.c
+++ b/cmd.c
@@ -95,10 +95,12 @@ const struct cmd_entry *cmd_table[] = {
        &cmd_server_info_entry,
        &cmd_set_buffer_entry,
        &cmd_set_environment_entry,
+       &cmd_set_hook_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..c41a5e3
--- /dev/null
+++ b/hooks.c
@@ -0,0 +1,112 @@
+/* $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 <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_prepare(cmd, cmdq);
+               /* TA:  FIXME:  How do we handle errors here, if at all??? */
+               cmd->entry->exec(cmd, cmdq);
+       }
+}
diff --git a/session.c b/session.c
index 3ac9fb2..4453164 100644
--- a/session.c
+++ b/session.c
@@ -105,6 +105,7 @@ session_create(const char *name, int argc, char **argv, 
const char *path,
        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)
@@ -163,6 +164,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 5a1988e..36ca7a8 100644
--- a/tmux.c
+++ b/tmux.c
@@ -39,6 +39,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;
 
@@ -289,6 +290,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 ab191c6..ba79969 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1027,6 +1027,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;
@@ -1052,6 +1064,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 */
@@ -1503,6 +1516,7 @@ struct options_table_entry {
 #define CMD_BUFFER_USAGE "[-b buffer-name]"
 
 /* tmux.c */
+extern struct hooks   global_hooks;
 extern struct options global_options;
 extern struct options global_s_options;
 extern struct options global_w_options;
@@ -1551,6 +1565,17 @@ void              format_window_pane(struct format_tree 
*,
 void            format_paste_buffer(struct format_tree *,
                     struct paste_buffer *, int);
 
+/* 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;
@@ -1828,10 +1853,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;


commit 574c60e83f44f85782b464b8e935df88aa762b3b
Author: Thomas Adam <tho...@xteddy.org>
Commit: Thomas Adam <tho...@xteddy.org>

    Introduce prepare mechanism for commands
    
    Commands now set their running context separately from executing.  The
    state is used at execution time of commands, and by separating this out, the
    command state can be queried for any hooked commands.
---
 cmd.c  |   32 ++++++++++++++++++++++++++++++++
 tmux.h |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/cmd.c b/cmd.c
index eeffe4c..66716bd 100644
--- a/cmd.c
+++ b/cmd.c
@@ -312,6 +312,38 @@ usage:
        return (NULL);
 }
 
+void
+cmd_prepare(struct cmd *cmd, struct cmd_q *cmdq)
+{
+       struct args             *args = cmd->args;
+       const char              *tflag = args_get(args, 't');
+       struct cmd_state        *state = &cmdq->state;
+
+       /* FIXME:  Handle this!  What should happen during cfg_load? */
+       if (cfg_finished == 0)
+               return;
+
+       /*
+        * Prepare the context for the command.  It might be the case that a
+        * hooked command is being called.  If this command doesn't have a
+        * tflag, use the same one as the command being hooked.
+        */
+       if (tflag == NULL && cmdq->state.prior_tflag != NULL)
+               tflag = state->prior_tflag;
+
+       if (cmd->entry->flags & CMD_PREPARESESSION)
+               state->s = cmd_find_session(cmdq, tflag, 0);
+       if (cmd->entry->flags & CMD_PREPAREWINDOW)
+               state->wl = cmd_find_window(cmdq, tflag, NULL);
+       if (cmd->entry->flags & CMD_PREPAREPANE)
+               state->wl = cmd_find_pane(cmdq, tflag, &state->s, &state->wp);
+       if (cmd->entry->flags & CMD_PREPARECLIENT)
+               state->c = cmd_find_client(cmdq, tflag, 0);
+
+       if (cmd->entry->prepare != NULL)
+               cmd->entry->prepare(cmd, cmdq);
+}
+
 size_t
 cmd_print(struct cmd *cmd, char *buf, size_t len)
 {
diff --git a/tmux.h b/tmux.h
index 8fbda56..ab191c6 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1347,6 +1347,31 @@ struct args {
        char                    **argv;
 };
 
+/* Context for a command about to be executed. */
+struct cmd_state {
+       struct client           *c;
+
+       struct session          *s;
+       struct session          *s2;
+
+       struct winlink          *wl;
+       struct winlink          *wl2;
+
+       struct window           *w;
+       struct window           *w2;
+
+       struct window_pane      *wp;
+       struct window_pane      *wp2;
+
+       int                      idx;
+
+       const char              *tflag;
+       const char              *sflag;
+
+       const char              *prior_tflag;
+       const char              *prior_sflag;
+};
+
 /* Command and list of commands. */
 struct cmd {
        const struct cmd_entry  *entry;
@@ -1391,6 +1416,7 @@ struct cmd_q {
        struct cmd_q_items       queue;
        struct cmd_q_item       *item;
        struct cmd              *cmd;
+       struct cmd_state         state;
 
        time_t                   time;
        u_int                    number;
@@ -1415,9 +1441,14 @@ struct cmd_entry {
 #define CMD_STARTSERVER 0x1
 #define CMD_CANTNEST 0x2
 #define CMD_READONLY 0x4
+#define CMD_PREPARESESSION 0x8
+#define CMD_PREPAREWINDOW 0x10
+#define CMD_PREPAREPANE 0x20
+#define CMD_PREPARECLIENT 0x40
        int              flags;
 
        enum cmd_retval  (*exec)(struct cmd *, struct cmd_q *);
+       void             (*prepare)(struct cmd *, struct cmd_q *);
 };
 
 /* Key binding. */
@@ -1713,6 +1744,7 @@ char             **cmd_copy_argv(int, char **);
 void            cmd_free_argv(int, char **);
 char           *cmd_stringify_argv(int, char **);
 struct cmd     *cmd_parse(int, char **, const char *, u_int, char **);
+void            cmd_prepare(struct cmd *, struct cmd_q *);
 size_t          cmd_print(struct cmd *, char *, size_t);
 struct session *cmd_current_session(struct cmd_q *, int);
 struct client  *cmd_current_client(struct cmd_q *);


-----------------------------------------------------------------------

Summary of changes:
 HOOK-NOTES              |  118 -----------------------------------------------
 Makefile.am             |    4 +-
 cmd-attach-session.c    |    2 +-
 cmd-break-pane.c        |    8 ++--
 cmd-capture-pane.c      |    2 +-
 cmd-choose-buffer.c     |    4 +-
 cmd-choose-client.c     |    4 +-
 cmd-choose-tree.c       |    6 +-
 cmd-clear-history.c     |    2 +-
 cmd-clock-mode.c        |    2 +-
 cmd-command-prompt.c    |    2 +-
 cmd-confirm-before.c    |    2 +-
 cmd-copy-mode.c         |    2 +-
 cmd-detach-client.c     |    8 ++--
 cmd-display-message.c   |   20 ++++----
 cmd-display-panes.c     |    2 +-
 cmd-find-window.c       |    4 +-
 cmd-has-session.c       |    2 +-
 cmd-if-shell.c          |   14 +++---
 cmd-join-pane.c         |   20 ++++----
 cmd-kill-pane.c         |    4 +-
 cmd-kill-session.c      |    2 +-
 cmd-kill-window.c       |    4 +-
 cmd-list-clients.c      |    2 +-
 cmd-list-panes.c        |   10 ++--
 cmd-list-windows.c      |    4 +-
 cmd-lock-server.c       |    8 ++--
 cmd-move-window.c       |   20 ++++----
 cmd-new-window.c        |   10 ++--
 cmd-paste-buffer.c      |    4 +-
 cmd-pipe-pane.c         |    4 +-
 cmd-queue.c             |   43 ++++++++---------
 cmd-refresh-client.c    |    2 +-
 cmd-rename-session.c    |    2 +-
 cmd-rename-window.c     |    2 +-
 cmd-resize-pane.c       |    4 +-
 cmd-respawn-pane.c      |    6 +-
 cmd-respawn-window.c    |    4 +-
 cmd-rotate-window.c     |    2 +-
 cmd-run-shell.c         |   17 ++-----
 cmd-select-layout.c     |    2 +-
 cmd-select-pane.c       |   12 ++--
 cmd-select-window.c     |   12 ++--
 cmd-send-keys.c         |    6 +-
 cmd-set-environment.c   |    2 +-
 cmd-set-hook.c          |    8 ++-
 cmd-show-environment.c  |    2 +-
 cmd-show-hooks.c        |    2 +-
 cmd-show-messages.c     |    2 +-
 cmd-show-options.c      |    8 ++--
 cmd-split-window.c      |   10 ++--
 cmd-swap-pane.c         |    4 +-
 cmd-swap-window.c       |   16 +++---
 cmd-switch-client.c     |    8 ++--
 cmd.c                   |   18 +++++--
 compat/asprintf.c       |    2 +
 configure.ac            |   94 +++++++++++++++++++-------------------
 examples/xterm-keys.vim |    3 -
 format.c                |   10 +++-
 grid-view.c             |    9 +---
 hooks.c                 |    5 ++-
 osdep-cygwin.c          |    2 +-
 osdep-openbsd.c         |    3 +-
 screen.c                |    4 +-
 server-fn.c             |    1 +
 server.c                |    1 +
 tmux.1                  |   13 ++++-
 tmux.h                  |   12 ++++-
 window-choose.c         |    9 +--
 window-copy.c           |   44 +++++++++++++----
 window.c                |    2 +
 71 files changed, 317 insertions(+), 391 deletions(-)
 delete mode 100644 HOOK-NOTES


hooks/post-receive
-- 
tmux

------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
tmux-cvs mailing list
tmux-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to