mirror of
https://github.com/tmux/tmux.git
synced 2025-03-25 23:38:48 +00:00
Add S-Up and S-Down to move windows in tree mode. From David Mandelberg
in GitHub issue 4415.
This commit is contained in:
parent
b7d640e764
commit
a541be3951
45
mode-tree.c
45
mode-tree.c
@ -58,6 +58,7 @@ struct mode_tree_data {
|
||||
mode_tree_menu_cb menucb;
|
||||
mode_tree_height_cb heightcb;
|
||||
mode_tree_key_cb keycb;
|
||||
mode_tree_swap_cb swapcb;
|
||||
|
||||
struct mode_tree_list children;
|
||||
struct mode_tree_list saved;
|
||||
@ -287,6 +288,35 @@ mode_tree_down(struct mode_tree_data *mtd, int wrap)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
mode_tree_swap(struct mode_tree_data *mtd, int direction)
|
||||
{
|
||||
u_int current_depth = mtd->line_list[mtd->current].depth;
|
||||
u_int swap_with, swap_with_depth;
|
||||
|
||||
if (mtd->swapcb == NULL)
|
||||
return;
|
||||
|
||||
/* Find the next line at the same depth with the same parent . */
|
||||
swap_with = mtd->current;
|
||||
do {
|
||||
if (direction < 0 && swap_with < (u_int)-direction)
|
||||
return;
|
||||
if (direction > 0 && swap_with + direction >= mtd->line_size)
|
||||
return;
|
||||
swap_with += direction;
|
||||
swap_with_depth = mtd->line_list[swap_with].depth;
|
||||
} while (swap_with_depth > current_depth);
|
||||
if (swap_with_depth != current_depth)
|
||||
return;
|
||||
|
||||
if (mtd->swapcb(mtd->line_list[mtd->current].item->itemdata,
|
||||
mtd->line_list[swap_with].item->itemdata)) {
|
||||
mtd->current = swap_with;
|
||||
mode_tree_build(mtd);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
mode_tree_get_current(struct mode_tree_data *mtd)
|
||||
{
|
||||
@ -410,9 +440,9 @@ struct mode_tree_data *
|
||||
mode_tree_start(struct window_pane *wp, struct args *args,
|
||||
mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb,
|
||||
mode_tree_search_cb searchcb, mode_tree_menu_cb menucb,
|
||||
mode_tree_height_cb heightcb, mode_tree_key_cb keycb, void *modedata,
|
||||
const struct menu_item *menu, const char **sort_list, u_int sort_size,
|
||||
struct screen **s)
|
||||
mode_tree_height_cb heightcb, mode_tree_key_cb keycb,
|
||||
mode_tree_swap_cb swapcb, void *modedata, const struct menu_item *menu,
|
||||
const char **sort_list, u_int sort_size, struct screen **s)
|
||||
{
|
||||
struct mode_tree_data *mtd;
|
||||
const char *sort;
|
||||
@ -455,6 +485,7 @@ mode_tree_start(struct window_pane *wp, struct args *args,
|
||||
mtd->menucb = menucb;
|
||||
mtd->heightcb = heightcb;
|
||||
mtd->keycb = keycb;
|
||||
mtd->swapcb = swapcb;
|
||||
|
||||
TAILQ_INIT(&mtd->children);
|
||||
|
||||
@ -1147,6 +1178,14 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
||||
case 'n'|KEYC_CTRL:
|
||||
mode_tree_down(mtd, 1);
|
||||
break;
|
||||
case KEYC_UP|KEYC_SHIFT:
|
||||
case 'K':
|
||||
mode_tree_swap(mtd, -1);
|
||||
break;
|
||||
case KEYC_DOWN|KEYC_SHIFT:
|
||||
case 'J':
|
||||
mode_tree_swap(mtd, 1);
|
||||
break;
|
||||
case KEYC_PPAGE:
|
||||
case 'b'|KEYC_CTRL:
|
||||
for (i = 0; i < mtd->height; i++) {
|
||||
|
6
tmux.1
6
tmux.1
@ -2713,6 +2713,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 "S-Up" Ta "Swap the current window with the previous one"
|
||||
.It Li "S-Down" Ta "Swap the current window with the next one"
|
||||
.It Li "+" Ta "Expand selected item"
|
||||
.It Li "-" Ta "Collapse selected item"
|
||||
.It Li "M-+" Ta "Expand all items"
|
||||
@ -5942,6 +5944,7 @@ The following variables are available, where appropriate:
|
||||
.It Li "command_list_name" Ta "" Ta "Command name if listing commands"
|
||||
.It Li "command_list_usage" Ta "" Ta "Command usage if listing commands"
|
||||
.It Li "config_files" Ta "" Ta "List of configuration files loaded"
|
||||
.It Li "cursor_blinking" Ta "" Ta "1 if the cursor is blinking"
|
||||
.It Li "copy_cursor_hyperlink" Ta "" Ta "Hyperlink under cursor in copy mode"
|
||||
.It Li "copy_cursor_line" Ta "" Ta "Line the cursor is on in copy mode"
|
||||
.It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode"
|
||||
@ -5949,7 +5952,10 @@ The following variables are available, where appropriate:
|
||||
.It Li "copy_cursor_y" Ta "" Ta "Cursor Y position in copy mode"
|
||||
.It Li "current_file" Ta "" Ta "Current configuration file"
|
||||
.It Li "cursor_character" Ta "" Ta "Character at cursor in pane"
|
||||
.It Li "cursor_colour" Ta "" Ta "Cursor colour in pane"
|
||||
.It Li "cursor_flag" Ta "" Ta "Pane cursor flag"
|
||||
.It Li "cursor_shape" Ta "" Ta "Cursor shape in pane"
|
||||
.It Li "cursor_very_visible" Ta "" Ta "1 if the cursor is in very visible mode"
|
||||
.It Li "cursor_x" Ta "" Ta "Cursor X position in pane"
|
||||
.It Li "cursor_y" Ta "" Ta "Cursor Y position in pane"
|
||||
.It Li "history_bytes" Ta "" Ta "Number of bytes in window history"
|
||||
|
6
tmux.h
6
tmux.h
@ -3276,6 +3276,7 @@ typedef int (*mode_tree_search_cb)(void *, void *, const char *);
|
||||
typedef void (*mode_tree_menu_cb)(void *, struct client *, key_code);
|
||||
typedef u_int (*mode_tree_height_cb)(void *, u_int);
|
||||
typedef key_code (*mode_tree_key_cb)(void *, void *, u_int);
|
||||
typedef int (*mode_tree_swap_cb)(void *, void *);
|
||||
typedef void (*mode_tree_each_cb)(void *, void *, struct client *, key_code);
|
||||
u_int mode_tree_count_tagged(struct mode_tree_data *);
|
||||
void *mode_tree_get_current(struct mode_tree_data *);
|
||||
@ -3290,8 +3291,9 @@ void mode_tree_up(struct mode_tree_data *, int);
|
||||
int mode_tree_down(struct mode_tree_data *, int);
|
||||
struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *,
|
||||
mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb,
|
||||
mode_tree_menu_cb, mode_tree_height_cb, mode_tree_key_cb, void *,
|
||||
const struct menu_item *, const char **, u_int, struct screen **);
|
||||
mode_tree_menu_cb, mode_tree_height_cb, mode_tree_key_cb,
|
||||
mode_tree_swap_cb, void *, const struct menu_item *, const char **,
|
||||
u_int, struct screen **);
|
||||
void mode_tree_zoom(struct mode_tree_data *, struct args *);
|
||||
void mode_tree_build(struct mode_tree_data *);
|
||||
void mode_tree_free(struct mode_tree_data *);
|
||||
|
@ -350,7 +350,7 @@ window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
|
||||
|
||||
data->data = mode_tree_start(wp, args, window_buffer_build,
|
||||
window_buffer_draw, window_buffer_search, window_buffer_menu, NULL,
|
||||
window_buffer_get_key, data, window_buffer_menu_items,
|
||||
window_buffer_get_key, NULL, data, window_buffer_menu_items,
|
||||
window_buffer_sort_list, nitems(window_buffer_sort_list), &s);
|
||||
mode_tree_zoom(data->data, args);
|
||||
|
||||
|
@ -310,7 +310,7 @@ window_client_init(struct window_mode_entry *wme,
|
||||
|
||||
data->data = mode_tree_start(wp, args, window_client_build,
|
||||
window_client_draw, NULL, window_client_menu, NULL,
|
||||
window_client_get_key, data, window_client_menu_items,
|
||||
window_client_get_key, NULL, data, window_client_menu_items,
|
||||
window_client_sort_list, nitems(window_client_sort_list), &s);
|
||||
mode_tree_zoom(data->data, args);
|
||||
|
||||
|
@ -891,8 +891,8 @@ window_customize_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
|
||||
|
||||
data->data = mode_tree_start(wp, args, window_customize_build,
|
||||
window_customize_draw, NULL, window_customize_menu,
|
||||
window_customize_height, NULL, data, window_customize_menu_items,
|
||||
NULL, 0, &s);
|
||||
window_customize_height, NULL, NULL, data,
|
||||
window_customize_menu_items, NULL, 0, &s);
|
||||
mode_tree_zoom(data->data, args);
|
||||
|
||||
mode_tree_build(data->data);
|
||||
|
@ -902,6 +902,58 @@ window_tree_get_key(void *modedata, void *itemdata, u_int line)
|
||||
return (key);
|
||||
}
|
||||
|
||||
static int
|
||||
window_tree_swap(void *cur_itemdata, void *other_itemdata)
|
||||
{
|
||||
struct window_tree_itemdata *cur = cur_itemdata;
|
||||
struct window_tree_itemdata *other = other_itemdata;
|
||||
struct session *cur_session, *other_session;
|
||||
struct winlink *cur_winlink, *other_winlink;
|
||||
struct window *cur_window, *other_window;
|
||||
struct window_pane *cur_pane, *other_pane;
|
||||
|
||||
if (cur->type != other->type)
|
||||
return (0);
|
||||
if (cur->type != WINDOW_TREE_WINDOW)
|
||||
return (0);
|
||||
|
||||
window_tree_pull_item(cur, &cur_session, &cur_winlink, &cur_pane);
|
||||
window_tree_pull_item(other, &other_session, &other_winlink,
|
||||
&other_pane);
|
||||
|
||||
if (cur_session != other_session)
|
||||
return (0);
|
||||
|
||||
if (window_tree_sort->field != WINDOW_TREE_BY_INDEX &&
|
||||
window_tree_cmp_window(&cur_winlink, &other_winlink) != 0) {
|
||||
/*
|
||||
* Swapping indexes would not swap positions in the tree, so
|
||||
* prevent swapping to avoid confusing the user.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
other_window = other_winlink->window;
|
||||
TAILQ_REMOVE(&other_window->winlinks, other_winlink, wentry);
|
||||
cur_window = cur_winlink->window;
|
||||
TAILQ_REMOVE(&cur_window->winlinks, cur_winlink, wentry);
|
||||
|
||||
other_winlink->window = cur_window;
|
||||
TAILQ_INSERT_TAIL(&cur_window->winlinks, other_winlink, wentry);
|
||||
cur_winlink->window = other_window;
|
||||
TAILQ_INSERT_TAIL(&other_window->winlinks, cur_winlink, wentry);
|
||||
|
||||
if (cur_session->curw == cur_winlink)
|
||||
session_set_current(cur_session, other_winlink);
|
||||
else if (cur_session->curw == other_winlink)
|
||||
session_set_current(cur_session, cur_winlink);
|
||||
session_group_synchronize_from(cur_session);
|
||||
server_redraw_session_group(cur_session);
|
||||
recalculate_sizes();
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static struct screen *
|
||||
window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
|
||||
struct args *args)
|
||||
@ -940,7 +992,7 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
|
||||
|
||||
data->data = mode_tree_start(wp, args, window_tree_build,
|
||||
window_tree_draw, window_tree_search, window_tree_menu, NULL,
|
||||
window_tree_get_key, data, window_tree_menu_items,
|
||||
window_tree_get_key, window_tree_swap, data, window_tree_menu_items,
|
||||
window_tree_sort_list, nitems(window_tree_sort_list), &s);
|
||||
mode_tree_zoom(data->data, args);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user