Instead of every command resolving the target (-t or -s) itself, prepare

the state (client, session, winlink, pane) for it it before entering the
command. Each command provides some flags that tell the prepare step
what it is expecting.

This is a requirement for having hooks on commands (for example, if you
hook "select-window -t1:2", the hook command should to operate on window
1:2 not whatever it thinks is the current window), and should allow some
other target improvements.

The old cmd_find_* functions remain for the moment but that layer will
be dropped later.

Joint work with Thomas Adam.
This commit is contained in:
nicm
2015-12-13 14:32:38 +00:00
parent 5ed17e84fa
commit 4a4daf1303
56 changed files with 606 additions and 599 deletions

View File

@ -41,7 +41,7 @@ const struct cmd_entry cmd_new_session_entry = {
"[-AdDEP] [-c start-directory] [-F format] [-n window-name] "
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
"[-y height] [command]",
CMD_STARTSERVER,
CMD_STARTSERVER|CMD_CANFAIL|CMD_SESSION_T,
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_SESSION_T,
cmd_new_session_exec
};
@ -57,8 +57,9 @@ enum cmd_retval
cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c = cmdq->client, *c0;
struct session *s, *groupwith;
struct client *c = cmdq->client;
struct session *s, *attach_sess;
struct session *groupwith = cmdq->state.tflag.s;
struct window *w;
struct environ *env;
struct termios tio, *tiop;
@ -71,8 +72,10 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
struct environ_entry *envent;
if (self->entry == &cmd_has_session_entry) {
if (cmd_find_session(cmdq, args_get(args, 't'), 0) == NULL)
return (CMD_RETURN_ERROR);
/*
* cmd_prepare() will fail if the session cannot be found,
* hence always return success here.
*/
return (CMD_RETURN_NORMAL);
}
@ -87,9 +90,16 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
cmdq_error(cmdq, "bad session name: %s", newname);
return (CMD_RETURN_ERROR);
}
if (session_find(newname) != NULL) {
if ((attach_sess = session_find(newname)) != NULL) {
if (args_has(args, 'A')) {
return (cmd_attach_session(cmdq, newname,
/*
* This cmdq is now destined for
* attach-session. Because attach-session
* will have already been prepared, copy this
* session into its tflag so it can be used.
*/
cmdq->state.tflag.s = attach_sess;
return (cmd_attach_session(cmdq,
args_has(args, 'D'), 0, NULL,
args_has(args, 'E')));
}
@ -98,12 +108,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
}
}
target = args_get(args, 't');
if (target != NULL) {
groupwith = cmd_find_session(cmdq, target, 0);
if (groupwith == NULL)
return (CMD_RETURN_ERROR);
} else
if ((target = args_get(args, 't')) == NULL)
groupwith = NULL;
/* Set -d if no client. */
@ -120,14 +125,11 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
to_free = NULL;
if (args_has(args, 'c')) {
ft = format_create(cmdq, 0);
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), NULL, NULL,
NULL);
format_defaults(ft, c, NULL, NULL, NULL);
to_free = cwd = format_expand(ft, args_get(args, 'c'));
format_free(ft);
} else if (c != NULL && c->session == NULL)
cwd = c->cwd;
else if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL)
cwd = c0->session->cwd;
else
cwd = ".";
@ -193,7 +195,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
/* Figure out the command for the new window. */
argc = -1;
argv = NULL;
if (target == NULL && args->argc != 0) {
if (!args_has(args, 't') && args->argc != 0) {
argc = args->argc;
argv = args->argv;
} else if (target == NULL) {
@ -245,7 +247,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
* If a target session is given, this is to be part of a session group,
* so add it to the group and synchronize.
*/
if (groupwith != NULL) {
if (args_has(args, 't')) {
session_group_add(groupwith, s);
session_group_synchronize_to(s);
session_select(s, RB_MIN(winlinks, &s->windows)->idx);
@ -285,8 +287,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
template = NEW_SESSION_TEMPLATE;
ft = format_create(cmdq, 0);
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL);
format_defaults(ft, c, s, NULL, NULL);
cp = format_expand(ft, template);
cmdq_print(cmdq, "%s", cp);