summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile4
-rw-r--r--Makefile4
-rw-r--r--TODO3
-rw-r--r--cmd-server-info.c8
-rw-r--r--cmd-swap-pane.c282
-rw-r--r--cmd.c3
-rw-r--r--key-bindings.c6
-rw-r--r--tmux.h3
8 files changed, 300 insertions, 13 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 687817f4..d4b213e9 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,4 +1,4 @@
-# $Id: GNUmakefile,v 1.79 2009-04-01 18:21:22 nicm Exp $
+# $Id: GNUmakefile,v 1.80 2009-04-02 23:28:15 nicm Exp $
.PHONY: clean
@@ -37,7 +37,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-resize-pane-up.c cmd-resize-pane-down.c cmd-kill-pane.c \
cmd-up-pane.c cmd-down-pane.c cmd-choose-window.c cmd-choose-session.c \
cmd-suspend-client.c cmd-find-window.c cmd-load-buffer.c \
- cmd-copy-buffer.c cmd-break-pane.c cmd-next-layout.c \
+ cmd-copy-buffer.c cmd-break-pane.c cmd-swap-pane.c cmd-next-layout.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
window-choose.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
diff --git a/Makefile b/Makefile
index 22dcefd2..6b5627db 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.118 2009-04-02 22:12:28 nicm Exp $
+# $Id: Makefile,v 1.119 2009-04-02 23:28:16 nicm Exp $
.SUFFIXES: .c .o .y .h
.PHONY: clean update-index.html upload-index.html
@@ -40,7 +40,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-resize-pane-up.c cmd-resize-pane-down.c cmd-kill-pane.c \
cmd-up-pane.c cmd-down-pane.c cmd-choose-window.c cmd-choose-session.c \
cmd-suspend-client.c cmd-find-window.c cmd-load-buffer.c \
- cmd-copy-buffer.c cmd-break-pane.c cmd-next-layout.c \
+ cmd-copy-buffer.c cmd-break-pane.c cmd-swap-pane.c cmd-next-layout.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
window-choose.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
diff --git a/TODO b/TODO
index e70f25d6..ab660c6e 100644
--- a/TODO
+++ b/TODO
@@ -85,7 +85,7 @@
- test bug sshing from freebsd console
- layout/split stuff:
horiz split command, and similar resizing commands as for vert split
- swap-pane command
+ rotate-window (-pane?) to rotate panes so first becomes last
display the layout in a readable format somewhere
previous-layout command
select-layout command
@@ -97,6 +97,7 @@
speed improvements?
hardcoded 81 for left-vertical is nasty
- document new layout stuff: next-layout
+- document swap-pane
- document repeat behaviour and -r on bind-key
- document status-keys
- document break-pane
diff --git a/cmd-server-info.c b/cmd-server-info.c
index ce680485..4cbd59aa 100644
--- a/cmd-server-info.c
+++ b/cmd-server-info.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-server-info.c,v 1.13 2009-04-01 18:21:28 nicm Exp $ */
+/* $Id: cmd-server-info.c,v 1.14 2009-04-02 23:28:16 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -133,9 +133,9 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
sizeof (**gd->udata);
}
}
- ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu "
- "bytes; UTF-8 %u/%u, %zu bytes", j, wp->tty,
- (u_long) wp->pid, wp->fd, lines,
+ ctx->print(ctx, "%6u: %p %s %lu %d %u/%u, %zu "
+ "bytes; UTF-8 %u/%u, %zu bytes", j, wp,
+ wp->tty, (u_long) wp->pid, wp->fd, lines,
gd->hsize + gd->sy, size, ulines,
gd->hsize + gd->sy, usize);
j++;
diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c
new file mode 100644
index 00000000..c68e0634
--- /dev/null
+++ b/cmd-swap-pane.c
@@ -0,0 +1,282 @@
+/* $Id: cmd-swap-pane.c,v 1.1 2009-04-02 23:28:16 nicm Exp $ */
+
+/*
+ * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+
+#include "tmux.h"
+
+/*
+ * Swap two panes.
+ */
+
+int cmd_swap_pane_parse(struct cmd *, int, char **, char **);
+int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
+void cmd_swap_pane_send(struct cmd *, struct buffer *);
+void cmd_swap_pane_recv(struct cmd *, struct buffer *);
+void cmd_swap_pane_free(struct cmd *);
+void cmd_swap_pane_init(struct cmd *, int);
+size_t cmd_swap_pane_print(struct cmd *, char *, size_t);
+
+struct cmd_swap_pane_data {
+ char *target;
+ int src;
+ int dst;
+ int flag_detached;
+ int flag_next;
+ int flag_previous;
+};
+
+const struct cmd_entry cmd_swap_pane_entry = {
+ "swap-pane", "swapp",
+ "[-dn] [-t target-window] [-p src-index] [-q dst-index]",
+ 0,
+ cmd_swap_pane_init,
+ cmd_swap_pane_parse,
+ cmd_swap_pane_exec,
+ cmd_swap_pane_send,
+ cmd_swap_pane_recv,
+ cmd_swap_pane_free,
+ cmd_swap_pane_print
+};
+
+void
+cmd_swap_pane_init(struct cmd *self, int key)
+{
+ struct cmd_swap_pane_data *data;
+
+ self->data = data = xmalloc(sizeof *data);
+ data->target = NULL;
+ data->src = -1;
+ data->dst = -1;
+ data->flag_detached = 0;
+ data->flag_next = 0;
+ data->flag_previous = 0;
+
+ switch (key) {
+ case '}':
+ data->flag_next = 1;
+ break;
+ case '{':
+ data->flag_previous = 1;
+ break;
+ }
+}
+
+int
+cmd_swap_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
+{
+ struct cmd_swap_pane_data *data;
+ int opt, n;
+ const char *errstr;
+
+ self->entry->init(self, 0);
+ data = self->data;
+
+ while ((opt = getopt(argc, argv, "dt:np:q:r")) != -1) {
+ switch (opt) {
+ case 'd':
+ data->flag_detached = 1;
+ break;
+ case 'n':
+ data->flag_next = 1;
+ data->flag_previous = 0;
+ data->dst = -1;
+ break;
+ case 't':
+ if (data->target == NULL)
+ data->target = xstrdup(optarg);
+ break;
+ case 'p':
+ if (data->src == -1) {
+ n = strtonum(optarg, 0, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ xasprintf(cause, "src %s", errstr);
+ goto error;
+ }
+ data->src = n;
+ }
+ break;
+ case 'q':
+ if (data->dst == -1) {
+ n = strtonum(optarg, 0, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ xasprintf(cause, "dst %s", errstr);
+ goto error;
+ }
+ data->dst = n;
+ }
+ data->flag_next = 0;
+ data->flag_previous = 0;
+ break;
+ case 'r':
+ data->flag_next = 0;
+ data->flag_previous = 1;
+ data->dst = -1;
+ break;
+
+ default:
+ goto usage;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc != 0)
+ goto usage;
+
+ return (0);
+
+usage:
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
+
+error:
+ self->entry->free(self);
+ return (-1);
+}
+
+int
+cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
+{
+ struct cmd_swap_pane_data *data = self->data;
+ struct winlink *wl;
+ struct window *w;
+ struct window_pane *tmp_wp, *src_wp, *dst_wp;
+ u_int xx, yy;
+
+ if (data == NULL)
+ return (0);
+
+ if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ return (-1);
+ w = wl->window;
+
+ if (data->src == -1)
+ src_wp = w->active;
+ else {
+ src_wp = window_pane_at_index(w, data->src);
+ if (src_wp == NULL) {
+ ctx->error(ctx, "no pane: %d", data->src);
+ return (-1);
+ }
+ }
+ if (data->dst == -1)
+ dst_wp = w->active;
+ else {
+ dst_wp = window_pane_at_index(w, data->dst);
+ if (dst_wp == NULL) {
+ ctx->error(ctx, "no pane: %d", data->dst);
+ return (-1);
+ }
+ }
+
+ if (data->dst == -1 && data->flag_next) {
+ if ((dst_wp = TAILQ_NEXT(src_wp, entry)) == NULL)
+ dst_wp = TAILQ_FIRST(&w->panes);
+ }
+ if (data->dst == -1 && data->flag_previous) {
+ if ((dst_wp = TAILQ_PREV(src_wp, window_panes, entry)) == NULL)
+ dst_wp = TAILQ_LAST(&w->panes, window_panes);
+ }
+
+ if (src_wp == dst_wp)
+ return (0);
+
+ tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry);
+ TAILQ_REMOVE(&w->panes, dst_wp, entry);
+ TAILQ_REPLACE(&w->panes, src_wp, dst_wp, entry);
+ if (tmp_wp == src_wp)
+ tmp_wp = dst_wp;
+ if (tmp_wp == NULL)
+ TAILQ_INSERT_HEAD(&w->panes, src_wp, entry);
+ else
+ TAILQ_INSERT_AFTER(&w->panes, tmp_wp, src_wp, entry);
+
+ xx = src_wp->xoff;
+ yy = src_wp->yoff;
+ src_wp->xoff = dst_wp->xoff;
+ src_wp->yoff = dst_wp->yoff;
+ dst_wp->xoff = xx;
+ dst_wp->yoff = yy;
+
+ xx = src_wp->sx;
+ yy = src_wp->sy;
+ window_pane_resize(src_wp, dst_wp->sx, dst_wp->sy);
+ window_pane_resize(dst_wp, xx, yy);
+
+ if (!data->flag_detached) {
+ window_set_active_pane(w, dst_wp);
+ layout_refresh(w, 0);
+ }
+
+ return (0);
+}
+
+void
+cmd_swap_pane_send(struct cmd *self, struct buffer *b)
+{
+ struct cmd_swap_pane_data *data = self->data;
+
+ buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->target);
+}
+
+void
+cmd_swap_pane_recv(struct cmd *self, struct buffer *b)
+{
+ struct cmd_swap_pane_data *data;
+
+ self->data = data = xmalloc(sizeof *data);
+ buffer_read(b, data, sizeof *data);
+ data->target = cmd_recv_string(b);
+}
+
+void
+cmd_swap_pane_free(struct cmd *self)
+{
+ struct cmd_swap_pane_data *data = self->data;
+
+ if (data->target != NULL)
+ xfree(data->target);
+ xfree(data);
+}
+
+size_t
+cmd_swap_pane_print(struct cmd *self, char *buf, size_t len)
+{
+ struct cmd_swap_pane_data *data = self->data;
+ size_t off = 0;
+
+ off += xsnprintf(buf, len, "%s", self->entry->name);
+ if (data == NULL)
+ return (off);
+ if (off < len && (data->flag_next || data->flag_detached)) {
+ off += xsnprintf(buf + off, len - off, " -");
+ if (off < len && data->flag_next)
+ off += xsnprintf(buf + off, len - off, "d");
+ if (off < len && data->flag_detached)
+ off += xsnprintf(buf + off, len - off, "n");
+ }
+ if (off < len && data->target != NULL)
+ off += cmd_prarg(buf + off, len - off, " -t ", data->target);
+ if (off < len && data->src != -1)
+ off += xsnprintf(buf + off, len - off, " -p %d", data->src);
+ if (off < len && data->dst != -1)
+ off += xsnprintf(buf + off, len - off, " -q %d", data->dst);
+ return (off);
+}
diff --git a/cmd.c b/cmd.c
index eade9e1b..07e7665e 100644
--- a/cmd.c
+++ b/cmd.c
@@ -1,4 +1,4 @@
-/* $Id: cmd.c,v 1.87 2009-04-01 18:21:29 nicm Exp $ */
+/* $Id: cmd.c,v 1.88 2009-04-02 23:28:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -86,6 +86,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_split_window_entry,
&cmd_start_server_entry,
&cmd_suspend_client_entry,
+ &cmd_swap_pane_entry,
&cmd_swap_window_entry,
&cmd_switch_client_entry,
&cmd_unbind_key_entry,
diff --git a/key-bindings.c b/key-bindings.c
index 02afc1c6..558a60e4 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -1,4 +1,4 @@
-/* $Id: key-bindings.c,v 1.64 2009-04-01 18:21:30 nicm Exp $ */
+/* $Id: key-bindings.c,v 1.65 2009-04-02 23:28:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -102,6 +102,7 @@ key_bindings_init(void)
{ '?', 0, &cmd_list_keys_entry },
{ '[', 0, &cmd_copy_mode_entry },
{ '\'', 0, &cmd_select_prompt_entry },
+ { '\032', /* C-z */ 0, &cmd_suspend_client_entry },
{ ']', 0, &cmd_paste_buffer_entry },
{ 'c', 0, &cmd_new_window_entry },
{ 'd', 0, &cmd_detach_client_entry },
@@ -115,7 +116,8 @@ key_bindings_init(void)
{ 't', 0, &cmd_clock_mode_entry },
{ 'w', 0, &cmd_choose_window_entry },
{ 'x', 0, &cmd_kill_pane_entry, },
- { '\032', 0, &cmd_suspend_client_entry },
+ { '{', 0, &cmd_swap_pane_entry },
+ { '}', 0, &cmd_swap_pane_entry },
{ META, 0, &cmd_send_prefix_entry },
{ KEYC_PPAGE, 0, &cmd_scroll_mode_entry },
{ KEYC_ADDESC('n'), 0, &cmd_next_window_entry },
diff --git a/tmux.h b/tmux.h
index b6f3d087..70cf2c34 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1,4 +1,4 @@
-/* $Id: tmux.h,v 1.297 2009-04-02 21:08:14 nicm Exp $ */
+/* $Id: tmux.h,v 1.298 2009-04-02 23:28:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -1230,6 +1230,7 @@ extern const struct cmd_entry cmd_source_file_entry;
extern const struct cmd_entry cmd_split_window_entry;
extern const struct cmd_entry cmd_start_server_entry;
extern const struct cmd_entry cmd_suspend_client_entry;
+extern const struct cmd_entry cmd_swap_pane_entry;
extern const struct cmd_entry cmd_swap_window_entry;
extern const struct cmd_entry cmd_switch_client_entry;
extern const struct cmd_entry cmd_unbind_key_entry;