diff options
author | Thomas Adam <thomas@xteddy.org> | 2018-04-10 13:02:28 +0100 |
---|---|---|
committer | Thomas Adam <thomas@xteddy.org> | 2018-04-10 13:02:28 +0100 |
commit | 1bd66b65a330ffdf46eac668de92bf632ab5ad82 (patch) | |
tree | 6fab4904461f291c7f873353523259aded2c57e7 | |
parent | 68bf7c532b83efdb1b29f1ee9a3e06f31f55dcd8 (diff) | |
parent | 051a29ca03718c8fedd5918ba86556f29672348e (diff) | |
download | rtmux-1bd66b65a330ffdf46eac668de92bf632ab5ad82.tar.gz rtmux-1bd66b65a330ffdf46eac668de92bf632ab5ad82.tar.bz2 rtmux-1bd66b65a330ffdf46eac668de92bf632ab5ad82.zip |
Merge branch 'obsd-master'
-rw-r--r-- | cmd-kill-pane.c | 12 | ||||
-rw-r--r-- | input.c | 25 | ||||
-rw-r--r-- | server-fn.c | 16 | ||||
-rw-r--r-- | tmux.1 | 2 | ||||
-rw-r--r-- | tmux.h | 1 | ||||
-rw-r--r-- | window-tree.c | 124 |
6 files changed, 156 insertions, 24 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); } @@ -1845,10 +1845,12 @@ input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i) ptr = copy = xstrdup(s); while ((out = strsep(&ptr, ":")) != NULL) { - p[n++] = strtonum(out, 0, INT_MAX, &errstr); - if (errstr != NULL || n == nitems(p)) { - free(copy); - return; + if (*out != '\0') { + p[n++] = strtonum(out, 0, INT_MAX, &errstr); + if (errstr != NULL || n == nitems(p)) { + free(copy); + return; + } } log_debug("%s: %u = %d", __func__, n - 1, p[n - 1]); } @@ -1856,16 +1858,21 @@ input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i) if (n == 0 || (p[0] != 38 && p[0] != 48)) return; - switch (p[1]) { + if (p[1] == -1) + i = 2; + else + i = 1; + switch (p[i]) { case 2: - if (n != 5) + if (n < i + 4) break; - input_csi_dispatch_sgr_rgb_do(ictx, p[0], p[2], p[3], p[4]); + input_csi_dispatch_sgr_rgb_do(ictx, p[0], p[i + 1], p[i + 2], + p[i + 3]); break; case 5: - if (n != 3) + if (n < i + 2) break; - input_csi_dispatch_sgr_256_do(ictx, p[0], p[2]); + input_csi_dispatch_sgr_256_do(ictx, p[0], p[i + 1]); break; } } diff --git a/server-fn.c b/server-fn.c index 383ac120..df4cc5b9 100644 --- a/server-fn.c +++ b/server-fn.c @@ -176,6 +176,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; @@ -1463,6 +1463,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" @@ -1924,6 +1924,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 2c466b36..234f4126 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) |