xref: /openbsd/usr.bin/tmux/cmd-move-window.c (revision a51dead1)
1*a51dead1Snicm /* $OpenBSD: cmd-move-window.c,v 1.34 2021/08/21 10:22:39 nicm Exp $ */
2311827fbSnicm 
3311827fbSnicm /*
498ca8272Snicm  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
5311827fbSnicm  *
6311827fbSnicm  * Permission to use, copy, modify, and distribute this software for any
7311827fbSnicm  * purpose with or without fee is hereby granted, provided that the above
8311827fbSnicm  * copyright notice and this permission notice appear in all copies.
9311827fbSnicm  *
10311827fbSnicm  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11311827fbSnicm  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12311827fbSnicm  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13311827fbSnicm  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14311827fbSnicm  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15311827fbSnicm  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16311827fbSnicm  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17311827fbSnicm  */
18311827fbSnicm 
19311827fbSnicm #include <sys/types.h>
20311827fbSnicm 
21311827fbSnicm #include <stdlib.h>
22311827fbSnicm 
23311827fbSnicm #include "tmux.h"
24311827fbSnicm 
25311827fbSnicm /*
26311827fbSnicm  * Move a window.
27311827fbSnicm  */
28311827fbSnicm 
2968e0a7f2Snicm static enum cmd_retval	cmd_move_window_exec(struct cmd *, struct cmdq_item *);
30311827fbSnicm 
31311827fbSnicm const struct cmd_entry cmd_move_window_entry = {
32c057646bSnicm 	.name = "move-window",
33c057646bSnicm 	.alias = "movew",
34c057646bSnicm 
35*a51dead1Snicm 	.args = { "abdkrs:t:", 0, 0, NULL },
364f91c935Snicm 	.usage = "[-abdkr] " CMD_SRCDST_WINDOW_USAGE,
37c057646bSnicm 
38bf0d297eSnicm 	.source = { 's', CMD_FIND_WINDOW, 0 },
39bf0d297eSnicm 	/* -t is special */
408d471e80Snicm 
418d471e80Snicm 	.flags = 0,
42c057646bSnicm 	.exec = cmd_move_window_exec
43311827fbSnicm };
44311827fbSnicm 
45abb3f5acSnicm const struct cmd_entry cmd_link_window_entry = {
46c057646bSnicm 	.name = "link-window",
47c057646bSnicm 	.alias = "linkw",
48c057646bSnicm 
49*a51dead1Snicm 	.args = { "abdks:t:", 0, 0, NULL },
504f91c935Snicm 	.usage = "[-abdk] " CMD_SRCDST_WINDOW_USAGE,
51c057646bSnicm 
52bf0d297eSnicm 	.source = { 's', CMD_FIND_WINDOW, 0 },
53bf0d297eSnicm 	/* -t is special */
548d471e80Snicm 
558d471e80Snicm 	.flags = 0,
56c057646bSnicm 	.exec = cmd_move_window_exec
57abb3f5acSnicm };
58abb3f5acSnicm 
59dc1f0f5fSnicm static enum cmd_retval
cmd_move_window_exec(struct cmd * self,struct cmdq_item * item)6068e0a7f2Snicm cmd_move_window_exec(struct cmd *self, struct cmdq_item *item)
61311827fbSnicm {
6290d7ba38Snicm 	struct args		*args = cmd_get_args(self);
63040343aeSnicm 	struct cmd_find_state	*source = cmdq_get_source(item);
64040343aeSnicm 	struct cmd_find_state	 target;
65bf0d297eSnicm 	const char		*tflag = args_get(args, 't');
66b196a1a7Snicm 	struct session		*src = source->s;
67bf0d297eSnicm 	struct session		*dst;
68b196a1a7Snicm 	struct winlink		*wl = source->wl;
69311827fbSnicm 	char			*cause;
704f91c935Snicm 	int			 idx, kflag, dflag, sflag, before;
713447b427Snicm 
72559d6335Snicm 	if (args_has(args, 'r')) {
73040343aeSnicm 		if (cmd_find_target(&target, item, tflag, CMD_FIND_SESSION,
74040343aeSnicm 		    CMD_FIND_QUIET) != 0)
75bf0d297eSnicm 			return (CMD_RETURN_ERROR);
76bf0d297eSnicm 
77040343aeSnicm 		session_renumber_windows(target.s);
7853c15224Snicm 		recalculate_sizes();
79040343aeSnicm 		server_status_session(target.s);
8053c15224Snicm 
81a224d0d3Snicm 		return (CMD_RETURN_NORMAL);
8253c15224Snicm 	}
83040343aeSnicm 	if (cmd_find_target(&target, item, tflag, CMD_FIND_WINDOW,
84bf0d297eSnicm 	    CMD_FIND_WINDOW_INDEX) != 0)
85bf0d297eSnicm 		return (CMD_RETURN_ERROR);
86040343aeSnicm 	dst = target.s;
87040343aeSnicm 	idx = target.idx;
8853c15224Snicm 
8990d7ba38Snicm 	kflag = args_has(args, 'k');
9090d7ba38Snicm 	dflag = args_has(args, 'd');
9190d7ba38Snicm 	sflag = args_has(args, 's');
92fe1fa7a5Snicm 
934f91c935Snicm 	before = args_has(args, 'b');
944f91c935Snicm 	if (args_has(args, 'a') || before) {
95b196a1a7Snicm 		if (target.wl != NULL)
964f91c935Snicm 			idx = winlink_shuffle_up(dst, target.wl, before);
97b196a1a7Snicm 		else
984f91c935Snicm 			idx = winlink_shuffle_up(dst, dst->curw, before);
99b196a1a7Snicm 		if (idx == -1)
100fe1fa7a5Snicm 			return (CMD_RETURN_ERROR);
101fe1fa7a5Snicm 	}
102fe1fa7a5Snicm 
103040343aeSnicm 	if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
104b196a1a7Snicm 		cmdq_error(item, "%s", cause);
1057d053cf9Snicm 		free(cause);
106a224d0d3Snicm 		return (CMD_RETURN_ERROR);
107311827fbSnicm 	}
10890d7ba38Snicm 	if (cmd_get_entry(self) == &cmd_move_window_entry)
10921ced74dSnicm 		server_unlink_window(src, wl);
1106df8b7e5Snicm 
1116df8b7e5Snicm 	/*
1126df8b7e5Snicm 	 * Renumber the winlinks in the src session only, the destination
1136df8b7e5Snicm 	 * session already has the correct winlink id to us, either
1146df8b7e5Snicm 	 * automatically or specified by -s.
1156df8b7e5Snicm 	 */
116d89252e5Snicm 	if (!sflag && options_get_number(src->options, "renumber-windows"))
1176df8b7e5Snicm 		session_renumber_windows(src);
1186df8b7e5Snicm 
119311827fbSnicm 	recalculate_sizes();
120311827fbSnicm 
121a224d0d3Snicm 	return (CMD_RETURN_NORMAL);
122311827fbSnicm }
123