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
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-users