diff --git a/cmd-break-pane.c b/cmd-break-pane.c
index 880ee7f5..87892d73 100644
--- a/cmd-break-pane.c
+++ b/cmd-break-pane.c
@@ -34,8 +34,8 @@ const struct cmd_entry cmd_break_pane_entry = {
 	.name = "break-pane",
 	.alias = "breakp",
 
-	.args = { "dPF:n:s:t:", 0, 0 },
-	.usage = "[-dP] [-F format] [-n window-name] [-s src-pane] "
+	.args = { "adPF:n:s:t:", 0, 0 },
+	.usage = "[-adP] [-F format] [-n window-name] [-s src-pane] "
 		 "[-t dst-window]",
 
 	.source = { 's', CMD_FIND_PANE, 0 },
@@ -63,17 +63,31 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
 	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);
+	if (args_has(args, 'a')) {
+		if (target->wl != NULL)
+			idx = winlink_shuffle_up(dst_s, target->wl);
+		else
+			idx = winlink_shuffle_up(dst_s, dst_s->curw);
+		if (idx == -1)
+			return (CMD_RETURN_ERROR);
 	}
 	server_unzoom_window(w);
 
+	if (window_count_panes(w) == 1) {
+		if (server_link_window(src_s, wl, dst_s, idx, 0,
+		    !args_has(args, 'd'), &cause) != 0) {
+			cmdq_error(item, "%s", cause);
+			free(cause);
+			return (CMD_RETURN_ERROR);
+		}
+		server_unlink_window(src_s, wl);
+		return (CMD_RETURN_NORMAL);
+	}
+	if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) {
+		cmdq_error(item, "index in use: %d", idx);
+		return (CMD_RETURN_ERROR);
+	}
+
 	TAILQ_REMOVE(&w->panes, wp, entry);
 	window_lost_pane(w, wp);
 	layout_close_pane(wp);
diff --git a/cmd-join-pane.c b/cmd-join-pane.c
index 6583db75..2e4bec50 100644
--- a/cmd-join-pane.c
+++ b/cmd-join-pane.c
@@ -49,8 +49,8 @@ const struct cmd_entry cmd_move_pane_entry = {
 	.name = "move-pane",
 	.alias = "movep",
 
-	.args = { "bdhvp:l:s:t:", 0, 0 },
-	.usage = "[-bdhv] [-l size] " CMD_SRCDST_PANE_USAGE,
+	.args = { "bdfhvp:l:s:t:", 0, 0 },
+	.usage = "[-bdfhv] [-l size] " CMD_SRCDST_PANE_USAGE,
 
 	.source = { 's', CMD_FIND_PANE, CMD_FIND_DEFAULT_MARKED },
 	.target = { 't', CMD_FIND_PANE, 0 },
@@ -71,16 +71,11 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
 	struct window		*src_w, *dst_w;
 	struct window_pane	*src_wp, *dst_wp;
 	char			*cause = NULL;
-	int			 size, percentage, dst_idx, not_same_window;
+	int			 size, percentage, dst_idx;
 	int			 flags;
 	enum layout_type	 type;
 	struct layout_cell	*lc;
 
-	if (cmd_get_entry(self) == &cmd_join_pane_entry)
-		not_same_window = 1;
-	else
-		not_same_window = 0;
-
 	dst_s = target->s;
 	dst_wl = target->wl;
 	dst_wp = target->wp;
@@ -93,11 +88,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
 	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) {
+	if (src_wp == dst_wp) {
 		cmdq_error(item, "source and target panes must be different");
 		return (CMD_RETURN_ERROR);
 	}
diff --git a/cmd-move-window.c b/cmd-move-window.c
index eb6f4f1a..94b6c950 100644
--- a/cmd-move-window.c
+++ b/cmd-move-window.c
@@ -63,9 +63,9 @@ cmd_move_window_exec(struct cmd *self, struct cmdq_item *item)
 	struct cmd_find_state	*source = cmdq_get_source(item);
 	struct cmd_find_state	 target;
 	const char		*tflag = args_get(args, 't');
-	struct session		*src;
+	struct session		*src = source->s;
 	struct session		*dst;
-	struct winlink		*wl;
+	struct winlink		*wl = source->wl;
 	char			*cause;
 	int			 idx, kflag, dflag, sflag;
 
@@ -83,9 +83,7 @@ cmd_move_window_exec(struct cmd *self, struct cmdq_item *item)
 	if (cmd_find_target(&target, item, tflag, CMD_FIND_WINDOW,
 	    CMD_FIND_WINDOW_INDEX) != 0)
 		return (CMD_RETURN_ERROR);
-	src = source->s;
 	dst = target.s;
-	wl = source->wl;
 	idx = target.idx;
 
 	kflag = args_has(args, 'k');
@@ -93,12 +91,16 @@ cmd_move_window_exec(struct cmd *self, struct cmdq_item *item)
 	sflag = args_has(args, 's');
 
 	if (args_has(args, 'a')) {
-		if ((idx = winlink_shuffle_up(dst, dst->curw)) == -1)
+		if (target.wl != NULL)
+			idx = winlink_shuffle_up(dst, target.wl);
+		else
+			idx = winlink_shuffle_up(dst, dst->curw);
+		if (idx == -1)
 			return (CMD_RETURN_ERROR);
 	}
 
 	if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
-		cmdq_error(item, "can't link window: %s", cause);
+		cmdq_error(item, "%s", cause);
 		free(cause);
 		return (CMD_RETURN_ERROR);
 	}
