From 51487ed22f0acf199f64728f3efc15a3c9ad615f Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sat, 11 Dec 2010 18:39:25 +0000 Subject: [PATCH] Track the last session for a client and add a flag to switch-client and a key binding (L) to move a client back to its last session. --- cmd-new-session.c | 8 +++++++ cmd-switch-client.c | 52 +++++++++++++++++++++++++++++++++------------ key-bindings.c | 1 + server-client.c | 1 + server-fn.c | 1 + tmux.1 | 8 +++++-- tmux.h | 1 + 7 files changed, 57 insertions(+), 15 deletions(-) diff --git a/cmd-new-session.c b/cmd-new-session.c index 290d5a3b..573b0ebb 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -279,9 +279,17 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) if (!detached) { if (ctx->cmdclient != NULL) { server_write_client(ctx->cmdclient, MSG_READY, NULL, 0); + if (ctx->cmdclient->session != NULL) { + session_index(ctx->cmdclient->session, + &ctx->cmdclient->last_session); + } ctx->cmdclient->session = s; server_redraw_client(ctx->cmdclient); } else { + if (ctx->curclient->session != NULL) { + session_index(ctx->curclient->session, + &ctx->curclient->last_session); + } ctx->curclient->session = s; server_redraw_client(ctx->curclient); } diff --git a/cmd-switch-client.c b/cmd-switch-client.c index bce42c2a..dfe8aca1 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -36,13 +36,14 @@ size_t cmd_switch_client_print(struct cmd *, char *, size_t); struct cmd_switch_client_data { char *name; char *target; + int flag_last; int flag_next; int flag_previous; }; const struct cmd_entry cmd_switch_client_entry = { "switch-client", "switchc", - "[-np] [-c target-client] [-t target-session]", + "[-lnp] [-c target-client] [-t target-session]", 0, "", cmd_switch_client_init, cmd_switch_client_parse, @@ -59,6 +60,7 @@ cmd_switch_client_init(struct cmd *self, int key) self->data = data = xmalloc(sizeof *data); data->name = NULL; data->target = NULL; + data->flag_last = 0; data->flag_next = 0; data->flag_previous = 0; @@ -69,6 +71,9 @@ cmd_switch_client_init(struct cmd *self, int key) case ')': data->flag_next = 1; break; + case 'L': + data->flag_last = 1; + break; } } @@ -81,28 +86,36 @@ cmd_switch_client_parse(struct cmd *self, int argc, char **argv, char **cause) self->entry->init(self, KEYC_NONE); data = self->data; - while ((opt = getopt(argc, argv, "c:t:")) != -1) { + while ((opt = getopt(argc, argv, "c:lnpt:")) != -1) { switch (opt) { case 'c': if (data->name == NULL) data->name = xstrdup(optarg); break; + case 'l': + if (data->flag_next || data->flag_previous || + data->target != NULL) + goto usage; + data->flag_last = 1; + break; + case 'n': + if (data->flag_previous || data->flag_last || + data->target != NULL) + goto usage; + data->flag_next = 1; + break; + case 'p': + if (data->flag_next || data->flag_last || + data->target != NULL) + goto usage; + data->flag_next = 1; + break; case 't': if (data->flag_next || data->flag_previous) goto usage; if (data->target == NULL) data->target = xstrdup(optarg); break; - case 'n': - if (data->flag_previous || data->target != NULL) - goto usage; - data->flag_next = 1; - break; - case 'p': - if (data->flag_next || data->target != NULL) - goto usage; - data->flag_next = 1; - break; default: goto usage; } @@ -134,6 +147,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx) if ((c = cmd_find_client(ctx, data->name)) == NULL) return (-1); + s = NULL; if (data->flag_next) { if ((s = session_next_session(c->session)) == NULL) { ctx->error(ctx, "can't find next session"); @@ -144,11 +158,21 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx) ctx->error(ctx, "can't find previous session"); return (-1); } + } else if (data->flag_last) { + if (c->last_session != UINT_MAX && + c->last_session < ARRAY_LENGTH(&sessions)) + s = ARRAY_ITEM(&sessions, c->last_session); + if (s == NULL) { + ctx->error(ctx, "can't find last session"); + return (-1); + } } else s = cmd_find_session(ctx, data->target); - if (s == NULL) return (-1); + + if (c->session != NULL) + session_index(c->session, &c->last_session); c->session = s; recalculate_sizes(); @@ -179,6 +203,8 @@ cmd_switch_client_print(struct cmd *self, char *buf, size_t len) off += xsnprintf(buf, len, "%s", self->entry->name); if (data == NULL) return (off); + if (off < len && data->flag_last) + off += xsnprintf(buf + off, len - off, "%s", " -l"); if (off < len && data->flag_next) off += xsnprintf(buf + off, len - off, "%s", " -n"); if (off < len && data->flag_previous) diff --git a/key-bindings.c b/key-bindings.c index 721620ff..32e81e94 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -128,6 +128,7 @@ key_bindings_init(void) { '=', 0, &cmd_choose_buffer_entry }, { '?', 0, &cmd_list_keys_entry }, { 'D', 0, &cmd_choose_client_entry }, + { 'L', 0, &cmd_switch_client_entry }, { '[', 0, &cmd_copy_mode_entry }, { '\'', 0, &cmd_command_prompt_entry }, { '\002', /* C-b */ 0, &cmd_send_prefix_entry }, diff --git a/server-client.c b/server-client.c index 80ec0e91..290a175a 100644 --- a/server-client.c +++ b/server-client.c @@ -78,6 +78,7 @@ server_client_create(int fd) c->title = NULL; c->session = NULL; + c->last_session = UINT_MAX; c->tty.sx = 80; c->tty.sy = 24; diff --git a/server-fn.c b/server-fn.c index 59f61373..20a245e0 100644 --- a/server-fn.c +++ b/server-fn.c @@ -399,6 +399,7 @@ server_destroy_session(struct session *s) c->session = NULL; c->flags |= CLIENT_EXIT; } else { + c->last_session = UINT_MAX; c->session = s_new; server_redraw_client(c); } diff --git a/tmux.1 b/tmux.1 index 28f71d83..2ebe43ce 100644 --- a/tmux.1 +++ b/tmux.1 @@ -282,6 +282,8 @@ Briefly display pane indexes. Force redraw of the attached client. .It s Select a new session for the attached client interactively. +.It L +Switch the attached client back to the last session. .It t Show the time. .It w @@ -662,7 +664,7 @@ Suspend a client by sending .Dv SIGTSTP (tty stop). .It Xo Ic switch-client -.Op Fl np +.Op Fl lnp .Op Fl c Ar target-client .Op Fl t Ar target-session .Xc @@ -672,10 +674,12 @@ Switch the current session for client to .Ar target-session . If +.Fl l, .Fl n or .Fl p -is used, the client is moved to the next or previous session respectively. +is used, the client is moved to the last, next or previous session +respectively. .El .Sh WINDOWS AND PANES A diff --git a/tmux.h b/tmux.h index 3fd5ef8b..11665195 100644 --- a/tmux.h +++ b/tmux.h @@ -1155,6 +1155,7 @@ struct client { struct mode_key_data prompt_mdata; struct session *session; + u_int last_session; int references; };