Add copy-pipe mode command to copy selection and also pipe to a command.

This commit is contained in:
Nicholas Marriott 2013-03-22 15:52:40 +00:00
parent 8478895eeb
commit 58932295fc
4 changed files with 94 additions and 23 deletions

View File

@ -46,7 +46,7 @@ enum cmd_retval
cmd_bind_key_check(struct args *args)
{
if (args_has(args, 't')) {
if (args->argc != 2)
if (args->argc != 2 && args->argc != 3)
return (CMD_RETURN_ERROR);
} else {
if (args->argc < 2)
@ -93,6 +93,7 @@ cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
const struct mode_key_table *mtab;
struct mode_key_binding *mbind, mtmp;
enum mode_key_cmd cmd;
const char *arg;
tablename = args_get(args, 't');
if ((mtab = mode_key_findtable(tablename)) == NULL) {
@ -106,16 +107,29 @@ cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
return (CMD_RETURN_ERROR);
}
if (cmd != MODEKEYCOPY_COPYPIPE) {
if (args->argc != 2) {
ctx->error(ctx, "no argument allowed");
return (CMD_RETURN_ERROR);
}
arg = NULL;
} else {
if (args->argc != 3) {
ctx->error(ctx, "no argument given");
return (CMD_RETURN_ERROR);
}
arg = args->argv[2];
}
mtmp.key = key;
mtmp.mode = !!args_has(args, 'c');
if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
mbind->cmd = cmd;
return (CMD_RETURN_NORMAL);
if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) == NULL) {
mbind = xmalloc(sizeof *mbind);
mbind->key = mtmp.key;
mbind->mode = mtmp.mode;
RB_INSERT(mode_key_tree, mtab->tree, mbind);
}
mbind = xmalloc(sizeof *mbind);
mbind->key = mtmp.key;
mbind->mode = mtmp.mode;
mbind->cmd = cmd;
RB_INSERT(mode_key_tree, mtab->tree, mbind);
mbind->arg = arg != NULL ? xstrdup(arg) : NULL;
return (CMD_RETURN_NORMAL);
}

View File

@ -138,9 +138,12 @@ cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx)
mode = "c";
cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd);
if (cmdstr != NULL) {
ctx->print(ctx, "bind-key -%st %s%s %*s %s",
ctx->print(ctx, "bind-key -%st %s%s %*s %s%s%s%s",
mode, any_mode && *mode == '\0' ? " " : "",
mtab->name, (int) width, key, cmdstr);
mtab->name, (int) width, key, cmdstr,
mbind->arg != NULL ? " \"" : "",
mbind->arg != NULL ? mbind->arg : "",
mbind->arg != NULL ? "\"": "");
}
}

View File

@ -99,6 +99,7 @@ const struct mode_key_cmdstr mode_key_cmdstr_copy[] = {
{ MODEKEYCOPY_BOTTOMLINE, "bottom-line" },
{ MODEKEYCOPY_CANCEL, "cancel" },
{ MODEKEYCOPY_CLEARSELECTION, "clear-selection" },
{ MODEKEYCOPY_COPYPIPE, "copy-pipe" },
{ MODEKEYCOPY_COPYLINE, "copy-line" },
{ MODEKEYCOPY_COPYENDOFLINE, "copy-end-of-line" },
{ MODEKEYCOPY_COPYSELECTION, "copy-selection" },
@ -513,6 +514,7 @@ mode_key_init_trees(void)
mbind->key = ment->key;
mbind->mode = ment->mode;
mbind->cmd = ment->cmd;
mbind->arg = NULL;
RB_INSERT(mode_key_tree, mtab->tree, mbind);
}
}
@ -526,7 +528,7 @@ mode_key_init(struct mode_key_data *mdata, struct mode_key_tree *mtree)
}
enum mode_key_cmd
mode_key_lookup(struct mode_key_data *mdata, int key)
mode_key_lookup(struct mode_key_data *mdata, int key, const char **arg)
{
struct mode_key_binding *mbind, mtmp;
@ -546,6 +548,8 @@ mode_key_lookup(struct mode_key_data *mdata, int key)
mdata->mode = 1 - mdata->mode;
/* FALLTHROUGH */
default:
if (arg != NULL)
*arg = mbind->arg;
return (mbind->cmd);
}
}

