コード例 #1
0
ファイル: cmd-kill-pane.c プロジェクト: psych0tik/tmux
int
cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct winlink		*wl;
	struct window_pane	*loopwp, *nextwp, *wp;

	if ((wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp)) == NULL)
		return (-1);

	if (window_count_panes(wl->window) == 1) {
		/* Only one pane, kill the window. */
		server_kill_window(wl->window);
		recalculate_sizes();
		return (0);
	}

	if (args_has(self->args, 'a')) {
		loopwp = TAILQ_FIRST(&wl->window->panes);
		while (loopwp != NULL) {
			nextwp = TAILQ_NEXT(loopwp, entry);
			if (loopwp != wp) {
				layout_close_pane(loopwp);
				window_remove_pane(wl->window, loopwp);
			}
			loopwp = nextwp;
		}
	} else {
		layout_close_pane(wp);
		window_remove_pane(wl->window, wp);
	}
	server_redraw_window(wl->window);

	return (0);
}
コード例 #2
0
ファイル: cmd-break-pane.c プロジェクト: bholt/tmux
int
cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
    struct args		*args = self->args;
    struct winlink		*wl;
    struct session		*s;
    struct window_pane	*wp;
    struct window		*w;
    char			*name;
    char			*cause;
    int			 base_idx;
    struct client		*c;

    if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL)
        return (-1);

    if (window_count_panes(wl->window) == 1) {
        ctx->error(ctx, "can't break with only one pane");
        return (-1);
    }

    w = wl->window;
    TAILQ_REMOVE(&w->panes, wp, entry);
    if (wp == w->active) {
        w->active = w->last;
        w->last = NULL;
        if (w->active == NULL) {
            w->active = TAILQ_PREV(wp, window_panes, entry);
            if (w->active == NULL)
                w->active = TAILQ_NEXT(wp, entry);
        }
    } else if (wp == w->last)
        w->last = NULL;
    layout_close_pane(wp);

    w = wp->window = window_create1(s->sx, s->sy);
    TAILQ_INSERT_HEAD(&w->panes, wp, entry);
    w->active = wp;
    name = default_window_name(w);
    window_set_name(w, name);
    xfree(name);
    layout_init(w);

    base_idx = options_get_number(&s->options, "base-index");
    wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
    if (!args_has(self->args, 'd'))
        session_select(s, wl->idx);

    server_redraw_session(s);
    server_status_session_group(s);

    /* Output the window ID for control clients. */
    c = cmd_find_client(ctx, NULL);
    if (c->flags & CLIENT_CONTROL) {
        ctx->print(ctx, "%d", w->id);
    }

    return (0);
}
コード例 #3
0
ファイル: cmd-break-pane.c プロジェクト: FauxFaux/tmux
enum cmd_retval
cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct winlink		*wl;
	struct session		*s;
	struct window_pane	*wp;
	struct window		*w;
	char			*name;
	char			*cause;
	int			 base_idx;
	struct client		*c;
	struct format_tree	*ft;
	const char		*template;
	char			*cp;

	if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
		return (CMD_RETURN_ERROR);

	if (window_count_panes(wl->window) == 1) {
		cmdq_error(cmdq, "can't break with only one pane");
		return (CMD_RETURN_ERROR);
	}

	w = wl->window;
	server_unzoom_window(w);

	TAILQ_REMOVE(&w->panes, wp, entry);
	if (wp == w->active) {
		w->active = w->last;
		w->last = NULL;
		if (w->active == NULL) {
			w->active = TAILQ_PREV(wp, window_panes, entry);
			if (w->active == NULL)
				w->active = TAILQ_NEXT(wp, entry);
		}
	} else if (wp == w->last)
		w->last = NULL;
	layout_close_pane(wp);

	w = wp->window = window_create1(s->sx, s->sy);
	TAILQ_INSERT_HEAD(&w->panes, wp, entry);
	w->active = wp;
	name = default_window_name(w);
	window_set_name(w, name);
	free(name);
	layout_init(w, wp);

	base_idx = options_get_number(&s->options, "base-index");
	wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
	if (!args_has(self->args, 'd'))
		session_select(s, wl->idx);

	server_redraw_session(s);
	server_status_session_group(s);

	if (args_has(args, 'P')) {
		if ((template = args_get(args, 'F')) == NULL)
コード例 #4
0
ファイル: cmd-break-pane.c プロジェクト: marcisme/tmate-slave
enum cmd_retval
cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
#ifdef TMATE_SLAVE
    return (CMD_RETURN_ERROR);
#else
    struct args		*args = self->args;
    struct winlink		*wl = cmdq->state.sflag.wl;
    struct session		*src_s = cmdq->state.sflag.s;
    struct session		*dst_s = cmdq->state.tflag.s;
    struct window_pane	*wp = cmdq->state.sflag.wp;
    struct window		*w = wl->window;
    char			*name;
    char			*cause;
    int			 idx = cmdq->state.tflag.idx;
    struct format_tree	*ft;
    const char		*template;
    char			*cp;

    if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) {
        cmdq_error(cmdq, "index %d already in use", idx);
        return (CMD_RETURN_ERROR);
    }

    if (window_count_panes(w) == 1) {
        cmdq_error(cmdq, "can't break with only one pane");
        return (CMD_RETURN_ERROR);
    }
    server_unzoom_window(w);

    TAILQ_REMOVE(&w->panes, wp, entry);
    window_lost_pane(w, wp);
    layout_close_pane(wp);

    w = wp->window = window_create1(dst_s->sx, dst_s->sy);
    TAILQ_INSERT_HEAD(&w->panes, wp, entry);
    w->active = wp;
    name = default_window_name(w);
    window_set_name(w, name);
    free(name);
    layout_init(w, wp);
    wp->flags |= PANE_CHANGED;

    if (idx == -1)
        idx = -1 - options_get_number(dst_s->options, "base-index");
    wl = session_attach(dst_s, w, idx, &cause); /* can't fail */
    if (!args_has(self->args, 'd'))
        session_select(dst_s, wl->idx);

    server_redraw_session(src_s);
    if (src_s != dst_s)
        server_redraw_session(dst_s);
    server_status_session_group(src_s);
    if (src_s != dst_s)
        server_status_session_group(dst_s);

    if (args_has(args, 'P')) {
        if ((template = args_get(args, 'F')) == NULL)
コード例 #5
0
int
cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct session		*dst_s;
	struct winlink		*src_wl, *dst_wl;
	struct window		*src_w, *dst_w;
	struct window_pane	*src_wp, *dst_wp;
	char			*cause;
	int			 size, percentage, dst_idx;
	enum layout_type	 type;
	struct layout_cell	*lc;

	dst_wl = cmd_find_pane(ctx, args_get(args, 't'), &dst_s, &dst_wp);
	if (dst_wl == NULL)
		return (-1);
	dst_w = dst_wl->window;
	dst_idx = dst_wl->idx;

	src_wl = cmd_find_pane(ctx, args_get(args, 's'), NULL, &src_wp);
	if (src_wl == NULL)
		return (-1);
	src_w = src_wl->window;

	if (src_w == dst_w) {
		ctx->error(ctx, "can't join a pane to its own window");
		return (-1);
	}

	type = LAYOUT_TOPBOTTOM;
	if (args_has(args, 'h'))
		type = LAYOUT_LEFTRIGHT;

	size = -1;
	if (args_has(args, 'l')) {
		size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "size %s", cause);
			xfree(cause);
			return (-1);
		}
	} else if (args_has(args, 'p')) {
		percentage = args_strtonum(args, 'p', 0, 100, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "percentage %s", cause);
			xfree(cause);
			return (-1);
		}
		if (type == LAYOUT_TOPBOTTOM)
			size = (dst_wp->sy * percentage) / 100;
		else
			size = (dst_wp->sx * percentage) / 100;
	}

	if ((lc = layout_split_pane(dst_wp, type, size)) == NULL) {
		ctx->error(ctx, "create pane failed: pane too small");
		return (-1);
	}

	layout_close_pane(src_wp);

	if (src_w->active == src_wp) {
		src_w->active = TAILQ_PREV(src_wp, window_panes, entry);
		if (src_w->active == NULL)
			src_w->active = TAILQ_NEXT(src_wp, entry);
	}
	TAILQ_REMOVE(&src_w->panes, src_wp, entry);

	if (window_count_panes(src_w) == 0)
		server_kill_window(src_w);

	src_wp->window = dst_w;
	TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
	layout_assign_pane(lc, src_wp);

	recalculate_sizes();

	server_redraw_window(src_w);
	server_redraw_window(dst_w);

	if (!args_has(args, 'd')) {
		window_set_active_pane(dst_w, src_wp);
		session_select(dst_s, dst_idx);
		server_redraw_session(dst_s);
	} else
		server_status_session(dst_s);

	return (0);
}
コード例 #6
0
ファイル: cmd-break-pane.c プロジェクト: SeamusConnor/tmux
static enum cmd_retval
cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
{
	struct args		*args = self->args;
	struct cmd_find_state	*current = &item->shared->current;
	struct client		*c = cmd_find_client(item, NULL, 1);
	struct winlink		*wl = item->source.wl;
	struct session		*src_s = item->source.s;
	struct session		*dst_s = item->target.s;
	struct window_pane	*wp = item->source.wp;
	struct window		*w = wl->window;
	char			*name, *cause;
	int			 idx = item->target.idx;
	const char		*template;
	char			*cp;

	if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) {
		cmdq_error(item, "index %d already in use", idx);
		return (CMD_RETURN_ERROR);
	}

	if (window_count_panes(w) == 1) {
		cmdq_error(item, "can't break with only one pane");
		return (CMD_RETURN_ERROR);
	}
	server_unzoom_window(w);

	TAILQ_REMOVE(&w->panes, wp, entry);
	window_lost_pane(w, wp);
	layout_close_pane(wp);

	w = wp->window = window_create(w->sx, w->sy);
	TAILQ_INSERT_HEAD(&w->panes, wp, entry);
	w->active = wp;

	if (!args_has(args, 'n')) {
		name = default_window_name(w);
		window_set_name(w, name);
		free(name);
	} else {
		window_set_name(w, args_get(args, 'n'));
		options_set_number(w->options, "automatic-rename", 0);
	}

	layout_init(w, wp);
	wp->flags |= PANE_CHANGED;

	if (idx == -1)
		idx = -1 - options_get_number(dst_s->options, "base-index");
	wl = session_attach(dst_s, w, idx, &cause); /* can't fail */
	if (!args_has(self->args, 'd')) {
		session_select(dst_s, wl->idx);
		cmd_find_from_session(current, dst_s, 0);
	}

	server_redraw_session(src_s);
	if (src_s != dst_s)
		server_redraw_session(dst_s);
	server_status_session_group(src_s);
	if (src_s != dst_s)
		server_status_session_group(dst_s);

	if (args_has(args, 'P')) {
		if ((template = args_get(args, 'F')) == NULL)
コード例 #7
0
ファイル: cmd-join-pane.c プロジェクト: byplayer/tmux
enum cmd_retval
join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
{
	struct args		*args = self->args;
	struct session		*dst_s;
	struct winlink		*src_wl, *dst_wl;
	struct window		*src_w, *dst_w;
	struct window_pane	*src_wp, *dst_wp;
	char			*cause;
	int			 size, percentage, dst_idx;
	enum layout_type	 type;
	struct layout_cell	*lc;

	dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), &dst_s, &dst_wp);
	if (dst_wl == NULL)
		return (CMD_RETURN_ERROR);
	dst_w = dst_wl->window;
	dst_idx = dst_wl->idx;
	server_unzoom_window(dst_w);

	src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
	if (src_wl == NULL)
		return (CMD_RETURN_ERROR);
	src_w = src_wl->window;
	server_unzoom_window(src_w);

	if (not_same_window && src_w == dst_w) {
		cmdq_error(cmdq, "can't join a pane to its own window");
		return (CMD_RETURN_ERROR);
	}
	if (!not_same_window && src_wp == dst_wp) {
		cmdq_error(cmdq, "source and target panes must be different");
		return (CMD_RETURN_ERROR);
	}

	type = LAYOUT_TOPBOTTOM;
	if (args_has(args, 'h'))
		type = LAYOUT_LEFTRIGHT;

	size = -1;
	if (args_has(args, 'l')) {
		size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "size %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
	} else if (args_has(args, 'p')) {
		percentage = args_strtonum(args, 'p', 0, 100, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "percentage %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
		if (type == LAYOUT_TOPBOTTOM)
			size = (dst_wp->sy * percentage) / 100;
		else
			size = (dst_wp->sx * percentage) / 100;
	}
	lc = layout_split_pane(dst_wp, type, size, args_has(args, 'b'));
	if (lc == NULL) {
		cmdq_error(cmdq, "create pane failed: pane too small");
		return (CMD_RETURN_ERROR);
	}

	layout_close_pane(src_wp);

	window_lost_pane(src_w, src_wp);
	TAILQ_REMOVE(&src_w->panes, src_wp, entry);

	if (window_count_panes(src_w) == 0)
		server_kill_window(src_w);
	else
		notify_window_layout_changed(src_w);

	src_wp->window = dst_w;
	TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
	layout_assign_pane(lc, src_wp);

	recalculate_sizes();

	server_redraw_window(src_w);
	server_redraw_window(dst_w);

	if (!args_has(args, 'd')) {
		window_set_active_pane(dst_w, src_wp);
		session_select(dst_s, dst_idx);
		server_redraw_session(dst_s);
	} else
		server_status_session(dst_s);

	notify_window_layout_changed(dst_w);
	return (CMD_RETURN_NORMAL);
}
コード例 #8
0
ファイル: cmd-join-pane.c プロジェクト: ThomasAdam/tmux
static enum cmd_retval
cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
{
	struct args		*args = self->args;
	struct cmd_find_state	*current = &item->shared->current;
	struct session		*dst_s;
	struct winlink		*src_wl, *dst_wl;
	struct window		*src_w, *dst_w;
	struct window_pane	*src_wp, *dst_wp;
	char			*cause;
	int			 size, percentage, dst_idx;
	enum layout_type	 type;
	struct layout_cell	*lc;
	int			 not_same_window, flags;

	if (self->entry == &cmd_join_pane_entry)
		not_same_window = 1;
	else
		not_same_window = 0;

	dst_s = item->target.s;
	dst_wl = item->target.wl;
	dst_wp = item->target.wp;
	dst_w = dst_wl->window;
	dst_idx = dst_wl->idx;
	server_unzoom_window(dst_w);

	src_wl = item->source.wl;
	src_wp = item->source.wp;
	src_w = src_wl->window;
	server_unzoom_window(src_w);

	if (not_same_window && src_w == dst_w) {
		cmdq_error(item, "can't join a pane to its own window");
		return (CMD_RETURN_ERROR);
	}
	if (!not_same_window && src_wp == dst_wp) {
		cmdq_error(item, "source and target panes must be different");
		return (CMD_RETURN_ERROR);
	}

	type = LAYOUT_TOPBOTTOM;
	if (args_has(args, 'h'))
		type = LAYOUT_LEFTRIGHT;

	size = -1;
	if (args_has(args, 'l')) {
		size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(item, "size %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
	} else if (args_has(args, 'p')) {
		percentage = args_strtonum(args, 'p', 0, 100, &cause);
		if (cause != NULL) {
			cmdq_error(item, "percentage %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
		if (type == LAYOUT_TOPBOTTOM)
			size = (dst_wp->sy * percentage) / 100;
		else
			size = (dst_wp->sx * percentage) / 100;
	}
	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);
	}

	layout_close_pane(src_wp);

	window_lost_pane(src_w, src_wp);
	TAILQ_REMOVE(&src_w->panes, src_wp, entry);

	src_wp->window = dst_w;
	TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
	layout_assign_pane(lc, src_wp);

	recalculate_sizes();

	server_redraw_window(src_w);
	server_redraw_window(dst_w);

	if (!args_has(args, 'd')) {
		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);
	} else
		server_status_session(dst_s);

	if (window_count_panes(src_w) == 0)
		server_kill_window(src_w);
	else
		notify_window("window-layout-changed", src_w);
	notify_window("window-layout-changed", dst_w);

	return (CMD_RETURN_NORMAL);
}