The branch, master has been updated
       via  c3859d1df1fbdb63b8aab15d10266e26c5e428eb (commit)
      from  5a5e285be8caf98c7777a2afa717d04ac44c9f75 (commit)

- Log -----------------------------------------------------------------
commit c3859d1df1fbdb63b8aab15d10266e26c5e428eb
Author: Nicholas Marriott <[email protected]>
Commit: Nicholas Marriott <[email protected]>

    Add copy-pipe mode command to copy selection and also pipe to a command.
---
 cmd-bind-key.c  |   30 ++++++++++++++++------
 cmd-list-keys.c |    7 +++-
 mode-key.c      |    6 +++-
 status.c        |    2 +-
 tmux.1          |   13 +++++++++-
 tmux.h          |   12 +++++---
 window-choose.c |    8 +++---
 window-copy.c   |   74 ++++++++++++++++++++++++++++++++++++++++++++++---------
 8 files changed, 118 insertions(+), 34 deletions(-)

diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index 28e94e2..2a7b482 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -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);
 }
diff --git a/cmd-list-keys.c b/cmd-list-keys.c
index 51eeb67..3cb35f2 100644
--- a/cmd-list-keys.c
+++ b/cmd-list-keys.c
@@ -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 ? "\"": "");
                }
        }
 
diff --git a/mode-key.c b/mode-key.c
index 86367ad..94115eb 100644
--- a/mode-key.c
+++ b/mode-key.c
@@ -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);
        }
 }
diff --git a/status.c b/status.c
index 4083f2a..3a315f4 100644
--- a/status.c
+++ b/status.c
@@ -1042,7 +1042,7 @@ status_prompt_key(struct client *c, int key)
        size_t                   size, n, off, idx;
 
        size = strlen(c->prompt_buffer);
-       switch (mode_key_lookup(&c->prompt_mdata, key)) {
+       switch (mode_key_lookup(&c->prompt_mdata, key, NULL)) {
        case MODEKEYEDIT_CURSORLEFT:
                if (c->prompt_index > 0) {
                        c->prompt_index--;
diff --git a/tmux.1 b/tmux.1
index c1380ff..fcca092 100644
--- a/tmux.1
+++ b/tmux.1
@@ -854,7 +854,7 @@ The following keys are supported as appropriate for the 
mode:
 .It Li "Start of line" Ta "0" Ta "C-a"
 .It Li "Start selection" Ta "Space" Ta "C-Space"
 .It Li "Top of history" Ta "g" Ta "M->"
-.It Li "Transpose chars" Ta "" Ta "C-t"
+.It Li "Transpose characters" Ta "" Ta "C-t"
 .El
 .Pp
 The next and previous word keys use space and the
@@ -916,6 +916,17 @@ command and keys modified or removed with
 .Ic bind-key
 and
 .Ic unbind-key .
+One command in accepts an argument,
+.Ic copy-pipe ,
+which copies the selection and pipes it to a command.
+For example the following will bind
+.Ql C-q
+to copy the selection into
+.Pa /tmp
+as well as the paste buffer:
+.Bd -literal -offset indent
+bind-key -temacs-copy C-q copy-pipe "cat >/tmp/out"
+.Ed
 .Pp
 The paste buffer key pastes the first line from the top paste buffer on the
 stack.
diff --git a/tmux.h b/tmux.h
index 8b3d4e1..f5691e9 100644
--- a/tmux.h
+++ b/tmux.h
@@ -562,6 +562,7 @@ enum mode_key_cmd {
        MODEKEYCOPY_BOTTOMLINE,
        MODEKEYCOPY_CANCEL,
        MODEKEYCOPY_CLEARSELECTION,
+       MODEKEYCOPY_COPYPIPE,
        MODEKEYCOPY_COPYLINE,
        MODEKEYCOPY_COPYENDOFLINE,
        MODEKEYCOPY_COPYSELECTION,
@@ -628,12 +629,13 @@ struct mode_key_data {
 
 /* Binding between a key and a command. */
 struct mode_key_binding {
-       int                     key;
+       int                              key;
 
-       int                     mode;
-       enum mode_key_cmd       cmd;
+       int                              mode;
+       enum mode_key_cmd                cmd;
+       const char                      *arg;
 
-       RB_ENTRY(mode_key_binding) entry;
+       RB_ENTRY(mode_key_binding)       entry;
 };
 RB_HEAD(mode_key_tree, mode_key_binding);
 
@@ -1544,7 +1546,7 @@ enum mode_key_cmd mode_key_fromstring(const struct 
mode_key_cmdstr *,
 const struct mode_key_table *mode_key_findtable(const char *);
 void   mode_key_init_trees(void);
 void   mode_key_init(struct mode_key_data *, struct mode_key_tree *);
-enum mode_key_cmd mode_key_lookup(struct mode_key_data *, int);
+enum mode_key_cmd mode_key_lookup(struct mode_key_data *, int, const char **);
 
 /* notify.c */
 void   notify_enable(void);
diff --git a/window-choose.c b/window-choose.c
index eb526ec..366c65d 100644
--- a/window-choose.c
+++ b/window-choose.c
@@ -492,7 +492,7 @@ window_choose_key(struct window_pane *wp, unused struct 
session *sess, int key)
        items = ARRAY_LENGTH(&data->list);
 
        if (data->input_type == WINDOW_CHOOSE_GOTO_ITEM) {
-               switch (mode_key_lookup(&data->mdata, key)) {
+               switch (mode_key_lookup(&data->mdata, key, NULL)) {
                case MODEKEYCHOICE_CANCEL:
                        data->input_type = WINDOW_CHOOSE_NORMAL;
                        window_choose_redraw_screen(wp);
@@ -523,7 +523,7 @@ window_choose_key(struct window_pane *wp, unused struct 
session *sess, int key)
                return;
        }
 
-       switch (mode_key_lookup(&data->mdata, key)) {
+       switch (mode_key_lookup(&data->mdata, key, NULL)) {
        case MODEKEYCHOICE_CANCEL:
                window_choose_fire_callback(wp, NULL);
                break;
@@ -777,7 +777,7 @@ window_choose_key_index(struct window_choose_mode_data 
*data, u_int idx)
        int                     mkey;
 
        for (ptr = keys; *ptr != '\0'; ptr++) {
-               mkey = mode_key_lookup(&data->mdata, *ptr);
+               mkey = mode_key_lookup(&data->mdata, *ptr, NULL);
                if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER)
                        continue;
                if (idx-- == 0)
@@ -797,7 +797,7 @@ window_choose_index_key(struct window_choose_mode_data 
*data, int key)
        u_int                   idx = 0;
 
        for (ptr = keys; *ptr != '\0'; ptr++) {
-               mkey = mode_key_lookup(&data->mdata, *ptr);
+               mkey = mode_key_lookup(&data->mdata, *ptr, NULL);
                if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER)
                        continue;
                if (key == *ptr)
diff --git a/window-copy.c b/window-copy.c
index be759d8..2228b38 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -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


-----------------------------------------------------------------------

Summary of changes:
 cmd-bind-key.c  |   30 ++++++++++++++++------
 cmd-list-keys.c |    7 +++-
 mode-key.c      |    6 +++-
 status.c        |    2 +-
 tmux.1          |   13 +++++++++-
 tmux.h          |   12 +++++---
 window-choose.c |    8 +++---
 window-copy.c   |   74 ++++++++++++++++++++++++++++++++++++++++++++++---------
 8 files changed, 118 insertions(+), 34 deletions(-)


hooks/post-receive
-- 
tmux

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
tmux-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to