View File

@ -52,6 +52,9 @@ void window_copy_goto_line(struct window_pane *, const char *);
void window_copy_update_cursor(struct window_pane *, u_int, u_int);
void window_copy_start_selection(struct window_pane *);
int window_copy_update_selection(struct window_pane *);
void *window_copy_get_selection(struct window_pane *, size_t *);
void window_copy_copy_buffer(struct window_pane *, int, void *, size_t);
void window_copy_copy_pipe(struct window_pane *, int, const char *);
void window_copy_copy_selection(struct window_pane *, int);
void window_copy_clear_selection(struct window_pane *);
void window_copy_copy_line(
@ -364,6 +367,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
u_int n;
int np, keys;
enum mode_key_cmd cmd;
const char *arg;
np = data->numprefix;
if (np <= 0)
@ -405,7 +409,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
return;
}
cmd = mode_key_lookup(&data->mdata, key);
cmd = mode_key_lookup(&data->mdata, key, &arg);
switch (cmd) {
case MODEKEYCOPY_CANCEL:
window_pane_reset_mode(wp);
@ -533,6 +537,13 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
window_copy_clear_selection(wp);
window_copy_redraw_screen(wp);
break;
case MODEKEYCOPY_COPYPIPE:
if (sess != NULL) {
window_copy_copy_pipe(wp, data->numprefix, arg);
window_pane_reset_mode(wp);
return;
}
break;
case MODEKEYCOPY_COPYSELECTION:
if (sess != NULL) {
window_copy_copy_selection(wp, data->numprefix);
@ -735,7 +746,7 @@ window_copy_key_input(struct window_pane *wp, int key)
size_t inputlen;
int np;
switch (mode_key_lookup(&data->mdata, key)) {
switch (mode_key_lookup(&data->mdata, key, NULL)) {
case MODEKEYEDIT_CANCEL:
data->numprefix = -1;
return (-1);
@ -1259,19 +1270,19 @@ window_copy_update_selection(struct window_pane *wp)
return (1);
}
void
window_copy_copy_selection(struct window_pane *wp, int idx)
void *
window_copy_get_selection(struct window_pane *wp, size_t *len)
{
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
char *buf;
size_t off;
u_int i, xx, yy, sx, sy, ex, ey, limit;
u_int i, xx, yy, sx, sy, ex, ey;
u_int firstsx, lastex, restex, restsx;
int keys;
if (!s->sel.flag)
return;
return (NULL);
buf = xmalloc(1);
off = 0;
@ -1364,19 +1375,58 @@ window_copy_copy_selection(struct window_pane *wp, int idx)
/* Don't bother if no data. */
if (off == 0) {
free(buf);
return;
return (NULL);
}
off--; /* remove final \n */
*len = off - 1; /* remove final \n */
return (buf);
}
void
window_copy_copy_buffer(struct window_pane *wp, int idx, void *buf, size_t len)
{
u_int limit;
if (options_get_number(&global_options, "set-clipboard"))
screen_write_setselection(&wp->ictx.ctx, buf, off);
screen_write_setselection(&wp->ictx.ctx, buf, len);
/* Add the buffer to the stack. */
if (idx == -1) {
limit = options_get_number(&global_options, "buffer-limit");
paste_add(&global_buffers, buf, off, limit);
paste_add(&global_buffers, buf, len, limit);
} else
paste_replace(&global_buffers, idx, buf, off);
paste_replace(&global_buffers, idx, buf, len);
}
void
window_copy_copy_pipe(struct window_pane *wp, int idx, const char *arg)
{
void* buf;
size_t len;
FILE* f;
buf = window_copy_get_selection(wp, &len);
if (buf == NULL)
return;
f = popen(arg, "w");
if (f != NULL) {
fwrite(buf, 1, len, f);
pclose(f);
}
window_copy_copy_buffer(wp, idx, buf, len);
}
void
window_copy_copy_selection(struct window_pane *wp, int idx)
{
void* buf;
size_t len;
buf = window_copy_get_selection(wp, &len);
if (buf == NULL)
return;
window_copy_copy_buffer(wp, idx, buf, len);
}
void