mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-23 16:43:11 +01:00
swap-pane command.
This commit is contained in:
parent
089f090c0a
commit
8216f7b3d9
@ -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 \
|
||||
|
4
Makefile
4
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 \
|
||||
|
3
TODO
3
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
|
||||
|
@ -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++;
|
||||
|
282
cmd-swap-pane.c
Normal file
282
cmd-swap-pane.c
Normal file
@ -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);
|
||||
}
|
3
cmd.c
3
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,
|
||||
|
@ -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 },
|
||||
|
3
tmux.h
3
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;
|
||||
|
Loading…
Reference in New Issue
Block a user