1/* $Id: cmd-choose-session.c,v 1.1.1.2 2011/08/17 18:40:04 jmmv Exp $ */ 2 3/* 4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/types.h> 20 21#include <ctype.h> 22 23#include "tmux.h" 24 25/* 26 * Enter choice mode to choose a session. 27 */ 28 29int cmd_choose_session_exec(struct cmd *, struct cmd_ctx *); 30 31void cmd_choose_session_callback(void *, int); 32void cmd_choose_session_free(void *); 33 34const struct cmd_entry cmd_choose_session_entry = { 35 "choose-session", NULL, 36 "t:", 0, 1, 37 CMD_TARGET_WINDOW_USAGE " [template]", 38 0, 39 NULL, 40 NULL, 41 cmd_choose_session_exec 42}; 43 44struct cmd_choose_session_data { 45 struct client *client; 46 char *template; 47}; 48 49int 50cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx) 51{ 52 struct args *args = self->args; 53 struct cmd_choose_session_data *cdata; 54 struct winlink *wl; 55 struct session *s; 56 struct session_group *sg; 57 u_int idx, sgidx, cur; 58 char tmp[64]; 59 60 if (ctx->curclient == NULL) { 61 ctx->error(ctx, "must be run interactively"); 62 return (-1); 63 } 64 65 if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) 66 return (-1); 67 68 if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) 69 return (0); 70 71 cur = idx = 0; 72 RB_FOREACH(s, sessions, &sessions) { 73 if (s == ctx->curclient->session) 74 cur = idx; 75 idx++; 76 77 sg = session_group_find(s); 78 if (sg == NULL) 79 *tmp = '\0'; 80 else { 81 sgidx = session_group_index(sg); 82 xsnprintf(tmp, sizeof tmp, " (group %u)", sgidx); 83 } 84 85 window_choose_add(wl->window->active, s->idx, 86 "%s: %u windows [%ux%u]%s%s", s->name, 87 winlink_count(&s->windows), s->sx, s->sy, 88 tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)"); 89 } 90 91 cdata = xmalloc(sizeof *cdata); 92 if (args->argc != 0) 93 cdata->template = xstrdup(args->argv[0]); 94 else 95 cdata->template = xstrdup("switch-client -t '%%'"); 96 cdata->client = ctx->curclient; 97 cdata->client->references++; 98 99 window_choose_ready(wl->window->active, 100 cur, cmd_choose_session_callback, cmd_choose_session_free, cdata); 101 102 return (0); 103} 104 105void 106cmd_choose_session_callback(void *data, int idx) 107{ 108 struct cmd_choose_session_data *cdata = data; 109 struct session *s; 110 struct cmd_list *cmdlist; 111 struct cmd_ctx ctx; 112 char *template, *cause; 113 114 if (idx == -1) 115 return; 116 if (cdata->client->flags & CLIENT_DEAD) 117 return; 118 119 s = session_find_by_index(idx); 120 if (s == NULL) 121 return; 122 template = cmd_template_replace(cdata->template, s->name, 1); 123 124 if (cmd_string_parse(template, &cmdlist, &cause) != 0) { 125 if (cause != NULL) { 126 *cause = toupper((u_char) *cause); 127 status_message_set(cdata->client, "%s", cause); 128 xfree(cause); 129 } 130 xfree(template); 131 return; 132 } 133 xfree(template); 134 135 ctx.msgdata = NULL; 136 ctx.curclient = cdata->client; 137 138 ctx.error = key_bindings_error; 139 ctx.print = key_bindings_print; 140 ctx.info = key_bindings_info; 141 142 ctx.cmdclient = NULL; 143 144 cmd_list_exec(cmdlist, &ctx); 145 cmd_list_free(cmdlist); 146} 147 148void 149cmd_choose_session_free(void *data) 150{ 151 struct cmd_choose_session_data *cdata = data; 152 153 cdata->client->references--; 154 xfree(cdata->template); 155 xfree(cdata); 156} 157