summaryrefslogtreecommitdiffstats
authornicm <nicm>2008-06-05 21:24:59 (GMT)
committer nicm <nicm>2008-06-05 21:24:59 (GMT)
commit0684cda274f56065d58bc672b7aca08a6931c642 (patch) (side-by-side diff)
treec2c4e58b122b6685d0363daacc3802ae484006eb
parent8ec72d5b7f72d1559d31388c92ed624420527ebb (diff)
downloadtmux-old-0684cda274f56065d58bc672b7aca08a6931c642.zip
tmux-old-0684cda274f56065d58bc672b7aca08a6931c642.tar.gz
tmux-old-0684cda274f56065d58bc672b7aca08a6931c642.tar.bz2
Big reorganisation of command-line syntax.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--CHANGES21
-rw-r--r--GNUmakefile2
-rw-r--r--Makefile2
-rw-r--r--TODO8
-rw-r--r--arg.c192
-rw-r--r--cmd-attach-session.c134
-rw-r--r--cmd-bind-key.c4
-rw-r--r--cmd-copy-mode.c17
-rw-r--r--cmd-detach-client.c19
-rw-r--r--cmd-generic.c332
-rw-r--r--cmd-has-session.c19
-rw-r--r--cmd-kill-server.c2
-rw-r--r--cmd-kill-session.c23
-rw-r--r--cmd-kill-window.c27
-rw-r--r--cmd-last-window.c21
-rw-r--r--cmd-link-window.c260
-rw-r--r--cmd-list-clients.c2
-rw-r--r--cmd-list-keys.c4
-rw-r--r--cmd-list-sessions.c2
-rw-r--r--cmd-list-windows.c17
-rw-r--r--cmd-new-session.c44
-rw-r--r--cmd-new-window.c79
-rw-r--r--cmd-next-window.c19
-rw-r--r--cmd-paste-buffer.c19
-rw-r--r--cmd-previous-window.c19
-rw-r--r--cmd-refresh-client.c21
-rw-r--r--cmd-rename-session.c125
-rw-r--r--cmd-rename-window.c155
-rw-r--r--cmd-scroll-mode.c19
-rw-r--r--cmd-select-window.c33
-rw-r--r--cmd-send-keys.c52
-rw-r--r--cmd-send-prefix.c21
-rw-r--r--cmd-set-option.c41
-rw-r--r--cmd-set-window-option.c58
-rw-r--r--cmd-start-server.c2
-rw-r--r--cmd-swap-window.c215
-rw-r--r--cmd-switch-client.c41
-rw-r--r--cmd-unbind-key.c4
-rw-r--r--cmd-unlink-window.c27
-rw-r--r--cmd.c152
-rw-r--r--tmux.117
-rw-r--r--tmux.h82
42 files changed, 871 insertions, 1482 deletions
diff --git a/CHANGES b/CHANGES
index 79fff07..74ccf36 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.
diff --git a/GNUmakefile b/GNUmakefile
index f0ccacc..b2025dc 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -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 a750fd7..5aff34d 100644
--- a/Makefile
+++ b/Makefile
@@ -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 c5effd8..d3122df 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 0000000..582b94b
--- a/dev/null
+++ b/arg.c
@@ -0,0 +1,192 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2008 Nicholas Marriott <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <fnmatch.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 42516b5..7827039 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -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 a933542..b8890e4 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -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 c5e49c8..270836b 100644
--- a/cmd-copy-mode.c
+++ b/cmd-copy-mode.c
@@ -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 b1330b6..d99dff1 100644
--- a/cmd-detach-client.c
+++ b/cmd-detach-client.c
@@ -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 06f257a..5957915 100644
--- a/cmd-generic.c
+++ b/cmd-generic.c
@@ -23,114 +23,43 @@
#include "tmux.h"
-int
-cmd_clientonly_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_clientonly_data *data;
- int opt;
-
- 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)
+cmd_target_init(struct cmd *self, unused int key)
{
- 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;
+ struct cmd_target_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;
-
- self->data = data = xmalloc(sizeof *data);
- data->cname = NULL;
- data->sname = NULL;
+ struct cmd_target_data *data;
+ int opt;
- while ((opt = getopt(argc, argv, "c:s:")) != EOF) {
+ self->entry->init(self, 0);
+ data = self->data;
+
+ 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);
+ 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 't':
+ if (data->target == NULL)
+ data->target = xstrdup(optarg);
break;
default:
goto usage;
@@ -138,9 +67,15 @@ cmd_sessiononly_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:
@@ -151,95 +86,99 @@ usage:
}
void
-cmd_sessiononly_send(struct cmd *self, struct buffer *b)
+cmd_target_send(struct cmd *self, struct buffer *b)
{
- struct cmd_sessiononly_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_sessiononly_recv(struct cmd *self, struct buffer *b)
+cmd_target_recv(struct cmd *self, struct buffer *b)
{
- struct cmd_sessiononly_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_sessiononly_free(struct cmd *self)
+cmd_target_free(struct cmd *self)
{
- struct cmd_sessiononly_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 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)
+cmd_target_print(struct cmd *self, char *buf, size_t len)
{
- struct cmd_sessiononly_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->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);
}
-int
-cmd_windowonly_parse(struct cmd *self, int argc, char **argv, char **cause)
+void
+cmd_srcdst_init(struct cmd *self, unused int key)
{
- struct cmd_windowonly_data *data;
- int opt;
- const char *errstr;
+ struct cmd_srcdst_data *data;
self->data = data = xmalloc(sizeof *data);
- data->cname = NULL;
- data->sname = NULL;
- data->idx = -1;
+ 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, "c:i:s:")) != EOF) {
+ while ((opt = getopt(argc, argv, "dks: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;
+ case 'd':
+ if (self->entry->flags & CMD_DFLAG) {
+ data->flags |= CMD_DFLAG;
+ break;
}
- break;
+ goto usage;
+ case 'k':
+ if (self->entry->flags & CMD_KFLAG) {
+ data->flags |= CMD_KFLAG;
+ break;
+ }
+ goto usage;
case 's':
- if (data->cname != NULL)
- goto usage;
- if (data->sname == NULL)
- data->sname = xstrdup(optarg);
+ if (data->src == NULL)
+ data->src = xstrdup(optarg);
+ break;
+ case 't':
+ if (data->dst == NULL)
+ data->dst = xstrdup(optarg);
break;
default:
goto usage;
@@ -247,79 +186,78 @@ 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_srcdst_send(struct cmd *self, struct buffer *b)
{
- struct cmd_windowonly_data *data = self->data;
+ struct cmd_srcdst_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->src);
+ cmd_send_string(b, data->dst);
+ cmd_send_string(b, data->arg);
}
void
-cmd_windowonly_recv(struct cmd *self, struct buffer *b)
+cmd_srcdst_recv(struct cmd *self, struct buffer *b)
{
- struct cmd_windowonly_data *data;
+ struct cmd_srcdst_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->src = cmd_recv_string(b);
+ data->dst = cmd_recv_string(b);
+ data->arg = cmd_recv_string(b);
}
void
-cmd_windowonly_free(struct cmd *self)
+cmd_srcdst_free(struct cmd *self)
{
- struct cmd_windowonly_data *data = self->data;
-
- if (data->cname != NULL)
- xfree(data->cname);
- if (data->sname != NULL)
- xfree(data->sname);
+ 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);
}
-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_srcdst_print(struct cmd *self, char *buf, size_t len)
{
- struct cmd_windowonly_data *data = self->data;
- size_t off = 0;
+ 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->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->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 b53825f..3727d78 100644
--- a/cmd-has-session.c
+++ b/cmd-has-session.c
@@ -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 2ec4762..82daa12 100644
--- a/cmd-kill-server.c
+++ b/cmd-kill-server.c
@@ -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 a45d5c3..f0e52d9 100644
--- a/cmd-kill-session.c
+++ b/cmd-kill-session.c
@@ -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 023fd2e..a48dbf6 100644
--- a/cmd-kill-window.c
+++ b/cmd-kill-window.c
@@ -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 10062cc..5297164 100644
--- a/cmd-last-window.c
+++ b/cmd-last-window.c
@@ -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 baacdbf..c93759f 100644
--- a/cmd-link-window.c
+++ b/cmd-link-window.c
@@ -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;
-
- if (data == NULL)
- return;
+ struct cmd_srcdst_data *data = self->data;
+ struct session *s;
+ struct winlink *wl_src, *wl_dst;
+ int idx;
- if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL)
+ if ((wl_src = cmd_find_window(ctx, data->src, NULL)) == NULL)
return;
- if ((src = session_find(data->srcname)) == NULL) {
- ctx->error(ctx, "session not found: %s", data->srcname);
+ if (arg_parse_window(data->dst, &s, &idx) != 0) {
+ ctx->error(ctx, "bad window: %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 (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->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 (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 (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 05b6018..84bbcd2 100644
--- a/cmd-list-clients.c
+++ b/cmd-list-clients.c
@@ -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 be0176d..3b91be1 100644
--- a/cmd-list-keys.c
+++ b/cmd-list-keys.c
@@ -31,12 +31,12 @@ const struct cmd_entry cmd_list_keys_entry = {
"",
0,
NULL,
- cmd_list_keys_exec,
- NULL,
NULL,
+ cmd_list_keys_exec,
NULL,
NULL,
NULL,
+ NULL
};
void
diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c
index c1d9f01..5152ecf 100644
--- a/cmd-list-sessions.c
+++ b/cmd-list-sessions.c
@@ -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 3d861cc..f1cb1ed 100644
--- a/cmd-list-windows.c
+++ b/cmd-list-windows.c
@@ -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 54ce084..c8755da 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -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 e501bc3..6c9a8ab 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -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 6eb3516..592a6bc 100644
--- a/cmd-next-window.c
+++ b/cmd-next-window.c
@@ -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 18959f3..29310d7 100644
--- a/cmd-paste-buffer.c
+++ b/cmd-paste-buffer.c
@@ -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 6f0a1dd..a867549 100644
--- a/cmd-previous-window.c
+++ b/cmd-previous-window.c
@@ -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 4c4a105..56ee2e4 100644
--- a/cmd-refresh-client.c
+++ b/cmd-refresh-client.c
@@ -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 45aacf9..f7dfd01 100644
--- a/cmd-rename-session.c
+++ b/cmd-rename-session.c
@@ -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;
-
- if (data == NULL)
- return;
+ struct cmd_target_data *data = self->data;
+ struct session *s;
- 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 2237692..801c501 100644
--- a/cmd-rename-window.c
+++ b/cmd-rename-window.c
@@ -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;
-
- if (data == NULL)
- return;
+ struct cmd_target_data *data = self->data;
+ struct session *s;
+ struct winlink *wl;
- 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 d1f0af3..cec382e 100644
--- a/cmd-scroll-mode.c
+++ b/cmd-scroll-mode.c
@@ -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 64d0f21..58334a5 100644
--- a/cmd-select-window.c
+++ b/cmd-select-window.c
@@ -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;
+
+ cmd_target_init(self, key);
+ data = self->data;
- self->data = data = xmalloc(sizeof *data);
- data->cname = NULL;
- data->sname = NULL;
- data->idx = arg - '0';
+ 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 13d80d3..ca66c41 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -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 9e295d1..d369ce9 100644
--- a/cmd-send-prefix.c
+++ b/cmd-send-prefix.c
@@ -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 573a628..ff808c9 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -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 f3b3082..dd735f6 100644
--- a/cmd-set-window-option.c
+++ b/cmd-set-window-option.c
@@ -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 503643d..b29adaf 100644
--- a/cmd-start-server.c
+++ b/cmd-start-server.c
@@ -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 03b98b5..7c4e300 100644
--- a/cmd-swap-window.c
+++ b/cmd-swap-window.c
@@ -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 ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL)
- return;
-
- if ((src = session_find(data->srcname)) == NULL) {
- ctx->error(ctx, "session not found: %s", data->srcname);
+ if ((wl_dst = cmd_find_window(ctx, data->dst, &dst)) == NULL)
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;
+ w = wl_dst->window;
+ wl_dst->window = wl_src->window;
+ wl_src->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 84d3b22..74443b2 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -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 e23a5b5..59bc8f9 100644
--- a/cmd-unbind-key.c
+++ b/cmd-unbind-key.c
@@ -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 2e7029d..dcb845c 100644
--- a/cmd-unlink-window.c
+++ b/cmd-unlink-window.c
@@ -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 a58792c..cfad9f2 100644
--- a/cmd.c
+++ b/cmd.c
@@ -19,8 +19,8 @@
#include <sys/types.h>
#include <sys/time.h>
-#include <fnmatch.h>
#include <getopt.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -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)
-{
- 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)
+cmd_current_session(struct cmd_ctx *ctx)
{
- 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 client *
+cmd_find_client(struct cmd_ctx *ctx, const char *arg)
+{
+ 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);
+}
+
+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 *cname, const char *sname, int idx, struct session **sp)
+cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
{
- struct session *s;
- struct winlink *wl;
+ struct session *s;
+ struct winlink *wl;
+ int idx;
- if ((s = cmd_find_session(ctx, cname, sname)) == NULL)
+ 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 9ee2247..e1e3bd2 100644
--- a/tmux.1
+++ b/tmux.1
@@ -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 c0c75d3..606d031 100644
--- a/tmux.h
+++ b/tmux.h
@@ -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);