summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2018-04-10 10:48:45 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2018-04-10 10:48:45 +0000
commit742eefdbef46eba88fc67e62bb1c6a3963dc19c8 (patch)
treec541f75ece70ffa29af6e307f3a817f2031ba04c
parentbeaabf6cd8d215b34e13b596af794e10b6b7dd1d (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.c14
-rw-r--r--usr.bin/tmux/server-fn.c18
-rw-r--r--usr.bin/tmux/tmux.16
-rw-r--r--usr.bin/tmux/tmux.h3
-rw-r--r--usr.bin/tmux/window-tree.c126
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)