From 743956edf898dceff67af785b7bda87cdbd3fdab Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 3 Jun 2008 16:55:09 +0000 Subject: [PATCH] Allow -c anywhere -s was allowed. --- CHANGES | 5 +- cmd-attach-session.c | 25 ++++++-- cmd-generic.c | 73 +++++++++++++--------- cmd-link-window.c | 25 ++++++-- cmd-new-window.c | 34 +++++++--- cmd-rename-session.c | 25 ++++++-- cmd-rename-window.c | 25 ++++++-- cmd-select-window.c | 25 ++++++-- cmd-send-keys.c | 44 ++++++++++--- cmd-send-prefix.c | 18 +++--- cmd-swap-window.c | 25 ++++++-- cmd.c | 143 +++++++++++++++++++++++++++++-------------- tmux.h | 10 +-- 13 files changed, 339 insertions(+), 138 deletions(-) diff --git a/CHANGES b/CHANGES index 621f9e45..be14b9c0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ 03 June 2008 +* Because a client has a session attached, any command needing a session can + take a client and use its session. So, anything that used to accept -s now + accepts -c as well. * -s to specify session name now supports fnmatch(3) wildcards; if multiple sessions are found, or if no -s is specified, the most newly created is used. * If no command is specified, assume new-session. As a byproduct, clean up @@ -376,4 +379,4 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.101 2008-06-03 05:47:09 nicm Exp $ +$Id: CHANGES,v 1.102 2008-06-03 16:55:09 nicm Exp $ diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 04b6c349..3a456a24 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-attach-session.c,v 1.14 2008-06-03 05:35:50 nicm Exp $ */ +/* $Id: cmd-attach-session.c,v 1.15 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -33,13 +33,14 @@ void cmd_attach_session_recv(void **, struct buffer *); void cmd_attach_session_free(void *); struct cmd_attach_session_data { + char *cname; char *sname; int flag_detach; }; const struct cmd_entry cmd_attach_session_entry = { "attach-session", "attach", - "[-d] [-s session-name]", + "[-d] [-c client-tty|-s session-name]", CMD_CANTNEST, cmd_attach_session_parse, cmd_attach_session_exec, @@ -57,16 +58,26 @@ cmd_attach_session_parse( int opt; *ptr = data = xmalloc(sizeof *data); + data->cname = NULL; data->sname = NULL; data->flag_detach = 0; - while ((opt = getopt(argc, argv, "ds:")) != EOF) { + 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': - data->sname = xstrdup(optarg); + if (data->cname != NULL) + goto usage; + if (data->sname == NULL) + data->sname = xstrdup(optarg); break; default: goto usage; @@ -96,7 +107,7 @@ cmd_attach_session_exec(void *ptr, struct cmd_ctx *ctx) if (ctx->flags & CMD_KEY) return; - if ((s = cmd_find_session(ctx, data->sname)) == NULL) + if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) return; if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) { @@ -125,6 +136,7 @@ cmd_attach_session_send(void *ptr, struct buffer *b) struct cmd_attach_session_data *data = ptr; buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->cname); cmd_send_string(b, data->sname); } @@ -135,6 +147,7 @@ cmd_attach_session_recv(void **ptr, struct buffer *b) *ptr = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); + data->cname = cmd_recv_string(b); data->sname = cmd_recv_string(b); } @@ -143,6 +156,8 @@ cmd_attach_session_free(void *ptr) { struct cmd_attach_session_data *data = ptr; + if (data->cname != NULL) + xfree(data->cname); if (data->sname != NULL) xfree(data->sname); xfree(data); diff --git a/cmd-generic.c b/cmd-generic.c index 070bbd0d..7152fd7c 100644 --- a/cmd-generic.c +++ b/cmd-generic.c @@ -1,4 +1,4 @@ -/* $Id: cmd-generic.c,v 1.3 2008-06-02 22:09:49 nicm Exp $ */ +/* $Id: cmd-generic.c,v 1.4 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -28,10 +28,12 @@ struct cmd_clientonly_data { }; struct cmd_sessiononly_data { + char *cname; char *sname; }; struct cmd_windowonly_data { + char *cname; char *sname; int idx; }; @@ -49,7 +51,8 @@ cmd_clientonly_parse( while ((opt = getopt(argc, argv, "c:")) != EOF) { switch (opt) { case 'c': - data->cname = xstrdup(optarg); + if (data->cname == NULL) + data->cname = xstrdup(optarg); break; default: goto usage; @@ -116,12 +119,22 @@ cmd_sessiononly_parse( int opt; *ptr = data = xmalloc(sizeof *data); + data->cname = NULL; data->sname = NULL; - while ((opt = getopt(argc, argv, "s:")) != EOF) { + 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': - data->sname = xstrdup(optarg); + if (data->cname != NULL) + goto usage; + if (data->sname == NULL) + data->sname = xstrdup(optarg); break; default: goto usage; @@ -147,6 +160,7 @@ cmd_sessiononly_send(void *ptr, struct buffer *b) struct cmd_sessiononly_data *data = ptr; buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->cname); cmd_send_string(b, data->sname); } @@ -157,6 +171,7 @@ cmd_sessiononly_recv(void **ptr, struct buffer *b) *ptr = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); + data->cname = cmd_recv_string(b); data->sname = cmd_recv_string(b); } @@ -165,6 +180,8 @@ cmd_sessiononly_free(void *ptr) { struct cmd_sessiononly_data *data = ptr; + if (data->cname != NULL) + xfree(data->cname); if (data->sname != NULL) xfree(data->sname); xfree(data); @@ -176,8 +193,8 @@ cmd_sessiononly_get(void *ptr, struct cmd_ctx *ctx) struct cmd_sessiononly_data *data = ptr; if (data != NULL) - return (cmd_find_session(ctx, data->sname)); - return (cmd_find_session(ctx, NULL)); + return (cmd_find_session(ctx, data->cname, data->sname)); + return (cmd_find_session(ctx, NULL, NULL)); } int @@ -189,11 +206,18 @@ cmd_windowonly_parse( const char *errstr; *ptr = data = xmalloc(sizeof *data); + data->cname = NULL; data->sname = NULL; data->idx = -1; - while ((opt = getopt(argc, argv, "i:s:")) != EOF) { + 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) { @@ -202,7 +226,10 @@ cmd_windowonly_parse( } break; case 's': - data->sname = xstrdup(optarg); + if (data->cname != NULL) + goto usage; + if (data->sname == NULL) + data->sname = xstrdup(optarg); break; default: goto usage; @@ -229,6 +256,7 @@ cmd_windowonly_send(void *ptr, struct buffer *b) struct cmd_windowonly_data *data = ptr; buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->cname); cmd_send_string(b, data->sname); } @@ -239,6 +267,7 @@ cmd_windowonly_recv(void **ptr, struct buffer *b) *ptr = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); + data->cname = cmd_recv_string(b); data->sname = cmd_recv_string(b); } @@ -247,6 +276,8 @@ cmd_windowonly_free(void *ptr) { struct cmd_windowonly_data *data = ptr; + if (data->cname != NULL) + xfree(data->cname); if (data->sname != NULL) xfree(data->sname); xfree(data); @@ -256,28 +287,12 @@ struct winlink * cmd_windowonly_get(void *ptr, struct cmd_ctx *ctx, struct session **sp) { struct cmd_windowonly_data *data = ptr; - struct session *s; struct winlink *wl; - int idx; - if (data != NULL) { - s = cmd_find_session(ctx, data->sname); - idx = data->idx; - } else { - s = cmd_find_session(ctx, NULL); - idx = -1; + if (data == NULL) { + wl = cmd_find_window(ctx, NULL, NULL, -1, sp); + return (wl); } - if (s == NULL) - return (NULL); - - 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); - return (NULL); - } - return (wl); + + return (cmd_find_window(ctx, data->cname, data->sname, data->idx, sp)); } diff --git a/cmd-link-window.c b/cmd-link-window.c index b2ef4486..f31c824d 100644 --- a/cmd-link-window.c +++ b/cmd-link-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-link-window.c,v 1.14 2008-06-03 05:35:51 nicm Exp $ */ +/* $Id: cmd-link-window.c,v 1.15 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -34,6 +34,7 @@ void cmd_link_window_recv(void **, struct buffer *); void cmd_link_window_free(void *); struct cmd_link_window_data { + char *cname; char *sname; int flag_detached; int flag_kill; @@ -44,7 +45,7 @@ struct cmd_link_window_data { const struct cmd_entry cmd_link_window_entry = { "link-window", "linkw", - "[-dk] [-i index] [-s session-name] session-name index", + "[-dk] [-c client-tty|-s session-name] [-i index] session-name index", 0, cmd_link_window_parse, cmd_link_window_exec, @@ -63,6 +64,7 @@ cmd_link_window_parse( int opt; *ptr = data = xmalloc(sizeof *data); + data->cname = NULL; data->sname = NULL; data->flag_detached = 0; data->flag_kill = 0; @@ -70,8 +72,14 @@ cmd_link_window_parse( data->srcidx = -1; data->srcname = NULL; - while ((opt = getopt(argc, argv, "di:ks:")) != EOF) { + 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; @@ -86,7 +94,10 @@ cmd_link_window_parse( data->flag_kill = 1; break; case 's': - data->sname = xstrdup(optarg); + if (data->cname != NULL) + goto usage; + if (data->sname == NULL) + data->sname = xstrdup(optarg); break; default: goto usage; @@ -124,7 +135,7 @@ cmd_link_window_exec(void *ptr, struct cmd_ctx *ctx) if (data == NULL) return; - if ((s = cmd_find_session(ctx, data->sname)) == NULL) + if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) return; if ((src = session_find(data->srcname)) == NULL) { @@ -196,6 +207,7 @@ cmd_link_window_send(void *ptr, struct buffer *b) struct cmd_link_window_data *data = ptr; buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->cname); cmd_send_string(b, data->sname); cmd_send_string(b, data->srcname); } @@ -207,6 +219,7 @@ cmd_link_window_recv(void **ptr, struct buffer *b) *ptr = 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); } @@ -216,6 +229,8 @@ cmd_link_window_free(void *ptr) { struct cmd_link_window_data *data = ptr; + if (data->cname != NULL) + xfree(data->cname); if (data->sname != NULL) xfree(data->sname); if (data->srcname != NULL) diff --git a/cmd-new-window.c b/cmd-new-window.c index cb13fd66..8f09da0a 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-new-window.c,v 1.18 2008-06-03 05:35:51 nicm Exp $ */ +/* $Id: cmd-new-window.c,v 1.19 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -35,6 +35,7 @@ void cmd_new_window_free(void *); void cmd_new_window_init(void **, int); struct cmd_new_window_data { + char *cname; char *sname; char *name; char *cmd; @@ -44,7 +45,7 @@ struct cmd_new_window_data { const struct cmd_entry cmd_new_window_entry = { "new-window", "neww", - "[-d] [-i index] [-n name] [-s session-name] [command]", + "[-d] [-c client-tty|-s session-name] [-i index] [-n name] [command]", 0, cmd_new_window_parse, cmd_new_window_exec, @@ -60,6 +61,7 @@ cmd_new_window_init(void **ptr, unused int arg) struct cmd_new_window_data *data; *ptr = data = xmalloc(sizeof *data); + data->cname = NULL; data->sname = NULL; data->idx = -1; data->flag_detached = 0; @@ -78,8 +80,17 @@ cmd_new_window_parse( self->entry->init(ptr, 0); data = *ptr; - while ((opt = getopt(argc, argv, "di:n:s:")) != EOF) { + while ((opt = getopt(argc, argv, "c:di:n: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) { @@ -88,13 +99,14 @@ cmd_new_window_parse( } break; case 'n': - data->name = xstrdup(optarg); - break; - case 'd': - data->flag_detached = 1; + if (data->name == NULL) + data->name = xstrdup(optarg); break; case 's': - data->sname = xstrdup(optarg); + if (data->cname != NULL) + goto usage; + if (data->sname == NULL) + data->sname = xstrdup(optarg); break; default: goto usage; @@ -130,7 +142,7 @@ cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx) if (cmd == NULL) cmd = default_command; - if ((s = cmd_find_session(ctx, data->sname)) == NULL) + if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) return; if (data->idx < 0) @@ -156,6 +168,7 @@ cmd_new_window_send(void *ptr, struct buffer *b) struct cmd_new_window_data *data = ptr; buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->cname); cmd_send_string(b, data->sname); cmd_send_string(b, data->name); cmd_send_string(b, data->cmd); @@ -168,6 +181,7 @@ cmd_new_window_recv(void **ptr, struct buffer *b) *ptr = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); + data->cname = cmd_recv_string(b); data->sname = cmd_recv_string(b); data->name = cmd_recv_string(b); data->cmd = cmd_recv_string(b); @@ -178,6 +192,8 @@ cmd_new_window_free(void *ptr) { struct cmd_new_window_data *data = ptr; + if (data->cname != NULL) + xfree(data->cname); if (data->sname != NULL) xfree(data->sname); if (data->name != NULL) diff --git a/cmd-rename-session.c b/cmd-rename-session.c index ed64c98f..48c91193 100644 --- a/cmd-rename-session.c +++ b/cmd-rename-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-rename-session.c,v 1.7 2008-06-03 05:35:51 nicm Exp $ */ +/* $Id: cmd-rename-session.c,v 1.8 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -34,13 +34,14 @@ void cmd_rename_session_recv(void **, struct buffer *); void cmd_rename_session_free(void *); struct cmd_rename_session_data { + char *cname; char *sname; char *newname; }; const struct cmd_entry cmd_rename_session_entry = { "rename-session", "rename", - "[-s session-name] new-name", + "[-c client-tty|-s session-name] new-name", 0, cmd_rename_session_parse, cmd_rename_session_exec, @@ -58,13 +59,23 @@ cmd_rename_session_parse( int opt; *ptr = data = xmalloc(sizeof *data); + data->cname = NULL; data->sname = NULL; data->newname = NULL; - while ((opt = getopt(argc, argv, "s:")) != EOF) { + 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': - data->sname = xstrdup(optarg); + if (data->cname != NULL) + goto usage; + if (data->sname == NULL) + data->sname = xstrdup(optarg); break; default: goto usage; @@ -95,7 +106,7 @@ cmd_rename_session_exec(void *ptr, struct cmd_ctx *ctx) if (data == NULL) return; - if ((s = cmd_find_session(ctx, data->sname)) == NULL) + if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) return; xfree(s->name); @@ -111,6 +122,7 @@ cmd_rename_session_send(void *ptr, struct buffer *b) struct cmd_rename_session_data *data = ptr; buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->cname); cmd_send_string(b, data->sname); cmd_send_string(b, data->newname); } @@ -122,6 +134,7 @@ cmd_rename_session_recv(void **ptr, struct buffer *b) *ptr = 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); } @@ -131,6 +144,8 @@ cmd_rename_session_free(void *ptr) { struct cmd_rename_session_data *data = ptr; + if (data->cname != NULL) + xfree(data->cname); if (data->sname != NULL) xfree(data->sname); if (data->newname != NULL) diff --git a/cmd-rename-window.c b/cmd-rename-window.c index ef6657b9..93af5be5 100644 --- a/cmd-rename-window.c +++ b/cmd-rename-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-rename-window.c,v 1.17 2008-06-03 05:35:51 nicm Exp $ */ +/* $Id: cmd-rename-window.c,v 1.18 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -34,6 +34,7 @@ void cmd_rename_window_recv(void **, struct buffer *); void cmd_rename_window_free(void *); struct cmd_rename_window_data { + char *cname; char *sname; int idx; char *newname; @@ -41,7 +42,7 @@ struct cmd_rename_window_data { const struct cmd_entry cmd_rename_window_entry = { "rename-window", "renamew", - "[-i index] [-s session-name] new-name", + "[-c client-tty|-s session-name] [-i index] new-name", 0, cmd_rename_window_parse, cmd_rename_window_exec, @@ -60,12 +61,19 @@ cmd_rename_window_parse( int opt; *ptr = data = xmalloc(sizeof *data); + data->cname = NULL; data->sname = NULL; data->idx = -1; data->newname = NULL; - while ((opt = getopt(argc, argv, "i:s:")) != EOF) { + 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) { @@ -74,7 +82,10 @@ cmd_rename_window_parse( } break; case 's': - data->sname = xstrdup(optarg); + if (data->cname != NULL) + goto usage; + if (data->sname == NULL) + data->sname = xstrdup(optarg); break; default: goto usage; @@ -107,7 +118,7 @@ cmd_rename_window_exec(void *ptr, struct cmd_ctx *ctx) if (data == NULL) return; - if ((s = cmd_find_session(ctx, data->sname)) == NULL) + if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) return; if (data->idx == -1) @@ -131,6 +142,7 @@ cmd_rename_window_send(void *ptr, struct buffer *b) struct cmd_rename_window_data *data = ptr; buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->cname); cmd_send_string(b, data->sname); cmd_send_string(b, data->newname); } @@ -142,6 +154,7 @@ cmd_rename_window_recv(void **ptr, struct buffer *b) *ptr = 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); } @@ -151,6 +164,8 @@ cmd_rename_window_free(void *ptr) { struct cmd_rename_window_data *data = ptr; + if (data->cname != NULL) + xfree(data->cname); if (data->sname != NULL) xfree(data->sname); if (data->newname != NULL) diff --git a/cmd-select-window.c b/cmd-select-window.c index a5a4e341..d1bf235f 100644 --- a/cmd-select-window.c +++ b/cmd-select-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-select-window.c,v 1.14 2008-06-03 05:35:51 nicm Exp $ */ +/* $Id: cmd-select-window.c,v 1.15 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -35,13 +35,14 @@ void cmd_select_window_free(void *); void cmd_select_window_init(void **, int); struct cmd_select_window_data { + char *cname; char *sname; int idx; }; const struct cmd_entry cmd_select_window_entry = { "select-window", "selectw", - "[-s session-name] index", + "[-c client-tty|-s session-name] index", 0, cmd_select_window_parse, cmd_select_window_exec, @@ -57,6 +58,7 @@ cmd_select_window_init(void **ptr, int arg) struct cmd_select_window_data *data; *ptr = data = xmalloc(sizeof *data); + data->cname = NULL; data->sname = NULL; data->idx = arg - '0'; } @@ -72,10 +74,19 @@ cmd_select_window_parse( *ptr = data = xmalloc(sizeof *data); data->sname = NULL; - while ((opt = getopt(argc, argv, "s:")) != EOF) { + 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': - data->sname = xstrdup(optarg); + if (data->cname != NULL) + goto usage; + if (data->sname == NULL) + data->sname = xstrdup(optarg); break; default: goto usage; @@ -111,7 +122,7 @@ cmd_select_window_exec(void *ptr, struct cmd_ctx *ctx) if (data == NULL) return; - if ((s = cmd_find_session(ctx, data->sname)) == NULL) + if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) return; switch (session_select(s, data->idx)) { @@ -135,6 +146,7 @@ cmd_select_window_send(void *ptr, struct buffer *b) struct cmd_select_window_data *data = ptr; buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->cname); cmd_send_string(b, data->sname); } @@ -145,6 +157,7 @@ cmd_select_window_recv(void **ptr, struct buffer *b) *ptr = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); + data->cname = cmd_recv_string(b); data->sname = cmd_recv_string(b); } @@ -153,6 +166,8 @@ cmd_select_window_free(void *ptr) { struct cmd_select_window_data *data = ptr; + if (data->cname != NULL) + xfree(data->cname); if (data->sname != NULL) xfree(data->sname); xfree(data); diff --git a/cmd-send-keys.c b/cmd-send-keys.c index 22f48323..6e9f7f43 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -1,4 +1,4 @@ -/* $Id: cmd-send-keys.c,v 1.6 2008-06-03 05:35:51 nicm Exp $ */ +/* $Id: cmd-send-keys.c,v 1.7 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -35,12 +35,15 @@ void cmd_send_keys_free(void *); struct cmd_send_keys_data { char *cname; + char *sname; + int idx; u_int nkeys; int *keys; }; const struct cmd_entry cmd_send_keys_entry = { - "send-keys", "send", "[-c client-tty] key ...", + "send-keys", "send", + "[-c client-tty|-s session-name] [-i index] key ...", 0, cmd_send_keys_parse, cmd_send_keys_exec, @@ -56,17 +59,36 @@ cmd_send_keys_parse( { struct cmd_send_keys_data *data; int opt, key; + const char *errstr; char *s; *ptr = data = xmalloc(sizeof *data); data->cname = NULL; + data->sname = NULL; + data->idx = -1; data->nkeys = 0; data->keys = NULL; - while ((opt = getopt(argc, argv, "c:")) != EOF) { + while ((opt = getopt(argc, argv, "c:i:s:")) != EOF) { switch (opt) { case 'c': - data->cname = xstrdup(optarg); + 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; @@ -98,6 +120,7 @@ cmd_send_keys_parse( usage: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); +error: cmd_send_keys_free(data); return (-1); } @@ -106,17 +129,18 @@ void cmd_send_keys_exec(void *ptr, struct cmd_ctx *ctx) { struct cmd_send_keys_data *data = ptr; - struct client *c; + struct winlink *wl; u_int i; if (data == NULL) return; - if ((c = cmd_find_client(ctx, data->cname)) == NULL) + wl = cmd_find_window(ctx, data->cname, data->sname, data->idx, NULL); + if (wl == NULL) return; for (i = 0; i < data->nkeys; i++) - window_key(c->session->curw->window, data->keys[i]); + window_key(wl->window, data->keys[i]); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); @@ -129,6 +153,7 @@ cmd_send_keys_send(void *ptr, struct buffer *b) buffer_write(b, data, sizeof *data); cmd_send_string(b, data->cname); + cmd_send_string(b, data->sname); buffer_write(b, data->keys, data->nkeys * sizeof *data->keys); } @@ -140,6 +165,7 @@ cmd_send_keys_recv(void **ptr, struct buffer *b) *ptr = data = xmalloc(sizeof *data); buffer_read(b, data, sizeof *data); data->cname = cmd_recv_string(b); + data->sname = cmd_recv_string(b); data->keys = xcalloc(data->nkeys, sizeof *data->keys); buffer_read(b, data->keys, data->nkeys * sizeof *data->keys); } @@ -151,7 +177,7 @@ cmd_send_keys_free(void *ptr) if (data->cname != NULL) xfree(data->cname); - if (data->keys != NULL) - xfree(data->keys); + if (data->sname != NULL) + xfree(data->sname); xfree(data); } diff --git a/cmd-send-prefix.c b/cmd-send-prefix.c index 4a67a434..87a8ba69 100644 --- a/cmd-send-prefix.c +++ b/cmd-send-prefix.c @@ -1,4 +1,4 @@ -/* $Id: cmd-send-prefix.c,v 1.10 2008-06-03 05:35:51 nicm Exp $ */ +/* $Id: cmd-send-prefix.c,v 1.11 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,25 +28,25 @@ void cmd_send_prefix_exec(void *, struct cmd_ctx *); const struct cmd_entry cmd_send_prefix_entry = { "send-prefix", NULL, - CMD_CLIENTONLY_USAGE, + CMD_WINDOWONLY_USAGE, 0, - cmd_clientonly_parse, + cmd_windowonly_parse, cmd_send_prefix_exec, - cmd_clientonly_send, - cmd_clientonly_recv, - cmd_clientonly_free, + cmd_windowonly_send, + cmd_windowonly_recv, + cmd_windowonly_free, NULL }; void cmd_send_prefix_exec(void *ptr, struct cmd_ctx *ctx) { - struct client *c; + struct winlink *wl; - if ((c = cmd_clientonly_get(ptr, ctx)) == NULL) + if ((wl = cmd_windowonly_get(ptr, ctx, NULL)) == NULL) return; - window_key(c->session->curw->window, prefix_key); + window_key(wl->window, prefix_key); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); diff --git a/cmd-swap-window.c b/cmd-swap-window.c index d76344c4..968bbc92 100644 --- a/cmd-swap-window.c +++ b/cmd-swap-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-swap-window.c,v 1.7 2008-06-03 05:35:51 nicm Exp $ */ +/* $Id: cmd-swap-window.c,v 1.8 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -34,6 +34,7 @@ void cmd_swap_window_recv(void **, struct buffer *); void cmd_swap_window_free(void *); struct cmd_swap_window_data { + char *cname; char *sname; int dstidx; int srcidx; @@ -43,7 +44,7 @@ struct cmd_swap_window_data { const struct cmd_entry cmd_swap_window_entry = { "swap-window", "swapw", - "[-i index] [-s session-name] session-name index", + "[-c client-tty|-s session-name] [-i index] session-name index", 0, cmd_swap_window_parse, cmd_swap_window_exec, @@ -62,14 +63,21 @@ cmd_swap_window_parse( int opt; *ptr = data = xmalloc(sizeof *data); + data->cname = NULL; data->sname = NULL; data->flag_detached = 0; data->dstidx = -1; data->srcidx = -1; data->srcname = NULL; - while ((opt = getopt(argc, argv, "di:s:")) != EOF) { + 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; @@ -81,7 +89,10 @@ cmd_swap_window_parse( } break; case 's': - data->sname = xstrdup(optarg); + if (data->cname != NULL) + goto usage; + if (data->sname == NULL) + data->sname = xstrdup(optarg); break; default: goto usage; @@ -120,7 +131,7 @@ cmd_swap_window_exec(void *ptr, struct cmd_ctx *ctx) if (data == NULL) return; - if ((s = cmd_find_session(ctx, data->sname)) == NULL) + if ((s = cmd_find_session(ctx, data->cname, data->sname)) == NULL) return; if ((src = session_find(data->srcname)) == NULL) { @@ -175,6 +186,7 @@ cmd_swap_window_send(void *ptr, struct buffer *b) struct cmd_swap_window_data *data = ptr; buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->cname); cmd_send_string(b, data->sname); cmd_send_string(b, data->srcname); } @@ -186,6 +198,7 @@ cmd_swap_window_recv(void **ptr, struct buffer *b) *ptr = 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); } @@ -195,6 +208,8 @@ cmd_swap_window_free(void *ptr) { struct cmd_swap_window_data *data = ptr; + if (data->cname != NULL) + xfree(data->cname); if (data->sname != NULL) xfree(data->sname); if (data->srcname != NULL) diff --git a/cmd.c b/cmd.c index 3b179b85..2fb90069 100644 --- a/cmd.c +++ b/cmd.c @@ -1,4 +1,4 @@ -/* $Id: cmd.c,v 1.38 2008-06-03 05:47:09 nicm Exp $ */ +/* $Id: cmd.c,v 1.39 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -61,6 +61,9 @@ 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) { @@ -231,34 +234,92 @@ 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; + time_t tim; + u_int i; + + tim = 0; + for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { + s = ARRAY_ITEM(&sessions, i); + if (s == NULL || fnmatch(sname, s->name, 0) != 0) + continue; + + if (s->tim > tim) { + newest = s; + tim = s->tim; + } + } + + return (newest); +} + +/* + * Figure out the client. Try the given client name first, then the current + * client. + */ +struct client * +cmd_find_client(unused struct cmd_ctx *ctx, const char *cname) +{ + struct client *c; + + if (cname != NULL) { + if ((c = cmd_lookup_client(cname)) == NULL) + ctx->error(ctx, "client not found: %s", cname); + return (c); + } + + if (ctx->curclient != NULL) + return (ctx->curclient); + + ctx->error(ctx, "must specify a client"); + return (NULL); +} + /* - * Attempt to establish session. This looks first at the command-line argument + * 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 *arg) +cmd_find_session(struct cmd_ctx *ctx, const char *cname, const char *sname) { - struct session *s, *sp; + struct session *s, *newest = NULL; + struct client *c; struct msg_command_data *data = ctx->msgdata; u_int i; time_t tim; - if (arg != NULL) { - s = NULL; - tim = 0; - for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { - sp = ARRAY_ITEM(&sessions, i); - if (sp != NULL && - fnmatch(arg, sp->name, 0) == 0 && sp->tim > tim) { - s = sp; - tim = s->tim; - } - } - if (s == NULL) { - ctx->error(ctx, "no sessions matching: %s", arg); + 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); } @@ -281,46 +342,34 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg) return (s); } - s = NULL; tim = 0; for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { - sp = ARRAY_ITEM(&sessions, i); - if (sp != NULL && sp->tim > tim) { - s = ARRAY_ITEM(&sessions, i); + s = ARRAY_ITEM(&sessions, i); + if (s != NULL && s->tim > tim) { + newest = ARRAY_ITEM(&sessions, i); tim = s->tim; } } - if (s == NULL) { + if (newest == NULL) ctx->error(ctx, "no sessions found"); - return (NULL); - } - return (s); + return (newest); } -/* - * Figure out the client. Try the current client (if any) first, then try to - * figure it out from the argument. - */ -struct client * -cmd_find_client(unused struct cmd_ctx *ctx, const char *arg) +struct winlink * +cmd_find_window(struct cmd_ctx *ctx, + const char *cname, const char *sname, int idx, struct session **sp) { - struct client *c; - u_int i; + struct session *s; + struct winlink *wl; - if (ctx->curclient != NULL) - return (ctx->curclient); - - if (arg == NULL) { - ctx->error(ctx, "must specify a client"); + if ((s = cmd_find_session(ctx, cname, sname)) == NULL) return (NULL); - } + if (sp != NULL) + *sp = s; - for (i = 0; i < ARRAY_LENGTH(&clients); i++) { - c = ARRAY_ITEM(&clients, i); - if (c != NULL && strcmp(arg, c->tty.path) == 0) - return (c); - } - - ctx->error(ctx, "client not found: %s", arg); - return (NULL); + if (idx == -1) + return (s->curw); + if ((wl = winlink_find_by_index(&s->windows, idx)) == NULL) + ctx->error(ctx, "no window %d", idx); + return (wl); } diff --git a/tmux.h b/tmux.h index d51f5d5c..9d3a22f7 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.122 2008-06-03 05:35:51 nicm Exp $ */ +/* $Id: tmux.h,v 1.123 2008-06-03 16:55:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -731,8 +731,10 @@ 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_find_session(struct cmd_ctx *, const char *); 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 **); 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; @@ -774,14 +776,14 @@ void cmd_clientonly_send(void *, struct buffer *); void cmd_clientonly_recv(void **, struct buffer *); void cmd_clientonly_free(void *); struct client *cmd_clientonly_get(void *, struct cmd_ctx *); -#define CMD_SESSIONONLY_USAGE "[-s session-name]" +#define CMD_SESSIONONLY_USAGE "[-c client-tty|-s session-name]" int cmd_sessiononly_parse(struct cmd *, void **, int, char **, char **); void cmd_sessiononly_exec(void *, struct cmd_ctx *); void cmd_sessiononly_send(void *, struct buffer *); void cmd_sessiononly_recv(void **, struct buffer *); void cmd_sessiononly_free(void *); struct session *cmd_sessiononly_get(void *, struct cmd_ctx *); -#define CMD_WINDOWONLY_USAGE "[-i index] [-s session-name]" +#define CMD_WINDOWONLY_USAGE "[-c client-tty|-s session-name] [-i index]" int cmd_windowonly_parse(struct cmd *, void **, int, char **, char **); void cmd_windowonly_exec(void *, struct cmd_ctx *); void cmd_windowonly_send(void *, struct buffer *);