summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--cmd-attach-session.c2
-rw-r--r--cmd-join-pane.c10
-rw-r--r--cmd-kill-session.c4
-rw-r--r--cmd-new-session.c105
-rw-r--r--cmd-new-window.c107
-rw-r--r--cmd-queue.c2
-rw-r--r--cmd-respawn-pane.c61
-rw-r--r--cmd-respawn-window.c72
-rw-r--r--cmd-rotate-window.c4
-rw-r--r--cmd-select-pane.c4
-rw-r--r--cmd-split-window.c139
-rw-r--r--cmd-swap-pane.c10
-rw-r--r--cmd-switch-client.c2
-rw-r--r--layout.c15
-rw-r--r--server-fn.c4
-rw-r--r--server.c2
-rw-r--r--session.c68
-rw-r--r--tmux.h58
-rw-r--r--window-tree.c2
-rw-r--r--window.c227
21 files changed, 275 insertions, 624 deletions
diff --git a/Makefile.am b/Makefile.am
index 16c842c8..0d5a789e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -162,6 +162,7 @@ dist_tmux_SOURCES = \
session.c \
status.c \
style.c \
+ spawn.c \
tmux.c \
tmux.h \
tty-acs.c \
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index 73ff530d..bcd6d895 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -87,7 +87,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
if (wl != NULL) {
if (wp != NULL)
- window_set_active_pane(wp->window, wp);
+ window_set_active_pane(wp->window, wp, 1);
session_set_current(s, wl);
if (wp != NULL)
cmd_find_from_winlink_pane(current, wl, wp, 0);
diff --git a/cmd-join-pane.c b/cmd-join-pane.c
index 947b2499..3d798e09 100644
--- a/cmd-join-pane.c
+++ b/cmd-join-pane.c
@@ -71,7 +71,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
int size, percentage, dst_idx;
enum layout_type type;
struct layout_cell *lc;
- int not_same_window;
+ int not_same_window, flags;
if (self->entry == &cmd_join_pane_entry)
not_same_window = 1;
@@ -123,7 +123,11 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
else
size = (dst_wp->sx * percentage) / 100;
}
- lc = layout_split_pane(dst_wp, type, size, args_has(args, 'b'), 0);
+ if (args_has(args, 'b'))
+ flags = SPAWN_BEFORE;
+ else
+ flags = 0;
+ lc = layout_split_pane(dst_wp, type, size, flags);
if (lc == NULL) {
cmdq_error(item, "create pane failed: pane too small");
return (CMD_RETURN_ERROR);
@@ -144,7 +148,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
server_redraw_window(dst_w);
if (!args_has(args, 'd')) {
- window_set_active_pane(dst_w, src_wp);
+ window_set_active_pane(dst_w, src_wp, 1);
session_select(dst_s, dst_idx);
cmd_find_from_session(current, dst_s, 0);
server_redraw_session(dst_s);
diff --git a/cmd-kill-session.c b/cmd-kill-session.c
index 00ea7789..dcef8097 100644
--- a/cmd-kill-session.c
+++ b/cmd-kill-session.c
@@ -61,12 +61,12 @@ cmd_kill_session_exec(struct cmd *self, struct cmdq_item *item)
RB_FOREACH_SAFE(sloop, sessions, &sessions, stmp) {
if (sloop != s) {
server_destroy_session(sloop);
- session_destroy(sloop, __func__);
+ session_destroy(sloop, 1, __func__);
}
}
} else {
server_destroy_session(s);
- session_destroy(s, __func__);
+ session_destroy(s, 1, __func__);
}
return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-new-session.c b/cmd-new-session.c
index e1be350b..f0a353d8 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -69,20 +69,17 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
struct args *args = self->args;
struct client *c = item->client;
struct session *s, *as, *groupwith;
- struct window *w;
struct environ *env;
struct options *oo;
struct termios tio, *tiop;
struct session_group *sg;
- const char *errstr, *template, *group, *prefix;
- const char *path, *cmd, *tmp, *value;
- char **argv, *cause, *cp, *newname, *cwd = NULL;
- int detached, already_attached, idx, argc;
- int is_control = 0;
- u_int sx, sy, dsx = 80, dsy = 24;
- struct environ_entry *envent;
- struct cmd_find_state fs;
+ const char *errstr, *template, *group, *prefix, *tmp;
+ char *cause, *cwd = NULL, *cp, *newname = NULL;
+ int detached, already_attached, is_control = 0;
+ u_int sx, sy, dsx, dsy;
+ struct spawn_context sc;
enum cmd_retval retval;
+ struct cmd_find_state fs;
if (self->entry == &cmd_has_session_entry) {
/*
@@ -97,13 +94,12 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_ERROR);
}
- newname = NULL;
if (args_has(args, 's')) {
newname = format_single(item, args_get(args, 's'), c, NULL,
NULL, NULL);
if (!session_check_name(newname)) {
cmdq_error(item, "bad session name: %s", newname);
- goto error;
+ goto fail;
}
if ((as = session_find(newname)) != NULL) {
if (args_has(args, 'A')) {
@@ -114,7 +110,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
return (retval);
}
cmdq_error(item, "duplicate session: %s", newname);
- goto error;
+ goto fail;
}
}
@@ -125,7 +121,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
if (groupwith == NULL) {
if (!session_check_name(group)) {
cmdq_error(item, "bad group name: %s", group);
- goto error;
+ goto fail;
}
sg = session_group_find(group);
} else
@@ -173,7 +169,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
if (server_client_check_nested(item->client)) {
cmdq_error(item, "sessions should be nested with care, "
"unset $TMUX to force");
- return (CMD_RETURN_ERROR);
+ goto fail;
}
if (tcgetattr(c->tty.fd, &tio) != 0)
fatal("tcgetattr failed");
@@ -186,7 +182,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
if (server_client_open(c, &cause) != 0) {
cmdq_error(item, "open terminal failed: %s", cause);
free(cause);
- goto error;
+ goto fail;
}
}
@@ -200,7 +196,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
dsx = strtonum(tmp, 1, USHRT_MAX, &errstr);
if (errstr != NULL) {
cmdq_error(item, "width %s", errstr);
- goto error;
+ goto fail;
}
}
}
@@ -213,7 +209,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
dsy = strtonum(tmp, 1, USHRT_MAX, &errstr);
if (errstr != NULL) {
cmdq_error(item, "height %s", errstr);
- goto error;
+ goto fail;
}
}
}
@@ -225,8 +221,8 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
if (sy > 0 && options_get_number(global_s_options, "status"))
sy--;
} else {
- value = options_get_string(global_s_options, "default-size");
- if (sscanf(value, "%ux%u", &sx, &sy) != 2) {
+ tmp = options_get_string(global_s_options, "default-size");
+ if (sscanf(tmp, "%ux%u", &sx, &sy) != 2) {
sx = 80;
sy = 24;
}
@@ -240,59 +236,34 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
if (sy == 0)
sy = 1;
- /* Figure out the command for the new window. */
- argc = -1;
- argv = NULL;
- if (!args_has(args, 't') && args->argc != 0) {
- argc = args->argc;
- argv = args->argv;
- } else if (sg == NULL && groupwith == NULL) {
- cmd = options_get_string(global_s_options, "default-command");
- if (cmd != NULL && *cmd != '\0') {
- argc = 1;
- argv = (char **)&cmd;
- } else {
- argc = 0;
- argv = NULL;
- }
- }
-
- path = NULL;
- if (c != NULL && c->session == NULL)
- envent = environ_find(c->environ, "PATH");
- else
- envent = environ_find(global_environ, "PATH");
- if (envent != NULL)
- path = envent->value;
-
- /* Construct the environment. */
+ /* Create the new session. */
+ oo = options_create(global_s_options);
+ if (args_has(args, 'x') || args_has(args, 'y'))
+ options_set_string(oo, "default-size", 0, "%ux%u", dsx, dsy);
env = environ_create();
if (c != NULL && !args_has(args, 'E'))
environ_update(global_s_options, c->environ, env);
+ s = session_create(prefix, newname, cwd, env, oo, tiop);
- /* Set up the options. */
- oo = options_create(global_s_options);
- if (args_has(args, 'x') || args_has(args, 'y'))
- options_set_string(oo, "default-size", 0, "%ux%u", dsx, dsy);
+ /* Spawn the initial window. */
+ memset(&sc, 0, sizeof sc);
+ sc.item = item;
+ sc.s = s;
- /* Create the new session. */
- idx = -1 - options_get_number(global_s_options, "base-index");
- s = session_create(prefix, newname, argc, argv, path, cwd, env, oo,
- tiop, idx, &cause);
- environ_free(env);
- if (s == NULL) {
- cmdq_error(item, "create session failed: %s", cause);
- free(cause);
- goto error;
- }
+ sc.name = args_get(args, 'n');
+ sc.argc = args->argc;
+ sc.argv = args->argv;
- /* Set the initial window name if one given. */
- if (argc >= 0 && (tmp = args_get(args, 'n')) != NULL) {
- cp = format_single(item, tmp, c, s, NULL, NULL);
- w = s->curw->window;
- window_set_name(w, cp);
- options_set_number(w->options, "automatic-rename", 0);
- free(cp);
+ sc.idx = -1;
+ sc.cwd = args_get(args, 'c');
+
+ sc.flags = 0;
+
+ if (spawn_window(&sc, &cause) == NULL) {
+ session_destroy(s, 0, __func__);
+ cmdq_error(item, "create window failed: %s", cause);
+ free(cause);
+ goto fail;
}
/*
@@ -364,7 +335,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
free(newname);
return (CMD_RETURN_NORMAL);
-error:
+fail:
free(cwd);
free(newname);
return (CMD_RETURN_ERROR);
diff --git a/cmd-new-window.c b/cmd-new-window.c
index 5baeff65..db320f3d 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -53,87 +53,45 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
struct cmd_find_state *current = &item->shared->current;
+ struct spawn_context sc;
+ struct client *c = cmd_find_client(item, NULL, 1);
struct session *s = item->target.s;
struct winlink *wl = item->target.wl;
- struct client *c = cmd_find_client(item, NULL, 1);
int idx = item->target.idx;
- const char *cmd, *path, *template, *tmp;
- char **argv, *cause, *cp, *cwd, *name;
- int argc, detached;
- struct environ_entry *envent;
+ struct winlink *new_wl;
+ char *cause = NULL, *cp;
+ const char *template;
struct cmd_find_state fs;
- if (args_has(args, 'a') && wl != NULL) {
- if ((idx = winlink_shuffle_up(s, wl)) == -1) {
- cmdq_error(item, "no free window indexes");
- return (CMD_RETURN_ERROR);
- }
- }
- detached = args_has(args, 'd');
-
- if (args->argc == 0) {
- cmd = options_get_string(s->options, "default-command");
- if (cmd != NULL && *cmd != '\0') {
- argc = 1;
- argv = (char **)&cmd;
- } else {
- argc = 0;
- argv = NULL;
- }
- } else {
- argc = args->argc;
- argv = args->argv;
+ if (args_has(args, 'a') && (idx = winlink_shuffle_up(s, wl)) == -1) {
+ cmdq_error(item, "couldn't get a window index");
+ return (CMD_RETURN_ERROR);
}
- path = NULL;
- if (item->client != NULL && item->client->session == NULL)
- envent = environ_find(item->client->environ, "PATH");
- else
- envent = environ_find(s->environ, "PATH");
- if (envent != NULL)
- path = envent->value;
-
- if ((tmp = args_get(args, 'c')) != NULL)
- cwd = format_single(item, tmp, c, s, NULL, NULL);
- else
- cwd = xstrdup(server_client_get_cwd(item->client, s));
-
- if ((tmp = args_get(args, 'n')) != NULL)
- name = format_single(item, tmp, c, s, NULL, NULL);
- else
- name = NULL;
-
- if (idx != -1)
- wl = winlink_find_by_index(&s->windows, idx);
- if (wl != NULL && args_has(args, 'k')) {
- /*
- * Can't use session_detach as it will destroy session if this
- * makes it empty.
- */
- notify_session_window("window-unlinked", s, wl->window);
- wl->flags &= ~WINLINK_ALERTFLAGS;
- winlink_stack_remove(&s->lastw, wl);
- winlink_remove(&s->windows, wl);
-
- /* Force select/redraw if current. */
- if (wl == s->curw) {
- detached = 0;
- s->curw = NULL;
- }
- }
+ memset(&sc, 0, sizeof sc);
+ sc.item = item;
+ sc.s = s;
- if (idx == -1)
- idx = -1 - options_get_number(s->options, "base-index");
- wl = session_new(s, name, argc, argv, path, cwd, idx,
- &cause);
- if (wl == NULL) {
+ sc.name = args_get(args, 'n');
+ sc.argc = args->argc;
+ sc.argv = args->argv;
+
+ sc.idx = idx;
+ sc.cwd = args_get(args, 'c');
+
+ sc.flags = 0;
+ if (args_has(args, 'd'))
+ sc.flags |= SPAWN_DETACHED;
+ if (args_has(args, 'k'))
+ sc.flags |= SPAWN_KILL;
+
+ if ((new_wl = spawn_window(&sc, &cause)) == NULL) {
cmdq_error(item, "create window failed: %s", cause);
free(cause);
- goto error;
+ return (CMD_RETURN_ERROR);
}
- if (!detached) {
- session_select(s, wl->idx);
- cmd_find_from_winlink(current, wl, 0);
+ if (!args_has(args, 'd') || new_wl == s->curw) {
+ cmd_find_from_winlink(current, new_wl, 0);
server_redraw_session_group(s);
} else
server_status_session_group(s);
@@ -141,7 +99,7 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'P')) {
if ((template = args_get(args, 'F')) == NULL)
template = NEW_WINDOW_TEMPLATE;
- cp = format_single(item, template, c, s, wl, NULL);
+ cp = format_single(item, template, c, s, new_wl, NULL);
cmdq_print(item, "%s", cp);
free(cp);
}
@@ -149,12 +107,5 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
cmd_find_from_winlink(&fs, wl, 0);
hooks_insert(s->hooks, item, &fs, "after-new-window");
- free(name);
- free(cwd);
return (CMD_RETURN_NORMAL);
-
-error:
- free(name);
- free(cwd);
- return (CMD_RETURN_ERROR);
}
diff --git a/cmd-queue.c b/cmd-queue.c
index 97b3c1c9..03fd5f10 100644
--- a/cmd-queue.c
+++ b/cmd-queue.c
@@ -111,7 +111,7 @@ cmdq_remove(struct cmdq_item *item)
if (item->client != NULL)
server_client_unref(item->client);
- if (item->type == CMDQ_COMMAND)
+ if (item->cmdlist != NULL)
cmd_list_free(item->cmdlist);
TAILQ_REMOVE(item->queue, item, entry);
diff --git a/cmd-respawn-pane.c b/cmd-respawn-pane.c
index eb4a7e09..df234cd3 100644
--- a/cmd-respawn-pane.c
+++ b/cmd-respawn-pane.c
@@ -20,7 +20,7 @@
#include <sys/types.h>
#include <stdlib.h>
-#include <unistd.h>
+#include <string.h>
#include "tmux.h"
@@ -36,7 +36,7 @@ const struct cmd_entry cmd_respawn_pane_entry = {
.args = { "c:kt:", 0, -1 },
.usage = "[-c start-directory] [-k] " CMD_TARGET_PANE_USAGE
- " [command]",
+ " [command]",
.target = { 't', CMD_FIND_PANE, 0 },
@@ -48,53 +48,40 @@ static enum cmd_retval
cmd_respawn_pane_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
+ struct spawn_context sc;
+ struct session *s = item->target.s;
struct winlink *wl = item->target.wl;
- struct window *w = wl->window;
struct window_pane *wp = item->target.wp;
- struct client *c = cmd_find_client(item, NULL, 1);
- struct session *s = item->target.s;
- struct environ *env;
- const char *path = NULL, *cp;
- char *cause, *cwd = NULL;
- u_int idx;
- struct environ_entry *envent;
-
- if (!args_has(self->args, 'k') && wp->fd != -1) {
- if (window_pane_index(wp, &idx) != 0)
- fatalx("index not found");
- cmdq_error(item, "pane still active: %s:%d.%u",
- s->name, wl->idx, idx);
- return (CMD_RETURN_ERROR);
- }
+ struct client *c = cmd_find_client(item, NULL, 1);
+ char *cause = NULL;
+
+ memset(&sc, 0, sizeof sc);
+ sc.item = item;
+ sc.s = s;
+ sc.wl = wl;
+
+ sc.wp0 = wp;
+ sc.lc = NULL;
- window_pane_reset_mode_all(wp);
- screen_reinit(&wp->base);
- input_init(wp);
+ sc.name = NULL;
+ sc.argc = args->argc;
+ sc.argv = args->argv;
- if (item->client != NULL && item->client->session == NULL)
- envent = environ_find(item->client->environ, "PATH");
- else
- envent = environ_find(s->environ, "PATH");
- if (envent != NULL)
- path = envent->value;
+ sc.idx = -1;
+ sc.cwd = args_get(args, 'c');
- if ((cp = args_get(args, 'c')) != NULL)
- cwd = format_single(item, cp, c, s, NULL, NULL);
+ sc.flags = SPAWN_RESPAWN;
+ if (args_has(args, 'k'))
+ sc.flags |= SPAWN_KILL;
- env = environ_for_session(s, 0);
- if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, cwd, env,
- s->tio, &cause) != 0) {
+ if (spawn_pane(&sc, &cause) == NULL) {
cmdq_error(item, "respawn pane failed: %s", cause);
free(cause);
- environ_free(env);
- free(cwd);
return (CMD_RETURN_ERROR);
}
- environ_free(env);
- free(cwd);
wp->flags |= PANE_REDRAW;
- server_status_window(w);
+ server_status_window(wp->window);
return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c
index 68791990..2ccb2fde 100644
--- a/cmd-respawn-window.c
+++ b/cmd-respawn-window.c
@@ -19,7 +19,7 @@
#include <sys/types.h>
#include <stdlib.h>
-#include <unistd.h>
+#include <string.h>
#include "tmux.h"
@@ -48,64 +48,34 @@ static enum cmd_retval
cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
+ struct spawn_context sc;
struct session *s = item->target.s;
struct winlink *wl = item->target.wl;
- struct window *w = wl->window;
- struct window_pane *wp;
- struct client *c = cmd_find_client(item, NULL, 1);
- struct environ *env;
- const char *path = NULL, *cp;
- char *cause, *cwd = NULL;
- struct environ_entry *envent;
-
- if (!args_has(self->args, 'k')) {
- TAILQ_FOREACH(wp, &w->panes, entry) {
- if (wp->fd == -1)
- continue;
- cmdq_error(item, "window still active: %s:%d", s->name,
- wl->idx);
- return (CMD_RETURN_ERROR);
- }
- }
+ char *cause = NULL;
+
+ memset(&sc, 0, sizeof sc);
+ sc.item = item;
+ sc.s = s;
+ sc.wl = wl;
+
+ sc.name = NULL;
+ sc.argc = args->argc;
+ sc.argv = args->argv;
- wp = TAILQ_FIRST(&w->panes);
- TAILQ_REMOVE(&w->panes, wp, entry);
- layout_free(w);
- window_destroy_panes(w);
- TAILQ_INSERT_HEAD(&w->panes, wp, entry);
- window_pane_resize(wp, w->sx, w->sy);
-
- if (item->client != NULL && item->client->session == NULL)
- envent = environ_find(item->client->environ, "PATH");
- else
- envent = environ_find(s->environ, "PATH");
- if (envent != NULL)
- path = envent->value;
-
- if ((cp = args_get(args, 'c')) != NULL)
- cwd = format_single(item, cp, c, s, NULL, NULL);
-
- env = environ_for_session(s, 0);
- if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, cwd, env,
- s->tio, &cause) != 0) {
+ sc.idx = -1;
+ sc.cwd = args_get(args, 'c');
+
+ sc.flags = SPAWN_RESPAWN;
+ if (args_has(args, 'k'))
+ sc.flags |= SPAWN_KILL;
+
+ if (spawn_window(&sc, &cause) == NULL) {
cmdq_error(item, "respawn window failed: %s", cause);
free(cause);
- environ_free(env);
- free(cwd);
- server_destroy_pane(wp, 0);
return (CMD_RETURN_ERROR);
}
- environ_free(env);
- free(cwd);
-
- layout_init(w, wp);
- window_pane_reset_mode_all(wp);
- screen_reinit(&wp->base);
- input_init(wp);
- window_set_active_pane(w, wp);
- recalculate_sizes();
- server_redraw_window(w);
+ server_redraw_window(wl->window);
return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-rotate-window.c b/cmd-rotate-window.c
index 5a900a13..6dc0f2a8 100644
--- a/cmd-rotate-window.c
+++ b/cmd-rotate-window.c
@@ -77,7 +77,7 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item)
if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL)
wp = TAILQ_LAST(&w->panes, window_panes);
- window_set_active_pane(w, wp);
+ window_set_active_pane(w, wp, 1);
cmd_find_from_winlink_pane(current, wl, wp, 0);
server_redraw_window(w);
} else {
@@ -105,7 +105,7 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item)
if ((wp = TAILQ_NEXT(w->active, entry)) == NULL)
wp = TAILQ_FIRST(&w->panes);
- window_set_active_pane(w, wp);
+ window_set_active_pane(w, wp, 1);
cmd_find_from_winlink_pane(current, wl, wp, 0);
server_redraw_window(w);
}
diff --git a/cmd-select-pane.c b/cmd-select-pane.c
index 2873737f..af0f033b 100644
--- a/cmd-select-pane.c
+++ b/cmd-select-pane.c
@@ -112,7 +112,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
else {
server_unzoom_window(w);
window_redraw_active_switch(w, lastwp);
- if (window_set_active_pane(w, lastwp)) {
+ if (window_set_active_pane(w, lastwp, 1)) {
cmd_find_from_winlink(current, wl, 0);
cmd_select_pane_redraw(w);
}
@@ -194,7 +194,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_NORMAL);
server_unzoom_window(wp->window);
window_redraw_active_switch(w, wp);
- if (window_set_active_pane(w, wp)) {
+ if (window_set_active_pane(w, wp, 1)) {
cmd_find_from_winlink_pane(current, wl, wp, 0);
hooks_insert(s->hooks, item, current, "after-select-pane");
cmd_select_pane_redraw(w);
diff --git a/cmd-split-window.c b/cmd-split-window.c
index f5dde751..e64e9247 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -52,111 +52,87 @@ const struct cmd_entry cmd_split_window_entry = {
static enum cmd_retval
cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
{
- struct cmd_find_state *current = &item->shared->current;
struct args *args = self->args;
+ struct cmd_find_state *current = &item->shared->current;
+ struct spawn_context sc;
struct client *c = cmd_find_client(item, NULL, 1);
struct session *s = item->target.s;
struct winlink *wl = item->target.wl;
- struct window *w = wl->window;
- struct window_pane *wp = item->target.wp, *new_wp = NULL;
- struct environ *env;
- const char *cmd, *path, *shell, *template, *tmp;
- char **argv, *cause, *new_cause, *cp, *cwd;
- u_int hlimit;
- int argc, size, percentage, before;
+ struct window_pane *wp = item->target.wp, *new_wp;
enum layout_type type;
struct layout_cell *lc;
- struct environ_entry *envent;
- struct cmd_find_state fs;
-
- server_unzoom_window(w);
-
- if (args->argc == 0) {
- cmd = options_get_string(s->options, "default-command");
- if (cmd != NULL && *cmd != '\0') {
- argc = 1;
- argv = (char **)&cmd;
- } else {
- argc = 0;
- argv = NULL;
- }
- } else {
- argc = args->argc;
- argv = args->argv;
- }
-
- if ((tmp = args_get(args, 'c')) != NULL)
- cwd = format_single(item, tmp, c, s, NULL, NULL);
- else
- cwd = xstrdup(server_client_get_cwd(item->client, s));
+ struct cmd_find_state fs;
+ int size, percentage, flags;
+ const char *template;
+ char *cause, *cp;
- type = LAYOUT_TOPBOTTOM;
if (args_has(args, 'h'))
type = LAYOUT_LEFTRIGHT;
- before = args_has(args, 'b');
-
- size = -1;
+ else
+ type = LAYOUT_TOPBOTTOM;
if (args_has(args, 'l')) {
size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
if (cause != NULL) {
- xasprintf(&new_cause, "size %s", cause);
+ cmdq_error(item, "create pane failed: -l %s", cause);
free(cause);
- cause = new_cause;
- goto error;
+ return (CMD_RETURN_ERROR);
}
} else if (args_has(args, 'p')) {
percentage = args_strtonum(args, 'p', 0, INT_MAX, &cause);
if (cause != NULL) {
- xasprintf(&new_cause, "percentage %s", cause);
+ cmdq_error(item, "create pane failed: -p %s", cause);
free(cause);
- cause = new_cause;
- goto error;
+ return (CMD_RETURN_ERROR);
}
if (type == LAYOUT_TOPBOTTOM)
size = (wp->sy * percentage) / 100;
else
size = (wp->sx * percentage) / 100;
- }
- hlimit = options_get_number(s->options, "history-limit");
+ } else
+ size = -1;
+
+ server_unzoom_window(wp->window);
- shell = options_get_string(s->options, "default-shell");
- if (*shell == '\0' || areshell(shell))
- shell = _PATH_BSHELL;
+ flags = 0;
+ if (args_has(args, 'b'))
+ flags |= SPAWN_BEFORE;
+ if (args_has(args, 'f'))
+ flags |= SPAWN_FULLSIZE;
- lc = layout_split_pane(wp, type, size, before, args_has(args, 'f'));
+ lc = layout_split_pane(wp, type, size, flags);
if (lc == NULL) {
- cause = xstrdup("pane too small");
- goto error;
+ cmdq_error(item, "no space for new pane");
+ return (CMD_RETURN_ERROR);
}
- new_wp = window_add_pane(w, wp, before, args_has(args, 'f'), hlimit);
- layout_make_leaf(lc, new_wp);
- path = NULL;
- if (item->client != NULL && item->client->session == NULL)
- envent = environ_find(item->client->environ, "PATH");
- else
- envent = environ_find(s->environ, "PATH");
- if (envent != NULL)
- path = envent->value;
-
- env = environ_for_session(s, 0);
- if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, env,
- s->tio, &cause) != 0) {
- environ_free(env);
- goto error;
- }
- environ_free(env);
+ memset(&sc, 0, sizeof sc);
+ sc.item = item;
+ sc.s = s;
+ sc.wl = wl;
- layout_fix_panes(w);
- server_redraw_window(w);
+ sc.wp0 = wp;
+ sc.lc = lc;
- if (!args_has(args, 'd')) {
- window_set_active_pane(w, new_wp);
- session_select(s, wl->idx);
- cmd_find_from_session(current, s, 0);
- server_redraw_session(s);
- } else
- server_status_session(s);
+ sc.name = NULL;
+ sc.argc = args->argc;
+ sc.argv = args->argv;
+
+ sc.idx = -1;
+ sc.cwd = args_get(args, 'c');
+
+ sc.flags = flags;
+ if (args_has(args, 'd'))
+ sc.flags |= SPAWN_DETACHED;
+
+ if ((new_wp = spawn_pane(&sc, &cause)) == NULL) {
+ cmdq_error(item, "create pane failed: %s", cause);
+ free(cause);
+ return (CMD_RETURN_ERROR);
+ }
+ if (!args_has(args, 'd'))
+ cmd_find_from_winlink_pane(current, wl, new_wp, 0);
+ server_redraw_window(wp->window);
+ server_status_session(s);
if (args_has(args, 'P')) {
if ((template = args_get(args, 'F')) == NULL)
@@ -165,22 +141,9 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
cmdq_print(item, "%s", cp);
free(cp);
}
- notify_window("window-layout-changed", w);
cmd_find_from_winlink_pane(&fs, wl, new_wp, 0);
hooks_insert(s->hooks, item, &fs, "after-split-window");
- free(cwd);
return (CMD_RETURN_NORMAL);
-
-error:
- if (new_wp != NULL) {
- layout_close_pane(new_wp);
- window_remove_pane(w, new_wp);
- }
- cmdq_error(item, "create pane failed: %s", cause);
- free(cause);
-
- free(cwd);
- return (CMD_RETURN_ERROR);
}
diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c
index 1de272c4..2ad05561 100644
--- a/cmd-swap-pane.c
+++ b/cmd-swap-pane.c
@@ -101,17 +101,17 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
if (!args_has(self->args, 'd')) {
if (src_w != dst_w) {
- window_set_active_pane(src_w, dst_wp);
- window_set_active_pane(dst_w, src_wp);
+ window_set_active_pane(src_w, dst_wp, 1);
+ window_set_active_pane(dst_w, src_wp, 1);
} else {
tmp_wp = dst_wp;
- window_set_active_pane(src_w, tmp_wp);
+ window_set_active_pane(src_w, tmp_wp, 1);
}
} else {
if (src_w->active == src_wp)
- window_set_active_pane(src_w, dst_wp);
+ window_set_active_pane(src_w, dst_wp, 1);
if (dst_w->active == dst_wp)
- window_set_active_pane(dst_w, src_wp);
+ window_set_active_pane(dst_w, src_wp, 1);
}
if (src_w != dst_w) {
if (src_w->last == src_wp)
diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index 3e19346e..a4f55102 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -116,7 +116,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
server_unzoom_window(wl->window);
if (wp != NULL) {
window_redraw_active_switch(wp->window, wp);
- window_set_active_pane(wp->window, wp);
+ window_set_active_pane(wp->window, wp, 1);
}
session_set_current(s, wl);
cmd_find_from_session(&item->shared->current, s, 0);
diff --git a/layout.c b/layout.c
index 7093c607..1a43014d 100644
--- a/layout.c
+++ b/layout.c
@@ -831,11 +831,12 @@ layout_resize_child_cells(struct window *w, struct layout_cell *lc)
*/
struct layout_cell *
layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
- int insert_before, int full_size)
+ int flags)
{
struct layout_cell *lc, *lcparent, *lcnew, *lc1, *lc2;
u_int sx, sy, xoff, yoff, size1, size2;
u_int new_size, saved_size, resize_first = 0;
+ int full_size = (flags & SPAWN_FULLSIZE);
/*
* If full_size is specified, add a new cell at the top of the window
@@ -876,7 +877,7 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
saved_size = sy;
if (size < 0)
size2 = ((saved_size + 1) / 2) - 1;
- else if (insert_before)
+ else if (flags & SPAWN_BEFORE)
size2 = saved_size - size - 1;
else
size2 = size;
@@ -887,7 +888,7 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
size1 = saved_size - 1 - size2;
/* Which size are we using? */
- if (insert_before)
+ if (flags & SPAWN_BEFORE)
new_size = size2;
else
new_size = size1;
@@ -903,7 +904,7 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
*/
lcparent = lc->parent;
lcnew = layout_create_cell(lcparent);
- if (insert_before)
+ if (flags & SPAWN_BEFORE)
TAILQ_INSERT_BEFORE(lc, lcnew, entry);
else
TAILQ_INSERT_AFTER(&lcparent->cells, lc, lcnew, entry);
@@ -932,7 +933,7 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
layout_set_size(lcnew, size, sy, 0, 0);
else if (lc->type == LAYOUT_TOPBOTTOM)
layout_set_size(lcnew, sx, size, 0, 0);
- if (insert_before)
+ if (flags & SPAWN_BEFORE)
TAILQ_INSERT_HEAD(&lc->cells, lcnew, entry);
else
TAILQ_INSERT_TAIL(&lc->cells, lcnew, entry);
@@ -956,12 +957,12 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
/* Create the new child cell. */
lcnew = layout_create_cell(lcparent);
- if (insert_before)
+ if (flags & SPAWN_BEFORE)