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