mirror of
https://github.com/tmux/tmux.git
synced 2025-09-03 14:27:09 +00:00
Add a customize mode where keys and options may be browsed and changed,
includes adding a brief description of each option. Bound to "C" by default.
This commit is contained in:
97
mode-tree.c
97
mode-tree.c
@ -45,6 +45,7 @@ struct mode_tree_data {
|
||||
mode_tree_draw_cb drawcb;
|
||||
mode_tree_search_cb searchcb;
|
||||
mode_tree_menu_cb menucb;
|
||||
mode_tree_height_cb heightcb;
|
||||
|
||||
struct mode_tree_list children;
|
||||
struct mode_tree_list saved;
|
||||
@ -79,6 +80,7 @@ struct mode_tree_item {
|
||||
|
||||
int expanded;
|
||||
int tagged;
|
||||
int draw_as_parent;
|
||||
|
||||
struct mode_tree_list children;
|
||||
TAILQ_ENTRY(mode_tree_item) entry;
|
||||
@ -210,7 +212,7 @@ mode_tree_clear_tagged(struct mode_tree_list *mtl)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
mode_tree_up(struct mode_tree_data *mtd, int wrap)
|
||||
{
|
||||
if (mtd->current == 0) {
|
||||
@ -247,6 +249,12 @@ mode_tree_get_current(struct mode_tree_data *mtd)
|
||||
return (mtd->line_list[mtd->current].item->itemdata);
|
||||
}
|
||||
|
||||
const char *
|
||||
mode_tree_get_current_name(struct mode_tree_data *mtd)
|
||||
{
|
||||
return (mtd->line_list[mtd->current].item->name);
|
||||
}
|
||||
|
||||
void
|
||||
mode_tree_expand_current(struct mode_tree_data *mtd)
|
||||
{
|
||||
@ -256,6 +264,15 @@ mode_tree_expand_current(struct mode_tree_data *mtd)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mode_tree_collapse_current(struct mode_tree_data *mtd)
|
||||
{
|
||||
if (mtd->line_list[mtd->current].item->expanded) {
|
||||
mtd->line_list[mtd->current].item->expanded = 0;
|
||||
mode_tree_build(mtd);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
mode_tree_get_tag(struct mode_tree_data *mtd, uint64_t tag, u_int *found)
|
||||
{
|
||||
@ -343,7 +360,8 @@ mode_tree_each_tagged(struct mode_tree_data *mtd, mode_tree_each_cb cb,
|
||||
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, void *modedata,
|
||||
mode_tree_search_cb searchcb, mode_tree_menu_cb menucb,
|
||||
mode_tree_height_cb heightcb, void *modedata,
|
||||
const struct menu_item *menu, const char **sort_list, u_int sort_size,
|
||||
struct screen **s)
|
||||
{
|
||||
@ -381,6 +399,7 @@ mode_tree_start(struct window_pane *wp, struct args *args,
|
||||
mtd->drawcb = drawcb;
|
||||
mtd->searchcb = searchcb;
|
||||
mtd->menucb = menucb;
|
||||
mtd->heightcb = heightcb;
|
||||
|
||||
TAILQ_INIT(&mtd->children);
|
||||
|
||||
@ -404,6 +423,27 @@ mode_tree_zoom(struct mode_tree_data *mtd, struct args *args)
|
||||
mtd->zoomed = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
mode_tree_set_height(struct mode_tree_data *mtd)
|
||||
{
|
||||
struct screen *s = &mtd->screen;
|
||||
u_int height;
|
||||
|
||||
if (mtd->heightcb != NULL) {
|
||||
height = mtd->heightcb(mtd, screen_size_y(s));
|
||||
if (height < screen_size_y(s))
|
||||
mtd->height = screen_size_y(s) - height;
|
||||
} else {
|
||||
mtd->height = (screen_size_y(s) / 3) * 2;
|
||||
if (mtd->height > mtd->line_size)
|
||||
mtd->height = screen_size_y(s) / 2;
|
||||
}
|
||||
if (mtd->height < 10)
|
||||
mtd->height = screen_size_y(s);
|
||||
if (screen_size_y(s) - mtd->height < 2)
|
||||
mtd->height = screen_size_y(s);
|
||||
}
|
||||
|
||||
void
|
||||
mode_tree_build(struct mode_tree_data *mtd)
|
||||
{
|
||||
@ -434,15 +474,9 @@ mode_tree_build(struct mode_tree_data *mtd)
|
||||
mode_tree_set_current(mtd, tag);
|
||||
|
||||
mtd->width = screen_size_x(s);
|
||||
if (mtd->preview) {
|
||||
mtd->height = (screen_size_y(s) / 3) * 2;
|
||||
if (mtd->height > mtd->line_size)
|
||||
mtd->height = screen_size_y(s) / 2;
|
||||
if (mtd->height < 10)
|
||||
mtd->height = screen_size_y(s);
|
||||
if (screen_size_y(s) - mtd->height < 2)
|
||||
mtd->height = screen_size_y(s);
|
||||
} else
|
||||
if (mtd->preview)
|
||||
mode_tree_set_height(mtd);
|
||||
else
|
||||
mtd->height = screen_size_y(s);
|
||||
mode_tree_check_selected(mtd);
|
||||
}
|
||||
@ -494,7 +528,7 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent,
|
||||
struct mode_tree_item *mti, *saved;
|
||||
|
||||
log_debug("%s: %llu, %s %s", __func__, (unsigned long long)tag,
|
||||
name, text);
|
||||
name, (text == NULL ? "" : text));
|
||||
|
||||
mti = xcalloc(1, sizeof *mti);
|
||||
mti->parent = parent;
|
||||
@ -502,7 +536,8 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent,
|
||||
|
||||
mti->tag = tag;
|
||||
mti->name = xstrdup(name);
|
||||
mti->text = xstrdup(text);
|
||||
if (text != NULL)
|
||||
mti->text = xstrdup(text);
|
||||
|
||||
saved = mode_tree_find_item(&mtd->saved, tag);
|
||||
if (saved != NULL) {
|
||||
@ -524,6 +559,12 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent,
|
||||
return (mti);
|
||||
}
|
||||
|
||||
void
|
||||
mode_tree_draw_as_parent(struct mode_tree_item *mti)
|
||||
{
|
||||
mti->draw_as_parent = 1;
|
||||
}
|
||||
|
||||
void
|
||||
mode_tree_remove(struct mode_tree_data *mtd, struct mode_tree_item *mti)
|
||||
{
|
||||
@ -621,8 +662,8 @@ mode_tree_draw(struct mode_tree_data *mtd)
|
||||
tag = "*";
|
||||
else
|
||||
tag = "";
|
||||
xasprintf(&text, "%-*s%s%s%s: ", keylen, key, start, mti->name,
|
||||
tag);
|
||||
xasprintf(&text, "%-*s%s%s%s%s", keylen, key, start, mti->name,
|
||||
tag, (mti->text != NULL) ? ": " : "" );
|
||||
width = utf8_cstrwidth(text);
|
||||
if (width > w)
|
||||
width = w;
|
||||
@ -636,11 +677,17 @@ mode_tree_draw(struct mode_tree_data *mtd)
|
||||
if (i != mtd->current) {
|
||||
screen_write_clearendofline(&ctx, 8);
|
||||
screen_write_nputs(&ctx, w, &gc0, "%s", text);
|
||||
format_draw(&ctx, &gc0, w - width, mti->text, NULL);
|
||||
if (mti->text != NULL) {
|
||||
format_draw(&ctx, &gc0, w - width, mti->text,
|
||||
NULL);
|
||||
}
|
||||
} else {
|
||||
screen_write_clearendofline(&ctx, gc.bg);
|
||||
screen_write_nputs(&ctx, w, &gc, "%s", text);
|
||||
format_draw(&ctx, &gc, w - width, mti->text, NULL);
|
||||
if (mti->text != NULL) {
|
||||
format_draw(&ctx, &gc, w - width, mti->text,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
free(text);
|
||||
|
||||
@ -658,13 +705,18 @@ mode_tree_draw(struct mode_tree_data *mtd)
|
||||
|
||||
line = &mtd->line_list[mtd->current];
|
||||
mti = line->item;
|
||||
if (mti->draw_as_parent)
|
||||
mti = mti->parent;
|
||||
|
||||
screen_write_cursormove(&ctx, 0, h, 0);
|
||||
screen_write_box(&ctx, w, sy - h);
|
||||
|
||||
xasprintf(&text, " %s (sort: %s%s)", mti->name,
|
||||
mtd->sort_list[mtd->sort_crit.field],
|
||||
mtd->sort_crit.reversed ? ", reversed" : "");
|
||||
if (mtd->sort_list != NULL) {
|
||||
xasprintf(&text, " %s (sort: %s%s)", mti->name,
|
||||
mtd->sort_list[mtd->sort_crit.field],
|
||||
mtd->sort_crit.reversed ? ", reversed" : "");
|
||||
} else
|
||||
xasprintf(&text, " %s", mti->name);
|
||||
if (w - 2 >= strlen(text)) {
|
||||
screen_write_cursormove(&ctx, 1, h, 0);
|
||||
screen_write_puts(&ctx, &gc0, "%s", text);
|
||||
@ -680,7 +732,8 @@ mode_tree_draw(struct mode_tree_data *mtd)
|
||||
else
|
||||
screen_write_puts(&ctx, &gc0, "active");
|
||||
screen_write_puts(&ctx, &gc0, ") ");
|
||||
}
|
||||
} else
|
||||
screen_write_puts(&ctx, &gc0, " ");
|
||||
}
|
||||
free(text);
|
||||
|
||||
@ -1027,7 +1080,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
||||
break;
|
||||
case 'O':
|
||||
mtd->sort_crit.field++;
|
||||
if (mtd->sort_crit.field == mtd->sort_size)
|
||||
if (mtd->sort_crit.field >= mtd->sort_size)
|
||||
mtd->sort_crit.field = 0;
|
||||
mode_tree_build(mtd);
|
||||
break;
|
||||
|
Reference in New Issue
Block a user