version 1.12, 2010/04/04 19:04:09 |
version 1.13, 2010/05/19 22:28:14 |
|
|
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
|
|
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
|
#include <vis.h> |
|
|
#include "tmux.h" |
#include "tmux.h" |
|
|
|
|
* Paste paste buffer if present. |
* Paste paste buffer if present. |
*/ |
*/ |
|
|
|
struct cmd_paste_buffer_data { |
|
char *target; |
|
int buffer; |
|
|
|
int flag_delete; |
|
char *sepstr; |
|
}; |
|
|
|
void cmd_paste_buffer_init(struct cmd *, int); |
|
int cmd_paste_buffer_parse(struct cmd *, int, char **, char **); |
int cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *); |
int cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *); |
void cmd_paste_buffer_lf2cr(struct window_pane *, const char *, size_t); |
void cmd_paste_buffer_filter( |
|
struct window_pane *, const char *, size_t, char *); |
|
void cmd_paste_buffer_free(struct cmd *); |
|
size_t cmd_paste_buffer_print(struct cmd *, char *, size_t); |
|
|
const struct cmd_entry cmd_paste_buffer_entry = { |
const struct cmd_entry cmd_paste_buffer_entry = { |
"paste-buffer", "pasteb", |
"paste-buffer", "pasteb", |
"[-dr] " CMD_BUFFER_PANE_USAGE, |
"[-dr] [-s separator] [-b buffer-index] [-t target-window]", |
0, "dr", |
0, "", |
cmd_buffer_init, |
cmd_paste_buffer_init, |
cmd_buffer_parse, |
cmd_paste_buffer_parse, |
cmd_paste_buffer_exec, |
cmd_paste_buffer_exec, |
cmd_buffer_free, |
cmd_paste_buffer_free, |
cmd_buffer_print |
cmd_paste_buffer_print |
}; |
}; |
|
|
|
/* ARGSUSED */ |
|
void |
|
cmd_paste_buffer_init(struct cmd *self, unused int arg) |
|
{ |
|
struct cmd_paste_buffer_data *data; |
|
|
|
self->data = data = xmalloc(sizeof *data); |
|
data->target = NULL; |
|
data->buffer = -1; |
|
data->flag_delete = 0; |
|
data->sepstr = xstrdup("\r"); |
|
} |
|
|
int |
int |
|
cmd_paste_buffer_parse(struct cmd *self, int argc, char **argv, char **cause) |
|
{ |
|
struct cmd_paste_buffer_data *data; |
|
int opt, n; |
|
const char *errstr; |
|
|
|
cmd_paste_buffer_init(self, 0); |
|
data = self->data; |
|
|
|
while ((opt = getopt(argc, argv, "b:ds:t:r")) != -1) { |
|
switch (opt) { |
|
case 'b': |
|
if (data->buffer == -1) { |
|
n = strtonum(optarg, 0, INT_MAX, &errstr); |
|
if (errstr != NULL) { |
|
xasprintf(cause, "buffer %s", errstr); |
|
goto error; |
|
} |
|
data->buffer = n; |
|
} |
|
break; |
|
case 'd': |
|
data->flag_delete = 1; |
|
break; |
|
case 's': |
|
if (data->sepstr != NULL) |
|
xfree(data->sepstr); |
|
data->sepstr = xstrdup(optarg); |
|
break; |
|
case 't': |
|
if (data->target == NULL) |
|
data->target = xstrdup(optarg); |
|
break; |
|
case 'r': |
|
if (data->sepstr != NULL) |
|
xfree(data->sepstr); |
|
data->sepstr = xstrdup("\n"); |
|
break; |
|
default: |
|
goto usage; |
|
} |
|
} |
|
argc -= optind; |
|
argv += optind; |
|
|
|
return (0); |
|
|
|
usage: |
|
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); |
|
|
|
error: |
|
self->entry->free(self); |
|
return (-1); |
|
} |
|
|
|
int |
cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) |
cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) |
{ |
{ |
struct cmd_buffer_data *data = self->data; |
struct cmd_paste_buffer_data *data = self->data; |
struct window_pane *wp; |
struct window_pane *wp; |
struct session *s; |
struct session *s; |
struct paste_buffer *pb; |
struct paste_buffer *pb; |
|
|
if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL) |
if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL) |
return (-1); |
return (-1); |
|
|
} |
} |
} |
} |
|
|
if (pb != NULL) { |
if (pb != NULL) |
/* -r means raw data without LF->CR conversion. */ |
cmd_paste_buffer_filter(wp, pb->data, pb->size, data->sepstr); |
if (cmd_check_flag(data->chflags, 'r')) |
|
bufferevent_write(wp->event, pb->data, pb->size); |
|
else |
|
cmd_paste_buffer_lf2cr(wp, pb->data, pb->size); |
|
} |
|
|
|
/* Delete the buffer if -d. */ |
/* Delete the buffer if -d. */ |
if (cmd_check_flag(data->chflags, 'd')) { |
if (data->flag_delete) { |
if (data->buffer == -1) |
if (data->buffer == -1) |
paste_free_top(&s->buffers); |
paste_free_top(&s->buffers); |
else |
else |
|
|
return (0); |
return (0); |
} |
} |
|
|
/* Add bytes to a buffer but change every '\n' to '\r'. */ |
/* Add bytes to a buffer and filter '\n' according to separator. */ |
void |
void |
cmd_paste_buffer_lf2cr(struct window_pane *wp, const char *data, size_t size) |
cmd_paste_buffer_filter( |
|
struct window_pane *wp, const char *data, size_t size, char *sep) |
{ |
{ |
const char *end = data + size; |
const char *end = data + size; |
const char *lf; |
const char *lf; |
|
size_t seplen; |
|
|
|
seplen = strlen(sep); |
while ((lf = memchr(data, '\n', end - data)) != NULL) { |
while ((lf = memchr(data, '\n', end - data)) != NULL) { |
if (lf != data) |
if (lf != data) |
bufferevent_write(wp->event, data, lf - data); |
bufferevent_write(wp->event, data, lf - data); |
bufferevent_write(wp->event, "\r", 1); |
bufferevent_write(wp->event, sep, seplen); |
data = lf + 1; |
data = lf + 1; |
} |
} |
|
|
if (end != data) |
if (end != data) |
bufferevent_write(wp->event, data, end - data); |
bufferevent_write(wp->event, data, end - data); |
|
} |
|
|
|
void |
|
cmd_paste_buffer_free(struct cmd *self) |
|
{ |
|
struct cmd_paste_buffer_data *data = self->data; |
|
|
|
if (data->target != NULL) |
|
xfree(data->target); |
|
if (data->sepstr != NULL) |
|
xfree(data->sepstr); |
|
xfree(data); |
|
} |
|
|
|
size_t |
|
cmd_paste_buffer_print(struct cmd *self, char *buf, size_t len) |
|
{ |
|
struct cmd_paste_buffer_data *data = self->data; |
|
size_t off = 0; |
|
char tmp[BUFSIZ]; |
|
int r_flag; |
|
|
|
r_flag = 0; |
|
if (data->sepstr != NULL) |
|
r_flag = (data->sepstr[0] == '\n' && data->sepstr[1] == '\0'); |
|
|
|
off += xsnprintf(buf, len, "%s", self->entry->name); |
|
if (data == NULL) |
|
return (off); |
|
if (off < len && data->flag_delete) |
|
off += xsnprintf(buf + off, len - off, " -d"); |
|
if (off < len && r_flag) |
|
off += xsnprintf(buf + off, len - off, " -r"); |
|
if (off < len && data->buffer != -1) |
|
off += xsnprintf(buf + off, len - off, " -b %d", data->buffer); |
|
if (off < len && data->sepstr != NULL && !r_flag) { |
|
strnvis( |
|
tmp, data->sepstr, sizeof tmp, VIS_OCTAL|VIS_TAB|VIS_NL); |
|
off += cmd_prarg(buf + off, len - off, " -s ", tmp); |
|
} |
|
if (off < len && data->target != NULL) |
|
off += cmd_prarg(buf + off, len - off, " -t ", data->target); |
|
return (off); |
} |
} |