I kept passing in global_buffers since that's what the existing code
did, and I thought there might be a reason (planned future
functionality?), so I kept it.  But it makes sense to not pass it in
if you don't expect other paste_stores.  But why not do the same with
buffer-limit?  paste_add can look it up instead of having every call
to paste_set look it up first and pass it in.

I thought you might object to having non-printable characters or long
buffer names because it might mess up the display in list-buffer and
choose-buffer.  But I'll remove both restrictions if that's not a
valid concern.


> I renamed the compare funcs and make some other minor tweaks but didn't
> change the sticky/unsticky bits.
>
> Why do you limit the buffer names to 16 characters? 16 characters is too
> short, but why limit them at all?
>
> Also not certain about limiting them to printables, seems like that will
> stop people using UTF-8 in buffer names.
>
>
> Index: cmd-capture-pane.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/cmd-capture-pane.c,v
> retrieving revision 1.26
> diff -u -p -r1.26 cmd-capture-pane.c
> --- cmd-capture-pane.c  24 Apr 2014 09:14:43 -0000      1.26
> +++ cmd-capture-pane.c  24 Apr 2014 09:44:42 -0000
> @@ -38,7 +38,7 @@ char          *cmd_capture_pane_history(struct a
>  const struct cmd_entry cmd_capture_pane_entry = {
>         "capture-pane", "capturep",
>         "ab:CeE:JpPqS:t:", 0, 0,
> -       "[-aCeJpPq] [-b buffer-index] [-E end-line] [-S start-line]"
> +       "[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] [-S start-line]"
>         CMD_TARGET_PANE_USAGE,
>         0,
>         NULL,
> @@ -165,7 +165,7 @@ cmd_capture_pane_exec(struct cmd *self,
>         struct client           *c;
>         struct window_pane      *wp;
>         char                    *buf, *cause;
> -       int                      buffer;
> +       const char              *bufname;
>         u_int                    limit;
>         size_t                   len;
>
> @@ -193,22 +193,15 @@ cmd_capture_pane_exec(struct cmd *self,
>                 server_push_stdout(c);
>         } else {
>                 limit = options_get_number(&global_options, "buffer-limit");
> -               if (!args_has(args, 'b')) {
> -                       paste_add(buf, len, limit);
> -                       return (CMD_RETURN_NORMAL);
> -               }
>
> -               buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
> -               if (cause != NULL) {
> -                       cmdq_error(cmdq, "buffer %s", cause);
> -                       free(buf);
> -                       free(cause);
> -                       return (CMD_RETURN_ERROR);
> -               }
> +               bufname = NULL;
> +               if (args_has(args, 'b'))
> +                       bufname = args_get(args, 'b');
>
> -               if (paste_replace(buffer, buf, len) != 0) {
> -                       cmdq_error(cmdq, "no buffer %d", buffer);
> +               if (paste_set(buf, len, limit, bufname, &cause) != 0) {
> +                       cmdq_error(cmdq, "%s", cause);
>                         free(buf);
> +                       free(cause);
>                         return (CMD_RETURN_ERROR);
>                 }
>         }
> Index: cmd-choose-buffer.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/cmd-choose-buffer.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 cmd-choose-buffer.c
> --- cmd-choose-buffer.c 24 Apr 2014 09:14:43 -0000      1.17
> +++ cmd-choose-buffer.c 24 Apr 2014 09:44:42 -0000
> @@ -75,19 +75,20 @@ cmd_choose_buffer_exec(struct cmd *self,
>                 action = xstrdup("paste-buffer -b '%%'");
>
>         idx = 0;
> -       while ((pb = paste_walk_stack(&idx)) != NULL) {
> +       pb = NULL;
> +       while ((pb = paste_walk(pb)) != NULL) {
>                 cdata = window_choose_data_create(TREE_OTHER, c, c->session);
> -               cdata->idx = idx - 1;
> +               cdata->idx = idx;
>
>                 cdata->ft_template = xstrdup(template);
> -               format_add(cdata->ft, "line", "%u", idx - 1);
>                 format_paste_buffer(cdata->ft, pb, utf8flag);
>
> -               xasprintf(&action_data, "%u", idx - 1);
> +               xasprintf(&action_data, "%s", pb->name);
>                 cdata->command = cmd_template_replace(action, action_data, 1);
>                 free(action_data);
>
>                 window_choose_add(wl->window->active, cdata);
> +               idx++;
>         }
>         free(action);
>
> Index: cmd-command-prompt.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/cmd-command-prompt.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 cmd-command-prompt.c
> --- cmd-command-prompt.c        10 Oct 2013 12:00:19 -0000      1.27
> +++ cmd-command-prompt.c        24 Apr 2014 09:44:42 -0000
> @@ -76,6 +76,9 @@ cmd_command_prompt_key_binding(struct cm
>                 self->args = args_create(1, "select-window -t ':%%'");
>                 args_set(self->args, 'p', "index");
>                 break;
> +       case 'P':
> +               self->args = args_create(1, "paste-buffer -b '%%'");
> +               break;
>         default:
>                 self->args = args_create(0);
>                 break;
> Index: cmd-delete-buffer.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/cmd-delete-buffer.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 cmd-delete-buffer.c
> --- cmd-delete-buffer.c 24 Apr 2014 09:14:43 -0000      1.11
> +++ cmd-delete-buffer.c 24 Apr 2014 09:44:42 -0000
> @@ -41,23 +41,16 @@ enum cmd_retval
>  cmd_delete_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
>  {
>         struct args     *args = self->args;
> -       char            *cause;
> -       int              buffer;
> +       const char      *bufname;
>
>         if (!args_has(args, 'b')) {
>                 paste_free_top();
>                 return (CMD_RETURN_NORMAL);
>         }
> +       bufname = args_get(args, 'b');
>
> -       buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
> -       if (cause != NULL) {
> -               cmdq_error(cmdq, "buffer %s", cause);
> -               free(cause);
> -               return (CMD_RETURN_ERROR);
> -       }
> -
> -       if (paste_free_index(buffer) != 0) {
> -               cmdq_error(cmdq, "no buffer %d", buffer);
> +       if (paste_free_name(bufname) != 0) {
> +               cmdq_error(cmdq, "no buffer %s", bufname);
>                 return (CMD_RETURN_ERROR);
>         }
>
> Index: cmd-list-buffers.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/cmd-list-buffers.c,v
> retrieving revision 1.20
> diff -u -p -r1.20 cmd-list-buffers.c
> --- cmd-list-buffers.c  24 Apr 2014 09:14:43 -0000      1.20
> +++ cmd-list-buffers.c  24 Apr 2014 09:44:43 -0000
> @@ -44,17 +44,15 @@ cmd_list_buffers_exec(unused struct cmd
>         struct args             *args = self->args;
>         struct paste_buffer     *pb;
>         struct format_tree      *ft;
> -       u_int                    idx;
>         char                    *line;
>         const char              *template;
>
>         if ((template = args_get(args, 'F')) == NULL)
>                 template = LIST_BUFFERS_TEMPLATE;
>
> -       idx = 0;
> -       while ((pb = paste_walk_stack(&idx)) != NULL) {
> +       pb = NULL;
> +       while ((pb = paste_walk(pb)) != NULL) {
>                 ft = format_create();
> -               format_add(ft, "line", "%u", idx - 1);
>                 format_paste_buffer(ft, pb, 0);
>
>                 line = format_expand(ft, template);
> Index: cmd-load-buffer.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/cmd-load-buffer.c,v
> retrieving revision 1.28
> diff -u -p -r1.28 cmd-load-buffer.c
> --- cmd-load-buffer.c   24 Apr 2014 09:14:43 -0000      1.28
> +++ cmd-load-buffer.c   24 Apr 2014 09:44:43 -0000
> @@ -50,30 +50,20 @@ cmd_load_buffer_exec(struct cmd *self, s
>         struct client   *c = cmdq->client;
>         struct session  *s;
>         FILE            *f;
> -       const char      *path;
> +       const char      *path, *bufname;
>         char            *pdata, *new_pdata, *cause;
>         size_t           psize;
>         u_int            limit;
> -       int              ch, error, buffer, *buffer_ptr, cwd, fd;
> +       int              ch, error, cwd, fd;
>
> -       if (!args_has(args, 'b'))
> -               buffer = -1;
> -       else {
> -               buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
> -               if (cause != NULL) {
> -                       cmdq_error(cmdq, "buffer %s", cause);
> -                       free(cause);
> -                       return (CMD_RETURN_ERROR);
> -               }
> -       }
> +       bufname = NULL;
> +       if (args_has(args, 'b'))
> +               bufname = args_get(args, 'b');
>
>         path = args->argv[0];
>         if (strcmp(path, "-") == 0) {
> -               buffer_ptr = xmalloc(sizeof *buffer_ptr);
> -               *buffer_ptr = buffer;
> -
>                 error = server_set_stdin_callback(c, cmd_load_buffer_callback,
> -                   buffer_ptr, &cause);
> +                   bufname, &cause);
>                 if (error != 0) {
>                         cmdq_error(cmdq, "%s: %s", path, cause);
>                         free(cause);
> @@ -118,13 +108,10 @@ cmd_load_buffer_exec(struct cmd *self, s
>         fclose(f);
>
>         limit = options_get_number(&global_options, "buffer-limit");
> -       if (buffer == -1) {
> -               paste_add(pdata, psize, limit);
> -               return (CMD_RETURN_NORMAL);
> -       }
> -       if (paste_replace(buffer, pdata, psize) != 0) {
> -               cmdq_error(cmdq, "no buffer %d", buffer);
> +       if (paste_set(pdata, psize, limit, bufname, &cause) != 0) {
> +               cmdq_error(cmdq, "%s", cause);
>                 free(pdata);
> +               free(cause);
>                 return (CMD_RETURN_ERROR);
>         }
>
> @@ -140,10 +127,10 @@ error:
>  void
>  cmd_load_buffer_callback(struct client *c, int closed, void *data)
>  {
> -       int     *buffer = data;
> -       char    *pdata;
> -       size_t   psize;
> -       u_int    limit;
> +       char            *pdata, *cause;
> +       const char      *bufname = data;
> +       size_t           psize;
> +       u_int            limit;
>
>         if (!closed)
>                 return;
> @@ -154,25 +141,21 @@ cmd_load_buffer_callback(struct client *
>                 return;
>
>         psize = EVBUFFER_LENGTH(c->stdin_data);
> -       if (psize == 0 || (pdata = malloc(psize + 1)) == NULL) {
> -               free(data);
> +       if (psize == 0 || (pdata = malloc(psize + 1)) == NULL)
>                 goto out;
> -       }
> +
>         memcpy(pdata, EVBUFFER_DATA(c->stdin_data), psize);
>         pdata[psize] = '\0';
>         evbuffer_drain(c->stdin_data, psize);
>
>         limit = options_get_number(&global_options, "buffer-limit");
> -       if (*buffer == -1)
> -               paste_add(pdata, psize, limit);
> -       else if (paste_replace(*buffer, pdata, psize) != 0) {
> +       if (paste_set(pdata, psize, limit, bufname, &cause) != 0) {
>                 /* No context so can't use server_client_msg_error. */
> -               evbuffer_add_printf(c->stderr_data, "no buffer %d\n", 
> *buffer);
> +               evbuffer_add_printf(c->stderr_data, "%s", cause);
>                 server_push_stderr(c);
>                 free(pdata);
> +               free(cause);
>         }
> -
> -       free(data);
>
>  out:
>         cmdq_continue(c->cmdq);
> Index: cmd-paste-buffer.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/cmd-paste-buffer.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 cmd-paste-buffer.c
> --- cmd-paste-buffer.c  24 Apr 2014 09:14:43 -0000      1.24
> +++ cmd-paste-buffer.c  24 Apr 2014 09:44:43 -0000
> @@ -36,7 +36,7 @@ void  cmd_paste_buffer_filter(struct wind
>  const struct cmd_entry cmd_paste_buffer_entry = {
>         "paste-buffer", "pasteb",
>         "db:prs:t:", 0, 0,
> -       "[-dpr] [-s separator] [-b buffer-index] " CMD_TARGET_PANE_USAGE,
> +       "[-dpr] [-s separator] " CMD_BUFFER_USAGE " " CMD_TARGET_PANE_USAGE,
>         0,
>         NULL,
>         cmd_paste_buffer_exec
> @@ -49,31 +49,22 @@ cmd_paste_buffer_exec(struct cmd *self,
>         struct window_pane      *wp;
>         struct session          *s;
>         struct paste_buffer     *pb;
> -       const char              *sepstr;
> -       char                    *cause;
> -       int                      buffer;
> +       const char              *sepstr, *bufname;
>         int                      pflag;
>
>         if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
>                 return (CMD_RETURN_ERROR);
>
> -       if (!args_has(args, 'b'))
> -               buffer = -1;
> -       else {
> -               buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
> -               if (cause != NULL) {
> -                       cmdq_error(cmdq, "buffer %s", cause);
> -                       free(cause);
> -                       return (CMD_RETURN_ERROR);
> -               }
> -       }
> +       bufname = NULL;
> +       if (args_has(args, 'b'))
> +               bufname = args_get(args, 'b');
>
> -       if (buffer == -1)
> +       if (bufname == NULL)
>                 pb = paste_get_top();
>         else {
> -               pb = paste_get_index(buffer);
> +               pb = paste_get_name(bufname);
>                 if (pb == NULL) {
> -                       cmdq_error(cmdq, "no buffer %d", buffer);
> +                       cmdq_error(cmdq, "no buffer %s", bufname);
>                         return (CMD_RETURN_ERROR);
>                 }
>         }
> @@ -92,10 +83,10 @@ cmd_paste_buffer_exec(struct cmd *self,
>
>         /* Delete the buffer if -d. */
>         if (args_has(args, 'd')) {
> -               if (buffer == -1)
> +               if (bufname == NULL)
>                         paste_free_top();
>                 else
> -                       paste_free_index(buffer);
> +                       paste_free_name(bufname);
>         }
>
>         return (CMD_RETURN_NORMAL);
> Index: cmd-save-buffer.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/cmd-save-buffer.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 cmd-save-buffer.c
> --- cmd-save-buffer.c   24 Apr 2014 09:14:43 -0000      1.24
> +++ cmd-save-buffer.c   24 Apr 2014 09:44:43 -0000
> @@ -59,10 +59,10 @@ cmd_save_buffer_exec(struct cmd *self, s
>         struct client           *c = cmdq->client;
>         struct session          *s;
>         struct paste_buffer     *pb;
> -       const char              *path;
> -       char                    *cause, *start, *end, *msg;
> +       const char              *path, *bufname;
> +       char                    *start, *end, *msg;
>         size_t                   size, used, msglen;
> -       int                      cwd, fd, buffer;
> +       int                      cwd, fd;
>         FILE                    *f;
>
>         if (!args_has(args, 'b')) {
> @@ -71,16 +71,10 @@ cmd_save_buffer_exec(struct cmd *self, s
>                         return (CMD_RETURN_ERROR);
>                 }
>         } else {
> -               buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
> -               if (cause != NULL) {
> -                       cmdq_error(cmdq, "buffer %s", cause);
> -                       free(cause);
> -                       return (CMD_RETURN_ERROR);
> -               }
> -
> -               pb = paste_get_index(buffer);
> +               bufname = args_get(args, 'b');
> +               pb = paste_get_name(bufname);
>                 if (pb == NULL) {
> -                       cmdq_error(cmdq, "no buffer %d", buffer);
> +                       cmdq_error(cmdq, "no buffer %s", bufname);
>                         return (CMD_RETURN_ERROR);
>                 }
>         }
> Index: cmd-set-buffer.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/cmd-set-buffer.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 cmd-set-buffer.c
> --- cmd-set-buffer.c    24 Apr 2014 09:14:43 -0000      1.17
> +++ cmd-set-buffer.c    24 Apr 2014 09:44:43 -0000
> @@ -31,8 +31,8 @@ enum cmd_retval        cmd_set_buffer_exec(str
>
>  const struct cmd_entry cmd_set_buffer_entry = {
>         "set-buffer", "setb",
> -       "ab:", 1, 1,
> -       "[-a] " CMD_BUFFER_USAGE " data",
> +       "ab:n:su", 0, 1,
> +       "[-asu] [-n new_buffer_name] " CMD_BUFFER_USAGE " data",
>         0,
>         NULL,
>         cmd_set_buffer_exec
> @@ -45,36 +45,104 @@ cmd_set_buffer_exec(struct cmd *self, st
>         struct paste_buffer     *pb;
>         u_int                    limit;
>         char                    *pdata, *cause;
> +       u_char                  sticky;
> +       const char              *bufname;
>         size_t                   psize, newsize;
> -       int                      buffer;
>
> +       bufname = NULL;
>         limit = options_get_number(&global_options, "buffer-limit");
>
> -       psize = 0;
> -       pdata = NULL;
>
> -       pb = NULL;
> -       buffer = -1;
> +       if (args_has(args, 'n')) {
> +               if (args_has(args, 's') || args_has(args, 'u')) {
> +                       cmdq_error(cmdq, "specify only 1 of n, s, or u 
> flags");
> +                       return (CMD_RETURN_ERROR);
> +               }
>
> -       if ((newsize = strlen(args->argv[0])) == 0)
> -               return (CMD_RETURN_NORMAL);
> +               if (args->argc > 0) {
> +                       cmdq_error(cmdq, "don't provide data with n flag");
> +                       return (CMD_RETURN_ERROR);
> +               }
>
> -       if (args_has(args, 'b')) {
> -               buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
> -               if (cause != NULL) {
> -                       cmdq_error(cmdq, "buffer %s", cause);
> +               if (args_has(args, 'b'))
> +                       bufname = args_get(args, 'b');
> +
> +               if (bufname == NULL) {
> +                       pb = paste_get_top();
> +                       if (pb == NULL) {
> +                               cmdq_error(cmdq, "no buffer");
> +                               return (CMD_RETURN_ERROR);
> +                       }
> +                       bufname = pb->name;
> +               }
> +
> +               if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) {
> +                       cmdq_error(cmdq, "%s", cause);
>                         free(cause);
>                         return (CMD_RETURN_ERROR);
>                 }
> -               pb = paste_get_index(buffer);
> +
> +               return (CMD_RETURN_NORMAL);
> +       }
> +
> +       if (args_has(args, 's') && args_has(args, 'u')) {
> +               cmdq_error(cmdq, "specify only 1 of s or u flags");
> +               return (CMD_RETURN_ERROR);
> +       }
> +
> +       if (args_has(args, 's') || args_has(args, 'u')) {
> +               sticky = 0;
> +               if (args_has(args, 's'))
> +                       sticky = 1;
> +
> +               if (args->argc > 0) {
> +                       cmdq_error(cmdq, "don't provide data with s or u 
> flags");
> +                       return (CMD_RETURN_ERROR);
> +               }
> +
> +               if (args_has(args, 'b'))
> +                       bufname = args_get(args, 'b');
> +
> +               if (bufname == NULL)
> +                       pb = paste_get_top();
> +               else
> +                       pb = paste_get_name(bufname);
> +
>                 if (pb == NULL) {
> -                       cmdq_error(cmdq, "no buffer %d", buffer);
> +                       if (bufname == NULL)
> +                               bufname = "";
> +                       cmdq_error(cmdq, "no buffer %s", bufname);
>                         return (CMD_RETURN_ERROR);
>                 }
> +
> +               if (sticky == 0)
> +                       paste_make_unsticky(pb->name, limit);
> +               else
> +                       paste_make_sticky(pb->name);
> +
> +               return (CMD_RETURN_NORMAL);
> +       }
> +
> +       if (args->argc != 1) {
> +               cmdq_error(cmdq, "no data specified");
> +               return (CMD_RETURN_ERROR);
> +       }
> +
> +       psize = 0;
> +       pdata = NULL;
> +
> +       pb = NULL;
> +
> +       if ((newsize = strlen(args->argv[0])) == 0)
> +               return (CMD_RETURN_NORMAL);
> +
> +       if (args_has(args, 'b')) {
> +               bufname = args_get(args, 'b');
> +               pb = paste_get_name(bufname);
>         } else if (args_has(args, 'a')) {
>                 pb = paste_get_top();
>                 if (pb != NULL)
> -                       buffer = 0;
> +                       bufname = pb->name;
>         }
>
>         if (args_has(args, 'a') && pb != NULL) {
> @@ -87,10 +155,12 @@ cmd_set_buffer_exec(struct cmd *self, st
>         memcpy(pdata + psize, args->argv[0], newsize);
>         psize += newsize;
>
> -       if (buffer == -1)
> -               paste_add(pdata, psize, limit);
> -       else
> -               paste_replace(buffer, pdata, psize);
> +       if (paste_set(pdata, psize, limit, bufname, &cause) != 0) {
> +               cmdq_error(cmdq, "%s", cause);
> +               free(pdata);
> +               free(cause);
> +               return (CMD_RETURN_ERROR);
> +       }
>
>         return (CMD_RETURN_NORMAL);
>  }
> Index: format.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/format.c,v
> retrieving revision 1.44
> diff -u -p -r1.44 format.c
> --- format.c    17 Apr 2014 15:37:55 -0000      1.44
> +++ format.c    24 Apr 2014 09:44:43 -0000
> @@ -608,6 +608,9 @@ format_paste_buffer(struct format_tree *
>         char    *s;
>
>         format_add(ft, "buffer_size", "%zu", pb->size);
> +       format_add(ft, "buffer_name", "%s", pb->name);
> +       format_add(ft, "buffer_stickiness", "%c",
> +           pb->sticky == 0 ? 'U' : 'S');
>
>         s = paste_make_sample(pb, utf8flag);
>         format_add(ft, "buffer_sample", "%s", s);
> Index: key-bindings.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/key-bindings.c,v
> retrieving revision 1.40
> diff -u -p -r1.40 key-bindings.c
> --- key-bindings.c      17 Apr 2014 07:55:43 -0000      1.40
> +++ key-bindings.c      24 Apr 2014 09:44:43 -0000
> @@ -130,6 +130,7 @@ key_bindings_init(void)
>                 { '?',                    0, &cmd_list_keys_entry },
>                 { 'D',                    0, &cmd_choose_client_entry },
>                 { 'L',                    0, &cmd_switch_client_entry },
> +               { 'P',                    0, &cmd_command_prompt_entry },
>                 { '[',                    0, &cmd_copy_mode_entry },
>                 { '\'',                   0, &cmd_command_prompt_entry },
>                 { '\002', /* C-b */       0, &cmd_send_prefix_entry },
> Index: mode-key.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/mode-key.c,v
> retrieving revision 1.58
> diff -u -p -r1.58 mode-key.c
> --- mode-key.c  31 Mar 2014 21:39:31 -0000      1.58
> +++ mode-key.c  24 Apr 2014 09:44:43 -0000
> @@ -51,6 +51,7 @@ const struct mode_key_cmdstr mode_key_cm
>         { MODEKEYEDIT_DELETEWORD, "delete-word" },
>         { MODEKEYEDIT_ENDOFLINE, "end-of-line" },
>         { MODEKEYEDIT_ENTER, "enter" },
> +       { MODEKEYEDIT_ENTERAPPEND, "enter-append" },
>         { MODEKEYEDIT_HISTORYDOWN, "history-down" },
>         { MODEKEYEDIT_HISTORYUP, "history-up" },
>         { MODEKEYEDIT_NEXTSPACE, "next-space" },
> @@ -141,6 +142,7 @@ const struct mode_key_cmdstr mode_key_cm
>         { MODEKEYCOPY_SEARCHREVERSE, "search-reverse" },
>         { MODEKEYCOPY_SEARCHUP, "search-backward" },
>         { MODEKEYCOPY_SELECTLINE, "select-line" },
> +       { MODEKEYCOPY_STARTNAMEDBUFFER, "start-named-buffer" },
>         { MODEKEYCOPY_STARTNUMBERPREFIX, "start-number-prefix" },
>         { MODEKEYCOPY_STARTOFLINE, "start-of-line" },
>         { MODEKEYCOPY_STARTSELECTION, "begin-selection" },
> @@ -160,6 +162,7 @@ const struct mode_key_entry mode_key_vi_
>         { '\033' /* Escape */,      0, MODEKEYEDIT_SWITCHMODE },
>         { '\n',                     0, MODEKEYEDIT_ENTER },
>         { '\r',                     0, MODEKEYEDIT_ENTER },
> +       { '\001' /* C-a */,         0, MODEKEYEDIT_ENTERAPPEND },
>         { KEYC_BSPACE,              0, MODEKEYEDIT_BACKSPACE },
>         { KEYC_DC,                  0, MODEKEYEDIT_DELETE },
>         { KEYC_DOWN,                0, MODEKEYEDIT_HISTORYDOWN },
> @@ -257,6 +260,7 @@ struct mode_key_tree mode_key_tree_vi_ch
>  /* vi copy mode keys. */
>  const struct mode_key_entry mode_key_vi_copy[] = {
>         { ' ',                      0, MODEKEYCOPY_STARTSELECTION },
> +       { '"',                      0, MODEKEYCOPY_STARTNAMEDBUFFER },
>         { '$',                      0, MODEKEYCOPY_ENDOFLINE },
>         { ',',                      0, MODEKEYCOPY_JUMPREVERSE },
>         { ';',                      0, MODEKEYCOPY_JUMPAGAIN },
> Index: paste.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/paste.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 paste.c
> --- paste.c     24 Apr 2014 09:14:43 -0000      1.18
> +++ paste.c     24 Apr 2014 09:44:43 -0000
> @@ -19,6 +19,7 @@
>  #include <sys/types.h>
>  #include <sys/time.h>
>
> +#include <ctype.h>
>  #include <stdlib.h>
>  #include <string.h>
>  #include <vis.h>
> @@ -30,124 +31,300 @@
>   * string!
>   */
>
> -ARRAY_DECL(, struct paste_buffer *) paste_buffers =  ARRAY_INITIALIZER;
> +u_int  paste_unsticky_idx;
> +u_int  paste_num_unsticky;
> +RB_HEAD(paste_name_tree, paste_buffer) paste_by_name;
> +RB_HEAD(paste_time_tree, paste_buffer) paste_by_time;
> +
> +int paste_cmp_names(const struct paste_buffer *, const struct paste_buffer 
> *);
> +RB_PROTOTYPE(paste_name_tree, paste_buffer, name_entry, paste_cmp_names);
> +RB_GENERATE(paste_name_tree, paste_buffer, name_entry, paste_cmp_names);
> +
> +int paste_cmp_times(const struct paste_buffer *, const struct paste_buffer 
> *);
> +RB_PROTOTYPE(paste_time_tree, paste_buffer, time_entry, paste_cmp_times);
> +RB_GENERATE(paste_time_tree, paste_buffer, time_entry, paste_cmp_times);
>
> -/* Return each item of the stack in turn. */
> -struct paste_buffer *
> -paste_walk_stack(u_int *idx)
> +int
> +paste_cmp_names(const struct paste_buffer *a, const struct paste_buffer *b)
>  {
> -       struct paste_buffer     *pb;
> +       return (strcmp(a->name, b->name));
> +}
>
> -       pb = paste_get_index(*idx);
> -       (*idx)++;
> -       return (pb);
> +int
> +paste_cmp_times(const struct paste_buffer *a, const struct paste_buffer *b)
> +{
> +       return (a->crtime < b->crtime ? -1 : a->crtime > b->crtime);
>  }
>
> -/* Get the top item on the stack. */
> +/* Walk paste buffers by name. */
>  struct paste_buffer *
> -paste_get_top(void)
> +paste_walk(struct paste_buffer *pb)
>  {
> -       if (ARRAY_LENGTH(&paste_buffers) == 0)
> -               return (NULL);
> -       return (ARRAY_FIRST(&paste_buffers));
> +       if (pb == NULL)
> +               return (RB_MIN(paste_name_tree, &paste_by_name));
> +       return (RB_NEXT(paste_name_tree, &paste_by_name, pb));
>  }
>
> -/* Get an item by its index. */
> +/* Get the most recent unsticky buffer */
>  struct paste_buffer *
> -paste_get_index(u_int idx)
> +paste_get_top(void)
>  {
> -       if (idx >= ARRAY_LENGTH(&paste_buffers))
> -               return (NULL);
> -       return (ARRAY_ITEM(&paste_buffers, idx));
> +       return (RB_MAX(paste_time_tree, &paste_by_time));
>  }
>
> -/* Free the top item on the stack. */
> +/* Free the most recent unsticky buffer */
>  int
>  paste_free_top(void)
>  {
>         struct paste_buffer     *pb;
>
> -       if (ARRAY_LENGTH(&paste_buffers) == 0)
> +       pb = paste_get_top();
> +       if (pb == NULL)
>                 return (-1);
> -
> -       pb = ARRAY_FIRST(&paste_buffers);
> -       ARRAY_REMOVE(&paste_buffers, 0);
> -
> -       free(pb->data);
> -       free(pb);
> -
> -       return (0);
> +       return (paste_free_name(pb->name));
>  }
>
> -/* Free an item by index. */
> +/* Free an item by name. */
>  int
> -paste_free_index(u_int idx)
> +paste_free_name(const char *name)
>  {
> -       struct paste_buffer     *pb;
> +       struct paste_buffer     *pb, pbfind;
> +
> +       if (name == NULL || *name == '\0')
> +               return (-1);
>
> -       if (idx >= ARRAY_LENGTH(&paste_buffers))
> +       pbfind.name = (char*)name;
> +       pb = RB_FIND(paste_name_tree, &paste_by_name, &pbfind);
> +       if (pb == NULL)
>                 return (-1);
>
> -       pb = ARRAY_ITEM(&paste_buffers, idx);
> -       ARRAY_REMOVE(&paste_buffers, idx);
> +       RB_REMOVE(paste_name_tree, &paste_by_name, pb);
> +       if (pb->sticky == 0) {
> +               RB_REMOVE(paste_time_tree, &paste_by_time, pb);
> +               paste_num_unsticky--;
> +       }
>
>         free(pb->data);
> +       free(pb->name);
>         free(pb);
> -
>         return (0);
>  }
>
>  /*
> - * Add an item onto the top of the stack, freeing the bottom if at limit. 
> Note
> + * Add an unsticky buffer, freeing the oldest unsticky item if at limit. Note
>   * that the caller is responsible for allocating data.
>   */
>  void
>  paste_add(char *data, size_t size, u_int limit)
>  {
>         struct paste_buffer     *pb;
> +       u_int                    next_crtime;
>
>         if (size == 0)
>                 return;
>
> -       while (ARRAY_LENGTH(&paste_buffers) >= limit) {
> -               pb = ARRAY_LAST(&paste_buffers);
> -               free(pb->data);
> -               free(pb);
> -               ARRAY_TRUNC(&paste_buffers, 1);
> +       while (paste_num_unsticky >= limit) {
> +               pb = RB_MIN(paste_time_tree, &paste_by_time);
> +               paste_free_name(pb->name);
> +       }
> +
> +       next_crtime = 0;
> +       if (paste_num_unsticky > 0) {
> +               pb = RB_MAX(paste_time_tree, &paste_by_time);
> +               next_crtime = pb->crtime + 1;
>         }
>
>         pb = xmalloc(sizeof *pb);
> -       ARRAY_INSERT(&paste_buffers, 0, pb);
> +       pb->name = NULL;
> +       do {
> +               free(pb->name);
> +               xasprintf(&pb->name, "buffer%04u", paste_unsticky_idx);
> +               paste_unsticky_idx++;
> +       } while (paste_get_name(pb->name) != NULL);
>
>         pb->data = data;
>         pb->size = size;
> +       pb->sticky = 0;
> +       pb->crtime = next_crtime;
> +
> +       RB_INSERT(paste_name_tree, &paste_by_name, pb);
> +       RB_INSERT(paste_time_tree, &paste_by_time, pb);
> +       paste_num_unsticky++;
>  }
>
> +/* Get an item by its name. */
> +struct paste_buffer *
> +paste_get_name(const char *name)
> +{
> +       struct paste_buffer     pbfind;
> +
> +       if (name == NULL || *name == '\0')
> +               return (NULL);
> +
> +       pbfind.name = (char*)name;
> +       return (RB_FIND(paste_name_tree, &paste_by_name, &pbfind));
> +}
> +
> +/* Rename a paste buffer. */
> +int
> +paste_rename(const char *oldname, const char *newname, char **cause)
> +{
> +       const char              *c;
> +       struct paste_buffer     *pb;
> +
> +       *cause = NULL;
> +
> +       if (oldname == NULL || *oldname == '\0') {
> +               *cause = xstrdup("no buffer");
> +               return (-1);
> +       }
> +
> +       if (newname == NULL || *newname == '\0') {
> +               *cause = xstrdup("new name is empty");
> +               return (-1);
> +       }
> +
> +       if ((pb = paste_get_name(oldname)) == NULL) {
> +               xasprintf(cause, "no buffer %s", oldname);
> +               return (-1);
> +       }
> +
> +       if (paste_get_name(newname) != NULL) {
> +               *cause = xstrdup("buffer with new name already exists");
> +               return (-1);
> +       }
> +
> +       if (strlen(newname) > 16) {
> +               *cause = xstrdup("buffer name too long");
> +               return (-1);
> +       }
> +
> +       for (c = newname; *c != '\0'; c++) {
> +               if (!isprint(*c) || isspace(*c)) {
> +                       *cause = xstrdup("bad characters in buffer name");
> +                       return (-1);
> +               }
> +       }
> +
> +       RB_REMOVE(paste_name_tree, &paste_by_name, pb);
> +       free(pb->name);
> +
> +       pb->name = xstrdup(newname);
> +       RB_INSERT(paste_name_tree, &paste_by_name, pb);
> +       return (0);
> +}
>
>  /*
> - * Replace an item on the stack. Note that the caller is responsible for
> + * Add or replace an item in the store. Note that the caller is responsible 
> for
>   * allocating data.
>   */
>  int
> -paste_replace(u_int idx, char *data, size_t size)
> +paste_set(char *data, size_t size, u_int limit, const char *name, char 
> **cause)
>  {
>         struct paste_buffer     *pb;
> +       const char              *c;
> +
> +       if (cause != NULL)
> +               *cause = NULL;
>
>         if (size == 0) {
>                 free(data);
>                 return (0);
>         }
>
> -       if (idx >= ARRAY_LENGTH(&paste_buffers))
> +       if (name == NULL) {
> +               paste_add(data, size, limit);
> +               return (0);
> +       }
> +
> +
> +       pb = paste_get_name(name);
> +
> +       if (pb != NULL) {
> +               free(pb->data);
> +               pb->data = data;
> +               pb->size = size;
> +               return (0);
> +       }
> +
> +
> +       if (*name == '\0') {
> +               if (cause != NULL)
> +                       *cause = xstrdup("empty buffer name");
>                 return (-1);
> +       }
>
> -       pb = ARRAY_ITEM(&paste_buffers, idx);
> -       free(pb->data);
> +       if (strlen(name) > 16) {
> +               if (cause != NULL)
> +                       *cause = xstrdup("buffer name too long");
> +               return (-1);
> +       }
> +       for (c = name; *c != '\0'; c++) {
> +               if (!isprint(*c) || isspace(*c)) {
> +                       if (cause != NULL)
> +                               *cause = xstrdup("invalid buffer name");
> +                       return (-1);
> +               }
> +       }
>
> +       pb = xmalloc(sizeof *pb);
>         pb->data = data;
>         pb->size = size;
> +       pb->name = xstrdup(name);
> +       pb->sticky = 1;
> +
> +       RB_INSERT(paste_name_tree, &paste_by_name, pb);
>
>         return (0);
> +}
> +
> +/* Set paste buffer sticky. */
> +void
> +paste_make_sticky(const char *name)
> +{
> +       struct paste_buffer     *pb;
> +
> +       if ((pb = paste_get_name(name)) == NULL)
> +               return;
> +
> +       if (pb->sticky == 1)
> +               return;
> +
> +       RB_REMOVE(paste_time_tree, &paste_by_time, pb);
> +       paste_num_unsticky--;
> +
> +       pb->sticky = 1;
> +}
> +
> +/* Set paste buffer unsticky. */
> +void
> +paste_make_unsticky(const char *name, u_int limit)
> +{
> +       struct paste_buffer     *pb, *tmppb;
> +       u_int                    next_crtime;
> +
> +       if ((pb = paste_get_name(name)) == NULL)
> +               return;
> +
> +       if (pb->sticky == 0)
> +               return;
> +
> +       while (paste_num_unsticky >= limit) {
> +               tmppb = RB_MIN(paste_time_tree, &paste_by_time);
> +               paste_free_name(tmppb->name);
> +       }
> +
> +       next_crtime = 0;
> +       if (paste_num_unsticky > 0) {
> +               tmppb = RB_MAX(paste_time_tree, &paste_by_time);
> +               next_crtime = tmppb->crtime + 1;
> +       }
> +
> +       pb->sticky = 0;
> +       pb->crtime = next_crtime;
> +
> +       RB_INSERT(paste_time_tree, &paste_by_time, pb);
> +       paste_num_unsticky++;
>  }
>
>  /* Convert start of buffer into a nice string. */
> Index: tmux.h
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/tmux.h,v
> retrieving revision 1.457
> diff -u -p -r1.457 tmux.h
> --- tmux.h      24 Apr 2014 09:14:43 -0000      1.457
> +++ tmux.h      24 Apr 2014 09:44:43 -0000
> @@ -85,7 +85,7 @@ extern char   **environ;
>
>  /* Default template for choose-buffer. */
>  #define CHOOSE_BUFFER_TEMPLATE                                 \
> -       "#{line}: #{buffer_size} bytes: #{buffer_sample}"
> +       "#{buffer_name}: #{buffer_size} bytes: #{buffer_sample}"
>
>  /* Default template for choose-client. */
>  #define CHOOSE_CLIENT_TEMPLATE                                 \
> @@ -118,7 +118,8 @@ extern char   **environ;
>
>  /* Default template for list-buffers. */
>  #define LIST_BUFFERS_TEMPLATE                                  \
> -       "#{line}: #{buffer_size} bytes: \"#{buffer_sample}\""
> +       "#{buffer_name}: #{buffer_size} bytes: "                \
> +       "\"#{buffer_sample}\""
>
>  /* Default template for list-clients. */
>  #define LIST_CLIENTS_TEMPLATE                                  \
> @@ -499,6 +500,7 @@ enum mode_key_cmd {
>         MODEKEYEDIT_DELETEWORD,
>         MODEKEYEDIT_ENDOFLINE,
>         MODEKEYEDIT_ENTER,
> +       MODEKEYEDIT_ENTERAPPEND,
>         MODEKEYEDIT_HISTORYDOWN,
>         MODEKEYEDIT_HISTORYUP,
>         MODEKEYEDIT_NEXTSPACE,
> @@ -582,6 +584,7 @@ enum mode_key_cmd {
>         MODEKEYCOPY_SEARCHREVERSE,
>         MODEKEYCOPY_SEARCHUP,
>         MODEKEYCOPY_SELECTLINE,
> +       MODEKEYCOPY_STARTNAMEDBUFFER,
>         MODEKEYCOPY_STARTNUMBERPREFIX,
>         MODEKEYCOPY_STARTOFLINE,
>         MODEKEYCOPY_STARTSELECTION,
> @@ -1035,7 +1038,13 @@ struct layout_cell {
>  /* Paste buffer. */
>  struct paste_buffer {
>         char            *data;
> +       char            *name;
> +       u_char           sticky;
>         size_t           size;
> +       u_int            crtime;
> +
> +       RB_ENTRY(paste_buffer) name_entry;
> +       RB_ENTRY(paste_buffer) time_entry;
>  };
>
>  /* Environment variable. */
> @@ -1496,7 +1505,7 @@ RB_HEAD(format_tree, format_entry);
>  #define CMD_SRCDST_WINDOW_USAGE "[-s src-window] [-t dst-window]"
>  #define CMD_SRCDST_SESSION_USAGE "[-s src-session] [-t dst-session]"
>  #define CMD_SRCDST_CLIENT_USAGE "[-s src-client] [-t dst-client]"
> -#define CMD_BUFFER_USAGE "[-b buffer-index]"
> +#define CMD_BUFFER_USAGE "[-b buffer-name]"
>
>  /* tmux.c */
>  extern struct options global_options;
> @@ -1708,14 +1717,17 @@ void    tty_keys_free(struct tty *);
>  int    tty_keys_next(struct tty *);
>
>  /* paste.c */
> -struct paste_buffer *paste_walk_stack(u_int *);
> +struct paste_buffer *paste_walk(struct paste_buffer *);
>  struct paste_buffer *paste_get_top(void);
> -struct paste_buffer *paste_get_index(u_int);
> +struct paste_buffer *paste_get_name(const char *);
>  int             paste_free_top(void);
> -int             paste_free_index(u_int);
> +int             paste_free_name(const char *);
>  void            paste_add(char *, size_t, u_int);
> -int             paste_replace(u_int, char *, size_t);
> +int             paste_rename(const char *, const char *, char **);
> +int             paste_set(char *, size_t, u_int, const char *, char **);
>  char           *paste_make_sample(struct paste_buffer *, int);
> +void            paste_make_sticky(const char *);
> +void            paste_make_unsticky(const char *, u_int);
>  void            paste_send_pane(struct paste_buffer *, struct window_pane *,
>                      const char *, int);
>
> Index: window-copy.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/window-copy.c,v
> retrieving revision 1.107
> diff -u -p -r1.107 window-copy.c
> --- window-copy.c       24 Apr 2014 09:14:43 -0000      1.107
> +++ window-copy.c       24 Apr 2014 09:44:43 -0000
> @@ -54,11 +54,12 @@ void        window_copy_update_cursor(struct wi
>  void   window_copy_start_selection(struct window_pane *);
>  int    window_copy_update_selection(struct window_pane *, int);
>  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_buffer(
> +           struct window_pane *, const char *, void *, size_t);
>  void   window_copy_copy_pipe(
> -           struct window_pane *, struct session *, int, const char *);
> -void   window_copy_copy_selection(struct window_pane *, int);
> -void   window_copy_append_selection(struct window_pane *, int);
> +           struct window_pane *, struct session *, const char *, const char 
> *);
> +void   window_copy_copy_selection(struct window_pane *, const char *);
> +void   window_copy_append_selection(struct window_pane *, const char *);
>  void   window_copy_clear_selection(struct window_pane *);
>  void   window_copy_copy_line(
>             struct window_pane *, char **, size_t *, u_int, u_int, u_int);
> @@ -94,6 +95,7 @@ const struct window_mode window_copy_mod
>
>  enum window_copy_input_type {
>         WINDOW_COPY_OFF,
> +       WINDOW_COPY_NAMEDBUFFER,
>         WINDOW_COPY_NUMERICPREFIX,
>         WINDOW_COPY_SEARCHUP,
>         WINDOW_COPY_SEARCHDOWN,
> @@ -417,7 +419,7 @@ window_copy_key(struct window_pane *wp,
>         switch (cmd) {
>         case MODEKEYCOPY_APPENDSELECTION:
>                 if (sess != NULL) {
> -                       window_copy_append_selection(wp, data->numprefix);
> +                       window_copy_append_selection(wp, NULL);
>                         window_pane_reset_mode(wp);
>                         return;
>                 }
> @@ -543,7 +545,7 @@ window_copy_key(struct window_pane *wp,
>                 if (sess != NULL &&
>                     (cmd == MODEKEYCOPY_COPYLINE ||
>                     cmd == MODEKEYCOPY_COPYENDOFLINE)) {
> -                       window_copy_copy_selection(wp, -1);
> +                       window_copy_copy_selection(wp, NULL);
>                         window_pane_reset_mode(wp);
>                         return;
>                 }
> @@ -554,14 +556,14 @@ window_copy_key(struct window_pane *wp,
>                 break;
>         case MODEKEYCOPY_COPYPIPE:
>                 if (sess != NULL) {
> -                       window_copy_copy_pipe(wp, sess, data->numprefix, arg);
> +                       window_copy_copy_pipe(wp, sess, NULL, arg);
>                         window_pane_reset_mode(wp);
>                         return;
>                 }
>                 break;
>         case MODEKEYCOPY_COPYSELECTION:
>                 if (sess != NULL) {
> -                       window_copy_copy_selection(wp, data->numprefix);
> +                       window_copy_copy_selection(wp, NULL);
>                         window_pane_reset_mode(wp);
>                         return;
>                 }
> @@ -676,6 +678,7 @@ window_copy_key(struct window_pane *wp,
>                 case WINDOW_COPY_JUMPBACK:
>                 case WINDOW_COPY_JUMPTOFORWARD:
>                 case WINDOW_COPY_JUMPTOBACK:
> +               case WINDOW_COPY_NAMEDBUFFER:
>                 case WINDOW_COPY_NUMERICPREFIX:
>                         break;
>                 case WINDOW_COPY_SEARCHUP:
> @@ -711,6 +714,11 @@ window_copy_key(struct window_pane *wp,
>                 data->inputprompt = "Goto Line";
>                 *data->inputstr = '\0';
>                 goto input_on;
> +       case MODEKEYCOPY_STARTNAMEDBUFFER:
> +               data->inputtype = WINDOW_COPY_NAMEDBUFFER;
> +               data->inputprompt = "Buffer";
> +               *data->inputstr = '\0';
> +               goto input_on;
>         case MODEKEYCOPY_STARTNUMBERPREFIX:
>                 key &= KEYC_MASK_KEY;
>                 if (key >= '0' && key <= '9') {
> @@ -814,6 +822,11 @@ window_copy_key_input(struct window_pane
>                         data->searchtype = data->inputtype;
>                         data->searchstr = xstrdup(data->inputstr);
>                         break;
> +               case WINDOW_COPY_NAMEDBUFFER:
> +                       window_copy_copy_selection(wp, data->inputstr);
> +                       *data->inputstr = '\0';
> +                       window_pane_reset_mode(wp);
> +                       return (0);
>                 case WINDOW_COPY_GOTOLINE:
>                         window_copy_goto_line(wp, data->inputstr);
>                         *data->inputstr = '\0';
> @@ -821,6 +834,17 @@ window_copy_key_input(struct window_pane
>                 }
>                 data->numprefix = -1;
>                 return (1);
> +       case MODEKEYEDIT_ENTERAPPEND:
> +               switch (data->inputtype) {
> +               case WINDOW_COPY_NAMEDBUFFER:
> +                       window_copy_append_selection(wp, data->inputstr);
> +                       *data->inputstr = '\0';
> +                       window_pane_reset_mode(wp);
> +                       return (0);
> +               default:
> +                       break;
> +               }
> +               break;
>         case MODEKEY_OTHER:
>                 if (key < 32 || key > 126)
>                         break;
> @@ -918,7 +942,7 @@ reset_mode:
>         s->mode &= ~MODE_MOUSE_BUTTON;
>         s->mode |= MODE_MOUSE_STANDARD;
>         if (sess != NULL) {
> -               window_copy_copy_selection(wp, -1);
> +               window_copy_copy_selection(wp, NULL);
>                 window_pane_reset_mode(wp);
>         }
>  }
> @@ -1452,10 +1476,11 @@ window_copy_get_selection(struct window_
>  }
>
>  void
> -window_copy_copy_buffer(struct window_pane *wp, int idx, void *buf, size_t 
> len)
> +window_copy_copy_buffer(struct window_pane *wp, const char *bufname, void 
> *buf,
> +    size_t len)
>  {
> -       u_int                   limit;
> -       struct screen_write_ctx ctx;
> +       u_int                            limit;
> +       struct screen_write_ctx          ctx;
>
>         if (options_get_number(&global_options, "set-clipboard")) {
>                 screen_write_start(&ctx, wp, NULL);
> @@ -1463,16 +1488,16 @@ window_copy_copy_buffer(struct window_pa
>                 screen_write_stop(&ctx);
>         }
>
> -       if (idx == -1) {
> -               limit = options_get_number(&global_options, "buffer-limit");
> -               paste_add(buf, len, limit);
> -       } else if (paste_replace(idx, buf, len) != 0)
> +       limit = options_get_number(&global_options, "buffer-limit");
> +       if (paste_set(buf, len, limit, bufname, NULL) != 0)
>                 free(buf);
> +
> +       return;
>  }
>
>  void
> -window_copy_copy_pipe(
> -    struct window_pane *wp, struct session *sess, int idx, const char *arg)
> +window_copy_copy_pipe(struct window_pane *wp, struct session *sess,
> +    const char *bufname, const char *arg)
>  {
>         void            *buf;
>         size_t           len;
> @@ -1486,11 +1511,11 @@ window_copy_copy_pipe(
>         job = job_run(arg, sess, NULL, NULL, NULL);
>         bufferevent_write(job->event, buf, len);
>
> -       window_copy_copy_buffer(wp, idx, buf, len);
> +       window_copy_copy_buffer(wp, bufname, buf, len);
>  }
>
>  void
> -window_copy_copy_selection(struct window_pane *wp, int idx)
> +window_copy_copy_selection(struct window_pane *wp, const char *bufname)
>  {
>         void*   buf;
>         size_t  len;
> @@ -1499,17 +1524,17 @@ window_copy_copy_selection(struct window
>         if (buf == NULL)
>                 return;
>
> -       window_copy_copy_buffer(wp, idx, buf, len);
> +       window_copy_copy_buffer(wp, bufname, buf, len);
>  }
>
>  void
> -window_copy_append_selection(struct window_pane *wp, int idx)
> +window_copy_append_selection(struct window_pane *wp, const char *bufname)
>  {
> -       char                    *buf;
> -       struct paste_buffer     *pb;
> -       size_t                   len;
> -       u_int                    limit;
> -       struct screen_write_ctx  ctx;
> +       char                            *buf;
> +       struct paste_buffer             *pb;
> +       size_t                           len;
> +       u_int                            limit;
> +       struct screen_write_ctx          ctx;
>
>         buf = window_copy_get_selection(wp, &len);
>         if (buf == NULL)
> @@ -1521,24 +1546,20 @@ window_copy_append_selection(struct wind
>                 screen_write_stop(&ctx);
>         }
>
> -       if (idx == -1)
> -               idx = 0;
> -
> -       if (idx == 0 && paste_get_top() == NULL) {
> -               limit = options_get_number(&global_options, "buffer-limit");
> -               paste_add(buf, len, limit);
> -               return;
> -       }
> -
> -       pb = paste_get_index(idx);
> +       limit = options_get_number(&global_options, "buffer-limit");
> +       if (bufname == NULL || *bufname == '\0') {
> +               pb = paste_get_top();
> +               if (pb != NULL)
> +                       bufname = pb->name;
> +       } else
> +               pb = paste_get_name(bufname);
>         if (pb != NULL) {
>                 buf = xrealloc(buf, 1, len + pb->size);
>                 memmove(buf + pb->size, buf, len);
>                 memcpy(buf, pb->data, pb->size);
>                 len += pb->size;
>         }
> -
> -       if (paste_replace(idx, buf, len) != 0)
> +       if (paste_set(buf, len, limit, bufname, NULL) != 0)
>                 free(buf);
>  }
>

------------------------------------------------------------------------------
Start Your Social Network Today - Download eXo Platform
Build your Enterprise Intranet with eXo Platform Software
Java Based Open Source Intranet - Social, Extensible, Cloud Ready
Get Started Now And Turn Your Intranet Into A Collaboration Platform
http://p.sf.net/sfu/ExoPlatform
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to