Add setb -a to append and a copy mode append command, from J Raynor with

minor changes.
This commit is contained in:
nicm 2014-03-31 21:39:31 +00:00
parent b11de5adc7
commit 0e4d1d8493
6 changed files with 104 additions and 28 deletions

View File

@ -24,15 +24,15 @@
#include "tmux.h" #include "tmux.h"
/* /*
* Add or set a paste buffer. * Add, set, or append to a paste buffer.
*/ */
enum cmd_retval cmd_set_buffer_exec(struct cmd *, struct cmd_q *); enum cmd_retval cmd_set_buffer_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_set_buffer_entry = { const struct cmd_entry cmd_set_buffer_entry = {
"set-buffer", "setb", "set-buffer", "setb",
"b:", 1, 1, "ab:", 1, 1,
CMD_BUFFER_USAGE " data", "[-a] " CMD_BUFFER_USAGE " data",
0, 0,
NULL, NULL,
cmd_set_buffer_exec cmd_set_buffer_exec
@ -41,35 +41,55 @@ const struct cmd_entry cmd_set_buffer_entry = {
enum cmd_retval enum cmd_retval
cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq) cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{ {
struct args *args = self->args; struct args *args = self->args;
u_int limit; struct paste_buffer *pb;
char *pdata, *cause; u_int limit;
size_t psize; char *pdata, *cause;
int buffer; size_t psize, newsize;
int buffer;
limit = options_get_number(&global_options, "buffer-limit"); limit = options_get_number(&global_options, "buffer-limit");
pdata = xstrdup(args->argv[0]); psize = 0;
psize = strlen(pdata); pdata = NULL;
if (!args_has(args, 'b')) { pb = NULL;
buffer = -1;
if (args_has(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);
}
pb = paste_get_index(&global_buffers, buffer);
if (pb == NULL) {
cmdq_error(cmdq, "no buffer %d", buffer);
return (CMD_RETURN_ERROR);
}
} else if (args_has(args, 'a')) {
pb = paste_get_top(&global_buffers);
if (pb != NULL)
buffer = 0;
}
if (args_has(args, 'a') && pb != NULL) {
psize = pb->size;
pdata = xmalloc(psize);
memcpy(pdata, pb->data, psize);
}
newsize = strlen(args->argv[0]);
pdata = xrealloc(pdata, 1, psize + newsize);
memcpy(pdata + psize, args->argv[0], newsize);
psize += newsize;
if (buffer == -1)
paste_add(&global_buffers, pdata, psize, limit); paste_add(&global_buffers, pdata, psize, limit);
return (CMD_RETURN_NORMAL); else
} paste_replace(&global_buffers, buffer, pdata, psize);
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
if (cause != NULL) {
cmdq_error(cmdq, "buffer %s", cause);
free(cause);
free(pdata);
return (CMD_RETURN_ERROR);
}
if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
cmdq_error(cmdq, "no buffer %d", buffer);
free(pdata);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@ -100,6 +100,7 @@ const struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
/* Copy keys command strings. */ /* Copy keys command strings. */
const struct mode_key_cmdstr mode_key_cmdstr_copy[] = { const struct mode_key_cmdstr mode_key_cmdstr_copy[] = {
{ MODEKEYCOPY_APPENDSELECTION, "append-selection" },
{ MODEKEYCOPY_BACKTOINDENTATION, "back-to-indentation" }, { MODEKEYCOPY_BACKTOINDENTATION, "back-to-indentation" },
{ MODEKEYCOPY_BOTTOMLINE, "bottom-line" }, { MODEKEYCOPY_BOTTOMLINE, "bottom-line" },
{ MODEKEYCOPY_CANCEL, "cancel" }, { MODEKEYCOPY_CANCEL, "cancel" },
@ -272,6 +273,7 @@ const struct mode_key_entry mode_key_vi_copy[] = {
{ '9', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, { '9', 0, MODEKEYCOPY_STARTNUMBERPREFIX },
{ ':', 0, MODEKEYCOPY_GOTOLINE }, { ':', 0, MODEKEYCOPY_GOTOLINE },
{ '?', 0, MODEKEYCOPY_SEARCHUP }, { '?', 0, MODEKEYCOPY_SEARCHUP },
{ 'A', 0, MODEKEYCOPY_APPENDSELECTION },
{ 'B', 0, MODEKEYCOPY_PREVIOUSSPACE }, { 'B', 0, MODEKEYCOPY_PREVIOUSSPACE },
{ 'D', 0, MODEKEYCOPY_COPYENDOFLINE }, { 'D', 0, MODEKEYCOPY_COPYENDOFLINE },
{ 'E', 0, MODEKEYCOPY_NEXTSPACEEND }, { 'E', 0, MODEKEYCOPY_NEXTSPACEEND },

View File

@ -172,7 +172,7 @@ paste_print(struct paste_buffer *pb, size_t width)
/* Paste into a window pane, filtering '\n' according to separator. */ /* Paste into a window pane, filtering '\n' according to separator. */
void void
paste_send_pane (struct paste_buffer *pb, struct window_pane *wp, paste_send_pane(struct paste_buffer *pb, struct window_pane *wp,
const char *sep, int bracket) const char *sep, int bracket)
{ {
const char *data = pb->data, *end = data + pb->size, *lf; const char *data = pb->data, *end = data + pb->size, *lf;

5
tmux.1
View File

@ -851,6 +851,7 @@ option).
The following keys are supported as appropriate for the mode: The following keys are supported as appropriate for the mode:
.Bl -column "FunctionXXXXXXXXXXXXXXXXX" "viXXXXXXXXXX" "emacs" -offset indent .Bl -column "FunctionXXXXXXXXXXXXXXXXX" "viXXXXXXXXXX" "emacs" -offset indent
.It Sy "Function" Ta Sy "vi" Ta Sy "emacs" .It Sy "Function" Ta Sy "vi" Ta Sy "emacs"
.It Li "Append selection" Ta "A" Ta ""
.It Li "Back to indentation" Ta "^" Ta "M-m" .It Li "Back to indentation" Ta "^" Ta "M-m"
.It Li "Bottom of history" Ta "G" Ta "M-<" .It Li "Bottom of history" Ta "G" Ta "M-<"
.It Li "Clear selection" Ta "Escape" Ta "C-g" .It Li "Clear selection" Ta "Escape" Ta "C-g"
@ -3543,12 +3544,16 @@ The
.Fl a .Fl a
option appends to rather than overwriting the file. option appends to rather than overwriting the file.
.It Xo Ic set-buffer .It Xo Ic set-buffer
.Op Fl a
.Op Fl b Ar buffer-index .Op Fl b Ar buffer-index
.Ar data .Ar data
.Xc .Xc
.D1 (alias: Ic setb ) .D1 (alias: Ic setb )
Set the contents of the specified buffer to Set the contents of the specified buffer to
.Ar data . .Ar data .
The
.Fl a
option appends to rather than overwriting the buffer.
.It Xo Ic show-buffer .It Xo Ic show-buffer
.Op Fl b Ar buffer-index .Op Fl b Ar buffer-index
.Xc .Xc

1
tmux.h
View File

@ -540,6 +540,7 @@ enum mode_key_cmd {
MODEKEYCHOICE_UP, MODEKEYCHOICE_UP,
/* Copy keys. */ /* Copy keys. */
MODEKEYCOPY_APPENDSELECTION,
MODEKEYCOPY_BACKTOINDENTATION, MODEKEYCOPY_BACKTOINDENTATION,
MODEKEYCOPY_BOTTOMLINE, MODEKEYCOPY_BOTTOMLINE,
MODEKEYCOPY_CANCEL, MODEKEYCOPY_CANCEL,

View File

@ -58,6 +58,7 @@ void window_copy_copy_buffer(struct window_pane *, int, void *, size_t);
void window_copy_copy_pipe( void window_copy_copy_pipe(
struct window_pane *, struct session *, int, const char *); struct window_pane *, struct session *, int, const char *);
void window_copy_copy_selection(struct window_pane *, int); void window_copy_copy_selection(struct window_pane *, int);
void window_copy_append_selection(struct window_pane *, int);
void window_copy_clear_selection(struct window_pane *); void window_copy_clear_selection(struct window_pane *);
void window_copy_copy_line( void window_copy_copy_line(
struct window_pane *, char **, size_t *, u_int, u_int, u_int); struct window_pane *, char **, size_t *, u_int, u_int, u_int);
@ -414,6 +415,13 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
cmd = mode_key_lookup(&data->mdata, key, &arg); cmd = mode_key_lookup(&data->mdata, key, &arg);
switch (cmd) { switch (cmd) {
case MODEKEYCOPY_APPENDSELECTION:
if (sess != NULL) {
window_copy_append_selection(wp, data->numprefix);
window_pane_reset_mode(wp);
return;
}
break;
case MODEKEYCOPY_CANCEL: case MODEKEYCOPY_CANCEL:
window_pane_reset_mode(wp); window_pane_reset_mode(wp);
return; return;
@ -1491,6 +1499,46 @@ window_copy_copy_selection(struct window_pane *wp, int idx)
window_copy_copy_buffer(wp, idx, buf, len); window_copy_copy_buffer(wp, idx, buf, len);
} }
void
window_copy_append_selection(struct window_pane *wp, int idx)
{
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)
return;
if (options_get_number(&global_options, "set-clipboard")) {
screen_write_start(&ctx, wp, NULL);
screen_write_setselection(&ctx, buf, len);
screen_write_stop(&ctx);
}
if (idx == -1)
idx = 0;
if (idx == 0 && paste_get_top(&global_buffers) == NULL) {
limit = options_get_number(&global_options, "buffer-limit");
paste_add(&global_buffers, buf, len, limit);
return;
}
pb = paste_get_index(&global_buffers, idx);
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(&global_buffers, idx, buf, len) != 0)
free(buf);
}
void void
window_copy_copy_line(struct window_pane *wp, window_copy_copy_line(struct window_pane *wp,
char **buf, size_t *off, u_int sy, u_int sx, u_int ex) char **buf, size_t *off, u_int sy, u_int sx, u_int ex)