mirror of
https://github.com/tmux/tmux.git
synced 2024-10-31 22:58:49 +00:00
Merge branch 'obsd-master'
This commit is contained in:
commit
c0116b2c5b
@ -34,9 +34,9 @@ const struct cmd_entry cmd_display_menu_entry = {
|
|||||||
.name = "display-menu",
|
.name = "display-menu",
|
||||||
.alias = "menu",
|
.alias = "menu",
|
||||||
|
|
||||||
.args = { "c:FM:t:T:x:y:", 0, 0 },
|
.args = { "c:t:T:x:y:", 1, -1 },
|
||||||
.usage = "[-F] [-c target-client] [-M menu] " CMD_TARGET_PANE_USAGE " "
|
.usage = "[-c target-client] " CMD_TARGET_PANE_USAGE " [-T title] "
|
||||||
"[-T title] [-x position] [-y position]",
|
"[-x position] [-y position] name key command ...",
|
||||||
|
|
||||||
.target = { 't', CMD_FIND_PANE, 0 },
|
.target = { 't', CMD_FIND_PANE, 0 },
|
||||||
|
|
||||||
@ -55,10 +55,11 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct cmd_find_state *fs = &item->target;
|
struct cmd_find_state *fs = &item->target;
|
||||||
struct menu *menu = NULL;
|
struct menu *menu = NULL;
|
||||||
struct style_range *sr;
|
struct style_range *sr;
|
||||||
const char *string, *xp, *yp;
|
struct menu_item menu_item;
|
||||||
int at, flags;
|
const char *xp, *yp, *key;
|
||||||
|
char *title, *name;
|
||||||
|
int at, flags, i;
|
||||||
u_int px, py, ox, oy, sx, sy;
|
u_int px, py, ox, oy, sx, sy;
|
||||||
char *title;
|
|
||||||
|
|
||||||
if ((c = cmd_find_client(item, args_get(args, 'c'), 0)) == NULL)
|
if ((c = cmd_find_client(item, args_get(args, 'c'), 0)) == NULL)
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
@ -66,23 +67,37 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
at = status_at_line(c);
|
at = status_at_line(c);
|
||||||
|
|
||||||
string = args_get(args, 'M');
|
|
||||||
if (string == NULL) {
|
|
||||||
cmdq_error(item, "no menu specified");
|
|
||||||
return (CMD_RETURN_ERROR);
|
|
||||||
}
|
|
||||||
if (args_has(args, 'F'))
|
|
||||||
string = format_single(NULL, string, c, s, wl, wp);
|
|
||||||
else
|
|
||||||
string = xstrdup(string);
|
|
||||||
if (args_has(args, 'T'))
|
if (args_has(args, 'T'))
|
||||||
title = format_single(NULL, args_get(args, 'T'), c, s, wl, wp);
|
title = format_single(NULL, args_get(args, 'T'), c, s, wl, wp);
|
||||||
else
|
else
|
||||||
title = xstrdup("");
|
title = xstrdup("");
|
||||||
menu = menu_create(string, item, c, fs, title);
|
|
||||||
|
menu = menu_create(title);
|
||||||
|
|
||||||
|
for (i = 0; i != args->argc; /* nothing */) {
|
||||||
|
name = args->argv[i++];
|
||||||
|
if (*name == '\0') {
|
||||||
|
menu_add_item(menu, NULL, item, c, fs);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->argc - i < 2) {
|
||||||
|
cmdq_error(item, "not enough arguments");
|
||||||
|
free(title);
|
||||||
|
menu_free(menu);
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
key = args->argv[i++];
|
||||||
|
|
||||||
|
menu_item.name = name;
|
||||||
|
menu_item.key = key_string_lookup_string(key);
|
||||||
|
menu_item.command = args->argv[i++];
|
||||||
|
|
||||||
|
menu_add_item(menu, &menu_item, item, c, fs);
|
||||||
|
}
|
||||||
free(title);
|
free(title);
|
||||||
if (menu == NULL) {
|
if (menu == NULL) {
|
||||||
cmdq_error(item, "invalid menu %s", string);
|
cmdq_error(item, "invalid menu arguments");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
if (menu->count == 0) {
|
if (menu->count == 0) {
|
||||||
|
51
format.c
51
format.c
@ -54,52 +54,6 @@ static void format_defaults_session(struct format_tree *,
|
|||||||
static void format_defaults_client(struct format_tree *, struct client *);
|
static void format_defaults_client(struct format_tree *, struct client *);
|
||||||
static void format_defaults_winlink(struct format_tree *, struct winlink *);
|
static void format_defaults_winlink(struct format_tree *, struct winlink *);
|
||||||
|
|
||||||
/* Default menus. */
|
|
||||||
#define DEFAULT_CLIENT_MENU \
|
|
||||||
"Detach,d,detach-client|" \
|
|
||||||
"Detach & Kill,X,detach-client -P|" \
|
|
||||||
"Detach Others,o,detach-client -a|" \
|
|
||||||
"|" \
|
|
||||||
"Lock,l,lock-client"
|
|
||||||
#define DEFAULT_SESSION_MENU \
|
|
||||||
"Next,n,switch-client -n|" \
|
|
||||||
"Previous,p,switch-client -p|" \
|
|
||||||
"|" \
|
|
||||||
"Renumber,N,move-window -r|" \
|
|
||||||
"Rename,n,command-prompt -I \"#S\" \"rename-session -- '%%'\"|" \
|
|
||||||
"|" \
|
|
||||||
"New Session,s,new-session|" \
|
|
||||||
"New Window,w,new-window"
|
|
||||||
#define DEFAULT_WINDOW_MENU \
|
|
||||||
"Swap Left,l,swap-window -t:-1|" \
|
|
||||||
"Swap Right,r,swap-window -t:+1|" \
|
|
||||||
"#{?pane_marked_set,,#[dim]}Swap Marked,s,swap-window|" \
|
|
||||||
"|" \
|
|
||||||
"Kill,X,kill-window|" \
|
|
||||||
"Respawn,R,respawn-window -k|" \
|
|
||||||
"#{?pane_marked,Unmark,Mark},m,select-pane -m|" \
|
|
||||||
"Rename,n,command-prompt -I \"#W\" \"rename-window -- '%%'\"|" \
|
|
||||||
"|" \
|
|
||||||
"New After,w,new-window -a|" \
|
|
||||||
"New At End,W,new-window"
|
|
||||||
#define DEFAULT_PANE_MENU \
|
|
||||||
"#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},},C-r,copy-mode -t=; send -Xt= search-backward \"#{q:mouse_word}\"|" \
|
|
||||||
"#{?mouse_word,Type #[underscore]#{=/9/...:mouse_word},},C-y,send-keys -l \"#{q:mouse_word}\"|" \
|
|
||||||
"#{?mouse_word,Copy #[underscore]#{=/9/...:mouse_word},},c,set-buffer \"#{q:mouse_word}\"|" \
|
|
||||||
"#{?mouse_line,Copy Line,},l,set-buffer \"#{q:mouse_line}\"|" \
|
|
||||||
"|" \
|
|
||||||
"Horizontal Split,h,split-window -h|" \
|
|
||||||
"Vertical Split,v,split-window -v|" \
|
|
||||||
"|" \
|
|
||||||
"Swap Up,u,swap-pane -U|" \
|
|
||||||
"Swap Down,d,swap-pane -D|" \
|
|
||||||
"#{?pane_marked_set,,#[dim]}Swap Marked,s,swap-pane|" \
|
|
||||||
"|" \
|
|
||||||
"Kill,X,kill-pane|" \
|
|
||||||
"Respawn,R,respawn-pane -k|" \
|
|
||||||
"#{?pane_marked,Unmark,Mark},m,select-pane -m|" \
|
|
||||||
"#{?window_zoomed_flag,Unzoom,Zoom},z,resize-pane -Z"
|
|
||||||
|
|
||||||
/* Entry in format job tree. */
|
/* Entry in format job tree. */
|
||||||
struct format_job {
|
struct format_job {
|
||||||
struct client *client;
|
struct client *client;
|
||||||
@ -960,11 +914,6 @@ format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
format_add(ft, "client_menu", "%s", DEFAULT_CLIENT_MENU);
|
|
||||||
format_add(ft, "session_menu", "%s", DEFAULT_SESSION_MENU);
|
|
||||||
format_add(ft, "window_menu", "%s", DEFAULT_WINDOW_MENU);
|
|
||||||
format_add(ft, "pane_menu", "%s", DEFAULT_PANE_MENU);
|
|
||||||
|
|
||||||
if (item != NULL)
|
if (item != NULL)
|
||||||
format_create_add_item(ft, item);
|
format_create_add_item(ft, item);
|
||||||
|
|
||||||
|
@ -280,10 +280,51 @@ key_bindings_init(void)
|
|||||||
"bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'",
|
"bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'",
|
||||||
"bind -n MouseDown3Pane if -Ft= '#{||:mouse_any_flag,pane_in_mode}' 'select-pane -t=; send-keys -M' 'select-pane -mt='",
|
"bind -n MouseDown3Pane if -Ft= '#{||:mouse_any_flag,pane_in_mode}' 'select-pane -t=; send-keys -M' 'select-pane -mt='",
|
||||||
"bind -n WheelUpPane if -Ft= '#{mouse_any_flag}' 'send-keys -M' 'if -Ft= \"#{pane_in_mode}\" \"send-keys -M\" \"copy-mode -et=\"'",
|
"bind -n WheelUpPane if -Ft= '#{mouse_any_flag}' 'send-keys -M' 'if -Ft= \"#{pane_in_mode}\" \"send-keys -M\" \"copy-mode -et=\"'",
|
||||||
"bind -n MouseDown3StatusRight display-menu -t= -xM -yS -F -M \"#{client_menu}\" -T \"#[align=centre]#{client_name}\"",
|
|
||||||
"bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -F -M \"#{session_menu}\" -T \"#[align=centre]#{session_name}\"",
|
"bind -n MouseDown3StatusRight display-menu -t= -xM -yS -T \"#[align=centre]#{client_name}\""
|
||||||
"bind -n MouseDown3Status display-menu -t= -xW -yS -F -M \"#{window_menu}\" -T \"#[align=centre]#{window_index}:#{window_name}\"",
|
" 'Detach' 'd' {detach-client}"
|
||||||
"bind -n M-MouseDown3Pane display-menu -t= -xM -yM -F -M \"#{pane_menu}\" -T \"#[align=centre]#{pane_index} (#{pane_id})\"",
|
" 'Detach & Kill' 'X' {detach-client -P}"
|
||||||
|
" 'Detach Others' 'o' {detach-client -a}"
|
||||||
|
" ''"
|
||||||
|
" 'Lock' 'l' {lock-client}",
|
||||||
|
"bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -T \"#[align=centre]#{session_name}\""
|
||||||
|
" 'Next' 'n' {switch-client -n}"
|
||||||
|
" 'Previous' 'p' {switch-client -p}"
|
||||||
|
" ''"
|
||||||
|
" 'Renumber' 'N' {move-window -r}"
|
||||||
|
" 'Rename' 'n' {command-prompt -I \"#S\" \"rename-session -- '%%'\"}"
|
||||||
|
" ''"
|
||||||
|
" 'New Session' 's' {new-session}"
|
||||||
|
" 'New Window' 'w' {new-window}",
|
||||||
|
"bind -n MouseDown3Status display-menu -t= -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\""
|
||||||
|
" 'Swap Left' 'l' {swap-window -t:-1}"
|
||||||
|
" 'Swap Right' 'r' {swap-window -t:+1}"
|
||||||
|
" '#{?pane_marked_set,,#[dim]}Swap Marked' 's' {swap-window}"
|
||||||
|
" ''"
|
||||||
|
" 'Kill' 'X' {kill-window}"
|
||||||
|
" 'Respawn' 'R' {respawn-window -k}"
|
||||||
|
" '#{?pane_marked,Unmark,Mark}' 'm' {select-pane -m}"
|
||||||
|
" 'Rename' 'n' {command-prompt -I \"#W\" \"rename-window -- '%%'\"}"
|
||||||
|
" ''"
|
||||||
|
" 'New After' 'w' {new-window -a}"
|
||||||
|
" 'New At End' 'W' {new-window}",
|
||||||
|
"bind -n M-MouseDown3Pane display-menu -t= -xM -yM -T \"#[align=centre]#{pane_index} (#{pane_id})\""
|
||||||
|
" '#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},}' 'C-r' {copy-mode -t=; send -Xt= search-backward \"#{q:mouse_word}\"}"
|
||||||
|
" '#{?mouse_word,Type #[underscore]#{=/9/...:mouse_word},}' 'C-y' {send-keys -l -- \"#{q:mouse_word}\"}"
|
||||||
|
" '#{?mouse_word,Copy #[underscore]#{=/9/...:mouse_word},}' 'c' {set-buffer -- \"#{q:mouse_word}\"}"
|
||||||
|
" '#{?mouse_line,Copy Line,}' 'l' {set-buffer -- \"#{q:mouse_line}\"}"
|
||||||
|
" ''"
|
||||||
|
" 'Horizontal Split' 'h' {split-window -h}"
|
||||||
|
" 'Vertical Split' 'v' {split-window -v}"
|
||||||
|
" ''"
|
||||||
|
" 'Swap Up' 'u' {swap-pane -U}"
|
||||||
|
" 'Swap Down' 'd' {swap-pane -D}"
|
||||||
|
" '#{?pane_marked_set,,#[dim]}Swap Marked' 's' {swap-pane}"
|
||||||
|
" ''"
|
||||||
|
" 'Kill' 'X' {kill-pane}"
|
||||||
|
" 'Respawn' 'R' {respawn-pane -k}"
|
||||||
|
" '#{?pane_marked,Unmark,Mark}' 'm' {select-pane -m}"
|
||||||
|
" '#{?window_zoomed_flag,Unzoom,Zoom}' 'z' {resize-pane -Z}",
|
||||||
|
|
||||||
"bind -Tcopy-mode C-Space send -X begin-selection",
|
"bind -Tcopy-mode C-Space send -X begin-selection",
|
||||||
"bind -Tcopy-mode C-a send -X start-of-line",
|
"bind -Tcopy-mode C-a send -X start-of-line",
|
||||||
|
114
menu.c
114
menu.c
@ -40,49 +40,63 @@ struct menu_data {
|
|||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
void
|
||||||
menu_add_item(struct menu *menu, struct menu_item *item,
|
menu_add_items(struct menu *menu, const struct menu_item *items,
|
||||||
|
struct cmdq_item *qitem, struct client *c, struct cmd_find_state *fs)
|
||||||
|
{
|
||||||
|
const struct menu_item *loop;
|
||||||
|
|
||||||
|
for (loop = items; loop->name != NULL; loop++)
|
||||||
|
menu_add_item(menu, loop, qitem, c, fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
menu_add_item(struct menu *menu, const struct menu_item *item,
|
||||||
struct cmdq_item *qitem, struct client *c, struct cmd_find_state *fs)
|
struct cmdq_item *qitem, struct client *c, struct cmd_find_state *fs)
|
||||||
{
|
{
|
||||||
struct menu_item *new_item;
|
struct menu_item *new_item;
|
||||||
const char *key;
|
const char *key, *cmd;
|
||||||
char *name;
|
char *s, *name;
|
||||||
u_int width;
|
u_int width;
|
||||||
|
int line;
|
||||||
|
|
||||||
|
line = (item == NULL || item->name == NULL || *item->name == '\0');
|
||||||
|
if (line && menu->count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
menu->items = xreallocarray(menu->items, menu->count + 1,
|
menu->items = xreallocarray(menu->items, menu->count + 1,
|
||||||
sizeof *menu->items);
|
sizeof *menu->items);
|
||||||
new_item = &menu->items[menu->count++];
|
new_item = &menu->items[menu->count++];
|
||||||
memset(new_item, 0, sizeof *new_item);
|
memset(new_item, 0, sizeof *new_item);
|
||||||
|
|
||||||
if (item == NULL || *item->name == '\0') /* horizontal line */
|
if (line)
|
||||||
return;
|
return;
|
||||||
if (fs != NULL) {
|
|
||||||
name = format_single(qitem, item->name, c, fs->s, fs->wl,
|
if (fs != NULL)
|
||||||
fs->wp);
|
s = format_single(qitem, item->name, c, fs->s, fs->wl, fs->wp);
|
||||||
} else
|
else
|
||||||
name = format_single(qitem, item->name, c, NULL, NULL, NULL);
|
s = format_single(qitem, item->name, c, NULL, NULL, NULL);
|
||||||
if (*name == '\0') { /* no item if empty after format expanded */
|
if (*s == '\0') { /* no item if empty after format expanded */
|
||||||
menu->count--;
|
menu->count--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (item->key != KEYC_UNKNOWN) {
|
if (item->key != KEYC_UNKNOWN && item->key != KEYC_NONE) {
|
||||||
key = key_string_lookup_key(item->key);
|
key = key_string_lookup_key(item->key);
|
||||||
xasprintf(&new_item->name, "%s#[default] #[align=right](%s)",
|
xasprintf(&name, "%s#[default] #[align=right](%s)", s, key);
|
||||||
name, key);
|
|
||||||
} else
|
} else
|
||||||
xasprintf(&new_item->name, "%s", name);
|
xasprintf(&name, "%s", s);
|
||||||
free(name);
|
new_item->name = name;
|
||||||
|
free(s);
|
||||||
|
|
||||||
if (item->command != NULL) {
|
cmd = item->command;
|
||||||
if (fs != NULL) {
|
if (cmd != NULL) {
|
||||||
new_item->command = format_single(qitem, item->command,
|
if (fs != NULL)
|
||||||
c, fs->s, fs->wl, fs->wp);
|
s = format_single(qitem, cmd, c, fs->s, fs->wl, fs->wp);
|
||||||
} else {
|
else
|
||||||
new_item->command = format_single(qitem, item->command,
|
s = format_single(qitem, cmd, c, NULL, NULL, NULL);
|
||||||
c, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
new_item->command = NULL;
|
s = NULL;
|
||||||
|
new_item->command = s;
|
||||||
new_item->key = item->key;
|
new_item->key = item->key;
|
||||||
|
|
||||||
width = format_width(new_item->name);
|
width = format_width(new_item->name);
|
||||||
@ -90,56 +104,14 @@ menu_add_item(struct menu *menu, struct menu_item *item,
|
|||||||
menu->width = width;
|
menu->width = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
menu_parse_item(struct menu *menu, const char *s, struct cmdq_item *qitem,
|
|
||||||
struct client *c, struct cmd_find_state *fs)
|
|
||||||
{
|
|
||||||
char *copy, *first;
|
|
||||||
const char *second, *third;
|
|
||||||
struct menu_item item;
|
|
||||||
|
|
||||||
first = copy = xstrdup(s);
|
|
||||||
if ((second = format_skip(first, ",")) != NULL) {
|
|
||||||
*(char *)second++ = '\0';
|
|
||||||
if ((third = format_skip(second, ",")) != NULL) {
|
|
||||||
*(char *)third++ = '\0';
|
|
||||||
|
|
||||||
item.name = first;
|
|
||||||
item.command = (char *)third;
|
|
||||||
item.key = key_string_lookup_string(second);
|
|
||||||
menu_add_item(menu, &item, qitem, c, fs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(copy);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct menu *
|
struct menu *
|
||||||
menu_create(const char *s, struct cmdq_item *qitem, struct client *c,
|
menu_create(const char *title)
|
||||||
struct cmd_find_state *fs, const char *title)
|
|
||||||
{
|
{
|
||||||
struct menu *menu;
|
struct menu *menu;
|
||||||
char *copy, *string, *next;
|
|
||||||
|
|
||||||
if (*s == '\0')
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
menu = xcalloc(1, sizeof *menu);
|
menu = xcalloc(1, sizeof *menu);
|
||||||
menu->title = xstrdup(title);
|
menu->title = xstrdup(title);
|
||||||
|
|
||||||
copy = string = xstrdup(s);
|
|
||||||
do {
|
|
||||||
next = (char *)format_skip(string, "|");
|
|
||||||
if (next != NULL)
|
|
||||||
*next++ = '\0';
|
|
||||||
if (*string == '\0') {
|
|
||||||
if (menu->count != 0)
|
|
||||||
menu_add_item(menu, NULL, qitem, c, fs);
|
|
||||||
} else
|
|
||||||
menu_parse_item(menu, string, qitem, c, fs);
|
|
||||||
string = next;
|
|
||||||
} while (next != NULL);
|
|
||||||
free(copy);
|
|
||||||
|
|
||||||
return (menu);
|
return (menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,12 +121,12 @@ menu_free(struct menu *menu)
|
|||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
for (i = 0; i < menu->count; i++) {
|
for (i = 0; i < menu->count; i++) {
|
||||||
free(menu->items[i].name);
|
free((void *)menu->items[i].name);
|
||||||
free(menu->items[i].command);
|
free((void *)menu->items[i].command);
|
||||||
}
|
}
|
||||||
free(menu->items);
|
free(menu->items);
|
||||||
|
|
||||||
free(menu->title);
|
free((void *)menu->title);
|
||||||
free(menu);
|
free(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
mode-tree.c
28
mode-tree.c
@ -35,7 +35,7 @@ struct mode_tree_data {
|
|||||||
|
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
void *modedata;
|
void *modedata;
|
||||||
const char *menu;
|
const struct menu_item *menu;
|
||||||
|
|
||||||
const char **sort_list;
|
const char **sort_list;
|
||||||
u_int sort_size;
|
u_int sort_size;
|
||||||
@ -100,11 +100,14 @@ struct mode_tree_menu {
|
|||||||
|
|
||||||
static void mode_tree_free_items(struct mode_tree_list *);
|
static void mode_tree_free_items(struct mode_tree_list *);
|
||||||
|
|
||||||
#define MODE_TREE_MENU \
|
static const struct menu_item mode_tree_menu_items[] = {
|
||||||
"Scroll Left,<,|" \
|
{ "Scroll Left", '<', NULL },
|
||||||
"Scroll Right,>,|" \
|
{ "Scroll Right", '>', NULL },
|
||||||
"|" \
|
{ "", KEYC_NONE, NULL },
|
||||||
"Cancel,q,"
|
{ "Cancel", 'q', NULL },
|
||||||
|
|
||||||
|
{ NULL, KEYC_NONE, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
static struct mode_tree_item *
|
static struct mode_tree_item *
|
||||||
mode_tree_find_item(struct mode_tree_list *mtl, uint64_t tag)
|
mode_tree_find_item(struct mode_tree_list *mtl, uint64_t tag)
|
||||||
@ -315,7 +318,7 @@ struct mode_tree_data *
|
|||||||
mode_tree_start(struct window_pane *wp, struct args *args,
|
mode_tree_start(struct window_pane *wp, struct args *args,
|
||||||
mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb,
|
mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb,
|
||||||
mode_tree_search_cb searchcb, mode_tree_menu_cb menucb, void *modedata,
|
mode_tree_search_cb searchcb, mode_tree_menu_cb menucb, void *modedata,
|
||||||
const char *menu, const char **sort_list, u_int sort_size,
|
const struct menu_item *menu, const char **sort_list, u_int sort_size,
|
||||||
struct screen **s)
|
struct screen **s)
|
||||||
{
|
{
|
||||||
struct mode_tree_data *mtd;
|
struct mode_tree_data *mtd;
|
||||||
@ -812,8 +815,8 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x,
|
|||||||
{
|
{
|
||||||
struct mode_tree_item *mti;
|
struct mode_tree_item *mti;
|
||||||
struct menu *menu;
|
struct menu *menu;
|
||||||
|
const struct menu_item *items;
|
||||||
struct mode_tree_menu *mtm;
|
struct mode_tree_menu *mtm;
|
||||||
const char *s;
|
|
||||||
char *title;
|
char *title;
|
||||||
u_int line;
|
u_int line;
|
||||||
|
|
||||||
@ -824,16 +827,15 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x,
|
|||||||
mti = mtd->line_list[line].item;
|
mti = mtd->line_list[line].item;
|
||||||
|
|
||||||
if (!outside) {
|
if (!outside) {
|
||||||
s = mtd->menu;
|
items = mtd->menu;
|
||||||
xasprintf(&title, "#[align=centre]%s", mti->name);
|
xasprintf(&title, "#[align=centre]%s", mti->name);
|
||||||
} else {
|
} else {
|
||||||
s = MODE_TREE_MENU;
|
items = mode_tree_menu_items;
|
||||||
title = xstrdup("");
|
title = xstrdup("");
|
||||||
}
|
}
|
||||||
menu = menu_create(s, NULL, c, NULL, title);
|
menu = menu_create(title);
|
||||||
|
menu_add_items(menu, items, NULL, NULL, NULL);
|
||||||
free(title);
|
free(title);
|
||||||
if (menu == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mtm = xmalloc(sizeof *mtm);
|
mtm = xmalloc(sizeof *mtm);
|
||||||
mtm->data = mtd;
|
mtm->data = mtd;
|
||||||
|
33
tmux.1
33
tmux.1
@ -4128,7 +4128,6 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "client_height" Ta "" Ta "Height of client"
|
.It Li "client_height" Ta "" Ta "Height of client"
|
||||||
.It Li "client_key_table" Ta "" Ta "Current key table"
|
.It Li "client_key_table" Ta "" Ta "Current key table"
|
||||||
.It Li "client_last_session" Ta "" Ta "Name of the client's last session"
|
.It Li "client_last_session" Ta "" Ta "Name of the client's last session"
|
||||||
.It Li "client_menu" Ta "" Ta "The default client menu"
|
|
||||||
.It Li "client_name" Ta "" Ta "Name of client"
|
.It Li "client_name" Ta "" Ta "Name of client"
|
||||||
.It Li "client_pid" Ta "" Ta "PID of client process"
|
.It Li "client_pid" Ta "" Ta "PID of client process"
|
||||||
.It Li "client_prefix" Ta "" Ta "1 if prefix key has been pressed"
|
.It Li "client_prefix" Ta "" Ta "1 if prefix key has been pressed"
|
||||||
@ -4190,7 +4189,6 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "pane_left" Ta "" Ta "Left of pane"
|
.It Li "pane_left" Ta "" Ta "Left of pane"
|
||||||
.It Li "pane_marked" Ta "" Ta "1 if this is the marked pane"
|
.It Li "pane_marked" Ta "" Ta "1 if this is the marked pane"
|
||||||
.It Li "pane_marked_set" Ta "" Ta "1 if a marked pane is set"
|
.It Li "pane_marked_set" Ta "" Ta "1 if a marked pane is set"
|
||||||
.It Li "pane_menu" Ta "" Ta "The default pane menu"
|
|
||||||
.It Li "pane_mode" Ta "" Ta "Name of pane mode, if any."
|
.It Li "pane_mode" Ta "" Ta "Name of pane mode, if any."
|
||||||
.It Li "pane_pid" Ta "" Ta "PID of first process in pane"
|
.It Li "pane_pid" Ta "" Ta "PID of first process in pane"
|
||||||
.It Li "pane_pipe" Ta "" Ta "1 if pane is being piped"
|
.It Li "pane_pipe" Ta "" Ta "1 if pane is being piped"
|
||||||
@ -4221,7 +4219,6 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "session_id" Ta "" Ta "Unique session ID"
|
.It Li "session_id" Ta "" Ta "Unique session ID"
|
||||||
.It Li "session_last_attached" Ta "" Ta "Time session last attached"
|
.It Li "session_last_attached" Ta "" Ta "Time session last attached"
|
||||||
.It Li "session_many_attached" Ta "" Ta "1 if multiple clients attached"
|
.It Li "session_many_attached" Ta "" Ta "1 if multiple clients attached"
|
||||||
.It Li "session_menu" Ta "" Ta "The default session menu"
|
|
||||||
.It Li "session_name" Ta "#S" Ta "Name of session"
|
.It Li "session_name" Ta "#S" Ta "Name of session"
|
||||||
.It Li "session_stack" Ta "" Ta "Window indexes in most recent order"
|
.It Li "session_stack" Ta "" Ta "Window indexes in most recent order"
|
||||||
.It Li "session_windows" Ta "" Ta "Number of windows in session"
|
.It Li "session_windows" Ta "" Ta "Number of windows in session"
|
||||||
@ -4242,7 +4239,6 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "window_last_flag" Ta "" Ta "1 if window is the last used"
|
.It Li "window_last_flag" Ta "" Ta "1 if window is the last used"
|
||||||
.It Li "window_layout" Ta "" Ta "Window layout description, ignoring zoomed window panes"
|
.It Li "window_layout" Ta "" Ta "Window layout description, ignoring zoomed window panes"
|
||||||
.It Li "window_linked" Ta "" Ta "1 if window is linked across sessions"
|
.It Li "window_linked" Ta "" Ta "1 if window is linked across sessions"
|
||||||
.It Li "window_menu" Ta "" Ta "The default window menu"
|
|
||||||
.It Li "window_name" Ta "#W" Ta "Name of window"
|
.It Li "window_name" Ta "#W" Ta "Name of window"
|
||||||
.It Li "window_offset_x" Ta "" Ta "X offset into window if larger than client"
|
.It Li "window_offset_x" Ta "" Ta "X offset into window if larger than client"
|
||||||
.It Li "window_offset_y" Ta "" Ta "Y offset into window if larger than client"
|
.It Li "window_offset_y" Ta "" Ta "Y offset into window if larger than client"
|
||||||
@ -4661,13 +4657,15 @@ option.
|
|||||||
This command works only from inside
|
This command works only from inside
|
||||||
.Nm .
|
.Nm .
|
||||||
.It Xo Ic display-menu
|
.It Xo Ic display-menu
|
||||||
.Op Fl F
|
|
||||||
.Op Fl c Ar target-client
|
.Op Fl c Ar target-client
|
||||||
.Op Fl M Ar menu
|
|
||||||
.Op Fl t Ar target-pane
|
.Op Fl t Ar target-pane
|
||||||
.Op Fl T Ar title
|
.Op Fl T Ar title
|
||||||
.Op Fl x Ar position
|
.Op Fl x Ar position
|
||||||
.Op Fl y Ar position
|
.Op Fl y Ar position
|
||||||
|
.Ar name
|
||||||
|
.Ar key
|
||||||
|
.Ar command
|
||||||
|
.Ar ...
|
||||||
.Xc
|
.Xc
|
||||||
.D1 (alias: Ic menu )
|
.D1 (alias: Ic menu )
|
||||||
Display a menu on
|
Display a menu on
|
||||||
@ -4675,27 +4673,16 @@ Display a menu on
|
|||||||
.Ar target-pane
|
.Ar target-pane
|
||||||
gives the target for any commands run from the menu.
|
gives the target for any commands run from the menu.
|
||||||
.Pp
|
.Pp
|
||||||
A menu is passed to
|
A menu is passed as a series of arguments: first the menu item name,
|
||||||
.Fl M
|
second the key shortcut (or empty for none) and third the command
|
||||||
as a list of menu items separated by
|
to run when the menu item is chosen.
|
||||||
.Ql | .
|
The name and command are formats, see the
|
||||||
Each menu item consists of three comma-separated parts:
|
|
||||||
.Bl -enum -width Ds
|
|
||||||
.It
|
|
||||||
The menu item name.
|
|
||||||
This is a format and may include embedded styles, see the
|
|
||||||
.Sx FORMATS
|
.Sx FORMATS
|
||||||
and
|
and
|
||||||
.Sx STYLES
|
.Sx STYLES
|
||||||
sections.
|
sections.
|
||||||
.It
|
The name may be empty for a separator line, in which case both the key and
|
||||||
The menu item shortcut key.
|
command should be omitted.
|
||||||
If this is empty the menu item has no key shortcut.
|
|
||||||
.It
|
|
||||||
The command run when the menu item is chosen.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
An empty menu item is a separator line.
|
|
||||||
.Pp
|
.Pp
|
||||||
.Fl T
|
.Fl T
|
||||||
is a format for the menu title (see
|
is a format for the menu title (see
|
||||||
|
20
tmux.h
20
tmux.h
@ -754,12 +754,12 @@ struct screen_redraw_ctx {
|
|||||||
|
|
||||||
/* Menu. */
|
/* Menu. */
|
||||||
struct menu_item {
|
struct menu_item {
|
||||||
char *name;
|
const char *name;
|
||||||
char *command;
|
|
||||||
key_code key;
|
key_code key;
|
||||||
|
const char *command;
|
||||||
};
|
};
|
||||||
struct menu {
|
struct menu {
|
||||||
char *title;
|
const char *title;
|
||||||
struct menu_item *items;
|
struct menu_item *items;
|
||||||
u_int count;
|
u_int count;
|
||||||
u_int width;
|
u_int width;
|
||||||
@ -2469,8 +2469,8 @@ void mode_tree_each_tagged(struct mode_tree_data *, mode_tree_each_cb,
|
|||||||
void mode_tree_down(struct mode_tree_data *, int);
|
void mode_tree_down(struct mode_tree_data *, int);
|
||||||
struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *,
|
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_build_cb, mode_tree_draw_cb, mode_tree_search_cb,
|
||||||
mode_tree_menu_cb, void *, const char *, const char **, u_int,
|
mode_tree_menu_cb, void *, const struct menu_item *, const char **,
|
||||||
struct screen **);
|
u_int, struct screen **);
|
||||||
void mode_tree_zoom(struct mode_tree_data *, struct args *);
|
void mode_tree_zoom(struct mode_tree_data *, struct args *);
|
||||||
void mode_tree_build(struct mode_tree_data *);
|
void mode_tree_build(struct mode_tree_data *);
|
||||||
void mode_tree_free(struct mode_tree_data *);
|
void mode_tree_free(struct mode_tree_data *);
|
||||||
@ -2604,8 +2604,14 @@ __dead void printflike(1, 2) fatal(const char *, ...);
|
|||||||
__dead void printflike(1, 2) fatalx(const char *, ...);
|
__dead void printflike(1, 2) fatalx(const char *, ...);
|
||||||
|
|
||||||
/* menu.c */
|
/* menu.c */
|
||||||
struct menu *menu_create(const char *, struct cmdq_item *, struct client *,
|
struct menu *menu_create(const char *);
|
||||||
struct cmd_find_state *, const char *);
|
void menu_add_items(struct menu *, const struct menu_item *,
|
||||||
|
struct cmdq_item *, struct client *,
|
||||||
|
struct cmd_find_state *);
|
||||||
|
void menu_add_item(struct menu *, const struct menu_item *,
|
||||||
|
struct cmdq_item *, struct client *,
|
||||||
|
struct cmd_find_state *);
|
||||||
|
|
||||||
void menu_free(struct menu *);
|
void menu_free(struct menu *);
|
||||||
int menu_display(struct menu *, int, struct cmdq_item *, u_int,
|
int menu_display(struct menu *, int, struct cmdq_item *, u_int,
|
||||||
u_int, struct client *, struct cmd_find_state *,
|
u_int, struct client *, struct cmd_find_state *,
|
||||||
|
@ -38,18 +38,21 @@ static void window_buffer_key(struct window_mode_entry *,
|
|||||||
#define WINDOW_BUFFER_DEFAULT_FORMAT \
|
#define WINDOW_BUFFER_DEFAULT_FORMAT \
|
||||||
"#{buffer_size} bytes (#{t:buffer_created})"
|
"#{buffer_size} bytes (#{t:buffer_created})"
|
||||||
|
|
||||||
#define WINDOW_BUFFER_MENU \
|
static const struct menu_item window_buffer_menu_items[] = {
|
||||||
"Paste,p,|" \
|
{ "Paste", 'p', NULL },
|
||||||
"Paste Tagged,P,|" \
|
{ "Paste Tagged", 'P', NULL },
|
||||||
"|" \
|
{ "", KEYC_NONE, NULL },
|
||||||
"Tag,t,|" \
|
{ "Tag", 't', NULL },
|
||||||
"Tag All,C-t,|" \
|
{ "Tag All", '\024', NULL },
|
||||||
"Tag None,T,|" \
|
{ "Tag None", 'T', NULL },
|
||||||
"|" \
|
{ "", KEYC_NONE, NULL },
|
||||||
"Delete,d,|" \
|
{ "Delete", 'd', NULL },
|
||||||
"Delete Tagged,D,|" \
|
{ "Delete Tagged", 'D', NULL },
|
||||||
"|" \
|
{ "", KEYC_NONE, NULL },
|
||||||
"Cancel,q,"
|
{ "Cancel", 'q', NULL },
|
||||||
|
|
||||||
|
{ NULL, KEYC_NONE, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
const struct window_mode window_buffer_mode = {
|
const struct window_mode window_buffer_mode = {
|
||||||
.name = "buffer-mode",
|
.name = "buffer-mode",
|
||||||
@ -314,7 +317,7 @@ window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
|
|||||||
|
|
||||||
data->data = mode_tree_start(wp, args, window_buffer_build,
|
data->data = mode_tree_start(wp, args, window_buffer_build,
|
||||||
window_buffer_draw, window_buffer_search, window_buffer_menu, data,
|
window_buffer_draw, window_buffer_search, window_buffer_menu, data,
|
||||||
WINDOW_BUFFER_MENU, window_buffer_sort_list,
|
window_buffer_menu_items, window_buffer_sort_list,
|
||||||
nitems(window_buffer_sort_list), &s);
|
nitems(window_buffer_sort_list), &s);
|
||||||
mode_tree_zoom(data->data, args);
|
mode_tree_zoom(data->data, args);
|
||||||
|
|
||||||
|
@ -40,15 +40,18 @@ static void window_client_key(struct window_mode_entry *,
|
|||||||
"session #{session_name} " \
|
"session #{session_name} " \
|
||||||
"(#{client_width}x#{client_height}, #{t:client_activity})"
|
"(#{client_width}x#{client_height}, #{t:client_activity})"
|
||||||
|
|
||||||
#define WINDOW_CLIENT_MENU \
|
static const struct menu_item window_client_menu_items[] = {
|
||||||
"Detach,d,|" \
|
{ "Detach", 'd', NULL },
|
||||||
"Detach Tagged,D,|" \
|
{ "Detach Tagged", 'D', NULL },
|
||||||
"|" \
|
{ "", KEYC_NONE, NULL },
|
||||||
"Tag,t,|" \
|
{ "Tag", 't', NULL },
|
||||||
"Tag All,C-t,|" \
|
{ "Tag All", '\024', NULL },
|
||||||
"Tag None,T,|" \
|
{ "Tag None", 'T', NULL },
|
||||||
"|" \
|
{ "", KEYC_NONE, NULL },
|
||||||
"Cancel,q,"
|
{ "Cancel", 'q', NULL },
|
||||||
|
|
||||||
|
{ NULL, KEYC_NONE, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
const struct window_mode window_client_mode = {
|
const struct window_mode window_client_mode = {
|
||||||
.name = "client-mode",
|
.name = "client-mode",
|
||||||
@ -296,7 +299,7 @@ window_client_init(struct window_mode_entry *wme,
|
|||||||
|
|
||||||
data->data = mode_tree_start(wp, args, window_client_build,
|
data->data = mode_tree_start(wp, args, window_client_build,
|
||||||
window_client_draw, NULL, window_client_menu, data,
|
window_client_draw, NULL, window_client_menu, data,
|
||||||
WINDOW_CLIENT_MENU, window_client_sort_list,
|
window_client_menu_items, window_client_sort_list,
|
||||||
nitems(window_client_sort_list), &s);
|
nitems(window_client_sort_list), &s);
|
||||||
mode_tree_zoom(data->data, args);
|
mode_tree_zoom(data->data, args);
|
||||||
|
|
||||||
|
@ -53,18 +53,21 @@ static void window_tree_key(struct window_mode_entry *,
|
|||||||
"}" \
|
"}" \
|
||||||
"}"
|
"}"
|
||||||
|
|
||||||
#define WINDOW_TREE_MENU \
|
static const struct menu_item window_tree_menu_items[] = {
|
||||||
"Select,Enter,|" \
|
{ "Select", 'E', NULL },
|
||||||
"Expand,Right,|" \
|
{ "Expand", 'R', NULL },
|
||||||
"|" \
|
{ "", KEYC_NONE, NULL },
|
||||||
"Tag,t,|" \
|
{ "Tag", 't', NULL },
|
||||||
"Tag All,C-t,|" \
|
{ "Tag All", '\024', NULL },
|
||||||
"Tag None,T,|" \
|
{ "Tag None", 'T', NULL },
|
||||||
"|" \
|
{ "", KEYC_NONE, NULL },
|
||||||
"Kill,x,|" \
|
{ "Kill", 'x', NULL },
|
||||||
"Kill Tagged,X,|" \
|
{ "Kill Tagged", 'X', NULL },
|
||||||
"|" \
|
{ "", KEYC_NONE, NULL },
|
||||||
"Cancel,q,"
|
{ "Cancel", 'q', NULL },
|
||||||
|
|
||||||
|
{ NULL, KEYC_NONE, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
const struct window_mode window_tree_mode = {
|
const struct window_mode window_tree_mode = {
|
||||||
.name = "tree-mode",
|
.name = "tree-mode",
|
||||||
@ -872,7 +875,7 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
|
|||||||
|
|
||||||
data->data = mode_tree_start(wp, args, window_tree_build,
|
data->data = mode_tree_start(wp, args, window_tree_build,
|
||||||
window_tree_draw, window_tree_search, window_tree_menu, data,
|
window_tree_draw, window_tree_search, window_tree_menu, data,
|
||||||
WINDOW_TREE_MENU, window_tree_sort_list,
|
window_tree_menu_items, window_tree_sort_list,
|
||||||
nitems(window_tree_sort_list), &s);
|
nitems(window_tree_sort_list), &s);
|
||||||
mode_tree_zoom(data->data, args);
|
mode_tree_zoom(data->data, args);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user