summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/tmux/cmd-bind-key.c32
-rw-r--r--usr.bin/tmux/cmd-list-keys.c9
-rw-r--r--usr.bin/tmux/mode-key.c8
-rw-r--r--usr.bin/tmux/status.c4
-rw-r--r--usr.bin/tmux/tmux.115
-rw-r--r--usr.bin/tmux/tmux.h14
-rw-r--r--usr.bin/tmux/window-choose.c10
-rw-r--r--usr.bin/tmux/window-copy.c76
8 files changed, 126 insertions, 42 deletions
diff --git a/usr.bin/tmux/cmd-bind-key.c b/usr.bin/tmux/cmd-bind-key.c
index 42a45fbf90f..54291a7a9f6 100644
--- a/usr.bin/tmux/cmd-bind-key.c
+++ b/usr.bin/tmux/cmd-bind-key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-bind-key.c,v 1.14 2012/07/11 07:10:15 nicm Exp $ */
+/* $OpenBSD: cmd-bind-key.c,v 1.15 2013/03/22 15:52:40 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -46,7 +46,7 @@ enum cmd_retval
cmd_bind_key_check(struct args *args)
{
if (args_has(args, 't')) {
- if (args->argc != 2)
+ if (args->argc != 2 && args->argc != 3)
return (CMD_RETURN_ERROR);
} else {
if (args->argc < 2)
@@ -93,6 +93,7 @@ cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
const struct mode_key_table *mtab;
struct mode_key_binding *mbind, mtmp;
enum mode_key_cmd cmd;
+ const char *arg;
tablename = args_get(args, 't');
if ((mtab = mode_key_findtable(tablename)) == NULL) {
@@ -106,16 +107,29 @@ cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
return (CMD_RETURN_ERROR);
}
+ if (cmd != MODEKEYCOPY_COPYPIPE) {
+ if (args->argc != 2) {
+ ctx->error(ctx, "no argument allowed");
+ return (CMD_RETURN_ERROR);
+ }
+ arg = NULL;
+ } else {
+ if (args->argc != 3) {
+ ctx->error(ctx, "no argument given");
+ return (CMD_RETURN_ERROR);
+ }
+ arg = args->argv[2];
+ }
+
mtmp.key = key;
mtmp.mode = !!args_has(args, 'c');
- if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
- mbind->cmd = cmd;
- return (CMD_RETURN_NORMAL);
+ if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) == NULL) {
+ mbind = xmalloc(sizeof *mbind);
+ mbind->key = mtmp.key;
+ mbind->mode = mtmp.mode;
+ RB_INSERT(mode_key_tree, mtab->tree, mbind);
}
- mbind = xmalloc(sizeof *mbind);
- mbind->key = mtmp.key;
- mbind->mode = mtmp.mode;
mbind->cmd = cmd;
- RB_INSERT(mode_key_tree, mtab->tree, mbind);
+ mbind->arg = arg != NULL ? xstrdup(arg) : NULL;
return (CMD_RETURN_NORMAL);
}
diff --git a/usr.bin/tmux/cmd-list-keys.c b/usr.bin/tmux/cmd-list-keys.c
index 534ed927504..9a2b27963d9 100644
--- a/usr.bin/tmux/cmd-list-keys.c
+++ b/usr.bin/tmux/cmd-list-keys.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-list-keys.c,v 1.19 2012/10/15 21:53:30 nicm Exp $ */
+/* $OpenBSD: cmd-list-keys.c,v 1.20 2013/03/22 15:52:40 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -138,9 +138,12 @@ cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx)
mode = "c";
cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd);
if (cmdstr != NULL) {
- ctx->print(ctx, "bind-key -%st %s%s %*s %s",
+ ctx->print(ctx, "bind-key -%st %s%s %*s %s%s%s%s",
mode, any_mode && *mode == '\0' ? " " : "",
- mtab->name, (int) width, key, cmdstr);
+ mtab->name, (int) width, key, cmdstr,
+ mbind->arg != NULL ? " \"" : "",
+ mbind->arg != NULL ? mbind->arg : "",
+ mbind->arg != NULL ? "\"": "");
}
}
diff --git a/usr.bin/tmux/mode-key.c b/usr.bin/tmux/mode-key.c
index 012a0c97c02..538562c3bb9 100644
--- a/usr.bin/tmux/mode-key.c
+++ b/usr.bin/tmux/mode-key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mode-key.c,v 1.51 2013/03/21 16:54:37 nicm Exp $ */
+/* $OpenBSD: mode-key.c,v 1.52 2013/03/22 15:52:40 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -99,6 +99,7 @@ const struct mode_key_cmdstr mode_key_cmdstr_copy[] = {
{ MODEKEYCOPY_BOTTOMLINE, "bottom-line" },
{ MODEKEYCOPY_CANCEL, "cancel" },
{ MODEKEYCOPY_CLEARSELECTION, "clear-selection" },
+ { MODEKEYCOPY_COPYPIPE, "copy-pipe" },
{ MODEKEYCOPY_COPYLINE, "copy-line" },
{ MODEKEYCOPY_COPYENDOFLINE, "copy-end-of-line" },
{ MODEKEYCOPY_COPYSELECTION, "copy-selection" },
@@ -513,6 +514,7 @@ mode_key_init_trees(void)
mbind->key = ment->key;
mbind->mode = ment->mode;
mbind->cmd = ment->cmd;
+ mbind->arg = NULL;
RB_INSERT(mode_key_tree, mtab->tree, mbind);
}
}
@@ -526,7 +528,7 @@ mode_key_init(struct mode_key_data *mdata, struct mode_key_tree *mtree)
}
enum mode_key_cmd
-mode_key_lookup(struct mode_key_data *mdata, int key)
+mode_key_lookup(struct mode_key_data *mdata, int key, const char **arg)
{
struct mode_key_binding *mbind, mtmp;
@@ -546,6 +548,8 @@ mode_key_lookup(struct mode_key_data *mdata, int key)
mdata->mode = 1 - mdata->mode;
/* FALLTHROUGH */
default:
+ if (arg != NULL)
+ *arg = mbind->arg;
return (mbind->cmd);
}
}
diff --git a/usr.bin/tmux/status.c b/usr.bin/tmux/status.c
index b245f135047..3c35ff4c54b 100644
--- a/usr.bin/tmux/status.c
+++ b/usr.bin/tmux/status.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: status.c,v 1.100 2013/03/22 10:31:22 nicm Exp $ */
+/* $OpenBSD: status.c,v 1.101 2013/03/22 15:52:40 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -1042,7 +1042,7 @@ status_prompt_key(struct client *c, int key)
size_t size, n, off, idx;
size = strlen(c->prompt_buffer);
- switch (mode_key_lookup(&c->prompt_mdata, key)) {
+ switch (mode_key_lookup(&c->prompt_mdata, key, NULL)) {
case MODEKEYEDIT_CURSORLEFT:
if (c->prompt_index > 0) {
c->prompt_index--;
diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1
index a8d543ec390..551937e589a 100644
--- a/usr.bin/tmux/tmux.1
+++ b/usr.bin/tmux/tmux.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.326 2013/03/22 15:51:54 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.327 2013/03/22 15:52:40 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\"
@@ -850,7 +850,7 @@ The following keys are supported as appropriate for the mode:
.It Li "Start of line" Ta "0" Ta "C-a"
.It Li "Start selection" Ta "Space" Ta "C-Space"
.It Li "Top of history" Ta "g" Ta "M->"
-.It Li "Transpose chars" Ta "" Ta "C-t"
+.It Li "Transpose characters" Ta "" Ta "C-t"
.El
.Pp
The next and previous word keys use space and the
@@ -912,6 +912,17 @@ command and keys modified or removed with
.Ic bind-key
and
.Ic unbind-key .
+One command in accepts an argument,
+.Ic copy-pipe ,
+which copies the selection and pipes it to a command.
+For example the following will bind
+.Ql C-q
+to copy the selection into
+.Pa /tmp
+as well as the paste buffer:
+.Bd -literal -offset indent
+bind-key -temacs-copy C-q copy-pipe "cat >/tmp/out"
+.Ed
.Pp
The paste buffer key pastes the first line from the top paste buffer on the
stack.
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index f016cf1984f..dcbe89175d3 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.388 2013/03/22 15:51:54 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.389 2013/03/22 15:52:41 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -566,6 +566,7 @@ enum mode_key_cmd {
MODEKEYCOPY_BOTTOMLINE,
MODEKEYCOPY_CANCEL,
MODEKEYCOPY_CLEARSELECTION,
+ MODEKEYCOPY_COPYPIPE,
MODEKEYCOPY_COPYLINE,
MODEKEYCOPY_COPYENDOFLINE,
MODEKEYCOPY_COPYSELECTION,
@@ -632,12 +633,13 @@ struct mode_key_data {
/* Binding between a key and a command. */
struct mode_key_binding {
- int key;
+ int key;
- int mode;
- enum mode_key_cmd cmd;
+ int mode;
+ enum mode_key_cmd cmd;
+ const char *arg;
- RB_ENTRY(mode_key_binding) entry;
+ RB_ENTRY(mode_key_binding) entry;
};
RB_HEAD(mode_key_tree, mode_key_binding);
@@ -1548,7 +1550,7 @@ enum mode_key_cmd mode_key_fromstring(const struct mode_key_cmdstr *,
const struct mode_key_table *mode_key_findtable(const char *);
void mode_key_init_trees(void);
void mode_key_init(struct mode_key_data *, struct mode_key_tree *);
-enum mode_key_cmd mode_key_lookup(struct mode_key_data *, int);
+enum mode_key_cmd mode_key_lookup(struct mode_key_data *, int, const char **);
/* notify.c */
void notify_enable(void);
diff --git a/usr.bin/tmux/window-choose.c b/usr.bin/tmux/window-choose.c
index 817ef94cfbf..eef2b5e2009 100644
--- a/usr.bin/tmux/window-choose.c
+++ b/usr.bin/tmux/window-choose.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: window-choose.c,v 1.42 2013/03/22 15:50:42 nicm Exp $ */
+/* $OpenBSD: window-choose.c,v 1.43 2013/03/22 15:52:42 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -492,7 +492,7 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key)
items = ARRAY_LENGTH(&data->list);
if (data->input_type == WINDOW_CHOOSE_GOTO_ITEM) {
- switch (mode_key_lookup(&data->mdata, key)) {
+ switch (mode_key_lookup(&data->mdata, key, NULL)) {
case MODEKEYCHOICE_CANCEL:
data->input_type = WINDOW_CHOOSE_NORMAL;
window_choose_redraw_screen(wp);
@@ -523,7 +523,7 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key)
return;
}
- switch (mode_key_lookup(&data->mdata, key)) {
+ switch (mode_key_lookup(&data->mdata, key, NULL)) {
case MODEKEYCHOICE_CANCEL:
window_choose_fire_callback(wp, NULL);
break;
@@ -777,7 +777,7 @@ window_choose_key_index(struct window_choose_mode_data *data, u_int idx)
int mkey;
for (ptr = keys; *ptr != '\0'; ptr++) {
- mkey = mode_key_lookup(&data->mdata, *ptr);
+ mkey = mode_key_lookup(&data->mdata, *ptr, NULL);
if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER)
continue;
if (idx-- == 0)
@@ -797,7 +797,7 @@ window_choose_index_key(struct window_choose_mode_data *data, int key)
u_int idx = 0;
for (ptr = keys; *ptr != '\0'; ptr++) {
- mkey = mode_key_lookup(&data->mdata, *ptr);
+ mkey = mode_key_lookup(&data->mdata, *ptr, NULL);
if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER)
continue;
if (key == *ptr)
diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c
index 47e13a94211..a14f5698fc2 100644
--- a/usr.bin/tmux/window-copy.c
+++ b/usr.bin/tmux/window-copy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: window-copy.c,v 1.88 2013/03/22 10:31:22 nicm Exp $ */
+/* $OpenBSD: window-copy.c,v 1.89 2013/03/22 15:52:42 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -52,6 +52,9 @@ void window_copy_goto_line(struct window_pane *, const char *);
void window_copy_update_cursor(struct window_pane *, u_int, u_int);
void window_copy_start_selection(struct window_pane *);
int window_copy_update_selection(struct window_pane *);
+void *window_copy_get_selection(struct window_pane *, size_t *);
+void window_copy_copy_buffer(struct window_pane *, int, void *, size_t);
+void window_copy_copy_pipe(struct window_pane *, int, const char *);
void window_copy_copy_selection(struct window_pane *, int);
void window_copy_clear_selection(struct window_pane *);
void window_copy_copy_line(
@@ -364,6 +367,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
u_int n;
int np, keys;
enum mode_key_cmd cmd;
+ const char *arg;
np = data->numprefix;
if (np <= 0)
@@ -405,7 +409,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
return;
}
- cmd = mode_key_lookup(&data->mdata, key);
+ cmd = mode_key_lookup(&data->mdata, key, &arg);
switch (cmd) {
case MODEKEYCOPY_CANCEL:
window_pane_reset_mode(wp);
@@ -533,6 +537,13 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
window_copy_clear_selection(wp);
window_copy_redraw_screen(wp);
break;
+ case MODEKEYCOPY_COPYPIPE:
+ if (sess != NULL) {
+ window_copy_copy_pipe(wp, data->numprefix, arg);
+ window_pane_reset_mode(wp);
+ return;
+ }
+ break;
case MODEKEYCOPY_COPYSELECTION:
if (sess != NULL) {
window_copy_copy_selection(wp, data->numprefix);
@@ -735,7 +746,7 @@ window_copy_key_input(struct window_pane *wp, int key)
size_t inputlen;
int np;
- switch (mode_key_lookup(&data->mdata, key)) {
+ switch (mode_key_lookup(&data->mdata, key, NULL)) {
case MODEKEYEDIT_CANCEL:
data->numprefix = -1;
return (-1);
@@ -1259,19 +1270,19 @@ window_copy_update_selection(struct window_pane *wp)
return (1);
}
-void
-window_copy_copy_selection(struct window_pane *wp, int idx)
+void *
+window_copy_get_selection(struct window_pane *wp, size_t *len)
{
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
char *buf;
size_t off;
- u_int i, xx, yy, sx, sy, ex, ey, limit;
+ u_int i, xx, yy, sx, sy, ex, ey;
u_int firstsx, lastex, restex, restsx;
int keys;
if (!s->sel.flag)
- return;
+ return (NULL);
buf = xmalloc(1);
off = 0;
@@ -1364,19 +1375,58 @@ window_copy_copy_selection(struct window_pane *wp, int idx)
/* Don't bother if no data. */
if (off == 0) {
free(buf);
- return;
+ return (NULL);
}
- off--; /* remove final \n */
+ *len = off - 1; /* remove final \n */
+ return (buf);
+}
+
+void
+window_copy_copy_buffer(struct window_pane *wp, int idx, void *buf, size_t len)
+{
+ u_int limit;
if (options_get_number(&global_options, "set-clipboard"))
- screen_write_setselection(&wp->ictx.ctx, buf, off);
+ screen_write_setselection(&wp->ictx.ctx, buf, len);
- /* Add the buffer to the stack. */
if (idx == -1) {
limit = options_get_number(&global_options, "buffer-limit");
- paste_add(&global_buffers, buf, off, limit);
+ paste_add(&global_buffers, buf, len, limit);
} else
- paste_replace(&global_buffers, idx, buf, off);
+ paste_replace(&global_buffers, idx, buf, len);
+}
+
+void
+window_copy_copy_pipe(struct window_pane *wp, int idx, const char *arg)
+{
+ void* buf;
+ size_t len;
+ FILE* f;
+
+ buf = window_copy_get_selection(wp, &len);
+ if (buf == NULL)
+ return;
+
+ f = popen(arg, "w");
+ if (f != NULL) {
+ fwrite(buf, 1, len, f);
+ pclose(f);
+ }
+
+ window_copy_copy_buffer(wp, idx, buf, len);
+}
+
+void
+window_copy_copy_selection(struct window_pane *wp, int idx)
+{
+ void* buf;
+ size_t len;
+
+ buf = window_copy_get_selection(wp, &len);
+ if (buf == NULL)
+ return;
+
+ window_copy_copy_buffer(wp, idx, buf, len);
}
void