The branch, hooks has been updated
discards cfd092f93e207d1594bb38745dcd274bf7de75a1 (commit)
discards 2b760991cf50fdec456919c4d43c2f0146f3f722 (commit)
discards 137e41da73235e1a06ca5895cfa1804b61851c79 (commit)
discards bc5bf9ce97f8033f1f364e820a7c77e84d3d9280 (commit)
discards 91e9eefdf5beb53fd39c15253039e2d196c557a8 (commit)
discards 9b8982f472a55c3cd44c3f5b00522ccfc995abce (commit)
discards 574c60e83f44f85782b464b8e935df88aa762b3b (commit)
discards 03c698e0a0ec3ee26170fe88334e8e8537c950e4 (commit)
discards 6dec9746b1f9a31e6a5fb0cbd0ebe20241a863dc (commit)
discards 0ad7514ec8301d6291b00d2288b440ea2556617c (commit)
via 245ecdcdc11da06aad59bc522596d16ce76ffaa6 (commit)
via abd0963734a8c93c4db96ca983611133bbd38514 (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 (cfd092f93e207d1594bb38745dcd274bf7de75a1)
\
N -- N -- N (245ecdcdc11da06aad59bc522596d16ce76ffaa6)
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 245ecdcdc11da06aad59bc522596d16ce76ffaa6
Author: Thomas Adam <[email protected]>
Commit: Thomas Adam <[email protected]>
Commands: Make use of prepare
Switch over all tmux commands to make use of prepare.
---
cmd-attach-session.c | 6 +++-
cmd-break-pane.c | 6 +++-
cmd-capture-pane.c | 4 +-
cmd-choose-buffer.c | 6 ++--
cmd-choose-client.c | 6 ++--
cmd-choose-tree.c | 13 ++++++----
cmd-clear-history.c | 7 ++---
cmd-clock-mode.c | 7 ++---
cmd-command-prompt.c | 4 +-
cmd-confirm-before.c | 4 +-
cmd-copy-mode.c | 5 +--
cmd-detach-client.c | 10 +++----
cmd-display-message.c | 21 ++++++----------
cmd-display-panes.c | 7 ++---
cmd-find-window.c | 6 ++--
cmd-has-session.c | 8 ++----
cmd-if-shell.c | 20 ++++++++--------
cmd-join-pane.c | 13 +++++----
cmd-kill-pane.c | 6 ++--
cmd-kill-session.c | 4 +-
cmd-kill-window.c | 8 +++---
cmd-list-clients.c | 11 +++-----
cmd-list-keys.c | 3 +-
cmd-list-panes.c | 8 +++---
cmd-list-windows.c | 5 +--
cmd-lock-server.c | 13 ++++------
cmd-move-window.c | 13 +++++----
cmd-new-session.c | 11 ++++----
cmd-new-window.c | 13 ++++-----
cmd-paste-buffer.c | 7 +++--
cmd-pipe-pane.c | 5 ++-
cmd-queue.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
cmd-refresh-client.c | 4 +-
cmd-rename-session.c | 4 +-
cmd-rename-window.c | 5 +--
cmd-resize-pane.c | 5 ++-
cmd-respawn-pane.c | 6 +++-
cmd-respawn-window.c | 5 ++-
cmd-rotate-window.c | 5 +--
cmd-run-shell.c | 14 ++++-------
cmd-select-layout.c | 8 +++---
cmd-select-pane.c | 11 ++++----
cmd-select-window.c | 16 +++++-------
cmd-send-keys.c | 8 ++++--
cmd-set-environment.c | 4 +-
cmd-set-hook.c | 4 +--
cmd-show-environment.c | 5 ++-
cmd-show-hooks.c | 3 +-
cmd-show-messages.c | 6 ++--
cmd-show-options.c | 10 +++----
cmd-split-window.c | 10 +++++--
cmd-swap-pane.c | 6 ++--
cmd-swap-window.c | 13 ++++------
cmd-switch-client.c | 5 +++-
cmd.c | 36 ++++++++++++++++++++++++++++
tmux.h | 30 ++++++++++++++++++++++++
56 files changed, 329 insertions(+), 214 deletions(-)
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index 160f2a8..7dbf503 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -36,7 +36,7 @@ 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_CANTNEST|CMD_STARTSERVER|CMD_PREPARESESSION,
cmd_attach_session_exec
};
@@ -76,6 +76,8 @@ 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);
}
+ if ((s = cmdq->state.s) == NULL)
+ return (CMD_RETURN_ERROR);
if (cmdq->client == NULL)
return (CMD_RETURN_NORMAL);
@@ -190,5 +192,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-break-pane.c b/cmd-break-pane.c
index 0025167..db59869 100644
--- a/cmd-break-pane.c
+++ b/cmd-break-pane.c
@@ -34,7 +34,7 @@ const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp",
"dPF:t:", 0, 0,
"[-dP] [-F format] " CMD_TARGET_PANE_USAGE,
- 0,
+ CMD_PREPAREPANE,
cmd_break_pane_exec
};
@@ -54,8 +54,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..dade852 100644
--- a/cmd-capture-pane.c
+++ b/cmd-capture-pane.c
@@ -40,7 +40,7 @@ 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_PREPAREPANE,
cmd_capture_pane_exec
};
@@ -178,7 +178,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..86d82d7 100644
--- a/cmd-choose-buffer.c
+++ b/cmd-choose-buffer.c
@@ -36,7 +36,7 @@ const struct cmd_entry cmd_choose_buffer_entry = {
"choose-buffer", NULL,
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
- 0,
+ CMD_PREPAREWINDOW,
cmd_choose_buffer_exec
};
@@ -53,7 +53,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 +61,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..5f3368d 100644
--- a/cmd-choose-client.c
+++ b/cmd-choose-client.c
@@ -41,7 +41,7 @@ const struct cmd_entry cmd_choose_client_entry = {
"choose-client", NULL,
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
- 0,
+ CMD_PREPAREWINDOW,
cmd_choose_client_exec
};
@@ -61,12 +61,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..9de3cc2 100644
--- a/cmd-choose-tree.c
+++ b/cmd-choose-tree.c
@@ -48,7 +48,7 @@ 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_PREPAREWINDOW,
cmd_choose_tree_exec
};
@@ -56,7 +56,7 @@ const struct cmd_entry cmd_choose_session_entry = {
"choose-session", NULL,
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
- 0,
+ CMD_PREPAREWINDOW,
cmd_choose_tree_exec
};
@@ -64,7 +64,7 @@ const struct cmd_entry cmd_choose_window_entry = {
"choose-window", NULL,
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
- 0,
+ CMD_PREPAREWINDOW,
cmd_choose_tree_exec
};
@@ -87,12 +87,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..0a9b3bb 100644
--- a/cmd-clear-history.c
+++ b/cmd-clear-history.c
@@ -30,18 +30,17 @@ const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist",
"t:", 0, 0,
CMD_TARGET_PANE_USAGE,
- 0,
+ CMD_PREPAREPANE,
cmd_clear_history_exec
};
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..95e1a61 100644
--- a/cmd-clock-mode.c
+++ b/cmd-clock-mode.c
@@ -30,17 +30,16 @@ const struct cmd_entry cmd_clock_mode_entry = {
"clock-mode", NULL,
"t:", 0, 0,
CMD_TARGET_PANE_USAGE,
- 0,
+ CMD_PREPAREPANE,
cmd_clock_mode_exec
};
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..8173e60 100644
--- a/cmd-command-prompt.c
+++ b/cmd-command-prompt.c
@@ -38,7 +38,7 @@ 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_PREPARECLIENT,
cmd_command_prompt_exec
};
@@ -62,7 +62,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..beb91f3 100644
--- a/cmd-confirm-before.c
+++ b/cmd-confirm-before.c
@@ -37,7 +37,7 @@ const struct cmd_entry cmd_confirm_before_entry = {
"confirm-before", "confirm",
"p:t:", 1, 1,
"[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
- 0,
+ CMD_PREPARECLIENT,
cmd_confirm_before_exec
};
@@ -55,7 +55,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..0f8f47a 100644
--- a/cmd-copy-mode.c
+++ b/cmd-copy-mode.c
@@ -30,17 +30,16 @@ const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL,
"t:u", 0, 0,
"[-u] " CMD_TARGET_PANE_USAGE,
- 0,
+ CMD_PREPAREPANE,
cmd_copy_mode_exec
};
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-detach-client.c b/cmd-detach-client.c
index 600554a..68e3a07 100644
--- a/cmd-detach-client.c
+++ b/cmd-detach-client.c
@@ -32,7 +32,7 @@ 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_READONLY|CMD_PREPARECLIENT|CMD_PREPARESESSION,
cmd_detach_client_exec
};
@@ -40,7 +40,7 @@ const struct cmd_entry cmd_suspend_client_entry = {
"suspend-client", "suspendc",
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
- 0,
+ CMD_PREPARECLIENT,
cmd_detach_client_exec
};
@@ -68,8 +68,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 = cmd_find_session(cmdq, args_get(args, 's'), 0)) ==
NULL)
return (CMD_RETURN_ERROR);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -80,8 +79,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..260a4e5 100644
--- a/cmd-display-message.c
+++ b/cmd-display-message.c
@@ -39,7 +39,7 @@ const struct cmd_entry cmd_display_message_entry = {
"c:pt:F:", 0, 1,
"[-p] [-c target-client] [-F format] " CMD_TARGET_PANE_USAGE
" [message]",
- 0,
+ CMD_PREPAREWINDOW|CMD_PREPARECLIENT,
cmd_display_message_exec
};
@@ -58,15 +58,12 @@ 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);
+
+ c = cmd_current_client(cmdq);
+ 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");
@@ -74,11 +71,9 @@ cmd_display_message_exec(struct cmd *self, struct cmd_q
*cmdq)
}
if (args_has(args, 'c')) {
- c = cmd_find_client(cmdq, args_get(args, 'c'), 0);
- if (c == NULL)
+ if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 0)) == 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..ae11429 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -30,17 +30,16 @@ const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
- 0,
+ CMD_PREPARECLIENT,
cmd_display_panes_exec
};
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..e1ad542 100644
--- a/cmd-find-window.c
+++ b/cmd-find-window.c
@@ -51,7 +51,7 @@ 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_PREPAREWINDOW,
cmd_find_window_exec
};
@@ -143,13 +143,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..65485ea 100644
--- a/cmd-has-session.c
+++ b/cmd-has-session.c
@@ -30,16 +30,14 @@ const struct cmd_entry cmd_has_session_entry = {
"has-session", "has",
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
- 0,
+ CMD_PREPAREWINDOW,
cmd_has_session_exec
};
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..3411128 100644
--- a/cmd-if-shell.c
+++ b/cmd-if-shell.c
@@ -39,7 +39,7 @@ const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if",
"bFt:", 2, 3,
"[-bF] " CMD_TARGET_PANE_USAGE " shell-command command [command]",
- 0,
+ CMD_PREPAREPANE,
cmd_if_shell_exec
};
@@ -64,15 +64,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 = cmd_find_client(cmdq, NULL, 1);
+
+ 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..e3bffa2 100644
--- a/cmd-join-pane.c
+++ b/cmd-join-pane.c
@@ -36,7 +36,7 @@ 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_PREPAREPANE|CMD_PREPAREPANE2,
cmd_join_pane_exec
};
@@ -44,7 +44,7 @@ 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_PREPAREWINDOW|CMD_PREPAREPANE2,
cmd_join_pane_exec
};
@@ -67,16 +67,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..8962b59 100644
--- a/cmd-kill-pane.c
+++ b/cmd-kill-pane.c
@@ -32,19 +32,19 @@ const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp",
"at:", 0, 0,
"[-a] " CMD_TARGET_PANE_USAGE,
- 0,
+ CMD_PREPAREPANE,
cmd_kill_pane_exec
};
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-session.c b/cmd-kill-session.c
index d7e2a21..4b6bcb6 100644
--- a/cmd-kill-session.c
+++ b/cmd-kill-session.c
@@ -33,7 +33,7 @@ const struct cmd_entry cmd_kill_session_entry = {
"kill-session", NULL,
"at:", 0, 0,
"[-a] " CMD_TARGET_SESSION_USAGE,
- 0,
+ CMD_PREPARESESSION,
cmd_kill_session_exec
};
@@ -43,7 +43,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..4876638 100644
--- a/cmd-kill-window.c
+++ b/cmd-kill-window.c
@@ -30,7 +30,7 @@ const struct cmd_entry cmd_kill_window_entry = {
"kill-window", "killw",
"at:", 0, 0,
"[-a] " CMD_TARGET_WINDOW_USAGE,
- 0,
+ CMD_PREPAREWINDOW,
cmd_kill_window_exec
};
@@ -38,7 +38,7 @@ const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw",
"kt:", 0, 0,
"[-k] " CMD_TARGET_WINDOW_USAGE,
- 0,
+ CMD_PREPAREWINDOW,
cmd_kill_window_exec
};
@@ -52,9 +52,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 +67,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-clients.c b/cmd-list-clients.c
index 292be72..39ff759 100644
--- a/cmd-list-clients.c
+++ b/cmd-list-clients.c
@@ -39,7 +39,7 @@ const struct cmd_entry cmd_list_clients_entry = {
"list-clients", "lsc",
"F:t:", 0, 0,
"[-F format] " CMD_TARGET_SESSION_USAGE,
- CMD_READONLY,
+ CMD_READONLY|CMD_PREPARESESSION,
cmd_list_clients_exec
};
@@ -54,12 +54,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..c8ef414 100644
--- a/cmd-list-keys.c
+++ b/cmd-list-keys.c
@@ -44,7 +44,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..8bb0488 100644
--- a/cmd-list-panes.c
+++ b/cmd-list-panes.c
@@ -39,7 +39,7 @@ const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp",
"asF:t:", 0, 0,
"[-as] [-F format] " CMD_TARGET_WINDOW_USAGE,
- 0,
+ CMD_PREPARESESSION|CMD_PREPARESESSION2|CMD_PREPAREWINDOW,
cmd_list_panes_exec
};
@@ -50,16 +50,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-windows.c b/cmd-list-windows.c
index 5f73e8d..b4ebb45 100644
--- a/cmd-list-windows.c
+++ b/cmd-list-windows.c
@@ -49,7 +49,7 @@ const struct cmd_entry cmd_list_windows_entry = {
"list-windows", "lsw",
"F:at:", 0, 0,
"[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
- 0,
+ CMD_PREPARESESSION,
cmd_list_windows_exec
};
@@ -62,8 +62,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-lock-server.c b/cmd-lock-server.c
index de76475..beaaad8 100644
--- a/cmd-lock-server.c
+++ b/cmd-lock-server.c
@@ -38,35 +38,32 @@ const struct cmd_entry cmd_lock_session_entry = {
"lock-session", "locks",
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
- 0,
- cmd_lock_server_exec
+ CMD_PREPARESESSION,
+ cmd_lock_server_exec,
};
const struct cmd_entry cmd_lock_client_entry = {
"lock-client", "lockc",
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
- 0,
+ CMD_PREPARECLIENT,
cmd_lock_server_exec
};
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..4b7b53e 100644
--- a/cmd-move-window.c
+++ b/cmd-move-window.c
@@ -32,7 +32,7 @@ const struct cmd_entry cmd_move_window_entry = {
"move-window", "movew",
"dkrs:t:", 0, 0,
"[-dkr] " CMD_SRCDST_WINDOW_USAGE,
- 0,
+ CMD_PREPARESESSION|CMD_PREPARESESSION2|CMD_PREPAREWINDOW,
cmd_move_window_exec
};
@@ -40,7 +40,7 @@ const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw",
"dks:t:", 0, 0,
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
- 0,
+ CMD_PREPARESESSION|CMD_PREPAREWINDOW,
cmd_move_window_exec
};
@@ -54,8 +54,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 +62,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..13fce54 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -41,7 +41,7 @@ const struct cmd_entry cmd_new_session_entry = {
"[-AdDP] [-c start-directory] [-F format] [-n window-name] "
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
"[-y height] [command]",
- CMD_STARTSERVER|CMD_CANTNEST,
+ CMD_STARTSERVER|CMD_CANTNEST|CMD_PREPARESESSION,
cmd_new_session_exec
};
@@ -49,7 +49,7 @@ const struct cmd_entry cmd_has_session_entry = {
"has-session", "has",
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
- 0,
+ CMD_PREPARESESSION,
cmd_new_session_exec
};
@@ -99,12 +99,11 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
}
target = args_get(args, 't');
+ groupwith = NULL;
if (target != NULL) {
- groupwith = cmd_find_session(cmdq, target, 0);
- if (groupwith == NULL)
+ if ((groupwith = cmdq->state.s) == NULL)
return (CMD_RETURN_ERROR);
- } else
- groupwith = NULL;
+ }
/* Set -d if no client. */
detached = args_has(args, 'd');
diff --git a/cmd-new-window.c b/cmd-new-window.c
index 7f14b21..5f66aa0 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -32,14 +32,14 @@
#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 *);
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_PREPAREWINDOW|CMD_PREPAREIDX,
cmd_new_window_exec
};
@@ -47,17 +47,17 @@ 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;
- int argc, idx, last, detached, cwd, fd = -1;
+ int argc, last, detached, cwd, fd = -1;
+ int idx = cmdq->state.idx;
struct format_tree *ft;
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;
@@ -79,7 +79,6 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
server_unlink_window(s, wl);
}
} else {
- idx = cmd_find_index(cmdq, args_get(args, 't'), &s);
if (idx == -2)
return (CMD_RETURN_ERROR);
}
diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c
index 5d91aef..e76acd0 100644
--- a/cmd-paste-buffer.c
+++ b/cmd-paste-buffer.c
@@ -36,7 +36,7 @@ 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_PREPAREPANE,
cmd_paste_buffer_exec
};
@@ -45,17 +45,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..952ceff 100644
--- a/cmd-pipe-pane.c
+++ b/cmd-pipe-pane.c
@@ -39,7 +39,7 @@ const struct cmd_entry cmd_pipe_pane_entry = {
"pipe-pane", "pipep",
"ot:", 0, 1,
"[-o] " CMD_TARGET_PANE_USAGE " [command]",
- 0,
+ CMD_PREPAREPANE,
cmd_pipe_pane_exec
};
@@ -52,8 +52,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..ced2823 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.idx = -1;
+
+ 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,14 @@ 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);
+
+ cmdq_set_state(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..258e781 100644
--- a/cmd-refresh-client.c
+++ b/cmd-refresh-client.c
@@ -30,7 +30,7 @@ const struct cmd_entry cmd_refresh_client_entry = {
"refresh-client", "refresh",
"C:St:", 0, 0,
"[-S] [-C size] " CMD_TARGET_CLIENT_USAGE,
- 0,
+ CMD_PREPARECLIENT,
cmd_refresh_client_exec
};
@@ -42,7 +42,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..9ce6919 100644
--- a/cmd-rename-session.c
+++ b/cmd-rename-session.c
@@ -32,7 +32,7 @@ const struct cmd_entry cmd_rename_session_entry = {
"rename-session", "rename",
"t:", 1, 1,
CMD_TARGET_SESSION_USAGE " new-name",
- 0,
+ CMD_PREPARESESSION,
cmd_rename_session_exec
};
@@ -53,7 +53,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..821592c 100644
--- a/cmd-rename-window.c
+++ b/cmd-rename-window.c
@@ -32,7 +32,7 @@ const struct cmd_entry cmd_rename_window_entry = {
"rename-window", "renamew",
"t:", 1, 1,
CMD_TARGET_WINDOW_USAGE " new-name",
- 0,
+ CMD_PREPAREWINDOW,
cmd_rename_window_exec
};
@@ -40,10 +40,9 @@ 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..5301a57 100644
--- a/cmd-resize-pane.c
+++ b/cmd-resize-pane.c
@@ -32,7 +32,7 @@ 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_PREPAREPANE,
cmd_resize_pane_exec
};
@@ -48,9 +48,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..e192772 100644
--- a/cmd-respawn-pane.c
+++ b/cmd-respawn-pane.c
@@ -34,7 +34,7 @@ const struct cmd_entry cmd_respawn_pane_entry = {
"respawn-pane", "respawnp",
"kt:", 0, -1,
"[-k] " CMD_TARGET_PANE_USAGE " [command]",
- 0,
+ CMD_PREPAREPANE,
cmd_respawn_pane_exec
};
@@ -52,9 +52,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..2fb68a0 100644
--- a/cmd-respawn-window.c
+++ b/cmd-respawn-window.c
@@ -33,7 +33,7 @@ const struct cmd_entry cmd_respawn_window_entry = {
"respawn-window", "respawnw",
"kt:", 0, -1,
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
- 0,
+ CMD_PREPAREWINDOW,
cmd_respawn_window_exec
};
@@ -50,9 +50,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..69b20d2 100644
--- a/cmd-rotate-window.c
+++ b/cmd-rotate-window.c
@@ -30,21 +30,20 @@ const struct cmd_entry cmd_rotate_window_entry = {
"rotate-window", "rotatew",
"Dt:U", 0, 0,
"[-DU] " CMD_TARGET_WINDOW_USAGE,
- 0,
+ CMD_PREPAREWINDOW,
cmd_rotate_window_exec
};
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..af4a701 100644
--- a/cmd-run-shell.c
+++ b/cmd-run-shell.c
@@ -39,7 +39,7 @@ const struct cmd_entry cmd_run_shell_entry = {
"run-shell", "run",
"bt:", 1, 1,
"[-b] " CMD_TARGET_PANE_USAGE " shell-command",
- 0,
+ CMD_PREPAREPANE|CMD_PREPARESESSION,
cmd_run_shell_exec
};
@@ -75,21 +75,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-select-layout.c b/cmd-select-layout.c
index 77137b7..2859e0b 100644
--- a/cmd-select-layout.c
+++ b/cmd-select-layout.c
@@ -30,7 +30,7 @@ const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
"npt:", 0, 1,
"[-np] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
- 0,
+ CMD_PREPAREWINDOW,
cmd_select_layout_exec
};
@@ -38,7 +38,7 @@ const struct cmd_entry cmd_next_layout_entry = {
"next-layout", "nextl",
"t:", 0, 0,
CMD_TARGET_WINDOW_USAGE,
- 0,
+ CMD_PREPAREWINDOW,
cmd_select_layout_exec
};
@@ -46,7 +46,7 @@ const struct cmd_entry cmd_previous_layout_entry = {
"previous-layout", "prevl",
"t:", 0, 0,
CMD_TARGET_WINDOW_USAGE,
- 0,
+ CMD_PREPAREWINDOW,
cmd_select_layout_exec
};
@@ -58,7 +58,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..6e55330 100644
--- a/cmd-select-pane.c
+++ b/cmd-select-pane.c
@@ -30,7 +30,7 @@ const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
"DdeLlRt:U", 0, 0,
"[-DdeLlRU] " CMD_TARGET_PANE_USAGE,
- 0,
+ CMD_PREPAREPANE,
cmd_select_pane_exec
};
@@ -38,7 +38,7 @@ const struct cmd_entry cmd_last_pane_entry = {
"last-pane", "lastp",
"det:", 0, 0,
"[-de] " CMD_TARGET_WINDOW_USAGE,
- 0,
+ CMD_PREPAREPANE,
cmd_select_pane_exec
};
@@ -50,8 +50,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 +72,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..d5e8846 100644
--- a/cmd-select-window.c
+++ b/cmd-select-window.c
@@ -32,7 +32,7 @@ const struct cmd_entry cmd_select_window_entry = {
"select-window", "selectw",
"lnpTt:", 0, 0,
"[-lnpT] " CMD_TARGET_WINDOW_USAGE,
- 0,
+ CMD_PREPAREWINDOW,
cmd_select_window_exec
};
@@ -40,7 +40,7 @@ const struct cmd_entry cmd_next_window_entry = {
"next-window", "next",
"at:", 0, 0,
"[-a] " CMD_TARGET_SESSION_USAGE,
- 0,
+ CMD_PREPAREWINDOW,
cmd_select_window_exec
};
@@ -48,7 +48,7 @@ const struct cmd_entry cmd_previous_window_entry = {
"previous-window", "prev",
"at:", 0, 0,
"[-a] " CMD_TARGET_SESSION_USAGE,
- 0,
+ CMD_PREPAREWINDOW,
cmd_select_window_exec
};
@@ -56,14 +56,13 @@ const struct cmd_entry cmd_last_window_entry = {
"last-window", "last",
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
- 0,
+ CMD_PREPAREWINDOW,
cmd_select_window_exec
};
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 +78,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 +101,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..a3c9654 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -33,7 +33,7 @@ const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send",
"lRt:", 0, -1,
"[-lR] " CMD_TARGET_PANE_USAGE " key ...",
- 0,
+ CMD_PREPAREPANE,
cmd_send_keys_exec
};
@@ -41,7 +41,7 @@ const struct cmd_entry cmd_send_prefix_entry = {
"send-prefix", NULL,
"2t:", 0, 0,
"[-2] " CMD_TARGET_PANE_USAGE,
- 0,
+ CMD_PREPAREPANE,
cmd_send_keys_exec
};
@@ -55,8 +55,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-environment.c b/cmd-set-environment.c
index 83e63b4..1be1666 100644
--- a/cmd-set-environment.c
+++ b/cmd-set-environment.c
@@ -33,7 +33,7 @@ const struct cmd_entry cmd_set_environment_entry = {
"set-environment", "setenv",
"grt:u", 1, 2,
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
- 0,
+ CMD_PREPARESESSION,
cmd_set_environment_exec
};
@@ -63,7 +63,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-hook.c b/cmd-set-hook.c
index 75aebb9..4864c66 100644
--- a/cmd-set-hook.c
+++ b/cmd-set-hook.c
@@ -28,15 +28,13 @@
*/
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
+ cmd_set_hook_exec
};
enum cmd_retval
diff --git a/cmd-show-environment.c b/cmd-show-environment.c
index 7737752..dafd724 100644
--- a/cmd-show-environment.c
+++ b/cmd-show-environment.c
@@ -28,12 +28,13 @@
*/
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_PREPARESESSION,
cmd_show_environment_exec
};
@@ -48,7 +49,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-hooks.c b/cmd-show-hooks.c
index 4babd76..aee0c27 100644
--- a/cmd-show-hooks.c
+++ b/cmd-show-hooks.c
@@ -34,8 +34,7 @@ const struct cmd_entry cmd_show_hooks_entry = {
"gt:", 0, 1,
"[-g] " CMD_TARGET_SESSION_USAGE,
CMD_PREPARESESSION,
- cmd_show_hooks_exec,
- NULL
+ cmd_show_hooks_exec
};
enum cmd_retval
diff --git a/cmd-show-messages.c b/cmd-show-messages.c
index 308668f..90f32f3 100644
--- a/cmd-show-messages.c
+++ b/cmd-show-messages.c
@@ -34,7 +34,7 @@ const struct cmd_entry cmd_show_messages_entry = {
"show-messages", "showmsgs",
"IJTt:", 0, 0,
"[-IJT] " CMD_TARGET_CLIENT_USAGE,
- 0,
+ CMD_PREPARECLIENT,
cmd_show_messages_exec
};
@@ -123,7 +123,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 +152,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..c87ab51 100644
--- a/cmd-show-options.c
+++ b/cmd-show-options.c
@@ -38,7 +38,7 @@ const struct cmd_entry cmd_show_options_entry = {
"show-options", "show",
"gqst:vw", 0, 1,
"[-gqsvw] [-t target-session|target-window] [option]",
- 0,
+ CMD_PREPARESESSION|CMD_PREPAREWINDOW,
cmd_show_options_exec
};
@@ -46,7 +46,7 @@ const struct cmd_entry cmd_show_window_options_entry = {
"show-window-options", "showw",
"gvt:", 0, 1,
"[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
- 0,
+ CMD_PREPARESESSION|CMD_PREPAREWINDOW,
cmd_show_options_exec
};
@@ -69,8 +69,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 +78,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-split-window.c b/cmd-split-window.c
index 6b90125..f2465e0 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -39,7 +39,7 @@ 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_PREPAREPANE,
cmd_split_window_exec
};
@@ -62,9 +62,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..75c610b 100644
--- a/cmd-swap-pane.c
+++ b/cmd-swap-pane.c
@@ -32,7 +32,7 @@ const struct cmd_entry cmd_swap_pane_entry = {
"swap-pane", "swapp",
"dDs:t:U", 0, 0,
"[-dDU] " CMD_SRCDST_PANE_USAGE,
- 0,
+ CMD_PREPAREPANE,
cmd_swap_pane_exec
};
@@ -46,10 +46,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..52f1dde 100644
--- a/cmd-swap-window.c
+++ b/cmd-swap-window.c
@@ -32,26 +32,23 @@ 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_PREPARESESSION2
};
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..de3721c 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -33,7 +33,7 @@ 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_READONLY|CMD_PREPARESESSION,
cmd_switch_client_exec
};
@@ -104,6 +104,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.c b/cmd.c
index 9837d8a..bbee673 100644
--- a/cmd.c
+++ b/cmd.c
@@ -314,6 +314,42 @@ 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');
+ const char *sflag = args_get(args, 's');
+ 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_PREPARESESSION2)
+ state->s2 = cmd_find_session(cmdq, sflag, 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_PREPAREPANE2)
+ state->wl2 = cmd_find_pane(cmdq, sflag, &state->s, &state->wp);
+ if (cmd->entry->flags & CMD_PREPARECLIENT)
+ state->c = cmd_find_client(cmdq, tflag, 0);
+ if (cmd->entry->flags & CMD_PREPAREIDX)
+ state->idx = cmd_find_index(cmdq, tflag, &state->s);
+}
+
size_t
cmd_print(struct cmd *cmd, char *buf, size_t len)
{
diff --git a/tmux.h b/tmux.h
index c99d439..3b34753 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1360,6 +1360,27 @@ 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_pane *wp;
+ struct window_pane *wp2;
+
+ int idx;
+
+ const char *tflag;
+ const char *prior_tflag;
+};
+
/* Command and list of commands. */
struct cmd {
const struct cmd_entry *entry;
@@ -1404,6 +1425,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;
@@ -1428,6 +1450,13 @@ struct cmd_entry {
#define CMD_STARTSERVER 0x1
#define CMD_CANTNEST 0x2
#define CMD_READONLY 0x4
+#define CMD_PREPARESESSION 0x8
+#define CMD_PREPARESESSION2 0x10
+#define CMD_PREPAREWINDOW 0x20
+#define CMD_PREPAREPANE 0x40
+#define CMD_PREPAREPANE2 0x80
+#define CMD_PREPARECLIENT 0x100
+#define CMD_PREPAREIDX 0x200
int flags;
enum cmd_retval (*exec)(struct cmd *, struct cmd_q *);
@@ -1738,6 +1767,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 *);
commit abd0963734a8c93c4db96ca983611133bbd38514
Author: Thomas Adam <[email protected]>
Commit: Thomas Adam <[email protected]>
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 <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "tmux.h"
+
+/*
+ * Set a global or session hook.
+ */
+
+enum cmd_retval cmd_set_hook_exec(struct cmd *, struct cmd_q *);
+void cmd_set_hook_prepare(struct cmd *, struct cmd_q *);
+
+const struct cmd_entry cmd_set_hook_entry = {
+ "set-hook", NULL,
+ "gt:u", 1, 2,
+ "[-gu]" CMD_TARGET_SESSION_USAGE " hook-name [command]",
+ 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 <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "tmux.h"
+
+/*
+ * Show global or session hooks.
+ */
+
+enum cmd_retval cmd_show_hooks_exec(struct cmd *, struct cmd_q *);
+
+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 eeffe4c..9837d8a 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 <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "tmux.h"
+
+RB_GENERATE(hooks_tree, hook, entry, hooks_cmp);
+
+struct hook *hooks_find1(struct hooks *, const char *);
+
+int
+hooks_cmp(struct hook *hook1, struct hook *hook2)
+{
+ return (strcmp(hook1->name, hook2->name));
+}
+
+void
+hooks_init(struct hooks *hooks, struct hooks *parent)
+{
+ RB_INIT(&hooks->tree);
+ hooks->parent = parent;
+}
+
+void
+hooks_free(struct hooks *hooks)
+{
+ struct hook *hook, *hook1;
+
+ RB_FOREACH_SAFE(hook, hooks_tree, &hooks->tree, hook1)
+ hooks_remove(hooks, hook);
+}
+
+void
+hooks_add(struct hooks *hooks, const char *name, struct cmd_list *cmdlist)
+{
+ struct hook *hook;
+
+ if ((hook = hooks_find1(hooks, name)) != NULL)
+ hooks_remove(hooks, hook);
+
+ hook = xcalloc(1, sizeof *hook);
+ hook->name = xstrdup(name);
+ hook->cmdlist = cmdlist;
+ hook->cmdlist->references++;
+
+ RB_INSERT(hooks_tree, &hooks->tree, hook);
+}
+
+void
+hooks_remove(struct hooks *hooks, struct hook *hook)
+{
+ RB_REMOVE(hooks_tree, &hooks->tree, hook);
+ cmd_list_free(hook->cmdlist);
+ free((char *) hook->name);
+ free(hook);
+}
+
+struct hook *
+hooks_find1(struct hooks *hooks, const char *name)
+{
+ struct hook hook;
+
+ hook.name = name;
+ return (RB_FIND(hooks_tree, &hooks->tree, &hook));
+}
+
+struct hook *
+hooks_find(struct hooks *hooks, const char *name)
+{
+ struct hook hook0, *hook;
+
+ hook0.name = name;
+ hook = RB_FIND(hooks_tree, &hooks->tree, &hook0);
+ while (hook == NULL) {
+ hooks = hooks->parent;
+ if (hooks == NULL)
+ break;
+ hook = RB_FIND(hooks_tree, &hooks->tree, &hook0);
+ }
+ return (hook);
+}
+
+void
+hooks_run(struct hook *hook, struct cmd_q *cmdq)
+{
+ struct cmd *cmd;
+
+ TAILQ_FOREACH(cmd, &hook->cmdlist->list, qentry) {
+ cmd_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 8fbda56..c99d439 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 */
@@ -1472,6 +1485,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;
@@ -1520,6 +1534,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;
@@ -1796,10 +1821,12 @@ extern const struct cmd_entry cmd_send_prefix_entry;
extern const struct cmd_entry cmd_server_info_entry;
extern const struct cmd_entry cmd_set_buffer_entry;
extern const struct cmd_entry cmd_set_environment_entry;
+extern const struct cmd_entry cmd_set_hook_entry;
extern const struct cmd_entry cmd_set_option_entry;
extern const struct cmd_entry cmd_set_window_option_entry;
extern const struct cmd_entry cmd_show_buffer_entry;
extern const struct cmd_entry cmd_show_environment_entry;
+extern const struct cmd_entry cmd_show_hooks_entry;
extern const struct cmd_entry cmd_show_messages_entry;
extern const struct cmd_entry cmd_show_options_entry;
extern const struct cmd_entry cmd_show_window_options_entry;
-----------------------------------------------------------------------
Summary of changes:
cmd-attach-session.c | 5 +----
cmd-bind-key.c | 3 +--
cmd-break-pane.c | 3 +--
cmd-capture-pane.c | 3 +--
cmd-choose-buffer.c | 3 +--
cmd-choose-client.c | 4 +---
cmd-choose-tree.c | 9 +++------
cmd-clear-history.c | 4 +---
cmd-clock-mode.c | 3 +--
cmd-command-prompt.c | 3 +--
cmd-confirm-before.c | 3 +--
cmd-copy-mode.c | 3 +--
cmd-delete-buffer.c | 3 +--
cmd-detach-client.c | 20 +++-----------------
cmd-display-message.c | 27 +++------------------------
cmd-display-panes.c | 3 +--
cmd-find-window.c | 3 +--
cmd-has-session.c | 3 +--
cmd-if-shell.c | 20 +++-----------------
cmd-join-pane.c | 22 ++++------------------
cmd-kill-pane.c | 4 +---
cmd-kill-server.c | 6 ++----
cmd-kill-session.c | 4 +---
cmd-kill-window.c | 8 +++-----
cmd-list-buffers.c | 3 +--
cmd-list-clients.c | 3 +--
cmd-list-keys.c | 3 +--
cmd-list-panes.c | 19 ++-----------------
cmd-list-sessions.c | 3 +--
cmd-list-windows.c | 13 +------------
cmd-load-buffer.c | 3 +--
cmd-lock-server.c | 23 ++++-------------------
cmd-move-window.c | 24 +++---------------------
cmd-new-session.c | 17 +++++++----------
cmd-new-window.c | 22 ++++------------------
cmd-paste-buffer.c | 3 +--
cmd-pipe-pane.c | 3 +--
cmd-queue.c | 3 ++-
cmd-refresh-client.c | 3 +--
cmd-rename-session.c | 4 +---
cmd-rename-window.c | 4 +---
cmd-resize-pane.c | 3 +--
cmd-respawn-pane.c | 3 +--
cmd-respawn-window.c | 3 +--
cmd-rotate-window.c | 3 +--
cmd-run-shell.c | 3 +--
cmd-save-buffer.c | 6 ++----
cmd-select-layout.c | 9 +++------
cmd-select-pane.c | 20 ++------------------
cmd-select-window.c | 36 ++++--------------------------------
cmd-send-keys.c | 7 ++-----
cmd-set-buffer.c | 3 +--
cmd-set-environment.c | 4 +---
cmd-set-hook.c | 4 +---
cmd-set-option.c | 6 ++----
cmd-show-environment.c | 3 +--
cmd-show-hooks.c | 3 +--
cmd-show-messages.c | 6 ++----
cmd-show-options.c | 22 +++-------------------
cmd-source-file.c | 3 +--
cmd-split-window.c | 3 +--
cmd-swap-pane.c | 3 +--
cmd-swap-window.c | 16 +---------------
cmd-switch-client.c | 17 +++--------------
cmd-unbind-key.c | 3 +--
cmd-wait-for.c | 3 +--
cmd.c | 10 +++++++---
tmux.h | 14 ++++++--------
68 files changed, 123 insertions(+), 415 deletions(-)
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs