diff options
Diffstat (limited to 'cmd-kill-window.c')
-rw-r--r-- | cmd-kill-window.c | 46 |
1 files changed, 37 insertions, 9 deletions
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); } |