diff options
author | Nicholas Marriott <nicholas.marriott@gmail.com> | 2009-01-11 23:31:46 +0000 |
---|---|---|
committer | Nicholas Marriott <nicholas.marriott@gmail.com> | 2009-01-11 23:31:46 +0000 |
commit | 162bacdcd91caf631db6979a21c27d208a66046b (patch) | |
tree | d678a35fa4c017ec034d6d6b19140f56fd8ca65a | |
parent | d78bc5dfc40fe8d1a3842bd91dcfa5ca4c44ae01 (diff) |
Window splitting. Two vertical panes fixed 50% each. This is a huge diff, still a couple of bugs (notably heap corruption somewhere causing segfault on exit).
-rw-r--r-- | CHANGES | 17 | ||||
-rw-r--r-- | GNUmakefile | 4 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | TODO | 21 | ||||
-rw-r--r-- | cmd-clock-mode.c | 4 | ||||
-rw-r--r-- | cmd-copy-mode.c | 4 | ||||
-rw-r--r-- | cmd-list-windows.c | 43 | ||||
-rw-r--r-- | cmd-paste-buffer.c | 6 | ||||
-rw-r--r-- | cmd-respawn-window.c | 16 | ||||
-rw-r--r-- | cmd-scroll-mode.c | 4 | ||||
-rw-r--r-- | cmd-send-keys.c | 8 | ||||
-rw-r--r-- | cmd-send-prefix.c | 4 | ||||
-rw-r--r-- | cmd-split-window.c | 211 | ||||
-rw-r--r-- | cmd-switch-pane.c | 61 | ||||
-rw-r--r-- | cmd.c | 4 | ||||
-rw-r--r-- | input-keys.c | 34 | ||||
-rw-r--r-- | input.c | 54 | ||||
-rw-r--r-- | key-bindings.c | 12 | ||||
-rw-r--r-- | resize.c | 9 | ||||
-rw-r--r-- | screen-redraw.c | 215 | ||||
-rw-r--r-- | screen-write.c | 181 | ||||
-rw-r--r-- | server-msg.c | 3 | ||||
-rw-r--r-- | server.c | 247 | ||||
-rw-r--r-- | status.c | 158 | ||||
-rw-r--r-- | tmux.h | 151 | ||||
-rw-r--r-- | tty-write.c | 77 | ||||
-rw-r--r-- | tty.c | 299 | ||||
-rw-r--r-- | window-clock.c | 55 | ||||
-rw-r--r-- | window-copy.c | 476 | ||||
-rw-r--r-- | window-more.c | 102 | ||||
-rw-r--r-- | window-scroll.c | 140 | ||||
-rw-r--r-- | window.c | 247 |
32 files changed, 1587 insertions, 1284 deletions
@@ -1,5 +1,20 @@ 11 January 2009 +* Vertical window splitting. Currently can only split a window into two panes. + New split-window command splits (bound to ") and switch-pane command (bound to + o) switches between panes. + + close-pane, swap-pane commands are to follow. Also to come are pane resizing, + >2 panes, the ability to break a pane out to a full window and vice versa and + possibly horizontal splitting. + + Panes are subelements of windows rather than being windows in their own + right. I tried to make them windows (so the splitting was at the session or + client level) but this rapidly became very complex and invasive. So in the + interests of having something working, I just made it so each window can have + two child processes instead of one (and it still took me 12 hours straight + coding). Now the concept is proven and much of the support code is there, + this may change in future if more flexibility is needed. * save-buffer command, from Tiago Cunha. 10 January 2009 @@ -859,7 +874,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.192 2009-01-11 23:14:57 nicm Exp $ +$Id: CHANGES,v 1.193 2009-01-11 23:31:46 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB diff --git a/GNUmakefile b/GNUmakefile index 93c96151..9fe2321d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,4 @@ -# $Id: GNUmakefile,v 1.50 2009-01-11 23:14:57 nicm Exp $ +# $Id: GNUmakefile,v 1.51 2009-01-11 23:31:46 nicm Exp $ .PHONY: clean @@ -33,7 +33,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \ cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \ cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \ - cmd-save-buffer.c \ + cmd-save-buffer.c cmd-switch-pane.c cmd-split-window.c \ window-clock.c window-scroll.c window-more.c window-copy.c \ options.c options-cmd.c paste.c colour.c utf8.c clock.c \ tty.c tty-term.c tty-keys.c tty-write.c @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.87 2009-01-11 23:14:57 nicm Exp $ +# $Id: Makefile,v 1.88 2009-01-11 23:31:46 nicm Exp $ .SUFFIXES: .c .o .y .h .PHONY: clean update-index.html upload-index.html @@ -37,7 +37,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \ cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \ cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \ - cmd-save-buffer.c \ + cmd-save-buffer.c cmd-switch-pane.c cmd-split-window.c \ window-clock.c window-scroll.c window-more.c window-copy.c \ options.c options-cmd.c paste.c colour.c utf8.c clock.c \ tty.c tty-term.c tty-keys.c tty-write.c @@ -13,7 +13,7 @@ - status-fg/status-bg should be able to set attributes: bold, etc - refer to windows by name etc (duplicates? fnmatch?) - commands: - command to run something without a window at all? + command to run something without a window at all - output to window-more command to purge window history extend list-clients to list clients attached to a session (-a for all?) bring back detach-session to detach all clients on a session? @@ -42,7 +42,7 @@ session not being watched? - tidy up window modes - problems with force-width when wrapping line in emacs? -- next prev word etc in command prompt; also ^K; also make is support modes +- next prev word etc in command prompt; also ^K; also make it support modes to support vi. is there something could use for this? editline(3)/readline? - many more info() displays for various things - vi half page scroll @@ -51,8 +51,8 @@ others do not. this might be hard: a flag for each grid line (top bit of size maybe)? a single flag is insufficient as can't then tell when to /stop/ unwrapping -- OPTIONS section in man page with description of new option handling -- update set/setw in man page with -g and -u flags +- document OPTIONS section in man page with description of new option handling +- document update set/setw in man page with -g and -u flags - more # commands in status-left,right eg #H for hostname. others? - input.c is too complicated. simplify? - try change from pass-though model to redraw model (use updated screen @@ -66,7 +66,9 @@ - document clock-mode - document password/locking commands - document lock-after-time +- document panes and window splitting: split-window and switch-pane - a command to display the status line briefly when it is turned off +- neww should support -k - FAQ "Can I have some examples of cool things I can do with tmux?" -- linkw, more?? 17:06 < NicM> tmux new then eg tmux linkw -s0:0 17:06 < simmel> NicM link-window? @@ -87,3 +89,14 @@ 17:09 < NicM> or kills it if it is only linked to one 17:09 < NicM> unlinkw only unlinks it - clone session command +- panes: + swap-panes + close-pane + move-pane (to window) + pane resizing + >2 panes per window +- would be nice if tmux could be the shell +- some sort of extension to command prompt so can do eg + bind m command-prompt 'split "man %%"' + bind r command-prompt 'renamew "%%"' + which then asks for a string, substitutes %% in command and executes it diff --git a/cmd-clock-mode.c b/cmd-clock-mode.c index 0e76135c..9c8e72d0 100644 --- a/cmd-clock-mode.c +++ b/cmd-clock-mode.c @@ -1,4 +1,4 @@ -/* $Id: cmd-clock-mode.c,v 1.1 2009-01-10 19:35:39 nicm Exp $ */ +/* $Id: cmd-clock-mode.c,v 1.2 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> @@ -48,7 +48,7 @@ cmd_clock_mode_exec(struct cmd *self, struct cmd_ctx *ctx) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return; - window_set_mode(wl->window, &window_clock_mode); + window_pane_set_mode(wl->window->active, &window_clock_mode); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index 3ddd4759..f342e3fe 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -1,4 +1,4 @@ -/* $Id: cmd-copy-mode.c,v 1.12 2009-01-10 18:08:55 nicm Exp $ */ +/* $Id: cmd-copy-mode.c,v 1.13 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -48,7 +48,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return; - window_set_mode(wl->window, &window_copy_mode); + window_pane_set_mode(wl->window->active, &window_copy_mode); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); diff --git a/cmd-list-windows.c b/cmd-list-windows.c index efc9d47e..56434f67 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -1,4 +1,4 @@ -/* $Id: cmd-list-windows.c,v 1.25 2008-09-26 06:45:25 nicm Exp $ */ +/* $Id: cmd-list-windows.c,v 1.26 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -48,8 +48,9 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx) struct session *s; struct winlink *wl; struct window *w; + struct window_pane *wp; struct grid_data *gd; - u_int i; + u_int i, j; unsigned long long size; const char *name; @@ -58,23 +59,31 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx) RB_FOREACH(wl, winlinks, &s->windows) { w = wl->window; - gd = w->base.grid; - size = 0; - for (i = 0; i < gd->hsize; i++) - size += gd->size[i] * sizeof **gd->data; - size += gd->hsize * (sizeof *gd->data); - size += gd->hsize * (sizeof *gd->size); - - if (w->fd != -1) - name = ttyname(w->fd); - else - name = ""; ctx->print(ctx, - "%d: %s \"%s\" (%s) [%ux%u] [history %u/%u, %llu bytes]", - wl->idx, w->name, w->base.title, name, - screen_size_x(&w->base), screen_size_y(&w->base), - gd->hsize, gd->hlimit, size); + "%d: %s [%ux%u]", wl->idx, w->name, w->sx, w->sy); + for (i = 0; i < 2; i++) { + wp = w->panes[i]; + if (wp == NULL) + continue; + gd = wp->base.grid; + + size = 0; + for (j = 0; j < gd->hsize; j++) + size += gd->size[j] * sizeof **gd->data; + size += gd->hsize * (sizeof *gd->data); + size += gd->hsize * (sizeof *gd->size); + + if (wp->fd != -1) + name = ttyname(wp->fd); + else + name = ""; + + ctx->print(ctx, " pane %d:" + " %s [%ux%u] [history %u/%u, %llu bytes]", i, name, + screen_size_x(&wp->base), screen_size_y(&wp->base), + gd->hsize, gd->hlimit, size); + } } if (ctx->cmdclient != NULL) diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c index 93ad57b5..5077b392 100644 --- a/cmd-paste-buffer.c +++ b/cmd-paste-buffer.c @@ -1,4 +1,4 @@ -/* $Id: cmd-paste-buffer.c,v 1.13 2009-01-11 00:48:42 nicm Exp $ */ +/* $Id: cmd-paste-buffer.c,v 1.14 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -46,11 +46,13 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct winlink *wl; + struct window *w; struct session *s; struct paste_buffer *pb; if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) return; + w = wl->window; if (data->buffer == -1) pb = paste_get_top(&s->buffers); @@ -60,7 +62,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) } if (pb != NULL) - buffer_write(wl->window->out, pb->data, strlen(pb->data)); + buffer_write(w->active->out, pb->data, strlen(pb->data)); /* Delete the buffer if -d. */ if (data->flags & CMD_DFLAG) { diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c index 20002c3e..4590206c 100644 --- a/cmd-respawn-window.c +++ b/cmd-respawn-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-respawn-window.c,v 1.6 2009-01-10 19:37:35 nicm Exp $ */ +/* $Id: cmd-respawn-window.c,v 1.7 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -46,6 +46,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; struct winlink *wl; + struct window *w; struct session *s; const char *env[] = { NULL /* TMUX= */, "TERM=screen", NULL @@ -55,8 +56,10 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) return; + w = wl->window; - if (wl->window->fd != -1 && !(data->flags & CMD_KFLAG)) { + if ((w->panes[0]->fd != -1 || (w->panes[1] != NULL && + w->panes[1]->fd != -1)) && !(data->flags & CMD_KFLAG)) { ctx->error(ctx, "window still active: %s:%d", s->name, wl->idx); return; } @@ -66,14 +69,17 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx) xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i); env[0] = buf; - if (window_spawn(wl->window, data->arg, wl->window->cwd, env) != 0) { + if (w->panes[1] != NULL) + window_remove_pane(w, 1); + + if (window_pane_spawn(w->panes[0], data->arg, NULL, env) != 0) { ctx->error(ctx, "respawn failed: %s:%d", s->name, wl->idx); return; } - screen_reinit(&wl->window->base); + screen_reinit(&w->panes[0]->base); recalculate_sizes(); - server_redraw_window(wl->window); + server_redraw_window(w); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); diff --git a/cmd-scroll-mode.c b/cmd-scroll-mode.c index b7e3c1aa..f1f448bd 100644 --- a/cmd-scroll-mode.c +++ b/cmd-scroll-mode.c @@ -1,4 +1,4 @@ -/* $Id: cmd-scroll-mode.c,v 1.13 2009-01-10 18:08:55 nicm Exp $ */ +/* $Id: cmd-scroll-mode.c,v 1.14 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -48,7 +48,7 @@ cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return; - window_set_mode(wl->window, &window_scroll_mode); + window_pane_set_mode(wl->window->active, &window_scroll_mode); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); diff --git a/cmd-send-keys.c b/cmd-send-keys.c index ac03a5ec..afded43c 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -1,4 +1,4 @@ -/* $Id: cmd-send-keys.c,v 1.15 2008-12-10 20:25:41 nicm Exp $ */ +/* $Id: cmd-send-keys.c,v 1.16 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -119,8 +119,10 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return; - for (i = 0; i < data->nkeys; i++) - window_key(wl->window, ctx->curclient, data->keys[i]); + for (i = 0; i < data->nkeys; i++) { + window_pane_key( + wl->window->active, ctx->curclient, data->keys[i]); + } if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); diff --git a/cmd-send-prefix.c b/cmd-send-prefix.c index 78cd4afa..2d17bea1 100644 --- a/cmd-send-prefix.c +++ b/cmd-send-prefix.c @@ -1,4 +1,4 @@ -/* $Id: cmd-send-prefix.c,v 1.19 2008-09-26 06:45:25 nicm Exp $ */ +/* $Id: cmd-send-prefix.c,v 1.20 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -51,7 +51,7 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx) return; key = options_get_number(&s->options, "prefix"); - window_key(wl->window, ctx->curclient, key); + window_pane_key(wl->window->active, ctx->curclient, key); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); diff --git a/cmd-split-window.c b/cmd-split-window.c new file mode 100644 index 00000000..5e9c0693 --- /dev/null +++ b/cmd-split-window.c @@ -0,0 +1,211 @@ +/* $Id: cmd-split-window.c,v 1.1 2009-01-11 23:31:46 nicm Exp $ */ + +/* + * Copyright (c) 2009 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 <unistd.h> + +#include "tmux.h" + +/* + * Create a new window. + */ + +int cmd_split_window_parse(struct cmd *, int, char **, char **); +void cmd_split_window_exec(struct cmd *, struct cmd_ctx *); +void cmd_split_window_send(struct cmd *, struct buffer *); +void cmd_split_window_recv(struct cmd *, struct buffer *); +void cmd_split_window_free(struct cmd *); +void cmd_split_window_init(struct cmd *, int); +void cmd_split_window_print(struct cmd *, char *, size_t); + +struct cmd_split_window_data { + char *target; + char *cmd; + int flag_detached; +}; + +const struct cmd_entry cmd_split_window_entry = { + "split-window", "splitw", + "[-d] [-t target-window] [command]", + 0, + cmd_split_window_init, + cmd_split_window_parse, + cmd_split_window_exec, + cmd_split_window_send, + cmd_split_window_recv, + cmd_split_window_free, + cmd_split_window_print +}; + +void +cmd_split_window_init(struct cmd *self, unused int arg) +{ + struct cmd_split_window_data *data; + + self->data = data = xmalloc(sizeof *data); + data->target = NULL; + data->cmd = NULL; + data->flag_detached = 0; +} + +int +cmd_split_window_parse(struct cmd *self, int argc, char **argv, char **cause) +{ + struct cmd_split_window_data *data; + int opt; + + self->entry->init(self, 0); + data = self->data; + + while ((opt = getopt(argc, argv, "dt:")) != -1) { + switch (opt) { + case 'd': + data->flag_detached = 1; + break; + case 't': + if (data->target == NULL) + data->target = xstrdup(optarg); + break; + default: + goto usage; + } + } + argc -= optind; + argv += optind; + if (argc != 0 && argc != 1) + goto usage; + + if (argc == 1) + data->cmd = xstrdup(argv[0]); + + return (0); + +usage: + xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); + + self->entry->free(self); + return (-1); +} + +void +cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx) +{ + struct cmd_split_window_data *data = self->data; + struct session *s; + struct winlink *wl; + const char *env[] = { + NULL /* TMUX= */, "TERM=screen", NULL + }; + char buf[256]; + char *cmd, *cwd; + u_int i, sx, sy, hlimit; + + if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) + return; + + if (wl->window->panes[1] != NULL) { + ctx->error(ctx, "window is already split"); + return; + } + + if (session_index(s, &i) != 0) + fatalx("session not found"); + xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i); + env[0] = buf; + + cmd = data->cmd; + if (cmd == NULL) + cmd = options_get_string(&s->options, "default-command"); + if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL) + cwd = options_get_string(&global_options, "default-path"); + else + cwd = ctx->cmdclient->cwd; + + hlimit = options_get_number(&s->options, "history-limit"); + sx = wl->window->sx; + sy = wl->window->sy - (wl->window->sy / 2); + wl->window->panes[1] = window_pane_create(wl->window, sx, sy, hlimit); + if (window_pane_spawn(wl->window->panes[1], cmd, cwd, env) != 0) { + ctx->error(ctx, "command failed: %s", cmd); + return; + } + window_resize(wl->window, wl->window->sx, wl->window->sy); + server_redraw_window(wl->window); + + if (!data->flag_detached) { + wl->window->active = wl->window->panes[1]; + session_select(s, wl->idx); + server_redraw_session(s); + } else + server_status_window(s); + + if (ctx->cmdclient != NULL) + server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); +} + +void +cmd_split_window_send(struct cmd *self, struct buffer *b) +{ + struct cmd_split_window_data *data = self->data; + + buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->target); + cmd_send_string(b, data->cmd); +} + +void +cmd_split_window_recv(struct cmd *self, struct buffer *b) +{ + struct cmd_split_window_data *data; + + self->data = data = xmalloc(sizeof *data); + buffer_read(b, data, sizeof *data); + data->target = cmd_recv_string(b); + data->cmd = cmd_recv_string(b); +} + +void +cmd_split_window_free(struct cmd *self) +{ + struct cmd_split_window_data *data = self->data; + + if (data->target != NULL) + xfree(data->target); + if (data->cmd != NULL) + xfree(data->cmd); + xfree(data); +} + +void +cmd_split_window_print(struct cmd *self, char *buf, size_t len) +{ + struct cmd_split_window_data *data = self->data; + size_t off = 0; + + off += xsnprintf(buf, len, "%s", self->entry->name); + if (data == NULL) + return; + if (off < len && data->flag_detached) + off += xsnprintf(buf + off, len - off, " -d"); + if (off < len && data->target != NULL) + off += xsnprintf(buf + off, len - off, " -t %s", data->target); + if (off < len && data->cmd != NULL) + off += xsnprintf(buf + off, len - off, " %s", data->cmd); +} diff --git a/cmd-switch-pane.c b/cmd-switch-pane.c new file mode 100644 index 00000000..a84f01fa --- /dev/null +++ b/cmd-switch-pane.c @@ -0,0 +1,61 @@ +/* $Id: cmd-switch-pane.c,v 1.1 2009-01-11 23:31:46 nicm Exp $ */ + +/* + * Copyright (c) 2009 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 "tmux.h" + +/* + * Enter clock mode. + */ + +void cmd_switch_pane_exec(struct cmd *, struct cmd_ctx *); + +const struct cmd_entry cmd_switch_pane_entry = { + "switch-pane", "switchp", + CMD_TARGET_WINDOW_USAGE, + 0, + cmd_target_init, + cmd_target_parse, + cmd_switch_pane_exec, + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print +}; + +void +cmd_switch_pane_exec(struct cmd *self, struct cmd_ctx *ctx) +{ + struct cmd_target_data *data = self->data; + struct winlink *wl; + + if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) + return; + + if (wl->window->panes[1] != NULL) { + if (wl->window->active == wl->window->panes[0]) + wl->window->active = wl->window->panes[1]; + else + wl->window->active = wl->window->panes[0]; + server_redraw_window(wl->window); + } + + if (ctx->cmdclient != NULL) + server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); +} @@ -1,4 +1,4 @@ -/* $Id: cmd.c,v 1.73 2009-01-11 23:14:57 nicm Exp $ */ +/* $Id: cmd.c,v 1.74 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -71,9 +71,11 @@ const struct cmd_entry *cmd_table[] = { &cmd_show_options_entry, &cmd_show_window_options_entry, &cmd_source_file_entry, + &cmd_split_window_entry, &cmd_start_server_entry, &cmd_swap_window_entry, &cmd_switch_client_entry, + &cmd_switch_pane_entry, &cmd_unbind_key_entry, &cmd_unlink_window_entry, NULL diff --git a/input-keys.c b/input-keys.c index 98d0e001..efddf217 100644 --- a/input-keys.c +++ b/input-keys.c @@ -1,4 +1,4 @@ -/* $Id: input-keys.c,v 1.20 2009-01-10 18:28:09 nicm Exp $ */ +/* $Id: input-keys.c,v 1.21 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -104,7 +104,7 @@ struct input_key_ent input_keys[] = { /* Translate a key code from client into an output key sequence. */ void -input_key(struct window *w, int key) +input_key(struct window_pane *wp, int key) { struct input_key_ent *ike; u_int i; @@ -115,8 +115,8 @@ input_key(struct window *w, int key) if (key != KEYC_NONE && KEYC_REMOVEESC(key) < KEYC_OFFSET) { if (KEYC_ISESC(key)) - buffer_write8(w->out, '\033'); - buffer_write8(w->out, (uint8_t) KEYC_REMOVEESC(key)); + buffer_write8(wp->out, '\033'); + buffer_write8(wp->out, (uint8_t) KEYC_REMOVEESC(key)); return; } @@ -124,10 +124,10 @@ input_key(struct window *w, int key) ike = &input_keys[i]; if ((ike->flags & INPUTKEY_KEYPAD) && - !(w->screen->mode & MODE_KKEYPAD)) + !(wp->screen->mode & MODE_KKEYPAD)) continue; if ((ike->flags & INPUTKEY_CURSOR) && - !(w->screen->mode & MODE_KCURSOR)) + !(wp->screen->mode & MODE_KCURSOR)) continue; if (ike->flags & INPUTKEY_MODIFIER) { @@ -150,7 +150,7 @@ input_key(struct window *w, int key) log_debug2("found key 0x%x: \"%s\"", key, ike->data); if (ike->flags & INPUTKEY_XTERM && - options_get_number(&w->options, "xterm-keys")) { + options_get_number(&wp->window->options, "xterm-keys")) { /* In xterm keys mode, append modifier argument. */ ch = '\0'; if (KEYC_ISSFT(key) && KEYC_ISESC(key) && KEYC_ISCTL(key)) @@ -169,12 +169,12 @@ input_key(struct window *w, int key) ch = '2'; if (ch != '\0') { log_debug("output argument is: %c", ch); - buffer_write(w->out, ike->data, dlen - 1); - buffer_write8(w->out, ';'); - buffer_write8(w->out, ch); - buffer_write8(w->out, ike->data[dlen - 1]); + buffer_write(wp->out, ike->data, dlen - 1); + buffer_write8(wp->out, ';'); + buffer_write8(wp->out, ch); + buffer_write8(wp->out, ike->data[dlen - 1]); } else - buffer_write(w->out, ike->data, dlen); + buffer_write(wp->out, ike->data, dlen); return; } if (ike->flags & INPUTKEY_MODIFIER) { @@ -183,15 +183,15 @@ input_key(struct window *w, int key) * control (shift not supported). */ if (KEYC_ISESC(key)) - buffer_write8(w->out, '\033'); + buffer_write8(wp->out, '\033'); if (!KEYC_ISCTL(key)) { - buffer_write(w->out, ike->data, dlen); + buffer_write(wp->out, ike->data, dlen); return; } - buffer_write(w->out, ike->data, dlen - 1); - buffer_write8(w->out, ike->data[dlen - 1] ^ 0x20); + buffer_write(wp->out, ike->data, dlen - 1); + buffer_write8(wp->out, ike->data[dlen - 1] ^ 0x20); return; } - buffer_write(w->out, ike->data, dlen); + buffer_write(wp->out, ike->data, dlen); } @@ -1,4 +1,4 @@ -/* $Id: input.c,v 1.72 2009-01-10 01:51:22 nicm Exp $ */ +/* $Id: input.c,v 1.73 2009-01-11 23:31:46 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -217,9 +217,9 @@ input_state(struct input_ctx *ictx, void *state) } |