diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2018-04-10 10:48:45 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2018-04-10 10:48:45 +0000 |
commit | 742eefdbef46eba88fc67e62bb1c6a3963dc19c8 (patch) | |
tree | c541f75ece70ffa29af6e307f3a817f2031ba04c | |
parent | beaabf6cd8d215b34e13b596af794e10b6b7dd1d (diff) |
Add x and X to choose-tree (with a confirmation prompt) to kill an
item. Suggested by Matt Zagrabelny.
-rw-r--r-- | usr.bin/tmux/cmd-kill-pane.c | 14 | ||||
-rw-r--r-- | usr.bin/tmux/server-fn.c | 18 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 6 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 3 | ||||
-rw-r--r-- | usr.bin/tmux/window-tree.c | 126 |
5 files changed, 146 insertions, 21 deletions
diff --git a/usr.bin/tmux/cmd-kill-pane.c b/usr.bin/tmux/cmd-kill-pane.c index c2bde0479fa..7652444bcf9 100644 --- a/usr.bin/tmux/cmd-kill-pane.c +++ b/usr.bin/tmux/cmd-kill-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-kill-pane.c,v 1.25 2017/04/22 10:22:39 nicm Exp $ */ +/* $OpenBSD: cmd-kill-pane.c,v 1.26 2018/04/10 10:48:44 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -47,9 +47,8 @@ cmd_kill_pane_exec(struct cmd *self, struct cmdq_item *item) struct winlink *wl = item->target.wl; struct window_pane *loopwp, *tmpwp, *wp = item->target.wp; - server_unzoom_window(wl->window); - if (args_has(self->args, 'a')) { + server_unzoom_window(wl->window); TAILQ_FOREACH_SAFE(loopwp, &wl->window->panes, entry, tmpwp) { if (loopwp == wp) continue; @@ -60,13 +59,6 @@ cmd_kill_pane_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_NORMAL); } - if (window_count_panes(wl->window) == 1) { - server_kill_window(wl->window); - recalculate_sizes(); - } else { - layout_close_pane(wp); - window_remove_pane(wl->window, wp); - server_redraw_window(wl->window); - } + server_kill_pane(wp); return (CMD_RETURN_NORMAL); } diff --git a/usr.bin/tmux/server-fn.c b/usr.bin/tmux/server-fn.c index 71a714e3b74..45433209a59 100644 --- a/usr.bin/tmux/server-fn.c +++ b/usr.bin/tmux/server-fn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-fn.c,v 1.113 2018/02/28 08:55:44 nicm Exp $ */ +/* $OpenBSD: server-fn.c,v 1.114 2018/04/10 10:48:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -178,6 +178,22 @@ server_lock_client(struct client *c) } void +server_kill_pane(struct window_pane *wp) +{ + struct window *w = wp->window; + + if (window_count_panes(w) == 1) { + server_kill_window(w); + recalculate_sizes(); + } else { + server_unzoom_window(w); + layout_close_pane(wp); + window_remove_pane(w, wp); + server_redraw_window(w); + } +} + +void server_kill_window(struct window *w) { struct session *s, *next_s, *target_s; diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index db8d3f604ec..bab90823bd4 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.593 2018/02/28 08:55:44 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.594 2018/04/10 10:48:44 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: February 28 2018 $ +.Dd $Mdocdate: April 10 2018 $ .Dt TMUX 1 .Os .Sh NAME @@ -1459,6 +1459,8 @@ The following keys may be used in tree mode: .It Li "Enter" Ta "Choose selected item" .It Li "Up" Ta "Select previous item" .It Li "Down" Ta "Select next item" +.It Li "x" Ta "Kill selected item" +.It Li "X" Ta "Kill tagged items" .It Li "<" Ta "Scroll list of previews left" .It Li ">" Ta "Scroll list of previews right" .It Li "C-s" Ta "Search by name" diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index fb86209cf54..d07f1fdf7ff 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.822 2018/03/16 15:15:39 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.823 2018/04/10 10:48:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -1920,6 +1920,7 @@ void server_status_window(struct window *); 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 *); int server_link_window(struct session *, struct winlink *, struct session *, int, int, int, char **); diff --git a/usr.bin/tmux/window-tree.c b/usr.bin/tmux/window-tree.c index 8e7e217fd03..35f083b5f53 100644 --- a/usr.bin/tmux/window-tree.c +++ b/usr.bin/tmux/window-tree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-tree.c,v 1.29 2018/03/29 08:03:51 nicm Exp $ */ +/* $OpenBSD: window-tree.c,v 1.30 2018/04/10 10:48:44 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -18,6 +18,7 @@ #include <sys/types.h> +#include <ctype.h> #include <stdlib.h> #include <string.h> @@ -860,8 +861,6 @@ window_tree_destroy(struct window_tree_modedata *data) if (--data->references != 0) return; - mode_tree_free(data->data); - for (i = 0; i < data->item_size; i++) window_tree_free_item(data->item_list[i]); free(data->item_list); @@ -881,6 +880,7 @@ window_tree_free(struct window_pane *wp) return; data->dead = 1; + mode_tree_free(data->data); window_tree_destroy(data); } @@ -965,7 +965,7 @@ window_tree_command_callback(struct client *c, void *modedata, const char *s, { struct window_tree_modedata *data = modedata; - if (s == NULL || data->dead) + if (s == NULL || *s == '\0' || data->dead) return (0); data->entered = s; @@ -987,6 +987,77 @@ window_tree_command_free(void *modedata) window_tree_destroy(data); } +static void +window_tree_kill_each(__unused void* modedata, void* itemdata, + __unused struct client *c, __unused key_code key) +{ + struct window_tree_itemdata *item = itemdata; + struct session *s; + struct winlink *wl; + struct window_pane *wp; + + window_tree_pull_item(item, &s, &wl, &wp); + + switch (item->type) { + case WINDOW_TREE_NONE: + break; + case WINDOW_TREE_SESSION: + if (s != NULL) { + server_destroy_session(s); + session_destroy(s, __func__); + } + break; + case WINDOW_TREE_WINDOW: + if (wl != NULL) + server_kill_window(wl->window); + break; + case WINDOW_TREE_PANE: + if (wp != NULL) + server_kill_pane(wp); + break; + } +} + +static int +window_tree_kill_current_callback(struct client *c, void *modedata, + const char *s, __unused int done) +{ + struct window_tree_modedata *data = modedata; + struct mode_tree_data *mtd = data->data; + + if (s == NULL || *s == '\0' || data->dead) + return (0); + if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') + return (0); + + window_tree_kill_each(data, mode_tree_get_current(mtd), c, KEYC_NONE); + + data->references++; + cmdq_append(c, cmdq_get_callback(window_tree_command_done, data)); + + return (0); +} + +static int +window_tree_kill_tagged_callback(struct client *c, void *modedata, + const char *s, __unused int done) +{ + struct window_tree_modedata *data = modedata; + struct mode_tree_data *mtd = data->data; + + if (s == NULL || *s == '\0' || data->dead) + return (0); + if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') + return (0); + + mode_tree_each_tagged(mtd, window_tree_kill_each, c, KEYC_NONE, 1); + + data->references++; + cmdq_append(c, cmdq_get_callback(window_tree_command_done, data)); + + return (0); +} + static key_code window_tree_mouse(struct window_tree_modedata *data, key_code key, u_int x, struct window_tree_itemdata *item) @@ -1054,10 +1125,13 @@ window_tree_key(struct window_pane *wp, struct client *c, { struct window_tree_modedata *data = wp->modedata; struct window_tree_itemdata *item, *new_item; - char *name, *prompt; + char *name, *prompt = NULL; struct cmd_find_state fs; int finished; - u_int tagged, x, y; + u_int tagged, x, y, idx; + struct session *ns; + struct winlink *nwl; + struct window_pane *nwp; item = mode_tree_get_current(data->data); finished = mode_tree_key(data->data, c, &key, m, &x, &y); @@ -1074,6 +1148,46 @@ window_tree_key(struct window_pane *wp, struct client *c, case '>': data->offset++; break; + case 'x': + window_tree_pull_item(item, &ns, &nwl, &nwp); + switch (item->type) { + case WINDOW_TREE_NONE: + break; + case WINDOW_TREE_SESSION: + if (ns == NULL) + break; + xasprintf(&prompt, "Kill session %s? ", ns->name); + break; + case WINDOW_TREE_WINDOW: + if (nwl == NULL) + break; + xasprintf(&prompt, "Kill window %u? ", nwl->idx); + break; + case WINDOW_TREE_PANE: + if (nwp == NULL || window_pane_index(nwp, &idx) != 0) + break; + xasprintf(&prompt, "Kill pane %u? ", idx); + break; + } + if (prompt == NULL) + break; + data->references++; + status_prompt_set(c, prompt, "", + window_tree_kill_current_callback, window_tree_command_free, + data, PROMPT_SINGLE|PROMPT_NOFORMAT); + free(prompt); + break; + case 'X': + tagged = mode_tree_count_tagged(data->data); + if (tagged == 0) + break; + xasprintf(&prompt, "Kill %u tagged? ", tagged); + data->references++; + status_prompt_set(c, prompt, "", + window_tree_kill_tagged_callback, window_tree_command_free, + data, PROMPT_SINGLE|PROMPT_NOFORMAT); + free(prompt); + break; case ':': tagged = mode_tree_count_tagged(data->data); if (tagged != 0) |