diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-07-17 15:03:12 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-07-17 15:03:12 +0000 |
commit | ff129840bbc95ad2f504d1fac3afee6547e707f2 (patch) | |
tree | f48c1fe6ed4fcaa70337210ea5dcf4ac69a6f9cd /usr.bin/tmux/cmd-new-session.c | |
parent | 1f6bbb790b00f2d31c281d739ce0ae4985fc9304 (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.c | 123 |
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 |