Update of /cvsroot/tmux/tmux
In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv1393

Modified Files:
        cmd-paste-buffer.c tmux.1 
Log Message:
Sync OpenBSD patchset 702:

Enhance paste-buffer to allow lines to be separated by any string, from
Andrea Barisani.


Index: cmd-paste-buffer.c
===================================================================
RCS file: /cvsroot/tmux/tmux/cmd-paste-buffer.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- cmd-paste-buffer.c  6 Apr 2010 21:59:37 -0000       1.26
+++ cmd-paste-buffer.c  6 Jun 2010 00:01:36 -0000       1.27
@@ -18,7 +18,9 @@
 
 #include <sys/types.h>
 
+#include <stdlib.h>
 #include <string.h>
+#include <vis.h>
 
 #include "tmux.h"
 
@@ -26,27 +28,109 @@
  * 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 *);
-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 = {
        "paste-buffer", "pasteb",
-       "[-dr] " CMD_BUFFER_PANE_USAGE,
-       0, "dr",
-       cmd_buffer_init,
-       cmd_buffer_parse,
+       "[-dr] [-s separator] [-b buffer-index] [-t target-window]",
+       0, "",
+       cmd_paste_buffer_init,
+       cmd_paste_buffer_parse,
        cmd_paste_buffer_exec,
-       cmd_buffer_free,
-       cmd_buffer_print
+       cmd_paste_buffer_free,
+       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
+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)
 {
-       struct cmd_buffer_data  *data = self->data;
-       struct window_pane      *wp;
-       struct session          *s;
-       struct paste_buffer     *pb;
+       struct cmd_paste_buffer_data    *data = self->data;
+       struct window_pane              *wp;
+       struct session                  *s;
+       struct paste_buffer             *pb;
 
        if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
                return (-1);
@@ -60,16 +144,11 @@
                }
        }
 
-       if (pb != NULL) {
-               /* -r means raw data without LF->CR conversion. */
-               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);
-       }
+       if (pb != NULL)
+               cmd_paste_buffer_filter(wp, pb->data, pb->size, data->sepstr);
 
        /* Delete the buffer if -d. */
-       if (cmd_check_flag(data->chflags, 'd')) {
+       if (data->flag_delete) {
                if (data->buffer == -1)
                        paste_free_top(&s->buffers);
                else
@@ -79,20 +158,66 @@
        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
-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      *lf;
+       size_t           seplen;
 
+       seplen = strlen(sep);
        while ((lf = memchr(data, '\n', end - data)) != NULL) {
                if (lf != data)
                        bufferevent_write(wp->event, data, lf - data);
-               bufferevent_write(wp->event, "\r", 1);
+               bufferevent_write(wp->event, sep, seplen);
                data = lf + 1;
        }
 
        if (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);
+}

Index: tmux.1
===================================================================
RCS file: /cvsroot/tmux/tmux/tmux.1,v
retrieving revision 1.251
retrieving revision 1.252
diff -u -d -r1.251 -r1.252
--- tmux.1      5 Jun 2010 23:56:29 -0000       1.251
+++ tmux.1      6 Jun 2010 00:01:36 -0000       1.252
@@ -14,7 +14,7 @@
 .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: May 14 2010 $
+.Dd $Mdocdate: May 19 2010 $
 .Dt TMUX 1
 .Os
 .Sh NAME
@@ -2387,6 +2387,7 @@
 .It Xo Ic paste-buffer
 .Op Fl dr
 .Op Fl b Ar buffer-index
+.Op Fl s Ar separator
 .Op Fl t Ar target-pane
 .Xc
 .D1 (alias: Ic pasteb )
@@ -2396,10 +2397,13 @@
 .Fl d ,
 also delete the paste buffer from the stack.
 When output, any linefeed (LF) characters in the paste buffer are replaced with
-carriage returns (CR).
-This translation may be disabled with the
-.Fl r
+a separator, by default carriage return (CR).
+A custom separator may be specified using the
+.Fl s
 flag.
+The
+.Fl r
+flag means to do no replacement (equivalent to a separator of LF).
 .It Xo Ic save-buffer
 .Op Fl a
 .Op Fl b Ar buffer-index


------------------------------------------------------------------------------
ThinkGeek and WIRED's GeekDad team up for the Ultimate 
GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the 
lucky parental unit.  See the prize list and enter to win: 
http://p.sf.net/sfu/thinkgeek-promo
_______________________________________________
tmux-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to