diff --git a/CHANGES b/CHANGES index 49947563..4ffc4210 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,26 @@ 05 June 2008 +* Completely reorganise command parsing. Much more common code in cmd-generic.c + and a new way of specifying windows, clients or sessions. Now, most commands + take a -t argument, which specifies a client, a session, or a window target. + Clients and sessions are given alone (sessions are fnmatch(3)d and + clients currently not), windows are give by (client|session):index. For + example, if a user is in session "1" window 0 on /dev/ttypi, these should all + be equivalent: + + tmux renamew newname (current session and window) + tmux renamew -t: newname (current session and window) + tmux renamew -t:0 newname (current session, window 0) + tmux renamew -t0 newname (current session, window 0) + tmux renamew -t1:0 newname (session 1, window 0) + tmux renamew -t1: newname (session 1, current window) + tmux renamew -t/dev/ttypi newname (client /dev/ttypi's current + session and window) + tmux renamew -t/dev/ttypi: newname (client /dev/ttypi's current + session and window) + tmux renamew -t/dev/ttypi:0 newname (client /dev/ttypi's current + session, window 0) + * Infrastructure for printing arguments in list-keys output. Easy ones only for now. @@ -408,4 +429,4 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.110 2008-06-05 16:35:31 nicm Exp $ +$Id: CHANGES,v 1.111 2008-06-05 21:24:59 nicm Exp $ diff --git a/GNUmakefile b/GNUmakefile index 6740ecd0..533350b4 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,4 @@ -# $Id: GNUmakefile,v 1.15 2008-06-05 05:04:47 nicm Exp $ +# $Id: GNUmakefile,v 1.16 2008-06-05 21:25:00 nicm Exp $ .PHONY: clean @@ -14,7 +14,7 @@ META?= \002 SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c screen-display.c \ window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \ - key-string.c key-bindings.c resize.c cmd.c cmd-generic.c \ + key-string.c key-bindings.c resize.c arg.c cmd.c cmd-generic.c \ cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \ cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \ cmd-set-option.c cmd-rename-window.c cmd-select-window.c \ diff --git a/Makefile b/Makefile index f926a3e7..24cd3e7b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.58 2008-06-04 17:54:26 nicm Exp $ +# $Id: Makefile,v 1.59 2008-06-05 21:25:00 nicm Exp $ .SUFFIXES: .c .o .y .h .PHONY: clean update-index.html upload-index.html @@ -18,7 +18,7 @@ META?= \002 # C-b SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c screen-display.c \ window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \ - key-string.c key-bindings.c resize.c cmd.c cmd-generic.c \ + key-string.c key-bindings.c resize.c arg.c cmd.c cmd-generic.c \ cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \ cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \ cmd-set-option.c cmd-rename-window.c cmd-select-window.c \ diff --git a/TODO b/TODO index c5effd8c..d3122dfa 100644 --- a/TODO +++ b/TODO @@ -83,11 +83,3 @@ - each command should have a print op as well for list keys - fix occasion start server problems - test and fix wsvt25 -- look again at stuff that doesn't use flags - swap-window - switch-client -audit for lookup window - link-window - look for dstidx - also lookup dstsess with find_session ---- diff --git a/arg.c b/arg.c new file mode 100644 index 00000000..9ff276fa --- /dev/null +++ b/arg.c @@ -0,0 +1,192 @@ +/* $Id: arg.c,v 1.1 2008-06-05 21:25:00 nicm Exp $ */ + +/* + * Copyright (c) 2008 Nicholas Marriott + * + * 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 + +#include +#include +#include + +#include "tmux.h" + +struct client *arg_lookup_client(const char *); +struct session *arg_lookup_session(const char *); + +struct client * +arg_lookup_client(const char *name) +{ + struct client *c; + u_int i; + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (c != NULL && strcmp(name, c->tty.path) == 0) + return (c); + } + + return (NULL); +} + +struct session * +arg_lookup_session(const char *name) +{ + struct session *s, *newest = NULL; + struct timespec *ts; + u_int i; + + ts = NULL; + for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { + s = ARRAY_ITEM(&sessions, i); + if (s == NULL || fnmatch(name, s->name, 0) != 0) + continue; + + if (ts == NULL || timespeccmp(&s->ts, ts, >)) { + newest = s; + ts = &s->ts; + } + } + + return (newest); +} + +struct client * +arg_parse_client(const char *arg) +{ + struct client *c; + char *arg2; + size_t n; + + if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) { + arg2 = xstrdup(arg); + + /* Trim a trailing : if any from the argument. */ + n = strlen(arg2); + if (arg2[n - 1] == ':') + arg2[n - 1] = '\0'; + + /* Try and lookup the client name. */ + c = arg_lookup_client(arg2); + xfree(arg2); + return (c); + } + + return (NULL); +} + +struct session * +arg_parse_session(const char *arg) +{ + struct session *s; + struct client *c; + char *arg2; + size_t n; + + if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) { + arg2 = xstrdup(arg); + + /* Trim a trailing : if any from the argument. */ + n = strlen(arg2); + if (arg2[n - 1] == ':') + arg2[n - 1] = '\0'; + + /* See if the argument matches a session. */ + if ((s = arg_lookup_session(arg2)) != NULL) { + xfree(arg2); + return (s); + } + + /* If not try a client. */ + if ((c = arg_lookup_client(arg2)) != NULL) { + xfree(arg2); + return (c->session); + } + } + + return (NULL); +} + +int +arg_parse_window(const char *arg, struct session **s, int *idx) +{ + char *arg2, *ptr; + const char *errstr; + + *idx = -1; + + /* Handle no argument or a single :. */ + if (arg == NULL || (arg[0] == ':' && arg[1] == '\0')) { + *s = arg_parse_session(NULL); + return (0); + } + + /* Find the separator if any. */ + arg2 = xstrdup(arg); + ptr = strrchr(arg2, ':'); + + /* + * If it is first, this means no session name, so use current session + * and try to convert the rest as index. + */ + if (ptr == arg2) { + *idx = strtonum(ptr + 1, 0, INT_MAX, &errstr); + if (errstr != NULL) { + xfree(arg2); + return (1); + } + + xfree(arg2); + *s = arg_parse_session(NULL); + return (0); + } + + /* If missing, try as an index, else lookup immediately. */ + if (ptr == NULL) { + *idx = strtonum(arg2, 0, INT_MAX, &errstr); + if (errstr == NULL) { + /* This is good as an index; use current session. */ + xfree(arg2); + *s = arg_parse_session(NULL); + return (0); + } + + *idx = -1; + goto lookup; + } + + /* If last, strip it and look up as a session. */ + if (ptr[1] == '\0') { + *ptr = '\0'; + goto lookup; + } + + /* Present but not first and not last. Break and convert both. */ + *ptr = '\0'; + *idx = strtonum(ptr + 1, 0, INT_MAX, &errstr); + if (errstr != NULL) { + xfree(arg2); + return (1); + } + +lookup: + /* Look up as session. */ + *s = arg_parse_session(arg2); + xfree(arg2); + if (*s == NULL) + return (1); + return (0); +} diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 820584b7..27e965bb 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-attach-session.c,v 1.17 2008-06-05 17:12:10 nicm Exp $ */ +/* $Id: cmd-attach-session.c,v 1.18 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -26,89 +26,32 @@ * Attach existing session to the current terminal. */ -int cmd_attach_session_parse(struct cmd *, int, char **, char **); void cmd_attach_session_exec(struct cmd *, struct cmd_ctx *); -void cmd_attach_session_send(struct cmd *, struct buffer *); -void cmd_attach_session_recv(struct cmd *, struct buffer *); -void cmd_attach_session_free(struct cmd *); -void cmd_attach_session_print(struct cmd *, char *, size_t); - -struct cmd_attach_session_data { - char *cname; - char *sname; - int flag_detach; -}; const struct cmd_entry cmd_attach_session_entry = { "attach-session", "attach", - "[-d] [-c client-tty|-s session-name]", - CMD_CANTNEST, - cmd_attach_session_parse, + "[-d] " CMD_TARGET_SESSION_USAGE, + CMD_DFLAG|CMD_CANTNEST, + cmd_target_init, + cmd_target_parse, cmd_attach_session_exec, - cmd_attach_session_send, - cmd_attach_session_recv, - cmd_attach_session_free, - NULL, - cmd_attach_session_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; -int -cmd_attach_session_parse(struct cmd *self, int argc, char **argv, char **cause) -{ - struct cmd_attach_session_data *data; - int opt; - - self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; - data->flag_detach = 0; - - while ((opt = getopt(argc, argv, "c:ds:")) != EOF) { - switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - break; - case 'd': - data->flag_detach = 1; - break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); - 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); - - self->entry->free(self); - return (-1); -} - void cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct cmd_attach_session_data *data = self->data; - struct session *s; - char *cause; + struct cmd_target_data *data = self->data; + struct session *s; + char *cause; if (ctx->flags & CMD_KEY) return; - - if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) + + if ((s = cmd_find_session(ctx, data->target)) == NULL) return; if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) { @@ -122,7 +65,7 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx) return; } - if (data->flag_detach) + if (data->flags & CMD_DFLAG) server_write_session(s, MSG_DETACH, NULL, 0); ctx->cmdclient->session = s; @@ -131,52 +74,3 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx) server_redraw_client(ctx->cmdclient); } -void -cmd_attach_session_send(struct cmd *self, struct buffer *b) -{ - struct cmd_attach_session_data *data = self->data; - - buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); -} - -void -cmd_attach_session_recv(struct cmd *self, struct buffer *b) -{ - struct cmd_attach_session_data *data; - - self->data = data = xmalloc(sizeof *data); - buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); -} - -void -cmd_attach_session_free(struct cmd *self) -{ - struct cmd_attach_session_data *data = self->data; - - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); - xfree(data); -} - -void -cmd_attach_session_print(struct cmd *self, char *buf, size_t len) -{ - struct cmd_attach_session_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_detach) - off += xsnprintf(buf + off, len - off, " -d"); - if (off < len && data->cname != NULL) - off += xsnprintf(buf + off, len - off, " -c %s", data->cname); - if (off < len && data->sname != NULL) - off += xsnprintf(buf + off, len - off, " -s %s", data->sname); -} diff --git a/cmd-bind-key.c b/cmd-bind-key.c index 03d38744..d8dcf310 100644 --- a/cmd-bind-key.c +++ b/cmd-bind-key.c @@ -1,4 +1,4 @@ -/* $Id: cmd-bind-key.c,v 1.13 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-bind-key.c,v 1.14 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -41,13 +41,13 @@ const struct cmd_entry cmd_bind_key_entry = { "bind-key", "bind", "key command [arguments]", 0, + NULL, cmd_bind_key_parse, cmd_bind_key_exec, cmd_bind_key_send, cmd_bind_key_recv, cmd_bind_key_free, - NULL, - NULL + NULL /* XXX */ }; int diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index 37bb4a2f..530ee947 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -1,4 +1,4 @@ -/* $Id: cmd-copy-mode.c,v 1.9 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-copy-mode.c,v 1.10 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,23 +28,24 @@ void cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_copy_mode_entry = { "copy-mode", NULL, - CMD_WINDOWONLY_USAGE, + CMD_TARGET_WINDOW_USAGE, 0, - cmd_windowonly_parse, + cmd_target_init, + cmd_target_parse, cmd_copy_mode_exec, - cmd_windowonly_send, - cmd_windowonly_recv, - cmd_windowonly_free, - NULL, + cmd_target_send, + cmd_target_recv, + cmd_target_free, NULL }; void cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct winlink *wl; + struct cmd_target_data *data = self->data; + struct winlink *wl; - if ((wl = cmd_windowonly_get(self, ctx, NULL)) == NULL) + if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return; window_set_mode(wl->window, &window_copy_mode); diff --git a/cmd-detach-client.c b/cmd-detach-client.c index 04ee1831..1697adcd 100644 --- a/cmd-detach-client.c +++ b/cmd-detach-client.c @@ -1,4 +1,4 @@ -/* $Id: cmd-detach-client.c,v 1.5 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-detach-client.c,v 1.6 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,23 +28,24 @@ void cmd_detach_client_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_detach_client_entry = { "detach-client", "detach", - CMD_CLIENTONLY_USAGE, + CMD_TARGET_CLIENT_USAGE, 0, - cmd_clientonly_parse, + cmd_target_init, + cmd_target_parse, cmd_detach_client_exec, - cmd_clientonly_send, - cmd_clientonly_recv, - cmd_clientonly_free, - NULL, - cmd_clientonly_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_detach_client_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct client *c; + struct cmd_target_data *data = self->data; + struct client *c; - if ((c = cmd_clientonly_get(self, ctx)) == NULL) + if ((c = cmd_find_client(ctx, data->target)) == NULL) return; server_write_client(c, MSG_DETACH, NULL, 0); diff --git a/cmd-generic.c b/cmd-generic.c index 8eece27b..debc051a 100644 --- a/cmd-generic.c +++ b/cmd-generic.c @@ -1,4 +1,4 @@ -/* $Id: cmd-generic.c,v 1.7 2008-06-05 17:12:10 nicm Exp $ */ +/* $Id: cmd-generic.c,v 1.8 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -23,223 +23,43 @@ #include "tmux.h" -int -cmd_clientonly_parse(struct cmd *self, int argc, char **argv, char **cause) +void +cmd_target_init(struct cmd *self, unused int key) { - struct cmd_clientonly_data *data; - int opt; + struct cmd_target_data *data; self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - - while ((opt = getopt(argc, argv, "c:")) != EOF) { - switch (opt) { - case 'c': - if (data->cname == NULL) - data->cname = xstrdup(optarg); - 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); - - self->entry->free(self); - return (-1); -} - -void -cmd_clientonly_send(struct cmd *self, struct buffer *b) -{ - struct cmd_clientonly_data *data = self->data; - - buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); -} - -void -cmd_clientonly_recv(struct cmd *self, struct buffer *b) -{ - struct cmd_clientonly_data *data; - - self->data = data = xmalloc(sizeof *data); - buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); -} - -void -cmd_clientonly_free(struct cmd *self) -{ - struct cmd_clientonly_data *data = self->data; - - if (data->cname != NULL) - xfree(data->cname); - xfree(data); -} - -struct client * -cmd_clientonly_get(struct cmd *self, struct cmd_ctx *ctx) -{ - struct cmd_clientonly_data *data = self->data; - - if (data != NULL) - return (cmd_find_client(ctx, data->cname)); - return (cmd_find_client(ctx, NULL)); -} - -void -cmd_clientonly_print(struct cmd *self, char *buf, size_t len) -{ - struct cmd_clientonly_data *data = self->data; - size_t off = 0; - - off += xsnprintf(buf, len, "%s", self->entry->name); - if (data == NULL) - return; - if (off < len && data->cname != NULL) - off += xsnprintf(buf + off, len - off, " -c %s", data->cname); + data->flags = 0; + data->target = NULL; + data->arg = NULL; } int -cmd_sessiononly_parse(struct cmd *self, int argc, char **argv, char **cause) +cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause) { - struct cmd_sessiononly_data *data; - int opt; + struct cmd_target_data *data; + int opt; + + self->entry->init(self, 0); + data = self->data; - self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; - - while ((opt = getopt(argc, argv, "c:s:")) != EOF) { + while ((opt = getopt(argc, argv, "dkt:")) != EOF) { switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); - 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); - - self->entry->free(self); - return (-1); -} - -void -cmd_sessiononly_send(struct cmd *self, struct buffer *b) -{ - struct cmd_sessiononly_data *data = self->data; - - buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); -} - -void -cmd_sessiononly_recv(struct cmd *self, struct buffer *b) -{ - struct cmd_sessiononly_data *data; - - self->data = data = xmalloc(sizeof *data); - buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); -} - -void -cmd_sessiononly_free(struct cmd *self) -{ - struct cmd_sessiononly_data *data = self->data; - - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); - xfree(data); -} - -struct session * -cmd_sessiononly_get(struct cmd *self, struct cmd_ctx *ctx) -{ - struct cmd_sessiononly_data *data = self->data; - - if (data != NULL) - return (cmd_find_session(ctx, data->cname, data->sname)); - return (cmd_find_session(ctx, NULL, NULL)); -} - -void -cmd_sessiononly_print(struct cmd *self, char *buf, size_t len) -{ - struct cmd_sessiononly_data *data = self->data; - size_t off = 0; - - off += xsnprintf(buf, len, "%s", self->entry->name); - if (data == NULL) - return; - if (off < len && data->cname != NULL) - off += xsnprintf(buf + off, len - off, " -c %s", data->cname); - if (off < len && data->sname != NULL) - off += xsnprintf(buf + off, len - off, " -s %s", data->sname); -} - -int -cmd_windowonly_parse(struct cmd *self, int argc, char **argv, char **cause) -{ - struct cmd_windowonly_data *data; - int opt; - const char *errstr; - - self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; - data->idx = -1; - - while ((opt = getopt(argc, argv, "c:i:s:")) != EOF) { - switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - break; - case 'i': - data->idx = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr != NULL) { - xasprintf(cause, "index %s", errstr); - goto error; + case 'd': + if (self->entry->flags & CMD_DFLAG) { + data->flags |= CMD_DFLAG; + break; } - break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); + goto usage; + case 'k': + if (self->entry->flags & CMD_KFLAG) { + data->flags |= CMD_KFLAG; + break; + } + goto usage; + case 't': + if (data->target == NULL) + data->target = xstrdup(optarg); break; default: goto usage; @@ -247,79 +67,197 @@ cmd_windowonly_parse(struct cmd *self, int argc, char **argv, char **cause) } argc -= optind; argv += optind; - if (argc != 0) - goto usage; + if (self->entry->flags & CMD_ONEARG) { + if (argc != 1) + goto usage; + data->arg = xstrdup(argv[0]); + } else { + 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); } void -cmd_windowonly_send(struct cmd *self, struct buffer *b) +cmd_target_send(struct cmd *self, struct buffer *b) { - struct cmd_windowonly_data *data = self->data; + struct cmd_target_data *data = self->data; buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); + cmd_send_string(b, data->target); + cmd_send_string(b, data->arg); } void -cmd_windowonly_recv(struct cmd *self, struct buffer *b) +cmd_target_recv(struct cmd *self, struct buffer *b) { - struct cmd_windowonly_data *data; + struct cmd_target_data *data; self->data = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); + data->target = cmd_recv_string(b); + data->arg = cmd_recv_string(b); } void -cmd_windowonly_free(struct cmd *self) +cmd_target_free(struct cmd *self) { - struct cmd_windowonly_data *data = self->data; + struct cmd_target_data *data = self->data; - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); + if (data->target != NULL) + xfree(data->target); + if (data->arg != NULL) + xfree(data->arg); xfree(data); } -struct winlink * -cmd_windowonly_get(struct cmd *self, struct cmd_ctx *ctx, struct session **sp) -{ - struct cmd_windowonly_data *data = self->data; - struct winlink *wl; - - if (data == NULL) { - wl = cmd_find_window(ctx, NULL, NULL, -1, sp); - return (wl); - } - - return (cmd_find_window(ctx, data->cname, data->sname, data->idx, sp)); -} - void -cmd_windowonly_print(struct cmd *self, char *buf, size_t len) +cmd_target_print(struct cmd *self, char *buf, size_t len) { - struct cmd_windowonly_data *data = self->data; - size_t off = 0; + struct cmd_target_data *data = self->data; + size_t off = 0; off += xsnprintf(buf, len, "%s", self->entry->name); if (data == NULL) return; - if (off < len && data->cname != NULL) - off += xsnprintf(buf + off, len - off, " -c %s", data->cname); - if (off < len && data->sname != NULL) - off += xsnprintf(buf + off, len - off, " -s %s", data->sname); - if (off < len && data->idx != -1) - off += xsnprintf(buf + off, len - off, " -i %d", data->idx); + if (off < len && data->flags & CMD_DFLAG) + off += xsnprintf(buf + off, len - off, " -d"); + if (off < len && data->flags & CMD_KFLAG) + off += xsnprintf(buf + off, len - off, " -k"); + if (off < len && data->target != NULL) + off += xsnprintf(buf + off, len - off, " -t %s", data->target); + if (off < len && data->arg != NULL) + off += xsnprintf(buf + off, len - off, " %s", data->arg); +} + +void +cmd_srcdst_init(struct cmd *self, unused int key) +{ + struct cmd_srcdst_data *data; + + self->data = data = xmalloc(sizeof *data); + data->flags = 0; + data->src = NULL; + data->dst = NULL; + data->arg = NULL; +} + +int +cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause) +{ + struct cmd_srcdst_data *data; + int opt; + + self->entry->init(self, 0); + data = self->data; + + while ((opt = getopt(argc, argv, "dks:t:")) != EOF) { + switch (opt) { + case 'd': + if (self->entry->flags & CMD_DFLAG) { + data->flags |= CMD_DFLAG; + break; + } + goto usage; + case 'k': + if (self->entry->flags & CMD_KFLAG) { + data->flags |= CMD_KFLAG; + break; + } + goto usage; + case 's': + if (data->src == NULL) + data->src = xstrdup(optarg); + break; + case 't': + if (data->dst == NULL) + data->dst = xstrdup(optarg); + break; + default: + goto usage; + } + } + argc -= optind; + argv += optind; + + if (self->entry->flags & CMD_ONEARG) { + if (argc != 1) + goto usage; + data->arg = xstrdup(argv[0]); + } else { + if (argc != 0) + goto usage; + } + return (0); + +usage: + xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); + + self->entry->free(self); + return (-1); +} + +void +cmd_srcdst_send(struct cmd *self, struct buffer *b) +{ + struct cmd_srcdst_data *data = self->data; + + buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->src); + cmd_send_string(b, data->dst); + cmd_send_string(b, data->arg); +} + +void +cmd_srcdst_recv(struct cmd *self, struct buffer *b) +{ + struct cmd_srcdst_data *data; + + self->data = data = xmalloc(sizeof *data); + buffer_read(b, data, sizeof *data); + data->src = cmd_recv_string(b); + data->dst = cmd_recv_string(b); + data->arg = cmd_recv_string(b); +} + +void +cmd_srcdst_free(struct cmd *self) +{ + struct cmd_srcdst_data *data = self->data; + + if (data->src != NULL) + xfree(data->src); + if (data->dst != NULL) + xfree(data->dst); + if (data->arg != NULL) + xfree(data->arg); + xfree(data); +} + +void +cmd_srcdst_print(struct cmd *self, char *buf, size_t len) +{ + struct cmd_srcdst_data *data = self->data; + size_t off = 0; + + off += xsnprintf(buf, len, "%s", self->entry->name); + if (data == NULL) + return; + if (off < len && data->flags & CMD_DFLAG) + off += xsnprintf(buf + off, len - off, " -d"); + if (off < len && data->flags & CMD_KFLAG) + off += xsnprintf(buf + off, len - off, " -k"); + if (off < len && data->src != NULL) + off += xsnprintf(buf + off, len - off, " -s %s", data->src); + if (off < len && data->dst != NULL) + off += xsnprintf(buf + off, len - off, " -t %s", data->dst); + if (off < len && data->arg != NULL) + off += xsnprintf(buf + off, len - off, " %s", data->arg); } diff --git a/cmd-has-session.c b/cmd-has-session.c index df4951b4..53e1c4d4 100644 --- a/cmd-has-session.c +++ b/cmd-has-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-has-session.c,v 1.8 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-has-session.c,v 1.9 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,23 +28,24 @@ void cmd_has_session_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_has_session_entry = { "has-session", "has", - CMD_SESSIONONLY_USAGE, + CMD_TARGET_SESSION_USAGE, 0, - cmd_sessiononly_parse, + cmd_target_init, + cmd_target_parse, cmd_has_session_exec, - cmd_sessiononly_send, - cmd_sessiononly_recv, - cmd_sessiononly_free, - NULL, - cmd_sessiononly_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_has_session_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct session *s; + struct cmd_target_data *data = self->data; + struct session *s; - if ((s = cmd_sessiononly_get(self, ctx)) == NULL) + if ((s = cmd_find_session(ctx, data->target)) == NULL) return; if (ctx->cmdclient != NULL) diff --git a/cmd-kill-server.c b/cmd-kill-server.c index a4d7c27c..0e80b94a 100644 --- a/cmd-kill-server.c +++ b/cmd-kill-server.c @@ -1,4 +1,4 @@ -/* $Id: cmd-kill-server.c,v 1.4 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-kill-server.c,v 1.5 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -34,8 +34,8 @@ const struct cmd_entry cmd_kill_server_entry = { "", 0, NULL, - cmd_kill_server_exec, NULL, + cmd_kill_server_exec, NULL, NULL, NULL, diff --git a/cmd-kill-session.c b/cmd-kill-session.c index 1a4fbaa0..e8e4754d 100644 --- a/cmd-kill-session.c +++ b/cmd-kill-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-kill-session.c,v 1.9 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-kill-session.c,v 1.10 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -31,25 +31,26 @@ void cmd_kill_session_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_kill_session_entry = { "kill-session", NULL, - CMD_SESSIONONLY_USAGE, + CMD_TARGET_SESSION_USAGE, 0, - cmd_sessiononly_parse, + cmd_target_init, + cmd_target_parse, cmd_kill_session_exec, - cmd_sessiononly_send, - cmd_sessiononly_recv, - cmd_sessiononly_free, - NULL, - cmd_sessiononly_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct session *s; - struct client *c; - u_int i; + struct cmd_target_data *data = self->data; + struct session *s; + struct client *c; + u_int i; - if ((s = cmd_sessiononly_get(self, ctx)) == NULL) + if ((s = cmd_find_session(ctx, data->target)) == NULL) return; for (i = 0; i < ARRAY_LENGTH(&clients); i++) { diff --git a/cmd-kill-window.c b/cmd-kill-window.c index 2d34217d..f0b4a92a 100644 --- a/cmd-kill-window.c +++ b/cmd-kill-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-kill-window.c,v 1.12 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-kill-window.c,v 1.13 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,27 +28,28 @@ void cmd_kill_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_kill_window_entry = { "kill-window", "killw", - CMD_WINDOWONLY_USAGE, + CMD_TARGET_WINDOW_USAGE, 0, - cmd_windowonly_parse, + cmd_target_init, + cmd_target_parse, cmd_kill_window_exec, - cmd_windowonly_send, - cmd_windowonly_recv, - cmd_windowonly_free, - NULL, - NULL + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_kill_window_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct winlink *wl; - struct session *s; - struct client *c; - u_int i; - int destroyed; + struct cmd_target_data *data = self->data; + struct winlink *wl; + struct session *s; + struct client *c; + u_int i; + int destroyed; - if ((wl = cmd_windowonly_get(self, ctx, &s)) == NULL) + if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) return; destroyed = session_detach(s, wl); diff --git a/cmd-last-window.c b/cmd-last-window.c index a9deef03..18bbf678 100644 --- a/cmd-last-window.c +++ b/cmd-last-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-last-window.c,v 1.10 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-last-window.c,v 1.11 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,23 +28,24 @@ void cmd_last_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_last_window_entry = { "last-window", "last", - CMD_SESSIONONLY_USAGE, + CMD_TARGET_SESSION_USAGE, 0, - cmd_sessiononly_parse, + cmd_target_init, + cmd_target_parse, cmd_last_window_exec, - cmd_sessiononly_send, - cmd_sessiononly_recv, - cmd_sessiononly_free, - NULL, - cmd_sessiononly_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_last_window_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct session *s; - - if ((s = cmd_sessiononly_get(self, ctx)) == NULL) + struct cmd_target_data *data = self->data; + struct session *s; + + if ((s = cmd_find_session(ctx, data->target)) == NULL) return; if (session_last(s) == 0) diff --git a/cmd-link-window.c b/cmd-link-window.c index 7bdd84c1..a1c298f4 100644 --- a/cmd-link-window.c +++ b/cmd-link-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-link-window.c,v 1.18 2008-06-05 17:12:10 nicm Exp $ */ +/* $Id: cmd-link-window.c,v 1.19 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -27,239 +27,83 @@ * Link a window into another session. */ -int cmd_link_window_parse(struct cmd *, int, char **, char **); void cmd_link_window_exec(struct cmd *, struct cmd_ctx *); -void cmd_link_window_send(struct cmd *, struct buffer *); -void cmd_link_window_recv(struct cmd *, struct buffer *); -void cmd_link_window_free(struct cmd *); -void cmd_link_window_print(struct cmd *, char *, size_t); - -struct cmd_link_window_data { - char *cname; - char *sname; - int idx; - int flag_detached; - int flag_kill; - int srcidx; - char *srcname; -}; const struct cmd_entry cmd_link_window_entry = { "link-window", "linkw", - "[-dk] [-c client-tty|-s session-name] [-i index] session-name index", - 0, - cmd_link_window_parse, + "[-dk] " CMD_SRCDST_WINDOW_USAGE, + CMD_DFLAG|CMD_KFLAG, + cmd_srcdst_init, + cmd_srcdst_parse, cmd_link_window_exec, - cmd_link_window_send, - cmd_link_window_recv, - cmd_link_window_free, - NULL, - cmd_link_window_print + cmd_srcdst_send, + cmd_srcdst_recv, + cmd_srcdst_free, + cmd_srcdst_print }; -int -cmd_link_window_parse(struct cmd *self, int argc, char **argv, char **cause) -{ - struct cmd_link_window_data *data; - const char *errstr; - int opt; - - self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; - data->flag_detached = 0; - data->flag_kill = 0; - data->idx = -1; - data->srcidx = -1; - data->srcname = NULL; - - while ((opt = getopt(argc, argv, "c:di:ks:")) != EOF) { - switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - break; - case 'd': - data->flag_detached = 1; - break; - case 'i': - data->idx = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr != NULL) { - xasprintf(cause, "index %s", errstr); - goto error; - } - break; - case 'k': - data->flag_kill = 1; - break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); - break; - default: - goto usage; - } - } - argc -= optind; - argv += optind; - if (argc != 2) - goto usage; - - data->srcname = xstrdup(argv[0]); - data->srcidx = strtonum(argv[1], 0, INT_MAX, &errstr); - if (errstr != NULL) { - xasprintf(cause, "index %s", errstr); - goto error; - } - - return (0); - -usage: - xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); - -error: - self->entry->free(self); - return (-1); -} - void cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct cmd_link_window_data *data = self->data; - struct session *s, *src; - struct winlink *wl, *wl2; + struct cmd_srcdst_data *data = self->data; + struct session *s; + struct winlink *wl_src, *wl_dst; + int idx; - if (data == NULL) + if ((wl_src = cmd_find_window(ctx, data->src, NULL)) == NULL) return; - if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) + if (arg_parse_window(data->dst, &s, &idx) != 0) { + ctx->error(ctx, "bad window: %s", data->dst); return; - - if ((src = session_find(data->srcname)) == NULL) { - ctx->error(ctx, "session not found: %s", data->srcname); + } + if (s == NULL) + s = ctx->cursession; + if (s == NULL) + s = cmd_current_session(ctx); + if (s == NULL) { + ctx->error(ctx, "session not found: %s", data->dst); return; } - if (data->srcidx < 0) - data->srcidx = -1; - if (data->srcidx == -1) - wl = src->curw; - else { - wl = winlink_find_by_index(&src->windows, data->srcidx); - if (wl == NULL) { - ctx->error(ctx, "no window %d", data->srcidx); - return; + if (data->flags & CMD_KFLAG) { + wl_dst = winlink_find_by_index(&s->windows, idx); + if (wl_dst != NULL) { + /* + * Can't use session_detach as it will destroy session + * if this makes it empty. + */ + session_alert_cancel(s, wl_dst); + winlink_remove(&s->windows, wl_dst); + + /* Force select/redraw if current. */ + if (wl_dst == s->curw) { + data->flags &= ~CMD_DFLAG; + s->curw = NULL; + } + if (wl_dst == s->lastw) + s->lastw = NULL; + + /* + * Can't error out after this or there could be an empty + * session! + */ } } - if (data->idx < 0) - data->idx = -1; - if (data->flag_kill && data->idx != -1) { - wl2 = winlink_find_by_index(&s->windows, data->idx); - if (wl2 == NULL) { - ctx->error(ctx, "no window %d", data->idx); - return; - } - - /* - * Can't use session_detach as it will destroy session if this - * makes it empty. - */ - session_alert_cancel(s, wl2); - winlink_remove(&s->windows, wl2); - - /* Force select/redraw if current. */ - if (wl2 == s->curw) { - data->flag_detached = 0; - s->curw = NULL; - } - if (wl2 == s->lastw) - s->lastw = NULL; - - /* - * Can't error out after this or there could be an empty - * session! - */ - } - - wl = session_attach(s, wl->window, data->idx); - if (wl == NULL) { - ctx->error(ctx, "index in use: %d", data->idx); + wl_dst = session_attach(s, wl_src->window, idx); + if (wl_dst == NULL) { + ctx->error(ctx, "index in use: %d", idx); return; } - if (!data->flag_detached) { - session_select(s, wl->idx); - server_redraw_session(s); - } else + if (data->flags & CMD_DFLAG) server_status_session(s); + else { + session_select(s, wl_dst->idx); + server_redraw_session(s); + } if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } - -void -cmd_link_window_send(struct cmd *self, struct buffer *b) -{ - struct cmd_link_window_data *data = self->data; - - buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); - cmd_send_string(b, data->srcname); -} - -void -cmd_link_window_recv(struct cmd *self, struct buffer *b) -{ - struct cmd_link_window_data *data; - - self->data = data = xmalloc(sizeof *data); - buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); - data->srcname = cmd_recv_string(b); -} - -void -cmd_link_window_free(struct cmd *self) -{ - struct cmd_link_window_data *data = self->data; - - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); - if (data->srcname != NULL) - xfree(data->srcname); - xfree(data); -} - -void -cmd_link_window_print(struct cmd *self, char *buf, size_t len) -{ - struct cmd_link_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->flag_kill) - off += xsnprintf(buf + off, len - off, " -k"); - if (off < len && data->cname != NULL) - off += xsnprintf(buf + off, len - off, " -c %s", data->cname); - if (off < len && data->sname != NULL) - off += xsnprintf(buf + off, len - off, " -s %s", data->sname); - if (off < len && data->idx != -1) - off += xsnprintf(buf + off, len - off, " -i %d", data->idx); - if (off < len && data->srcname != NULL) - off += xsnprintf(buf + off, len - off, " %s", data->srcname); - if (off < len && data->srcidx != -1) - off += xsnprintf(buf + off, len - off, " %d", data->srcidx); -} diff --git a/cmd-list-clients.c b/cmd-list-clients.c index c25d53e2..49dd5da7 100644 --- a/cmd-list-clients.c +++ b/cmd-list-clients.c @@ -1,4 +1,4 @@ -/* $Id: cmd-list-clients.c,v 1.7 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-list-clients.c,v 1.8 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -34,8 +34,8 @@ const struct cmd_entry cmd_list_clients_entry = { "", 0, NULL, - cmd_list_clients_exec, NULL, + cmd_list_clients_exec, NULL, NULL, NULL, diff --git a/cmd-list-keys.c b/cmd-list-keys.c index def2fb6f..9dba321e 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -1,4 +1,4 @@ -/* $Id: cmd-list-keys.c,v 1.9 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-list-keys.c,v 1.10 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -31,12 +31,12 @@ const struct cmd_entry cmd_list_keys_entry = { "", 0, NULL, + NULL, cmd_list_keys_exec, NULL, NULL, NULL, - NULL, - NULL, + NULL }; void diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c index 92e64dbb..6b36460c 100644 --- a/cmd-list-sessions.c +++ b/cmd-list-sessions.c @@ -1,4 +1,4 @@ -/* $Id: cmd-list-sessions.c,v 1.14 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-list-sessions.c,v 1.15 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -33,8 +33,8 @@ const struct cmd_entry cmd_list_sessions_entry = { "list-sessions", "ls", "", 0, NULL, - cmd_list_sessions_exec, NULL, + cmd_list_sessions_exec, NULL, NULL, NULL, diff --git a/cmd-list-windows.c b/cmd-list-windows.c index 8e29d0fc..19a2fc5d 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -1,4 +1,4 @@ -/* $Id: cmd-list-windows.c,v 1.19 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-list-windows.c,v 1.20 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -30,27 +30,28 @@ void cmd_list_windows_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_list_windows_entry = { "list-windows", "lsw", - CMD_SESSIONONLY_USAGE, + CMD_TARGET_SESSION_USAGE, 0, - cmd_sessiononly_parse, + cmd_target_init, + cmd_target_parse, cmd_list_windows_exec, - cmd_sessiononly_send, - cmd_sessiononly_recv, - cmd_sessiononly_free, - NULL, - cmd_sessiononly_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx) { + struct cmd_target_data *data = self->data; struct session *s; struct winlink *wl; struct window *w; u_int i; unsigned long long size; - if ((s = cmd_sessiononly_get(self, ctx)) == NULL) + if ((s = cmd_find_session(ctx, data->target)) == NULL) return; RB_FOREACH(wl, winlinks, &s->windows) { diff --git a/cmd-new-session.c b/cmd-new-session.c index 3d598ca4..479cc01a 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-new-session.c,v 1.26 2008-06-05 17:12:10 nicm Exp $ */ +/* $Id: cmd-new-session.c,v 1.27 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -35,7 +35,7 @@ void cmd_new_session_init(struct cmd *, int); void cmd_new_session_print(struct cmd *, char *, size_t); struct cmd_new_session_data { - char *name; + char *newname; char *winname; char *cmd; int flag_detached; @@ -43,14 +43,14 @@ struct cmd_new_session_data { const struct cmd_entry cmd_new_session_entry = { "new-session", "new", - "[-d] [-n window-name] [-s session-name] [command]", + "[-d] [-s session-name] [-n window-name] [command]", CMD_STARTSERVER|CMD_CANTNEST, + cmd_new_session_init, cmd_new_session_parse, cmd_new_session_exec, cmd_new_session_send, cmd_new_session_recv, cmd_new_session_free, - cmd_new_session_init, cmd_new_session_print }; @@ -61,7 +61,7 @@ cmd_new_session_init(struct cmd *self, unused int arg) self->data = data = xmalloc(sizeof *data); data->flag_detached = 0; - data->name = NULL; + data->newname = NULL; data->winname = NULL; data->cmd = NULL; } @@ -81,10 +81,12 @@ cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause) data->flag_detached = 1; break; case 's': - data->name = xstrdup(optarg); + if (data->newname == NULL) + data->newname = xstrdup(optarg); break; case 'n': - data->winname = xstrdup(optarg); + if (data->winname == NULL) + data->winname = xstrdup(optarg); break; default: goto usage; @@ -130,8 +132,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) } } - if (data->name != NULL && session_find(data->name) != NULL) { - ctx->error(ctx, "duplicate session: %s", data->name); + if (data->newname != NULL && session_find(data->newname) != NULL) { + ctx->error(ctx, "duplicate session: %s", data->newname); return; } @@ -158,7 +160,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) } - if ((s = session_create(data->name, cmd, sx, sy)) == NULL) + if ((s = session_create(data->newname, cmd, sx, sy)) == NULL) fatalx("session_create failed"); if (data->winname != NULL) { xfree(s->curw->window->name); @@ -181,7 +183,7 @@ cmd_new_session_send(struct cmd *self, struct buffer *b) struct cmd_new_session_data *data = self->data; buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->name); + cmd_send_string(b, data->newname); cmd_send_string(b, data->winname); cmd_send_string(b, data->cmd); } @@ -193,7 +195,7 @@ cmd_new_session_recv(struct cmd *self, struct buffer *b) self->data = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); - data->name = cmd_recv_string(b); + data->newname = cmd_recv_string(b); data->winname = cmd_recv_string(b); data->cmd = cmd_recv_string(b); } @@ -203,8 +205,8 @@ cmd_new_session_free(struct cmd *self) { struct cmd_new_session_data *data = self->data; - if (data->name != NULL) - xfree(data->name); + if (data->newname != NULL) + xfree(data->newname); if (data->winname != NULL) xfree(data->winname); if (data->cmd != NULL) @@ -213,6 +215,20 @@ cmd_new_session_free(struct cmd *self) } void -cmd_new_session_print(struct cmd *cmd, char *buf, size_t len) +cmd_new_session_print(struct cmd *self, char *buf, size_t len) { + struct cmd_new_session_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->newname != NULL) + off += xsnprintf(buf + off, len - off, " -s %s", data->newname); + if (off < len && data->winname != NULL) + off += xsnprintf(buf + off, len - off, " -n %s", data->winname); + if (off < len && data->cmd != NULL) + off += xsnprintf(buf + off, len - off, " %s", data->cmd); } diff --git a/cmd-new-window.c b/cmd-new-window.c index 9cc3fc3d..2f30f35b 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-new-window.c,v 1.22 2008-06-05 17:12:10 nicm Exp $ */ +/* $Id: cmd-new-window.c,v 1.23 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -36,9 +36,7 @@ void cmd_new_window_init(struct cmd *, int); void cmd_new_window_print(struct cmd *, char *, size_t); struct cmd_new_window_data { - char *cname; - char *sname; - int idx; + char *target; char *name; char *cmd; int flag_detached; @@ -46,14 +44,14 @@ struct cmd_new_window_data { const struct cmd_entry cmd_new_window_entry = { "new-window", "neww", - "[-d] [-c client-tty|-s session-name] [-i index] [-n name] [command]", + "[-d] [-t target-window] [-n window-name] [command]", 0, + cmd_new_window_init, cmd_new_window_parse, cmd_new_window_exec, cmd_new_window_send, cmd_new_window_recv, cmd_new_window_free, - cmd_new_window_init, cmd_new_window_print }; @@ -63,52 +61,34 @@ cmd_new_window_init(struct cmd *self, unused int arg) struct cmd_new_window_data *data; self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; - data->idx = -1; - data->flag_detached = 0; + data->target = NULL; data->name = NULL; data->cmd = NULL; + data->flag_detached = 0; } int cmd_new_window_parse(struct cmd *self, int argc, char **argv, char **cause) { struct cmd_new_window_data *data; - const char *errstr; int opt; self->entry->init(self, 0); data = self->data; - while ((opt = getopt(argc, argv, "c:di:n:s:")) != EOF) { + while ((opt = getopt(argc, argv, "dt:n:")) != EOF) { switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - break; case 'd': data->flag_detached = 1; break; - case 'i': - data->idx = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr != NULL) { - xasprintf(cause, "index %s", errstr); - goto error; - } + case 't': + if (data->target == NULL) + data->target = xstrdup(optarg); break; case 'n': if (data->name == NULL) data->name = xstrdup(optarg); break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); - break; default: goto usage; } @@ -126,7 +106,6 @@ cmd_new_window_parse(struct cmd *self, int argc, char **argv, char **cause) usage: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); -error: self->entry->free(self); return (-1); } @@ -138,17 +117,29 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx) struct session *s; struct winlink *wl; char *cmd; + int idx; - if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) + if (data == NULL) return; + if (arg_parse_window(data->target, &s, &idx) != 0) { + ctx->error(ctx, "bad window: %s", data->target); + return; + } + if (s == NULL) + s = ctx->cursession; + if (s == NULL) + s = cmd_current_session(ctx); + if (s == NULL) { + ctx->error(ctx, "session not found: %s", data->target); + return; + } + cmd = data->cmd; if (cmd == NULL) cmd = options_get_string(&s->options, "default-command"); - if (data->idx < 0) - data->idx = -1; - wl = session_new(s, data->name, cmd, data->idx); + wl = session_new(s, data->name, cmd, idx); if (wl == NULL) { ctx->error(ctx, "command failed: %s", cmd); return; @@ -169,8 +160,7 @@ cmd_new_window_send(struct cmd *self, struct buffer *b) struct cmd_new_window_data *data = self->data; buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); + cmd_send_string(b, data->target); cmd_send_string(b, data->name); cmd_send_string(b, data->cmd); } @@ -182,8 +172,7 @@ cmd_new_window_recv(struct cmd *self, struct buffer *b) self->data = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); + data->target = cmd_recv_string(b); data->name = cmd_recv_string(b); data->cmd = cmd_recv_string(b); } @@ -193,10 +182,8 @@ cmd_new_window_free(struct cmd *self) { struct cmd_new_window_data *data = self->data; - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); + if (data->target != NULL) + xfree(data->target); if (data->name != NULL) xfree(data->name); if (data->cmd != NULL) @@ -215,12 +202,8 @@ cmd_new_window_print(struct cmd *self, char *buf, size_t len) return; if (off < len && data->flag_detached) off += xsnprintf(buf + off, len - off, " -d"); - if (off < len && data->cname != NULL) - off += xsnprintf(buf + off, len - off, " -c %s", data->cname); - if (off < len && data->sname != NULL) - off += xsnprintf(buf + off, len - off, " -s %s", data->sname); - if (off < len && data->idx != -1) - off += xsnprintf(buf + off, len - off, " -i %d", data->idx); + if (off < len && data->target != NULL) + off += xsnprintf(buf + off, len - off, " -t %s", data->target); if (off < len && data->name != NULL) off += xsnprintf(buf + off, len - off, " -n %s", data->name); if (off < len && data->cmd != NULL) diff --git a/cmd-next-window.c b/cmd-next-window.c index c15589b7..7296ffc5 100644 --- a/cmd-next-window.c +++ b/cmd-next-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-next-window.c,v 1.10 2008-06-05 16:35:31 nicm Exp $ */ +/* $Id: cmd-next-window.c,v 1.11 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,23 +28,24 @@ void cmd_next_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_next_window_entry = { "next-window", "next", - CMD_SESSIONONLY_USAGE, + CMD_TARGET_SESSION_USAGE, 0, - cmd_sessiononly_parse, + cmd_target_init, + cmd_target_parse, cmd_next_window_exec, - cmd_sessiononly_send, - cmd_sessiononly_recv, - cmd_sessiononly_free, - NULL, - cmd_sessiononly_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_next_window_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct session *s; + struct cmd_target_data *data = self->data; + struct session *s; - if ((s = cmd_sessiononly_get(self, ctx)) == NULL) + if ((s = cmd_find_session(ctx, data->target)) == NULL) return; if (session_next(s) == 0) diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c index a9cd7004..1ac4a11e 100644 --- a/cmd-paste-buffer.c +++ b/cmd-paste-buffer.c @@ -1,4 +1,4 @@ -/* $Id: cmd-paste-buffer.c,v 1.7 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: cmd-paste-buffer.c,v 1.8 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -30,23 +30,24 @@ void cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_paste_buffer_entry = { "paste-buffer", "paste", - CMD_WINDOWONLY_USAGE, + CMD_TARGET_WINDOW_USAGE, 0, - cmd_windowonly_parse, + cmd_target_init, + cmd_target_parse, cmd_paste_buffer_exec, - cmd_windowonly_send, - cmd_windowonly_recv, - cmd_windowonly_free, - NULL, - NULL + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct winlink *wl; + struct cmd_target_data *data = self->data; + struct winlink *wl; - if ((wl = cmd_windowonly_get(self, ctx, NULL)) == NULL) + if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return; if (paste_buffer != NULL && *paste_buffer != '\0') { diff --git a/cmd-previous-window.c b/cmd-previous-window.c index 173333a9..c22155f9 100644 --- a/cmd-previous-window.c +++ b/cmd-previous-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-previous-window.c,v 1.10 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: cmd-previous-window.c,v 1.11 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,23 +28,24 @@ void cmd_previous_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_previous_window_entry = { "previous-window", "prev", - CMD_SESSIONONLY_USAGE, + CMD_TARGET_SESSION_USAGE, 0, - cmd_sessiononly_parse, + cmd_target_init, + cmd_target_parse, cmd_previous_window_exec, - cmd_sessiononly_send, - cmd_sessiononly_recv, - cmd_sessiononly_free, - NULL, - cmd_sessiononly_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_previous_window_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct session *s; + struct cmd_target_data *data = self->data; + struct session *s; - if ((s = cmd_sessiononly_get(self, ctx)) == NULL) + if ((s = cmd_find_session(ctx, data->target)) == NULL) return; if (session_previous(s) == 0) diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c index a8cce215..51896ec7 100644 --- a/cmd-refresh-client.c +++ b/cmd-refresh-client.c @@ -1,4 +1,4 @@ -/* $Id: cmd-refresh-client.c,v 1.5 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: cmd-refresh-client.c,v 1.6 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,25 +28,26 @@ void cmd_refresh_client_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_refresh_client_entry = { "refresh-client", "refresh", - CMD_CLIENTONLY_USAGE, + CMD_TARGET_CLIENT_USAGE, 0, - cmd_clientonly_parse, + cmd_target_init, + cmd_target_parse, cmd_refresh_client_exec, - cmd_clientonly_send, - cmd_clientonly_recv, - cmd_clientonly_free, - NULL, - cmd_clientonly_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_refresh_client_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct client *c; + struct cmd_target_data *data = self->data; + struct client *c; - if ((c = cmd_clientonly_get(self, ctx)) == NULL) + if ((c = cmd_find_client(ctx, data->target)) == NULL) return; - + server_redraw_client(c); if (ctx->cmdclient != NULL) diff --git a/cmd-rename-session.c b/cmd-rename-session.c index 904963b8..ab0f0469 100644 --- a/cmd-rename-session.c +++ b/cmd-rename-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-rename-session.c,v 1.10 2008-06-05 17:12:10 nicm Exp $ */ +/* $Id: cmd-rename-session.c,v 1.11 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -27,134 +27,33 @@ * Change session name. */ -int cmd_rename_session_parse(struct cmd *, int, char **, char **); void cmd_rename_session_exec(struct cmd *, struct cmd_ctx *); -void cmd_rename_session_send(struct cmd *, struct buffer *); -void cmd_rename_session_recv(struct cmd *, struct buffer *); -void cmd_rename_session_free(struct cmd *); -void cmd_rename_session_print(struct cmd *, char *, size_t); - -struct cmd_rename_session_data { - char *cname; - char *sname; - char *newname; -}; const struct cmd_entry cmd_rename_session_entry = { "rename-session", "rename", - "[-c client-tty|-s session-name] new-name", - 0, - cmd_rename_session_parse, + CMD_TARGET_SESSION_USAGE " new-name", + CMD_ONEARG, + cmd_target_init, + cmd_target_parse, cmd_rename_session_exec, - cmd_rename_session_send, - cmd_rename_session_recv, - cmd_rename_session_free, - NULL, - cmd_rename_session_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; -int -cmd_rename_session_parse(struct cmd *self, int argc, char **argv, char **cause) -{ - struct cmd_rename_session_data *data; - int opt; - - self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; - data->newname = NULL; - - while ((opt = getopt(argc, argv, "c:s:")) != EOF) { - switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); - break; - default: - goto usage; - } - } - argc -= optind; - argv += optind; - if (argc != 1) - goto usage; - - data->newname = 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_rename_session_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct cmd_rename_session_data *data = self->data; - struct session *s; + struct cmd_target_data *data = self->data; + struct session *s; - if (data == NULL) - return; - - if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) + if ((s = cmd_find_session(ctx, data->target)) == NULL) return; xfree(s->name); - s->name = xstrdup(data->newname); + s->name = xstrdup(data->arg); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } - -void -cmd_rename_session_send(struct cmd *self, struct buffer *b) -{ - struct cmd_rename_session_data *data = self->data; - - buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); - cmd_send_string(b, data->newname); -} - -void -cmd_rename_session_recv(struct cmd *self, struct buffer *b) -{ - struct cmd_rename_session_data *data; - - self->data = data = xmalloc(sizeof *data); - buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); - data->newname = cmd_recv_string(b); -} - -void -cmd_rename_session_free(struct cmd *self) -{ - struct cmd_rename_session_data *data = self->data; - - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); - if (data->newname != NULL) - xfree(data->newname); - xfree(data); -} - -void -cmd_rename_session_print(struct cmd *cmd, char *buf, size_t len) -{ -} diff --git a/cmd-rename-window.c b/cmd-rename-window.c index 145683cf..f8a87560 100644 --- a/cmd-rename-window.c +++ b/cmd-rename-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-rename-window.c,v 1.21 2008-06-05 17:12:10 nicm Exp $ */ +/* $Id: cmd-rename-window.c,v 1.22 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -24,166 +24,39 @@ #include "tmux.h" /* - * Rename window by index. + * Rename a window. */ -int cmd_rename_window_parse(struct cmd *, int, char **, char **); void cmd_rename_window_exec(struct cmd *, struct cmd_ctx *); -void cmd_rename_window_send(struct cmd *, struct buffer *); -void cmd_rename_window_recv(struct cmd *, struct buffer *); -void cmd_rename_window_free(struct cmd *); -void cmd_rename_window_print(struct cmd *, char *, size_t); - -struct cmd_rename_window_data { - char *cname; - char *sname; - int idx; - char *newname; -}; const struct cmd_entry cmd_rename_window_entry = { "rename-window", "renamew", - "[-c client-tty|-s session-name] [-i index] new-name", - 0, - cmd_rename_window_parse, + CMD_TARGET_WINDOW_USAGE " new-name", + CMD_ONEARG, + cmd_target_init, + cmd_target_parse, cmd_rename_window_exec, - cmd_rename_window_send, - cmd_rename_window_recv, - cmd_rename_window_free, - NULL, - cmd_rename_window_print + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; -int -cmd_rename_window_parse(struct cmd *self, int argc, char **argv, char **cause) -{ - struct cmd_rename_window_data *data; - const char *errstr; - int opt; - - self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; - data->idx = -1; - data->newname = NULL; - - while ((opt = getopt(argc, argv, "c:i:s:")) != EOF) { - switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - break; - case 'i': - data->idx = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr != NULL) { - xasprintf(cause, "index %s", errstr); - goto error; - } - break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); - break; - default: - goto usage; - } - } - argc -= optind; - argv += optind; - if (argc != 1) - goto usage; - - data->newname = xstrdup(argv[0]); - - return (0); - -usage: - xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); - -error: - self->entry->free(self); - return (-1); -} - void cmd_rename_window_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct cmd_rename_window_data *data = self->data; - struct session *s; - struct winlink *wl; + struct cmd_target_data *data = self->data; + struct session *s; + struct winlink *wl; - if (data == NULL) - return; - - wl = cmd_find_window(ctx, data->cname, data->sname, data->idx, &s); - if (wl == NULL) + if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) return; xfree(wl->window->name); - wl->window->name = xstrdup(data->newname); + wl->window->name = xstrdup(data->arg); server_status_session(s); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } - -void -cmd_rename_window_send(struct cmd *self, struct buffer *b) -{ - struct cmd_rename_window_data *data = self->data; - - buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); - cmd_send_string(b, data->newname); -} - -void -cmd_rename_window_recv(struct cmd *self, struct buffer *b) -{ - struct cmd_rename_window_data *data; - - self->data = data = xmalloc(sizeof *data); - buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); - data->newname = cmd_recv_string(b); -} - -void -cmd_rename_window_free(struct cmd *self) -{ - struct cmd_rename_window_data *data = self->data; - - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); - if (data->newname != NULL) - xfree(data->newname); - xfree(data); -} - -void -cmd_rename_window_print(struct cmd *self, char *buf, size_t len) -{ - struct cmd_rename_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->cname != NULL) - off += xsnprintf(buf + off, len - off, " -c %s", data->cname); - if (off < len && data->sname != NULL) - off += xsnprintf(buf + off, len - off, " -s %s", data->sname); - if (off < len && data->idx != -1) - off += xsnprintf(buf + off, len - off, " -i %d", data->idx); - if (off < len && data->newname != NULL) - off += xsnprintf(buf + off, len - off, " %s", data->newname); -} diff --git a/cmd-scroll-mode.c b/cmd-scroll-mode.c index 16199310..2f22babd 100644 --- a/cmd-scroll-mode.c +++ b/cmd-scroll-mode.c @@ -1,4 +1,4 @@ -/* $Id: cmd-scroll-mode.c,v 1.11 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: cmd-scroll-mode.c,v 1.12 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,23 +28,24 @@ void cmd_scroll_mode_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_scroll_mode_entry = { "scroll-mode", NULL, - CMD_WINDOWONLY_USAGE, + CMD_TARGET_WINDOW_USAGE, 0, - cmd_windowonly_parse, + cmd_target_init, + cmd_target_parse, cmd_scroll_mode_exec, - cmd_windowonly_send, - cmd_windowonly_recv, - cmd_windowonly_free, - NULL, - NULL + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct winlink *wl; + struct cmd_target_data *data = self->data; + struct winlink *wl; - if ((wl = cmd_windowonly_get(self, ctx, NULL)) == NULL) + if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return; window_set_mode(wl->window, &window_scroll_mode); diff --git a/cmd-select-window.c b/cmd-select-window.c index 23ac48b4..0fbbe942 100644 --- a/cmd-select-window.c +++ b/cmd-select-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-select-window.c,v 1.17 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: cmd-select-window.c,v 1.18 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -32,35 +32,36 @@ void cmd_select_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_select_window_entry = { "select-window", "selectw", - CMD_WINDOWONLY_USAGE, + CMD_TARGET_WINDOW_USAGE, 0, - cmd_windowonly_parse, - cmd_select_window_exec, - cmd_windowonly_send, - cmd_windowonly_recv, - cmd_windowonly_free, cmd_select_window_init, - cmd_windowonly_print + cmd_target_parse, + cmd_select_window_exec, + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void -cmd_select_window_init(struct cmd *self, int arg) +cmd_select_window_init(struct cmd *self, int key) { - struct cmd_windowonly_data *data; + struct cmd_target_data *data; - self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; - data->idx = arg - '0'; + cmd_target_init(self, key); + data = self->data; + + xasprintf(&data->target, ":%d", key - '0'); } void cmd_select_window_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct winlink *wl; - struct session *s; + struct cmd_target_data *data = self->data; + struct winlink *wl; + struct session *s; - if ((wl = cmd_windowonly_get(self, ctx, &s)) == NULL) + if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) return; if (session_select(s, wl->idx) == 0) diff --git a/cmd-send-keys.c b/cmd-send-keys.c index e0a85406..05912d0d 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -1,4 +1,4 @@ -/* $Id: cmd-send-keys.c,v 1.9 2008-06-05 17:12:10 nicm Exp $ */ +/* $Id: cmd-send-keys.c,v 1.10 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -35,8 +35,7 @@ void cmd_send_keys_free(struct cmd *); void cmd_send_keys_print(struct cmd *, char *, size_t); struct cmd_send_keys_data { - char *cname; - char *sname; + char *target; int idx; u_int nkeys; int *keys; @@ -46,12 +45,12 @@ const struct cmd_entry cmd_send_keys_entry = { "send-keys", "send", "[-c client-tty|-s session-name] [-i index] key ...", 0, + NULL, cmd_send_keys_parse, cmd_send_keys_exec, cmd_send_keys_send, cmd_send_keys_recv, cmd_send_keys_free, - NULL, cmd_send_keys_print }; @@ -60,36 +59,19 @@ cmd_send_keys_parse(struct cmd *self, int argc, char **argv, char **cause) { struct cmd_send_keys_data *data; int opt, key; - const char *errstr; char *s; self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; + data->target = NULL; data->idx = -1; data->nkeys = 0; data->keys = NULL; - while ((opt = getopt(argc, argv, "c:i:s:")) != EOF) { + while ((opt = getopt(argc, argv, "t:")) != EOF) { switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - break; - case 'i': - data->idx = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr != NULL) { - xasprintf(cause, "index %s", errstr); - goto error; - } - break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); + case 't': + if (data->target == NULL) + data->target = xstrdup(optarg); break; default: goto usage; @@ -121,7 +103,6 @@ cmd_send_keys_parse(struct cmd *self, int argc, char **argv, char **cause) usage: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); -error: self->entry->free(self); return (-1); } @@ -136,8 +117,7 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx) if (data == NULL) return; - wl = cmd_find_window(ctx, data->cname, data->sname, data->idx, NULL); - if (wl == NULL) + if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return; for (i = 0; i < data->nkeys; i++) @@ -153,8 +133,7 @@ cmd_send_keys_send(struct cmd *self, struct buffer *b) struct cmd_send_keys_data *data = self->data; buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); + cmd_send_string(b, data->target); buffer_write(b, data->keys, data->nkeys * sizeof *data->keys); } @@ -165,8 +144,7 @@ cmd_send_keys_recv(struct cmd *self, struct buffer *b) self->data = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); + data->target = cmd_recv_string(b); data->keys = xcalloc(data->nkeys, sizeof *data->keys); buffer_read(b, data->keys, data->nkeys * sizeof *data->keys); } @@ -176,10 +154,8 @@ cmd_send_keys_free(struct cmd *self) { struct cmd_send_keys_data *data = self->data; - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); + if (data->target != NULL) + xfree(data->target); xfree(data); } @@ -193,9 +169,7 @@ cmd_send_keys_print(struct cmd *self, char *buf, size_t len) off += xsnprintf(buf, len, "%s", self->entry->name); if (data == NULL) return; - off += xsnprintf(buf + off, len - off, " -c %s", data->cname); - if (off < len && data->sname != NULL) - off += xsnprintf(buf + off, len - off, " -s %s", data->sname); + off += xsnprintf(buf + off, len - off, " -t %s", data->target); if (off < len && data->idx != -1) off += xsnprintf(buf + off, len - off, " -i %d", data->idx); diff --git a/cmd-send-prefix.c b/cmd-send-prefix.c index c8df7da6..b9c236a6 100644 --- a/cmd-send-prefix.c +++ b/cmd-send-prefix.c @@ -1,4 +1,4 @@ -/* $Id: cmd-send-prefix.c,v 1.13 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: cmd-send-prefix.c,v 1.14 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,24 +28,25 @@ void cmd_send_prefix_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_send_prefix_entry = { "send-prefix", NULL, - CMD_WINDOWONLY_USAGE, + CMD_TARGET_WINDOW_USAGE, 0, - cmd_windowonly_parse, + cmd_target_init, + cmd_target_parse, cmd_send_prefix_exec, - cmd_windowonly_send, - cmd_windowonly_recv, - cmd_windowonly_free, - NULL, - NULL + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct session *s; - struct winlink *wl; + struct cmd_target_data *data = self->data; + struct session *s; + struct winlink *wl; - if ((wl = cmd_windowonly_get(self, ctx, &s)) == NULL) + if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) return; window_key(wl->window, options_get_number(&s->options, "prefix-key")); diff --git a/cmd-set-option.c b/cmd-set-option.c index a1ac9a9f..ee962da9 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -1,4 +1,4 @@ -/* $Id: cmd-set-option.c,v 1.24 2008-06-05 17:12:11 nicm Exp $ */ +/* $Id: cmd-set-option.c,v 1.25 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -36,8 +36,7 @@ void cmd_set_option_free(struct cmd *); void cmd_set_option_print(struct cmd *, char *, size_t); struct cmd_set_option_data { - char *cname; - char *sname; + char *target; int flag_global; char *option; char *value; @@ -45,14 +44,14 @@ struct cmd_set_option_data { const struct cmd_entry cmd_set_option_entry = { "set-option", "set", - "[-c client-tty|-s session-name] option value", + "[-t target-window] option value", 0, + NULL, cmd_set_option_parse, cmd_set_option_exec, cmd_set_option_send, cmd_set_option_recv, cmd_set_option_free, - NULL, cmd_set_option_print }; @@ -63,26 +62,16 @@ cmd_set_option_parse(struct cmd *self, int argc, char **argv, char **cause) int opt; self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; + data->target = NULL; data->flag_global = 1; data->option = NULL; data->value = NULL; - while ((opt = getopt(argc, argv, "c:s:")) != EOF) { + while ((opt = getopt(argc, argv, "t:s:")) != EOF) { switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - data->flag_global = 0; - break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); + case 't': + if (data->target == NULL) + data->target = xstrdup(optarg); data->flag_global = 0; break; default: @@ -123,7 +112,7 @@ cmd_set_option_exec(struct cmd *self, unused struct cmd_ctx *ctx) return; if (data->flag_global || - ((s = cmd_find_session(ctx, data->cname, data->sname))) == NULL) + ((s = cmd_find_session(ctx, data->target))) == NULL) oo = &global_options; else oo = &s->options; @@ -282,8 +271,7 @@ cmd_set_option_send(struct cmd *self, struct buffer *b) struct cmd_set_option_data *data = self->data; buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); + cmd_send_string(b, data->target); cmd_send_string(b, data->option); cmd_send_string(b, data->value); } @@ -295,8 +283,7 @@ cmd_set_option_recv(struct cmd *self, struct buffer *b) self->data = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); + data->target = cmd_recv_string(b); data->option = cmd_recv_string(b); data->value = cmd_recv_string(b); } @@ -306,10 +293,8 @@ cmd_set_option_free(struct cmd *self) { struct cmd_set_option_data *data = self->data; - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); + if (data->target != NULL) + xfree(data->target); if (data->option != NULL) xfree(data->option); if (data->value != NULL) diff --git a/cmd-set-window-option.c b/cmd-set-window-option.c index b91596e5..bed3d3aa 100644 --- a/cmd-set-window-option.c +++ b/cmd-set-window-option.c @@ -1,4 +1,4 @@ -/* $Id: cmd-set-window-option.c,v 1.4 2008-06-05 17:12:11 nicm Exp $ */ +/* $Id: cmd-set-window-option.c,v 1.5 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -36,23 +36,21 @@ void cmd_set_window_option_free(struct cmd *); void cmd_set_window_option_print(struct cmd *, char *, size_t); struct cmd_set_window_option_data { - char *cname; - char *sname; - int idx; + char *target; char *option; char *value; }; const struct cmd_entry cmd_set_window_option_entry = { "set-window-option", "setw", - "[-c client-tty|-s session-name] [-i index] option value", + "[-t target-window] option value", 0, + NULL, cmd_set_window_option_parse, cmd_set_window_option_exec, cmd_set_window_option_send, cmd_set_window_option_recv, cmd_set_window_option_free, - NULL, cmd_set_window_option_print }; @@ -62,35 +60,17 @@ cmd_set_window_option_parse( { struct cmd_set_window_option_data *data; int opt; - const char *errstr; self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; - data->idx = -1; + data->target = NULL; data->option = NULL; data->value = NULL; - while ((opt = getopt(argc, argv, "c:i:s:")) != EOF) { + while ((opt = getopt(argc, argv, "t:")) != EOF) { switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - break; - case 'i': - data->idx = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr != NULL) { - xasprintf(cause, "index %s", errstr); - goto error; - } - break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); + case 't': + if (data->target == NULL) + data->target = xstrdup(optarg); break; default: goto usage; @@ -110,13 +90,12 @@ cmd_set_window_option_parse( usage: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); -error: self->entry->free(self); return (-1); } void -cmd_set_window_option_exec(struct cmd *self, unused struct cmd_ctx *ctx) +cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_set_window_option_data *data = self->data; struct winlink *wl; @@ -128,10 +107,7 @@ cmd_set_window_option_exec(struct cmd *self, unused struct cmd_ctx *ctx) if (data == NULL) return; - if (data == NULL) - return; - - wl = cmd_find_window(ctx, data->cname, data->sname, data->idx, &s); + wl = cmd_find_window(ctx, data->target, &s); if (wl == NULL) return; @@ -189,8 +165,7 @@ cmd_set_window_option_send(struct cmd *self, struct buffer *b) struct cmd_set_window_option_data *data = self->data; buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); + cmd_send_string(b, data->target); cmd_send_string(b, data->option); cmd_send_string(b, data->value); } @@ -202,8 +177,7 @@ cmd_set_window_option_recv(struct cmd *self, struct buffer *b) self->data = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); + data->target = cmd_recv_string(b); data->option = cmd_recv_string(b); data->value = cmd_recv_string(b); } @@ -213,10 +187,8 @@ cmd_set_window_option_free(struct cmd *self) { struct cmd_set_window_option_data *data = self->data; - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); + if (data->target != NULL) + xfree(data->target); if (data->option != NULL) xfree(data->option); if (data->value != NULL) @@ -233,6 +205,8 @@ cmd_set_window_option_print(struct cmd *self, char *buf, size_t len) off += xsnprintf(buf, len, "%s", self->entry->name); if (data == NULL) return; + if (off < len && data->target != NULL) + off += xsnprintf(buf + off, len - off, " -t %s", data->target); if (off < len && data->option != NULL) off += xsnprintf(buf + off, len - off, " %s", data->option); if (off < len && data->value != NULL) diff --git a/cmd-start-server.c b/cmd-start-server.c index 08e4bd18..ca2e1cb2 100644 --- a/cmd-start-server.c +++ b/cmd-start-server.c @@ -1,4 +1,4 @@ -/* $Id: cmd-start-server.c,v 1.4 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: cmd-start-server.c,v 1.5 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -31,8 +31,8 @@ const struct cmd_entry cmd_start_server_entry = { "", CMD_STARTSERVER, NULL, - cmd_start_server_exec, NULL, + cmd_start_server_exec, NULL, NULL, NULL, diff --git a/cmd-swap-window.c b/cmd-swap-window.c index bb567b79..1f473e19 100644 --- a/cmd-swap-window.c +++ b/cmd-swap-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-swap-window.c,v 1.10 2008-06-05 17:12:11 nicm Exp $ */ +/* $Id: cmd-swap-window.c,v 1.11 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -27,216 +27,47 @@ * Swap one window with another. */ -int cmd_swap_window_parse(struct cmd *, int, char **, char **); void cmd_swap_window_exec(struct cmd *, struct cmd_ctx *); -void cmd_swap_window_send(struct cmd *, struct buffer *); -void cmd_swap_window_recv(struct cmd *, struct buffer *); -void cmd_swap_window_free(struct cmd *); -void cmd_swap_window_print(struct cmd *, char *, size_t); - -struct cmd_swap_window_data { - char *cname; - char *sname; - int idx; - int srcidx; - char *srcname; - int flag_detached; -}; const struct cmd_entry cmd_swap_window_entry = { "swap-window", "swapw", - "[-d] [-c client-tty|-s session-name] [-i index] session-name index", - 0, - cmd_swap_window_parse, + "[-d] " CMD_SRCDST_WINDOW_USAGE, + CMD_DFLAG, + cmd_srcdst_init, + cmd_srcdst_parse, cmd_swap_window_exec, - cmd_swap_window_send, - cmd_swap_window_recv, - cmd_swap_window_free, - NULL, - cmd_swap_window_print + cmd_srcdst_send, + cmd_srcdst_recv, + cmd_srcdst_free, + cmd_srcdst_print }; -int -cmd_swap_window_parse(struct cmd *self, int argc, char **argv, char **cause) -{ - struct cmd_swap_window_data *data; - const char *errstr; - int opt; - - self->data = data = xmalloc(sizeof *data); - data->cname = NULL; - data->sname = NULL; - data->flag_detached = 0; - data->idx = -1; - data->srcidx = -1; - data->srcname = NULL; - - while ((opt = getopt(argc, argv, "c:di:s:")) != EOF) { - switch (opt) { - case 'c': - if (data->sname != NULL) - goto usage; - if (data->cname == NULL) - data->cname = xstrdup(optarg); - break; - case 'd': - data->flag_detached = 1; - break; - case 'i': - data->idx = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr != NULL) { - xasprintf(cause, "index %s", errstr); - goto error; - } - break; - case 's': - if (data->cname != NULL) - goto usage; - if (data->sname == NULL) - data->sname = xstrdup(optarg); - break; - default: - goto usage; - } - } - argc -= optind; - argv += optind; - if (argc != 2) - goto usage; - - data->srcname = xstrdup(argv[0]); - data->srcidx = strtonum(argv[1], 0, INT_MAX, &errstr); - if (errstr != NULL) { - xasprintf(cause, "index %s", errstr); - goto error; - } - - return (0); - -usage: - xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); - -error: - self->entry->free(self); - return (-1); -} - void cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct cmd_swap_window_data *data = self->data; - struct session *s, *src; - struct winlink *srcwl, *dstwl; - struct window *w; + struct cmd_srcdst_data *data = self->data; + struct session *src, *dst; + struct winlink *wl_src, *wl_dst; + struct window *w; - if (data == NULL) + if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL) + return; + if ((wl_dst = cmd_find_window(ctx, data->dst, &dst)) == NULL) return; - if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) - return; + w = wl_dst->window; + wl_dst->window = wl_src->window; + wl_src->window = w; - if ((src = session_find(data->srcname)) == NULL) { - ctx->error(ctx, "session not found: %s", data->srcname); - return; - } - - if (data->srcidx < 0) - data->srcidx = -1; - if (data->srcidx == -1) - srcwl = src->curw; - else { - srcwl = winlink_find_by_index(&src->windows, data->srcidx); - if (srcwl == NULL) { - ctx->error(ctx, "no window %d", data->srcidx); - return; - } - } - - if (data->idx < 0) - data->idx = -1; - if (data->idx == -1) - dstwl = s->curw; - else { - dstwl = winlink_find_by_index(&s->windows, data->idx); - if (dstwl == NULL) { - ctx->error(ctx, "no window %d", data->idx); - return; - } - } - - w = dstwl->window; - dstwl->window = srcwl->window; - srcwl->window = w; - - if (!data->flag_detached) { - session_select(s, dstwl->idx); - if (src != s) - session_select(src, srcwl->idx); + if (!(data->flags & CMD_DFLAG)) { + session_select(dst, wl_dst->idx); + if (src != dst) + session_select(src, wl_src->idx); } server_redraw_session(src); - if (src != s) - server_redraw_session(s); + if (src != dst) + server_redraw_session(dst); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } - -void -cmd_swap_window_send(struct cmd *self, struct buffer *b) -{ - struct cmd_swap_window_data *data = self->data; - - buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); - cmd_send_string(b, data->sname); - cmd_send_string(b, data->srcname); -} - -void -cmd_swap_window_recv(struct cmd *self, struct buffer *b) -{ - struct cmd_swap_window_data *data; - - self->data = data = xmalloc(sizeof *data); - buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); - data->sname = cmd_recv_string(b); - data->srcname = cmd_recv_string(b); -} - -void -cmd_swap_window_free(struct cmd *self) -{ - struct cmd_swap_window_data *data = self->data; - - if (data->cname != NULL) - xfree(data->cname); - if (data->sname != NULL) - xfree(data->sname); - if (data->srcname != NULL) - xfree(data->srcname); - xfree(data); -} - -void -cmd_swap_window_print(struct cmd *self, char *buf, size_t len) -{ - struct cmd_swap_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->cname != NULL) - off += xsnprintf(buf + off, len - off, " -c %s", data->cname); - if (off < len && data->sname != NULL) - off += xsnprintf(buf + off, len - off, " -s %s", data->sname); - if (off < len && data->idx != -1) - off += xsnprintf(buf + off, len - off, " -i %d", data->idx); - if (off < len && data->srcname != NULL) - off += xsnprintf(buf + off, len - off, " %s", data->srcname); - if (off < len && data->srcidx != -1) - off += xsnprintf(buf + off, len - off, " %d", data->srcidx); -} diff --git a/cmd-switch-client.c b/cmd-switch-client.c index ddff1fef..e8e5b93f 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -1,4 +1,4 @@ -/* $Id: cmd-switch-client.c,v 1.8 2008-06-05 17:12:11 nicm Exp $ */ +/* $Id: cmd-switch-client.c,v 1.9 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -36,20 +36,20 @@ void cmd_switch_client_free(struct cmd *); void cmd_switch_client_print(struct cmd *, char *, size_t); struct cmd_switch_client_data { - char *cname; char *name; + char *target; }; const struct cmd_entry cmd_switch_client_entry = { "switch-client", "switchc", - "[-c client-tty] session-name", + "[-c client-tty] [-t target-session]", 0, + NULL, cmd_switch_client_parse, cmd_switch_client_exec, cmd_switch_client_send, cmd_switch_client_recv, cmd_switch_client_free, - NULL, cmd_switch_client_print }; @@ -60,13 +60,16 @@ cmd_switch_client_parse(struct cmd *self, int argc, char **argv, char **cause) int opt; self->data = data = xmalloc(sizeof *data); - data->cname = NULL; data->name = NULL; + data->target = NULL; - while ((opt = getopt(argc, argv, "c:")) != EOF) { + while ((opt = getopt(argc, argv, "c:t:")) != EOF) { switch (opt) { case 'c': - data->cname = xstrdup(optarg); + data->name = xstrdup(optarg); + break; + case 't': + data->target = xstrdup(optarg); break; default: goto usage; @@ -74,11 +77,9 @@ cmd_switch_client_parse(struct cmd *self, int argc, char **argv, char **cause) } argc -= optind; argv += optind; - if (argc != 1) + if (argc != 0) goto usage; - data->name = xstrdup(argv[0]); - return (0); usage: @@ -98,13 +99,11 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx) if (data == NULL) return; - if ((c = cmd_find_client(ctx, data->cname)) == NULL) + if ((c = cmd_find_client(ctx, data->name)) == NULL) return; - - if ((s = session_find(data->name)) == NULL) { - ctx->error(ctx, "session not found: %s", data->name); + if ((s = cmd_find_session(ctx, data->target)) == NULL) return; - } + c->session = s; recalculate_sizes(); @@ -120,8 +119,8 @@ cmd_switch_client_send(struct cmd *self, struct buffer *b) struct cmd_switch_client_data *data = self->data; buffer_write(b, data, sizeof *data); - cmd_send_string(b, data->cname); cmd_send_string(b, data->name); + cmd_send_string(b, data->target); } void @@ -131,8 +130,8 @@ cmd_switch_client_recv(struct cmd *self, struct buffer *b) self->data = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); - data->cname = cmd_recv_string(b); data->name = cmd_recv_string(b); + data->target = cmd_recv_string(b); } void @@ -140,10 +139,10 @@ cmd_switch_client_free(struct cmd *self) { struct cmd_switch_client_data *data = self->data; - if (data->cname != NULL) - xfree(data->cname); if (data->name != NULL) xfree(data->name); + if (data->target != NULL) + xfree(data->target); xfree(data); } @@ -156,8 +155,8 @@ cmd_switch_client_print(struct cmd *self, char *buf, size_t len) off += xsnprintf(buf, len, "%s", self->entry->name); if (data == NULL) return; - if (off < len && data->cname != NULL) - off += xsnprintf(buf + off, len - off, " -c %s", data->cname); if (off < len && data->name != NULL) - off += xsnprintf(buf + off, len - off, " %s", data->name); + off += xsnprintf(buf + off, len - off, " -c %s", data->name); + if (off < len && data->target != NULL) + off += xsnprintf(buf + off, len - off, " -t %s", data->target); } diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c index 8dc02d55..0ee85fea 100644 --- a/cmd-unbind-key.c +++ b/cmd-unbind-key.c @@ -1,4 +1,4 @@ -/* $Id: cmd-unbind-key.c,v 1.12 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: cmd-unbind-key.c,v 1.13 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -33,19 +33,19 @@ void cmd_unbind_key_recv(struct cmd *, struct buffer *); void cmd_unbind_key_free(struct cmd *); struct cmd_unbind_key_data { - int key; + int key; }; const struct cmd_entry cmd_unbind_key_entry = { "unbind-key", "unbind", "key", 0, + NULL, cmd_unbind_key_parse, cmd_unbind_key_exec, cmd_unbind_key_send, cmd_unbind_key_recv, cmd_unbind_key_free, - NULL, NULL }; diff --git a/cmd-unlink-window.c b/cmd-unlink-window.c index 9b835372..23a488bd 100644 --- a/cmd-unlink-window.c +++ b/cmd-unlink-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-unlink-window.c,v 1.10 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: cmd-unlink-window.c,v 1.11 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,27 +28,28 @@ void cmd_unlink_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_unlink_window_entry = { "unlink-window", "unlinkw", - CMD_WINDOWONLY_USAGE, + CMD_TARGET_WINDOW_USAGE, 0, - cmd_windowonly_parse, + cmd_target_init, + cmd_target_parse, cmd_unlink_window_exec, - cmd_windowonly_send, - cmd_windowonly_recv, - cmd_windowonly_free, - NULL, - NULL + cmd_target_send, + cmd_target_recv, + cmd_target_free, + cmd_target_print }; void cmd_unlink_window_exec(struct cmd *self, struct cmd_ctx *ctx) { - struct winlink *wl; - struct session *s; - struct client *c; - u_int i; - int destroyed; + struct cmd_target_data *data = self->data; + struct winlink *wl; + struct session *s; + struct client *c; + u_int i; + int destroyed; - if ((wl = cmd_windowonly_get(self, ctx, &s)) == NULL) + if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) return; if (wl->window->references == 1) { diff --git a/cmd.c b/cmd.c index 295f453e..5ac2874e 100644 --- a/cmd.c +++ b/cmd.c @@ -1,4 +1,4 @@ -/* $Id: cmd.c,v 1.42 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: cmd.c,v 1.43 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -19,8 +19,8 @@ #include #include -#include #include +#include #include #include @@ -63,9 +63,6 @@ const struct cmd_entry *cmd_table[] = { NULL }; -struct client *cmd_lookup_client(const char *); -struct session *cmd_lookup_session(const char *); - struct cmd * cmd_parse(int argc, char **argv, char **cause) { @@ -236,94 +233,13 @@ cmd_recv_string(struct buffer *b) return (s); } -struct client * -cmd_lookup_client(const char *cname) -{ - struct client *c; - u_int i; - - for (i = 0; i < ARRAY_LENGTH(&clients); i++) { - c = ARRAY_ITEM(&clients, i); - if (c != NULL && strcmp(cname, c->tty.path) == 0) - return (c); - } - - return (NULL); -} - struct session * -cmd_lookup_session(const char *sname) +cmd_current_session(struct cmd_ctx *ctx) { - struct session *s, *newest = NULL; - struct timespec *ts; - u_int i; - - ts = NULL; - for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { - s = ARRAY_ITEM(&sessions, i); - if (s == NULL || fnmatch(sname, s->name, 0) != 0) - continue; - - if (ts == NULL || timespeccmp(&s->ts, ts, >)) { - newest = s; - ts = &s->ts; - } - } - - return (newest); -} - -/* - * Figure out the client. Try the given client name first, then the current - * client. - */ -struct client * -cmd_find_client(unused struct cmd_ctx *ctx, const char *cname) -{ - struct client *c; - - if (cname != NULL) { - if ((c = cmd_lookup_client(cname)) == NULL) - ctx->error(ctx, "client not found: %s", cname); - return (c); - } - - if (ctx->curclient != NULL) - return (ctx->curclient); - - ctx->error(ctx, "must specify a client"); - return (NULL); -} - -/* - * Attempt to establish session. This looks first at the given arguments, - * if any, then sees if there is a session in the context, then finally tries - * the session data passed up from the client $TMUX variable. - */ -struct session * -cmd_find_session(struct cmd_ctx *ctx, const char *cname, const char *sname) -{ - struct session *s, *newest = NULL; - struct client *c; struct msg_command_data *data = ctx->msgdata; - u_int i; struct timespec *ts; - - if (cname != NULL) { - if ((c = cmd_lookup_client(cname)) == NULL) { - ctx->error(ctx, "client not found: %s", cname); - return (NULL); - } - if (c->session == NULL) - ctx->error(ctx, "client has no session: %s", cname); - return (c->session); - } - - if (sname != NULL) { - if ((s = cmd_lookup_session(sname)) == NULL) - ctx->error(ctx, "session not found: %s", sname); - return (s); - } + struct session *s, *newest = NULL; + u_int i; if (ctx->cursession != NULL) return (ctx->cursession); @@ -343,7 +259,7 @@ cmd_find_session(struct cmd_ctx *ctx, const char *cname, const char *sname) } return (s); } - + ts = NULL; for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { s = ARRAY_ITEM(&sessions, i); @@ -352,26 +268,60 @@ cmd_find_session(struct cmd_ctx *ctx, const char *cname, const char *sname) ts = &s->ts; } } - if (newest == NULL) - ctx->error(ctx, "no sessions found"); return (newest); } -struct winlink * -cmd_find_window(struct cmd_ctx *ctx, - const char *cname, const char *sname, int idx, struct session **sp) +struct client * +cmd_find_client(struct cmd_ctx *ctx, const char *arg) { - struct session *s; - struct winlink *wl; + struct client *c; + + if ((c = arg_parse_client(arg)) == NULL) + c = ctx->curclient; + if (c == NULL) + ctx->error(ctx, "client not found: %s", arg); + return (c); +} - if ((s = cmd_find_session(ctx, cname, sname)) == NULL) +struct session * +cmd_find_session(struct cmd_ctx *ctx, const char *arg) +{ + struct session *s; + + if ((s = arg_parse_session(arg)) == NULL) + s = ctx->cursession; + if (s == NULL) + s = cmd_current_session(ctx); + if (s == NULL) + ctx->error(ctx, "session not found: %s", arg); + return (s); +} + +struct winlink * +cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp) +{ + struct session *s; + struct winlink *wl; + int idx; + + wl = NULL; + if (arg_parse_window(arg, &s, &idx) != 0) { + ctx->error(ctx, "bad window: %s", arg); return (NULL); + } + if (s == NULL) + s = ctx->cursession; + if (s == NULL) + s = cmd_current_session(ctx); + if (s != NULL) { + if (idx == -1) + wl = s->curw; + else + wl = winlink_find_by_index(&s->windows, idx); + } if (sp != NULL) *sp = s; - - if (idx == -1) - return (s->curw); - if ((wl = winlink_find_by_index(&s->windows, idx)) == NULL) - ctx->error(ctx, "no window %d", idx); + if (wl == NULL) + ctx->error(ctx, "window not found: %s:%d", s->name, idx); return (wl); } diff --git a/tmux.1 b/tmux.1 index 0a443b5f..4669ba3a 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $Id: tmux.1,v 1.28 2008-06-05 15:55:59 nicm Exp $ +.\" $Id: tmux.1,v 1.29 2008-06-05 21:25:00 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -185,8 +185,9 @@ and keys or .Xr vi 1 style -.Ql j , -.Ql k , +.Ql j +and +.Ql k keys may be used to scroll the output up and down. The .Ql q @@ -212,8 +213,14 @@ In addition, .Ql ^A and .Ql ^E -move to the start and end of the line; the space key begins a selection; and the -enter key or +(or the +.Xr vi 1 +style +.Ql 0 +and +.Ql $ +keys) move to the start and end of the line; the space key begins a selection; +and the enter key or .Ql ^W copies the selection to the paste buffer and exits copy mode. .Pp @@ -387,7 +394,7 @@ The .Ev TERM environment variable must be set to .Dq screen -for all program running +for all programs running .Em inside .Nm . New windows will automatically have diff --git a/tmux.h b/tmux.h index e96e46ed..1d3eb913 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.132 2008-06-05 16:35:32 nicm Exp $ */ +/* $Id: tmux.h,v 1.133 2008-06-05 21:25:00 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -685,31 +685,32 @@ struct cmd_entry { #define CMD_STARTSERVER 0x1 #define CMD_CANTNEST 0x2 +#define CMD_KFLAG 0x4 +#define CMD_DFLAG 0x8 +#define CMD_ONEARG 0x10 int flags; + void (*init)(struct cmd *, int); int (*parse)(struct cmd *, int, char **, char **); void (*exec)(struct cmd *, struct cmd_ctx *); void (*send)(struct cmd *, struct buffer *); void (*recv)(struct cmd *, struct buffer *); void (*free)(struct cmd *); - void (*init)(struct cmd *, int); void (*print)(struct cmd *, char *, size_t); }; /* Generic command data. */ -struct cmd_clientonly_data { - char *cname; +struct cmd_target_data { + int flags; + char *target; + char *arg; }; -struct cmd_sessiononly_data { - char *cname; - char *sname; -}; - -struct cmd_windowonly_data { - char *cname; - char *sname; - int idx; +struct cmd_srcdst_data { + int flags; + char *src; + char *dst; + char *arg; }; /* Key binding. */ @@ -781,6 +782,11 @@ void tty_vwrite_window(void *, int, va_list); void tty_write_session(void *, int, ...); void tty_vwrite_session(void *, int, va_list); +/* arg.c */ +struct client *arg_parse_client(const char *); +struct session *arg_parse_session(const char *); +int arg_parse_window(const char *, struct session **, int *); + /* cmd.c */ struct cmd *cmd_parse(int, char **, char **); void cmd_exec(struct cmd *, struct cmd_ctx *); @@ -789,10 +795,11 @@ struct cmd *cmd_recv(struct buffer *); void cmd_free(struct cmd *); void cmd_send_string(struct buffer *, const char *); char *cmd_recv_string(struct buffer *); +struct session *cmd_current_session(struct cmd_ctx *); struct client *cmd_find_client(struct cmd_ctx *, const char *); -struct session *cmd_find_session(struct cmd_ctx *, const char *, const char *); -struct winlink *cmd_find_window(struct cmd_ctx *, - const char *, const char *, int, struct session **); +struct session *cmd_find_session(struct cmd_ctx *, const char *); +struct winlink *cmd_find_window( + struct cmd_ctx *, const char *, struct session **); extern const struct cmd_entry cmd_attach_session_entry; extern const struct cmd_entry cmd_bind_key_entry; extern const struct cmd_entry cmd_copy_mode_entry; @@ -828,31 +835,26 @@ extern const struct cmd_entry cmd_unbind_key_entry; extern const struct cmd_entry cmd_unlink_window_entry; /* cmd-generic.c */ -#define CMD_CLIENTONLY_USAGE "[-c client-tty]" -int cmd_clientonly_parse(struct cmd *, int, char **, char **); -void cmd_clientonly_exec(struct cmd *, struct cmd_ctx *); -void cmd_clientonly_send(struct cmd *, struct buffer *); -void cmd_clientonly_recv(struct cmd *, struct buffer *); -void cmd_clientonly_free(struct cmd *); -struct client *cmd_clientonly_get(struct cmd *, struct cmd_ctx *); -void cmd_clientonly_print(struct cmd *, char *, size_t); -#define CMD_SESSIONONLY_USAGE "[-c client-tty|-s session-name]" -int cmd_sessiononly_parse(struct cmd *, int, char **, char **); -void cmd_sessiononly_exec(struct cmd *, struct cmd_ctx *); -void cmd_sessiononly_send(struct cmd *, struct buffer *); -void cmd_sessiononly_recv(struct cmd *, struct buffer *); -void cmd_sessiononly_free(struct cmd *); -struct session *cmd_sessiononly_get(struct cmd *, struct cmd_ctx *); -void cmd_sessiononly_print(struct cmd *, char *, size_t); -#define CMD_WINDOWONLY_USAGE "[-c client-tty|-s session-name] [-i index]" -int cmd_windowonly_parse(struct cmd *, int, char **, char **); -void cmd_windowonly_exec(struct cmd *, struct cmd_ctx *); -void cmd_windowonly_send(struct cmd *, struct buffer *); -void cmd_windowonly_recv(struct cmd *, struct buffer *); -void cmd_windowonly_free(struct cmd *); -struct winlink *cmd_windowonly_get( - struct cmd *, struct cmd_ctx *, struct session **); -void cmd_windowonly_print(struct cmd *, char *, size_t); +#define CMD_TARGET_WINDOW_USAGE "[-t target-window]" +#define CMD_TARGET_SESSION_USAGE "[-t target-session]" +#define CMD_TARGET_CLIENT_USAGE "[-t target-client]" +void cmd_target_init(struct cmd *, int); +int cmd_target_parse(struct cmd *, int, char **, char **); +void cmd_target_exec(struct cmd *, struct cmd_ctx *); +void cmd_target_send(struct cmd *, struct buffer *); +void cmd_target_recv(struct cmd *, struct buffer *); +void cmd_target_free(struct cmd *); +void cmd_target_print(struct cmd *, char *, size_t); +#define CMD_SRCDST_WINDOW_USAGE "[-s src-window] [-t dst-window]" +#define CMD_SRCDST_SESSION_USAGE "[-s src-session] [-t dst-session]" +#define CMD_SRCDST_CLIENT_USAGE "[-s src-client] [-t dst-client]" +void cmd_srcdst_init(struct cmd *, int); +int cmd_srcdst_parse(struct cmd *, int, char **, char **); +void cmd_srcdst_exec(struct cmd *, struct cmd_ctx *); +void cmd_srcdst_send(struct cmd *, struct buffer *); +void cmd_srcdst_recv(struct cmd *, struct buffer *); +void cmd_srcdst_free(struct cmd *); +void cmd_srcdst_print(struct cmd *, char *, size_t); /* client.c */ int client_init(const char *, struct client_ctx *, int);