aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd-join-pane.c2
-rw-r--r--cmd-kill-window.c46
-rw-r--r--server-fn.c50
-rw-r--r--tmux.h4
-rw-r--r--window-tree.c2
5 files changed, 74 insertions, 30 deletions
diff --git a/cmd-join-pane.c b/cmd-join-pane.c
index 9802083d..904d2c29 100644
--- a/cmd-join-pane.c
+++ b/cmd-join-pane.c
@@ -160,7 +160,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
server_status_session(dst_s);
if (window_count_panes(src_w) == 0)
- server_kill_window(src_w);
+ server_kill_window(src_w, 1);
else
notify_window("window-layout-changed", src_w);
notify_window("window-layout-changed", dst_w);
diff --git a/cmd-kill-window.c b/cmd-kill-window.c
index 68139faa..430f667e 100644
--- a/cmd-kill-window.c
+++ b/cmd-kill-window.c
@@ -57,9 +57,10 @@ cmd_kill_window_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = cmd_get_args(self);
struct cmd_find_state *target = cmdq_get_target(item);
- struct winlink *wl = target->wl, *wl2, *wl3;
+ struct winlink *wl = target->wl, *loop;
struct window *w = wl->window;
struct session *s = target->s;
+ u_int found;
if (cmd_get_entry(self) == &cmd_unlink_window_entry) {
if (!args_has(args, 'k') && !session_is_linked(s, w)) {
@@ -67,16 +68,43 @@ cmd_kill_window_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_ERROR);
}
server_unlink_window(s, wl);
- } else {
- if (args_has(args, 'a')) {
- RB_FOREACH_SAFE(wl2, winlinks, &s->windows, wl3) {
- if (wl != wl2)
- server_kill_window(wl2->window);
+ recalculate_sizes();
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args_has(args, 'a')) {
+ if (RB_PREV(winlinks, &s->windows, wl) == NULL &&
+ RB_NEXT(winlinks, &s->windows, wl) == NULL)
+ return (CMD_RETURN_NORMAL);
+
+ /* Kill all windows except the current one. */
+ do {
+ found = 0;
+ RB_FOREACH(loop, winlinks, &s->windows) {
+ if (loop->window != wl->window) {
+ server_kill_window(loop->window, 0);
+ found++;
+ break;
+ }
}
- } else
- server_kill_window(wl->window);
+ } while (found != 0);
+
+ /*
+ * If the current window appears in the session more than once,
+ * kill it as well.
+ */
+ found = 0;
+ RB_FOREACH(loop, winlinks, &s->windows) {
+ if (loop->window == wl->window)
+ found++;
+ }
+ if (found > 1)
+ server_kill_window(wl->window, 0);
+
+ server_renumber_all();
+ return (CMD_RETURN_NORMAL);
}
- recalculate_sizes();
+ server_kill_window(wl->window, 1);
return (CMD_RETURN_NORMAL);
}
diff --git a/server-fn.c b/server-fn.c
index d66aed0b..84ec4123 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -183,7 +183,7 @@ server_kill_pane(struct window_pane *wp)
struct window *w = wp->window;
if (window_count_panes(w) == 1) {
- server_kill_window(w);
+ server_kill_window(w, 1);
recalculate_sizes();
} else {
server_unzoom_window(w);
@@ -195,19 +195,15 @@ server_kill_pane(struct window_pane *wp)
}
void
-server_kill_window(struct window *w)
+server_kill_window(struct window *w, int renumber)
{
- struct session *s, *next_s, *target_s;
- struct session_group *sg;
- struct winlink *wl;
-
- next_s = RB_MIN(sessions, &sessions);
- while (next_s != NULL) {
- s = next_s;
- next_s = RB_NEXT(sessions, &sessions, s);
+ struct session *s, *s1;
+ struct winlink *wl;
+ RB_FOREACH_SAFE(s, sessions, &sessions, s1) {
if (!session_has(s, w))
continue;
+
server_unzoom_window(w);
while ((wl = winlink_find_by_window(&s->windows, w)) != NULL) {
if (session_detach(s, wl)) {
@@ -217,17 +213,35 @@ server_kill_window(struct window *w)
server_redraw_session_group(s);
}
- if (options_get_number(s->options, "renumber-windows")) {
- if ((sg = session_group_contains(s)) != NULL) {
- TAILQ_FOREACH(target_s, &sg->sessions, gentry)
- session_renumber_windows(target_s);
- } else
- session_renumber_windows(s);
- }
+ if (renumber)
+ server_renumber_session(s);
}
recalculate_sizes();
}
+void
+server_renumber_session(struct session *s)
+{
+ struct session_group *sg;
+
+ if (options_get_number(s->options, "renumber-windows")) {
+ if ((sg = session_group_contains(s)) != NULL) {
+ TAILQ_FOREACH(s, &sg->sessions, gentry)
+ session_renumber_windows(s);
+ } else
+ session_renumber_windows(s);
+ }
+}
+
+void
+server_renumber_all(void)
+{
+ struct session *s;
+
+ RB_FOREACH(s, sessions, &sessions)
+ server_renumber_session(s);
+}
+
int
server_link_window(struct session *src, struct winlink *srcwl,
struct session *dst, int dstidx, int killflag, int selectflag,
@@ -354,7 +368,7 @@ server_destroy_pane(struct window_pane *wp, int notify)
window_remove_pane(w, wp);
if (TAILQ_EMPTY(&w->panes))
- server_kill_window(w);
+ server_kill_window(w, 1);
else
server_redraw_window(w);
}
diff --git a/tmux.h b/tmux.h
index 0a1a740b..a8c67051 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2420,7 +2420,9 @@ void server_lock(void);
void server_lock_session(struct session *);
void server_lock_client(struct client *);
void server_kill_pane(struct window_pane *);
-void server_kill_window(struct window *);
+void server_kill_window(struct window *, int);
+void server_renumber_session(struct session *);
+void server_renumber_all(void);
int server_link_window(struct session *,
struct winlink *, struct session *, int, int, int, char **);
void server_unlink_window(struct session *, struct winlink *);
diff --git a/window-tree.c b/window-tree.c
index 32b94e15..384cf392 100644
--- a/window-tree.c
+++ b/window-tree.c
@@ -1054,7 +1054,7 @@ window_tree_kill_each(__unused void *modedata, void *itemdata,
break;
case WINDOW_TREE_WINDOW:
if (wl != NULL)
- server_kill_window(wl->window);
+ server_kill_window(wl->window, 1);
break;
case WINDOW_TREE_PANE:
if (wp != NULL)