diff --git a/mode-tree.c b/mode-tree.c
index 0177d618..783ffcfa 100644
--- a/mode-tree.c
+++ b/mode-tree.c
@@ -256,8 +256,8 @@ mode_tree_expand_current(struct mode_tree_data *mtd)
 	}
 }
 
-void
-mode_tree_set_current(struct mode_tree_data *mtd, uint64_t tag)
+static int
+mode_tree_get_tag(struct mode_tree_data *mtd, uint64_t tag, u_int *found)
 {
 	u_int	i;
 
@@ -266,15 +266,41 @@ mode_tree_set_current(struct mode_tree_data *mtd, uint64_t tag)
 			break;
 	}
 	if (i != mtd->line_size) {
-		mtd->current = i;
+		*found = i;
+		return (1);
+	}
+	return (0);
+}
+
+void
+mode_tree_expand(struct mode_tree_data *mtd, uint64_t tag)
+{
+	u_int	found;
+
+	if (!mode_tree_get_tag(mtd, tag, &found))
+	    return;
+	if (!mtd->line_list[found].item->expanded) {
+		mtd->line_list[found].item->expanded = 1;
+		mode_tree_build(mtd);
+	}
+}
+
+int
+mode_tree_set_current(struct mode_tree_data *mtd, uint64_t tag)
+{
+	u_int	found;
+
+	if (mode_tree_get_tag(mtd, tag, &found)) {
+		mtd->current = found;
 		if (mtd->current > mtd->height - 1)
 			mtd->offset = mtd->current - mtd->height + 1;
 		else
 			mtd->offset = 0;
-	} else {
-		mtd->current = 0;
-		mtd->offset = 0;
+		return (1);
 	}
+	mtd->current = 0;
+	mtd->offset = 0;
+	return (0);
 }
 
 u_int
diff --git a/tmux.1 b/tmux.1
index 9cd120a4..6a77a273 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1714,7 +1714,7 @@ from which the layout was originally defined.
 Commands related to windows and panes are as follows:
 .Bl -tag -width Ds
 .It Xo Ic break-pane
-.Op Fl dP
+.Op Fl adP
 .Op Fl F Ar format
 .Op Fl n Ar window-name
 .Op Fl s Ar src-pane
@@ -1725,6 +1725,10 @@ Break
 .Ar src-pane
 off from its containing window to make it the only pane in
 .Ar dst-window .
+With
+.Fl a ,
+the window is moved to the next index up (following windows
+are moved if necessary).
 If
 .Fl d
 is given, the new window does not become the current window.
@@ -1873,12 +1877,15 @@ The following keys may be used in tree mode:
 .It Li "<" Ta "Scroll list of previews left"
 .It Li ">" Ta "Scroll list of previews right"
 .It Li "C-s" Ta "Search by name"
+.It Li "m" Ta "Set the marked pane"
+.It Li "M" Ta "Clear the marked pane"
 .It Li "n" Ta "Repeat last search"
 .It Li "t" Ta "Toggle if item is tagged"
 .It Li "T" Ta "Tag no items"
 .It Li "C-t" Ta "Tag all items"
 .It Li "\&:" Ta "Run a command for each tagged item"
 .It Li "f" Ta "Enter a format to filter items"
