xref: /openbsd-src/usr.bin/tmux/cmd-select-layout.c (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /* $OpenBSD: cmd-select-layout.c,v 1.16 2012/07/11 07:10:15 nicm Exp $ */
2 
3 /*
4  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 
21 #include "tmux.h"
22 
23 /*
24  * Switch window to selected layout.
25  */
26 
27 void		 cmd_select_layout_key_binding(struct cmd *, int);
28 enum cmd_retval	 cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
29 
30 const struct cmd_entry cmd_select_layout_entry = {
31 	"select-layout", "selectl",
32 	"nprut:", 0, 1,
33 	"[-npUu] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
34 	0,
35 	cmd_select_layout_key_binding,
36 	NULL,
37 	cmd_select_layout_exec
38 };
39 
40 const struct cmd_entry cmd_next_layout_entry = {
41 	"next-layout", "nextl",
42 	"t:", 0, 0,
43 	CMD_TARGET_WINDOW_USAGE,
44 	0,
45 	NULL,
46 	NULL,
47 	cmd_select_layout_exec
48 };
49 
50 const struct cmd_entry cmd_previous_layout_entry = {
51 	"previous-layout", "prevl",
52 	"t:", 0, 0,
53 	CMD_TARGET_WINDOW_USAGE,
54 	0,
55 	NULL,
56 	NULL,
57 	cmd_select_layout_exec
58 };
59 
60 void
61 cmd_select_layout_key_binding(struct cmd *self, int key)
62 {
63 	switch (key) {
64 	case '1' | KEYC_ESCAPE:
65 		self->args = args_create(1, "even-horizontal");
66 		break;
67 	case '2' | KEYC_ESCAPE:
68 		self->args = args_create(1, "even-vertical");
69 		break;
70 	case '3' | KEYC_ESCAPE:
71 		self->args = args_create(1, "main-horizontal");
72 		break;
73 	case '4' | KEYC_ESCAPE:
74 		self->args = args_create(1, "main-vertical");
75 		break;
76 	case '5' | KEYC_ESCAPE:
77 		self->args = args_create(1, "tiled");
78 		break;
79 	case 'u':
80 		self->args = args_create(0);
81 		args_set(self->args, 'u', NULL);
82 		break;
83 	case 'U':
84 		self->args = args_create(0);
85 		args_set(self->args, 'U', NULL);
86 		break;
87 	default:
88 		self->args = args_create(0);
89 		break;
90 	}
91 }
92 
93 enum cmd_retval
94 cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
95 {
96 	struct args	*args = self->args;
97 	struct winlink	*wl;
98 	struct window	*w;
99 	const char	*layoutname;
100 	int		 next, previous, layout;
101 
102 	if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
103 		return (CMD_RETURN_ERROR);
104 	w = wl->window;
105 
106 	next = self->entry == &cmd_next_layout_entry;
107 	if (args_has(self->args, 'n'))
108 		next = 1;
109 	previous = self->entry == &cmd_previous_layout_entry;
110 	if (args_has(self->args, 'p'))
111 		previous = 1;
112 
113 	layout_list_add(w);
114 	if (args_has(self->args, 'U')) {
115 		if ((layoutname = layout_list_redo(w)) == NULL) {
116 			ctx->info(ctx, "no more layout history");
117 			return (CMD_RETURN_ERROR);
118 		}
119 		goto set_layout;
120 	} else if (args_has(self->args, 'u')) {
121 		if ((layoutname = layout_list_undo(w)) == NULL) {
122 			ctx->info(ctx, "no more layout history");
123 			return (CMD_RETURN_ERROR);
124 		}
125 		goto set_layout;
126 	}
127 
128 	if (next || previous) {
129 		if (next)
130 			layout = layout_set_next(wl->window);
131 		else
132 			layout = layout_set_previous(wl->window);
133 		server_redraw_window(wl->window);
134 		ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
135 		return (CMD_RETURN_NORMAL);
136 	}
137 
138 	if (args->argc == 0)
139 		layout = wl->window->lastlayout;
140 	else
141 		layout = layout_set_lookup(args->argv[0]);
142 	if (layout != -1) {
143 		layout = layout_set_select(wl->window, layout);
144 		server_redraw_window(wl->window);
145 		ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
146 		return (CMD_RETURN_NORMAL);
147 	}
148 
149 	if (args->argc == 0)
150 		return (CMD_RETURN_NORMAL);
151 	layoutname = args->argv[0];
152 
153 set_layout:
154 	if (layout_parse(wl->window, layoutname) == -1) {
155 		ctx->error(ctx, "can't set layout: %s", layoutname);
156 		return (CMD_RETURN_ERROR);
157 	}
158 	server_redraw_window(wl->window);
159 	ctx->info(ctx, "arranging in: %s", layoutname);
160 	return (CMD_RETURN_NORMAL);
161 }
162