Add x and X to choose-tree (with a confirmation prompt) to kill an

item. Suggested by Matt Zagrabelny.
pull/1298/merge
nicm 2018-04-10 10:48:44 +00:00
parent 5d616f4c72
commit c6975b3bb4
5 changed files with 140 additions and 15 deletions

View File

@ -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);
}

View File

@ -177,6 +177,22 @@ server_lock_client(struct client *c)
proc_send(c->peer, MSG_LOCK, -1, cmd, strlen(cmd) + 1);
}
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)
{

2
tmux.1
View File

@ -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"

1
tmux.h
View File

@ -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 **);

View File

@ -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)