diff --git a/CHANGES b/CHANGES index 7f32b2a4..c908c444 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,6 @@ 26 October 2007 +* (nicm) unlink-window command. * (nicm) link-window command to link an existing window into another session (or another index in the same session). Syntax: @@ -175,5 +176,5 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.53 2007-10-26 13:03:59 nicm Exp $ +$Id: CHANGES,v 1.54 2007-10-26 16:57:32 nicm Exp $ diff --git a/Makefile b/Makefile index 1ef4da8b..f908b128 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.32 2007-10-26 13:03:59 nicm Exp $ +# $Id: Makefile,v 1.33 2007-10-26 16:57:32 nicm Exp $ .SUFFIXES: .c .o .y .h .PHONY: clean @@ -24,7 +24,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ cmd-set-option.c cmd-rename-window.c cmd-select-window.c \ cmd-list-windows.c cmd-attach-session.c cmd-send-prefix.c \ cmd-refresh-session.c cmd-kill-window.c cmd-list-clients.c \ - cmd-has-session.c cmd-link-window.c + cmd-has-session.c cmd-link-window.c cmd-unlink-window.c YACC= yacc -d diff --git a/cmd-kill-window.c b/cmd-kill-window.c index dce7f768..401d6faa 100644 --- a/cmd-kill-window.c +++ b/cmd-kill-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-kill-window.c,v 1.2 2007-10-26 12:29:07 nicm Exp $ */ +/* $Id: cmd-kill-window.c,v 1.3 2007-10-26 16:57:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -60,7 +60,7 @@ cmd_kill_window_parse(void **ptr, int argc, char **argv, char **cause) while ((opt = getopt(argc, argv, "i:")) != EOF) { switch (opt) { case 'i': - data->idx = strtonum(optarg, 0, UINT_MAX, &errstr); + data->idx = strtonum(optarg, 0, INT_MAX, &errstr); if (errstr != NULL) { xasprintf(cause, "index %s", errstr); goto error; @@ -106,7 +106,7 @@ cmd_kill_window_exec(void *ptr, struct cmd_ctx *ctx) return; } - destroyed = session_detach(s, wl); + destroyed = session_detach(s, wl); for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); if (c == NULL || c->session != s) diff --git a/cmd-link-window.c b/cmd-link-window.c index 0fb0b7ea..ee8ddd83 100644 --- a/cmd-link-window.c +++ b/cmd-link-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-link-window.c,v 1.2 2007-10-26 13:35:39 nicm Exp $ */ +/* $Id: cmd-link-window.c,v 1.3 2007-10-26 16:57:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -66,7 +66,7 @@ cmd_link_window_parse(void **ptr, int argc, char **argv, char **cause) while ((opt = getopt(argc, argv, "di:")) != EOF) { switch (opt) { case 'i': - data->dstidx = strtonum(optarg, 0, UINT_MAX, &errstr); + data->dstidx = strtonum(optarg, 0, INT_MAX, &errstr); if (errstr != NULL) { xasprintf(cause, "index %s", errstr); goto error; @@ -85,7 +85,7 @@ cmd_link_window_parse(void **ptr, int argc, char **argv, char **cause) goto usage; data->srcname = xstrdup(argv[0]); - data->srcidx = strtonum(argv[1], 0, UINT_MAX, &errstr); + data->srcidx = strtonum(argv[1], 0, INT_MAX, &errstr); if (errstr != NULL) { xasprintf(cause, "index %s", errstr); goto error; diff --git a/cmd-new-window.c b/cmd-new-window.c index ea81734d..094d877e 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-new-window.c,v 1.10 2007-10-26 12:29:07 nicm Exp $ */ +/* $Id: cmd-new-window.c,v 1.11 2007-10-26 16:57:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -66,7 +66,7 @@ cmd_new_window_parse(void **ptr, int argc, char **argv, char **cause) while ((opt = getopt(argc, argv, "di:n:")) != EOF) { switch (opt) { case 'i': - data->idx = strtonum(optarg, 0, UINT_MAX, &errstr); + data->idx = strtonum(optarg, 0, INT_MAX, &errstr); if (errstr != NULL) { xasprintf(cause, "index %s", errstr); goto error; diff --git a/cmd-rename-window.c b/cmd-rename-window.c index 1816d082..6a949cc0 100644 --- a/cmd-rename-window.c +++ b/cmd-rename-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-rename-window.c,v 1.8 2007-10-26 12:29:07 nicm Exp $ */ +/* $Id: cmd-rename-window.c,v 1.9 2007-10-26 16:57:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -62,7 +62,7 @@ cmd_rename_window_parse(void **ptr, int argc, char **argv, char **cause) while ((opt = getopt(argc, argv, "i:")) != EOF) { switch (opt) { case 'i': - data->idx = strtonum(optarg, 0, UINT_MAX, &errstr); + data->idx = strtonum(optarg, 0, INT_MAX, &errstr); if (errstr != NULL) { xasprintf(cause, "index %s", errstr); goto error; diff --git a/cmd-select-window.c b/cmd-select-window.c index 9b906ea4..8685dd30 100644 --- a/cmd-select-window.c +++ b/cmd-select-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-select-window.c,v 1.5 2007-10-26 12:29:07 nicm Exp $ */ +/* $Id: cmd-select-window.c,v 1.6 2007-10-26 16:57:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -34,7 +34,7 @@ void cmd_select_window_recv(void **, struct buffer *); void cmd_select_window_free(void *); struct cmd_select_window_data { - u_int idx; + int idx; }; const struct cmd_entry cmd_select_window_entry = { @@ -81,7 +81,7 @@ cmd_select_window_parse(void **ptr, int argc, char **argv, char **cause) if (argc != 1) goto usage; - data->idx = strtonum(argv[0], 0, UINT_MAX, &errstr); + data->idx = strtonum(argv[0], 0, INT_MAX, &errstr); if (errstr != NULL) { xasprintf(cause, "index %s", errstr); goto error; diff --git a/cmd-unlink-window.c b/cmd-unlink-window.c new file mode 100644 index 00000000..ea3c0aa4 --- /dev/null +++ b/cmd-unlink-window.c @@ -0,0 +1,158 @@ +/* $Id: cmd-unlink-window.c,v 1.1 2007-10-26 16:57:32 nicm Exp $ */ + +/* + * Copyright (c) 2007 Nicholas Marriott + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include "tmux.h" + +/* + * Unlink a window, unless it would be destroyed by doing so (only one link). + */ + +int cmd_unlink_window_parse(void **, int, char **, char **); +void cmd_unlink_window_exec(void *, struct cmd_ctx *); +void cmd_unlink_window_send(void *, struct buffer *); +void cmd_unlink_window_recv(void **, struct buffer *); +void cmd_unlink_window_free(void *); + +struct cmd_unlink_window_data { + int idx; +}; + +const struct cmd_entry cmd_unlink_window_entry = { + "unlink-window", "unlinkw", "[-i index", + 0, + cmd_unlink_window_parse, + cmd_unlink_window_exec, + cmd_unlink_window_send, + cmd_unlink_window_recv, + cmd_unlink_window_free +}; + +int +cmd_unlink_window_parse(void **ptr, int argc, char **argv, char **cause) +{ + struct cmd_unlink_window_data *data; + const char *errstr; + int opt; + + *ptr = data = xmalloc(sizeof *data); + data->idx = -1; + + while ((opt = getopt(argc, argv, "i:")) != EOF) { + switch (opt) { + case 'i': + data->idx = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr != NULL) { + xasprintf(cause, "index %s", errstr); + goto error; + } + break; + default: + goto usage; + } + } + argc -= optind; + argv += optind; + if (argc != 0) + goto usage; + + return (0); + +usage: + usage(cause, "%s %s", + cmd_unlink_window_entry.name, cmd_unlink_window_entry.usage); + +error: + cmd_unlink_window_free(data); + return (-1); +} + +void +cmd_unlink_window_exec(void *ptr, struct cmd_ctx *ctx) +{ + struct cmd_unlink_window_data *data = ptr; + struct client *c = ctx->client; + struct session *s = ctx->session; + struct winlink *wl; + u_int i; + int destroyed; + + if (data == NULL) + return; + + if (data->idx < 0) + data->idx = -1; + if (data->idx == -1) + wl = s->curw; + else { + wl = winlink_find_by_index(&s->windows, data->idx); + if (wl == NULL) { + ctx->error(ctx, "no window %u", data->idx); + return; + } + } + + if (wl->window->references == 1) { + ctx->error(ctx, "window is only linked to one session"); + return; + } + + destroyed = session_detach(s, wl); + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (c == NULL || c->session != s) + continue; + if (destroyed) { + c->session = NULL; + server_write_client(c, MSG_EXIT, NULL, 0); + } else + server_redraw_client(c); + } + + if (!(ctx->flags & CMD_KEY)) + server_write_client(c, MSG_EXIT, NULL, 0); +} + +void +cmd_unlink_window_send(void *ptr, struct buffer *b) +{ + struct cmd_unlink_window_data *data = ptr; + + buffer_write(b, data, sizeof *data); +} + +void +cmd_unlink_window_recv(void **ptr, struct buffer *b) +{ + struct cmd_unlink_window_data *data; + + *ptr = data = xmalloc(sizeof *data); + buffer_read(b, data, sizeof *data); +} + +void +cmd_unlink_window_free(void *ptr) +{ + struct cmd_unlink_window_data *data = ptr; + + xfree(data); +} diff --git a/cmd.c b/cmd.c index b6902647..c71d52ee 100644 --- a/cmd.c +++ b/cmd.c @@ -1,4 +1,4 @@ -/* $Id: cmd.c,v 1.21 2007-10-26 13:03:59 nicm Exp $ */ +/* $Id: cmd.c,v 1.22 2007-10-26 16:57:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -45,6 +45,7 @@ const struct cmd_entry *cmd_table[] = { &cmd_send_prefix_entry, &cmd_set_option_entry, &cmd_unbind_key_entry, + &cmd_unlink_window_entry, NULL }; diff --git a/session.c b/session.c index 5f589e13..ded3959f 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $Id: session.c,v 1.26 2007-10-26 13:35:39 nicm Exp $ */ +/* $Id: session.c,v 1.27 2007-10-26 16:57:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -253,11 +253,11 @@ session_previous(struct session *s) /* Move session to specific window. */ int -session_select(struct session *s, u_int i) +session_select(struct session *s, int idx) { struct winlink *wl; - wl = winlink_find_by_index(&s->windows, i); + wl = winlink_find_by_index(&s->windows, idx); if (wl == NULL) return (-1); if (wl == s->curw) diff --git a/tmux.h b/tmux.h index 9ff5362b..327a612e 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.72 2007-10-26 13:03:59 nicm Exp $ */ +/* $Id: tmux.h,v 1.73 2007-10-26 16:57:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -558,6 +558,7 @@ extern const struct cmd_entry cmd_select_window_entry; extern const struct cmd_entry cmd_send_prefix_entry; extern const struct cmd_entry cmd_set_option_entry; extern const struct cmd_entry cmd_unbind_key_entry; +extern const struct cmd_entry cmd_unlink_window_entry; void cmd_select_window_default(void **, int); /* client.c */ @@ -706,7 +707,7 @@ int session_detach(struct session *, struct winlink *); int session_has(struct session *, struct window *); int session_next(struct session *); int session_previous(struct session *); -int session_select(struct session *, u_int); +int session_select(struct session *, int); int session_last(struct session *); /* buffer.c */