1/* $Id: cmd-choose-buffer.c,v 1.1.1.2 2011/08/17 18:40:04 jmmv Exp $ */ 2 3/* 4 * Copyright (c) 2010 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 buffer. 27 */ 28 29int cmd_choose_buffer_exec(struct cmd *, struct cmd_ctx *); 30 31void cmd_choose_buffer_callback(void *, int); 32void cmd_choose_buffer_free(void *); 33 34const struct cmd_entry cmd_choose_buffer_entry = { 35 "choose-buffer", NULL, 36 "t:", 0, 1, 37 CMD_TARGET_WINDOW_USAGE " [template]", 38 0, 39 NULL, 40 NULL, 41 cmd_choose_buffer_exec 42}; 43 44struct cmd_choose_buffer_data { 45 struct client *client; 46 char *template; 47}; 48 49int 50cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) 51{ 52 struct args *args = self->args; 53 struct cmd_choose_buffer_data *cdata; 54 struct winlink *wl; 55 struct paste_buffer *pb; 56 u_int idx; 57 char *tmp; 58 59 if (ctx->curclient == NULL) { 60 ctx->error(ctx, "must be run interactively"); 61 return (-1); 62 } 63 64 if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) 65 return (-1); 66 67 if (paste_get_top(&global_buffers) == NULL) 68 return (0); 69 70 if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) 71 return (0); 72 73 idx = 0; 74 while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) { 75 tmp = paste_print(pb, 50); 76 window_choose_add(wl->window->active, idx - 1, 77 "%u: %zu bytes: \"%s\"", idx - 1, pb->size, tmp); 78 xfree(tmp); 79 } 80 81 cdata = xmalloc(sizeof *cdata); 82 if (args->argc != 0) 83 cdata->template = xstrdup(args->argv[0]); 84 else 85 cdata->template = xstrdup("paste-buffer -b '%%'"); 86 cdata->client = ctx->curclient; 87 cdata->client->references++; 88 89 window_choose_ready(wl->window->active, 90 0, cmd_choose_buffer_callback, cmd_choose_buffer_free, cdata); 91 92 return (0); 93} 94 95void 96cmd_choose_buffer_callback(void *data, int idx) 97{ 98 struct cmd_choose_buffer_data *cdata = data; 99 struct cmd_list *cmdlist; 100 struct cmd_ctx ctx; 101 char *template, *cause, tmp[16]; 102 103 if (idx == -1) 104 return; 105 if (cdata->client->flags & CLIENT_DEAD) 106 return; 107 108 xsnprintf(tmp, sizeof tmp, "%u", idx); 109 template = cmd_template_replace(cdata->template, tmp, 1); 110 111 if (cmd_string_parse(template, &cmdlist, &cause) != 0) { 112 if (cause != NULL) { 113 *cause = toupper((u_char) *cause); 114 status_message_set(cdata->client, "%s", cause); 115 xfree(cause); 116 } 117 xfree(template); 118 return; 119 } 120 xfree(template); 121 122 ctx.msgdata = NULL; 123 ctx.curclient = cdata->client; 124 125 ctx.error = key_bindings_error; 126 ctx.print = key_bindings_print; 127 ctx.info = key_bindings_info; 128 129 ctx.cmdclient = NULL; 130 131 cmd_list_exec(cmdlist, &ctx); 132 cmd_list_free(cmdlist); 133} 134 135void 136cmd_choose_buffer_free(void *data) 137{ 138 struct cmd_choose_buffer_data *cdata = data; 139 140 cdata->client->references--; 141 xfree(cdata->template); 142 xfree(cdata); 143} 144