+.It Li "H" Ta "Jump to the starting pane"
 .It Li "O" Ta "Change sort field"
 .It Li "r" Ta "Reverse sort order"
 .It Li "v" Ta "Toggle preview"
@@ -2125,19 +2132,14 @@ See the
 .Sx FORMATS
 section.
 .It Xo Ic move-pane
-.Op Fl bdhv
+.Op Fl bdfhv
 .Op Fl l Ar size
 .Op Fl s Ar src-pane
 .Op Fl t Ar dst-pane
 .Xc
 .D1 (alias: Ic movep )
-Like
-.Ic join-pane ,
-but
-.Ar src-pane
-and
-.Ar dst-pane
-may belong to the same window.
+Does the same as
+.Ic join-pane .
 .It Xo Ic move-window
 .Op Fl ardk
 .Op Fl s Ar src-window
diff --git a/tmux.h b/tmux.h
index 6b604f26..f95726d5 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2623,7 +2623,8 @@ typedef void (*mode_tree_each_cb)(void *, void *, struct client *, key_code);
 u_int	 mode_tree_count_tagged(struct mode_tree_data *);
 void	*mode_tree_get_current(struct mode_tree_data *);
 void	 mode_tree_expand_current(struct mode_tree_data *);
-void	 mode_tree_set_current(struct mode_tree_data *, uint64_t);
+void	 mode_tree_expand(struct mode_tree_data *, uint64_t);
+int	 mode_tree_set_current(struct mode_tree_data *, uint64_t);
 void	 mode_tree_each_tagged(struct mode_tree_data *, mode_tree_each_cb,
 	     struct client *, key_code, int);
 void	 mode_tree_down(struct mode_tree_data *, int);
diff --git a/window-tree.c b/window-tree.c
index 3bb2af34..095520e2 100644
--- a/window-tree.c
+++ b/window-tree.c
@@ -37,9 +37,11 @@ static void		 window_tree_key(struct window_mode_entry *,
 
 #define WINDOW_TREE_DEFAULT_FORMAT \
 	"#{?pane_format," \
-		"#{pane_current_command} \"#{pane_title}\"" \
+		"#{?pane_marked,#[reverse],}" \
+		"#{pane_current_command}#{?pane_active,*,}#{?pane_marked,M,} \"#{pane_title}\"" \
 	"," \
 		"#{?window_format," \
+			"#{?window_marked_flag,#[reverse],}" \
 			"#{window_name}#{window_flags} " \
 			"(#{window_panes} panes)" \
 			"#{?#{==:#{window_panes},1}, \"#{pane_title}\",}" \
@@ -56,6 +58,7 @@ static void		 window_tree_key(struct window_mode_entry *,
 static const struct menu_item window_tree_menu_items[] = {
 	{ "Select", '\r', NULL },
 	{ "Expand", KEYC_RIGHT, NULL },
+	{ "Mark", 'm', NULL },
 	{ "", KEYC_NONE, NULL },
 	{ "Tag", 't', NULL },
 	{ "Tag All", '\024', NULL },
@@ -1170,7 +1173,7 @@ window_tree_key(struct window_mode_entry *wme, struct client *c,
 	struct window_tree_modedata	*data = wme->data;
 	struct window_tree_itemdata	*item, *new_item;
 	char				*name, *prompt = NULL;
-	struct cmd_find_state		 fs;
+	struct cmd_find_state		 fs, *fsp = &data->fs;
 	int				 finished;
 	u_int				 tagged, x, y, idx;
 	struct session			*ns;
@@ -1192,6 +1195,21 @@ window_tree_key(struct window_mode_entry *wme, struct client *c,
 	case '>':
 		data->offset++;
 		break;
+	case 'H':
+		mode_tree_expand(data->data, (uint64_t)fsp->s);
+		mode_tree_expand(data->data, (uint64_t)fsp->wl);
+		if (!mode_tree_set_current(data->data, (uint64_t)wme->wp))
+			mode_tree_set_current(data->data, (uint64_t)fsp->wl);
+		break;
+	case 'm':
+		window_tree_pull_item(item, &ns, &nwl, &nwp);
+		server_set_marked(ns, nwl, nwp);
+		mode_tree_build(data->data);
+		break;
+	case 'M':
+		server_clear_marked();
+		mode_tree_build(data->data);
+		break;
 	case 'x':
 		window_tree_pull_item(item, &ns, &nwl, &nwp);
 		switch (item->type) {