summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2018-04-10 10:48:44 +0000
committernicm <nicm>2018-04-10 10:48:44 +0000
commitc6975b3bb46c35f8b41d934fd622033aa79a828c (patch)
tree95f20f3d706b4ecd406a8066961feadc2447489d
parent5d616f4c729d295f85c35696dd31975bbf670566 (diff)
Add x and X to choose-tree (with a confirmation prompt) to kill an
item. Suggested by Matt Zagrabelny.
-rw-r--r--cmd-kill-pane.c12
-rw-r--r--server-fn.c16
-rw-r--r--tmux.12
-rw-r--r--tmux.h1
-rw-r--r--window-tree.c124
5 files changed, 140 insertions, 15 deletions
diff --git a/cmd-kill-pane.c b/cmd-kill-pane.c
index a8a423d0..01b1f518 100644
--- a/cmd-kill-pane.c
+++ b/cmd-kill-pane.c
@@ -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/server-fn.c b/server-fn.c
index ef96bf58..b4defdd4 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -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/tmux.1 b/tmux.1
index 3db23786..31faa1f6 100644
--- a/tmux.1
+++ b/tmux.1
@@ -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/tmux.h b/tmux.h
index aa3ba3d1..9c901bd5 100644
--- a/tmux.h
+++ b/tmux.h
@@ -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/window-tree.c b/window-tree.c
index 926eaec1..52ab195e 100644
--- a/window-tree.c
+++ b/window-tree.c
@@ -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)