4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
28 * Paste paste buffer if present.
31 struct cmd_paste_buffer_data
{
39 void cmd_paste_buffer_init(struct cmd
*, int);
40 int cmd_paste_buffer_parse(struct cmd
*, int, char **, char **);
41 int cmd_paste_buffer_exec(struct cmd
*, struct cmd_ctx
*);
42 void cmd_paste_buffer_filter(
43 struct window_pane
*, const char *, size_t, char *);
44 void cmd_paste_buffer_free(struct cmd
*);
45 size_t cmd_paste_buffer_print(struct cmd
*, char *, size_t);
47 const struct cmd_entry cmd_paste_buffer_entry
= {
48 "paste-buffer", "pasteb",
49 "[-dr] [-s separator] [-b buffer-index] [-t target-pane]",
51 cmd_paste_buffer_init
,
52 cmd_paste_buffer_parse
,
53 cmd_paste_buffer_exec
,
54 cmd_paste_buffer_free
,
55 cmd_paste_buffer_print
60 cmd_paste_buffer_init(struct cmd
*self
, unused
int arg
)
62 struct cmd_paste_buffer_data
*data
;
64 self
->data
= data
= xmalloc(sizeof *data
);
67 data
->flag_delete
= 0;
68 data
->sepstr
= xstrdup("\r");
72 cmd_paste_buffer_parse(struct cmd
*self
, int argc
, char **argv
, char **cause
)
74 struct cmd_paste_buffer_data
*data
;
78 cmd_paste_buffer_init(self
, 0);
81 while ((opt
= getopt(argc
, argv
, "b:ds:t:r")) != -1) {
84 if (data
->buffer
== -1) {
85 n
= strtonum(optarg
, 0, INT_MAX
, &errstr
);
87 xasprintf(cause
, "buffer %s", errstr
);
94 data
->flag_delete
= 1;
97 if (data
->sepstr
!= NULL
)
99 data
->sepstr
= xstrdup(optarg
);
102 if (data
->target
== NULL
)
103 data
->target
= xstrdup(optarg
);
106 if (data
->sepstr
!= NULL
)
108 data
->sepstr
= xstrdup("\n");
120 xasprintf(cause
, "usage: %s %s", self
->entry
->name
, self
->entry
->usage
);
123 self
->entry
->free(self
);
128 cmd_paste_buffer_exec(struct cmd
*self
, struct cmd_ctx
*ctx
)
130 struct cmd_paste_buffer_data
*data
= self
->data
;
131 struct window_pane
*wp
;
133 struct paste_buffer
*pb
;
135 if (cmd_find_pane(ctx
, data
->target
, &s
, &wp
) == NULL
)
138 if (data
->buffer
== -1)
139 pb
= paste_get_top(&s
->buffers
);
141 if ((pb
= paste_get_index(&s
->buffers
, data
->buffer
)) == NULL
) {
142 ctx
->error(ctx
, "no buffer %d", data
->buffer
);
148 cmd_paste_buffer_filter(wp
, pb
->data
, pb
->size
, data
->sepstr
);
150 /* Delete the buffer if -d. */
151 if (data
->flag_delete
) {
152 if (data
->buffer
== -1)
153 paste_free_top(&s
->buffers
);
155 paste_free_index(&s
->buffers
, data
->buffer
);
161 /* Add bytes to a buffer and filter '\n' according to separator. */
163 cmd_paste_buffer_filter(
164 struct window_pane
*wp
, const char *data
, size_t size
, char *sep
)
166 const char *end
= data
+ size
;
170 seplen
= strlen(sep
);
171 while ((lf
= memchr(data
, '\n', end
- data
)) != NULL
) {
173 bufferevent_write(wp
->event
, data
, lf
- data
);
174 bufferevent_write(wp
->event
, sep
, seplen
);
179 bufferevent_write(wp
->event
, data
, end
- data
);
183 cmd_paste_buffer_free(struct cmd
*self
)
185 struct cmd_paste_buffer_data
*data
= self
->data
;
187 if (data
->target
!= NULL
)
189 if (data
->sepstr
!= NULL
)
195 cmd_paste_buffer_print(struct cmd
*self
, char *buf
, size_t len
)
197 struct cmd_paste_buffer_data
*data
= self
->data
;
203 if (data
->sepstr
!= NULL
)
204 r_flag
= (data
->sepstr
[0] == '\n' && data
->sepstr
[1] == '\0');
206 off
+= xsnprintf(buf
, len
, "%s", self
->entry
->name
);
209 if (off
< len
&& data
->flag_delete
)
210 off
+= xsnprintf(buf
+ off
, len
- off
, " -d");
211 if (off
< len
&& r_flag
)
212 off
+= xsnprintf(buf
+ off
, len
- off
, " -r");
213 if (off
< len
&& data
->buffer
!= -1)
214 off
+= xsnprintf(buf
+ off
, len
- off
, " -b %d", data
->buffer
);
215 if (off
< len
&& data
->sepstr
!= NULL
&& !r_flag
) {
217 tmp
, data
->sepstr
, sizeof tmp
, VIS_OCTAL
|VIS_TAB
|VIS_NL
);
218 off
+= cmd_prarg(buf
+ off
, len
- off
, " -s ", tmp
);
220 if (off
< len
&& data
->target
!= NULL
)
221 off
+= cmd_prarg(buf
+ off
, len
- off
, " -t ", data
->target
);