mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +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