summaryrefslogtreecommitdiff
path: root/usr.bin/tmux/cmd-new-session.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2009-07-17 15:03:12 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2009-07-17 15:03:12 +0000
commitff129840bbc95ad2f504d1fac3afee6547e707f2 (patch)
treef48c1fe6ed4fcaa70337210ea5dcf4ac69a6f9cd /usr.bin/tmux/cmd-new-session.c
parent1f6bbb790b00f2d31c281d739ce0ae4985fc9304 (diff)
Tidy up new-session and attach-session and change them to work from inside
tmux, switching the current client to the new or requested session. Written with Josh Elsasser.
Diffstat (limited to 'usr.bin/tmux/cmd-new-session.c')
-rw-r--r--usr.bin/tmux/cmd-new-session.c123
1 files changed, 76 insertions, 47 deletions
diff --git a/usr.bin/tmux/cmd-new-session.c b/usr.bin/tmux/cmd-new-session.c
index 7e20496085c..56a0abba850 100644
--- a/usr.bin/tmux/cmd-new-session.c
+++ b/usr.bin/tmux/cmd-new-session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-new-session.c,v 1.3 2009/07/13 23:11:35 nicm Exp $ */
+/* $OpenBSD: cmd-new-session.c,v 1.4 2009/07/17 15:03:11 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -111,65 +111,80 @@ int
cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_new_session_data *data = self->data;
- struct client *c = ctx->cmdclient;
struct session *s;
char *cmd, *cwd, *cause;
u_int sx, sy;
- if (ctx->curclient != NULL)
- return (0);
+ if (data->newname != NULL && session_find(data->newname) != NULL) {
+ ctx->error(ctx, "duplicate session: %s", data->newname);
+ return (-1);
+ }
- if (!data->flag_detached) {
- if (c == NULL) {
- ctx->error(ctx, "no client to attach to");
+ /*
+ * There are two cases:
+ *
+ * 1. If cmdclient is non-NULL, new-session has been called from the
+ * command-line - cmdclient is to become a new attached, interactive
+ * client. Unless -d is given, the terminal must be opened and then
+ * the client sent MSG_READY.
+ *
+ * 2. If cmdclient is NULL, new-session has been called from an
+ * existing client (such as a key binding).
+ *
+ * In both cases, a new additional session needs to be created and
+ * (unless -d) set as the current session for the client.
+ */
+
+ /* Open the terminal if necessary. */
+ if (!data->flag_detached && ctx->cmdclient != NULL) {
+ if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
+ ctx->error(ctx, "not a terminal");
return (-1);
}
- if (!(c->flags & CLIENT_TERMINAL)) {
- ctx->error(ctx, "not a terminal");
+
+ if (tty_open(&ctx->cmdclient->tty, &cause) != 0) {
+ ctx->error(ctx, "open terminal failed: %s", cause);
+ xfree(cause);
return (-1);
}
}
- if (data->newname != NULL && session_find(data->newname) != NULL) {
- ctx->error(ctx, "duplicate session: %s", data->newname);
- return (-1);
+ /* Find new session size and options. */
+ if (data->flag_detached) {
+ sx = 80;
+ sy = 25;
+ } else {
+ if (ctx->cmdclient != NULL) {
+ sx = ctx->cmdclient->tty.sx;
+ sy = ctx->cmdclient->tty.sy;
+ } else {
+ sx = ctx->curclient->tty.sx;
+ sy = ctx->curclient->tty.sy;
+ }
}
-
- cmd = data->cmd;
- if (cmd == NULL)
- cmd = options_get_string(&global_s_options, "default-command");
- if (c == NULL || c->cwd == NULL)
+ if (sy > 0 && options_get_number(&global_s_options, "status"))
+ sy--;
+ if (sx == 0)
+ sx = 1;
+ if (sy == 0)
+ sy = 1;
+ if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
+ cwd = ctx->cmdclient->cwd;
+ else
cwd = options_get_string(&global_s_options, "default-path");
+ if (data->cmd != NULL)
+ cmd = data->cmd;
else
- cwd = c->cwd;
-
- sx = 80;
- sy = 25;
- if (!data->flag_detached) {
- sx = c->tty.sx;
- sy = c->tty.sy;
- }
-
- if (options_get_number(&global_s_options, "status")) {
- if (sy == 0)
- sy = 1;
- else
- sy--;
- }
-
- if (!data->flag_detached && tty_open(&c->tty, &cause) != 0) {
- ctx->error(ctx, "open terminal failed: %s", cause);
- xfree(cause);
- return (-1);
- }
-
+ cmd = options_get_string(&global_s_options, "default-command");
+ /* Create the new session. */
s = session_create(data->newname, cmd, cwd, sx, sy, &cause);
if (s == NULL) {
ctx->error(ctx, "create session failed: %s", cause);
xfree(cause);
return (-1);
}
+
if (data->winname != NULL) {
xfree(s->curw->window->name);
s->curw->window->name = xstrdup(data->winname);
@@ -177,17 +192,31 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
&s->curw->window->options, "automatic-rename", 0);
}
- if (data->flag_detached) {
- if (c != NULL)
- server_write_client(c, MSG_EXIT, NULL, 0);
- } else {
- c->session = s;
- server_write_client(c, MSG_READY, NULL, 0);
- server_redraw_client(c);
+ /*
+ * If a command client exists, it is either taking this session (and
+ * needs to get MSG_READY and stay around), or -d is given and it needs
+ * to exit.
+ */
+ if (ctx->cmdclient != NULL) {
+ if (!data->flag_detached)
+ server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
+ else
+ server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
+ }
+
+ /* Set the client to the new session. */
+ if (!data->flag_detached) {
+ if (ctx->cmdclient != NULL) {
+ ctx->cmdclient->session = s;
+ server_redraw_client(ctx->cmdclient);
+ } else {
+ ctx->curclient->session = s;
+ server_redraw_client(ctx->curclient);
+ }
}
recalculate_sizes();
- return (1);
+ return (1); /* 1 means don't tell command client to exit */
}
void