Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2026-06-26 09:30:07 +01:00
9 changed files with 369 additions and 203 deletions

View File

@@ -36,6 +36,24 @@ enum mode_tree_preview {
MODE_TREE_PREVIEW_BIG MODE_TREE_PREVIEW_BIG
}; };
#define MODE_TREE_PREFIX_STYLE \
"#{?mode_tree_selected,#[default]#[noacs]," \
"#[fg=themelightgrey]#[bg=default]#[noacs]}"
#define MODE_TREE_PREFIX_FORMAT \
MODE_TREE_PREFIX_STYLE \
"#{p/#{mode_tree_key_width}:" \
"#{?#{!=:#{mode_tree_key},},(#{mode_tree_key}),}}" \
"#{R:#{?mode_tree_parent_last, ," \
"#[acs]x" MODE_TREE_PREFIX_STYLE " }," \
"#{mode_tree_repeat}}" \
"#{?mode_tree_branch," \
"#[acs]#{?mode_tree_last,mq,tq}" MODE_TREE_PREFIX_STYLE "> ,}" \
"#{?mode_tree_has_children," \
"#{?mode_tree_expanded,#[fg=themered]-" MODE_TREE_PREFIX_STYLE " ," \
"#[fg=themegreen]+" MODE_TREE_PREFIX_STYLE " }," \
"#{?mode_tree_flat,, }}"
struct mode_tree_item; struct mode_tree_item;
struct mode_tree_prompt; struct mode_tree_prompt;
TAILQ_HEAD(mode_tree_list, mode_tree_item); TAILQ_HEAD(mode_tree_list, mode_tree_item);
@@ -159,31 +177,53 @@ static const struct menu_item mode_tree_menu_items[] = {
}; };
static const char* mode_tree_help_start[] = { static const char* mode_tree_help_start[] = {
"#[bold] Up, k #[default]#[acs]x#[default] Move cursor up", "#[fg=themelightgrey]"
"#[bold] Down, j #[default]#[acs]x#[default] Move cursor down", " Up, k #[#{E:tree-mode-border-style},acs]x#[default] Move cursor up",
"#[bold] g #[default]#[acs]x#[default] Go to top", "#[fg=themelightgrey]"
"#[bold] G #[default]#[acs]x#[default] Go to bottom", " Down, j #[#{E:tree-mode-border-style},acs]x#[default] Move cursor down",
"#[bold] PPage, C-b #[default]#[acs]x#[default] Page up", "#[fg=themelightgrey]"
"#[bold] NPage, C-f #[default]#[acs]x#[default] Page down", " g #[#{E:tree-mode-border-style},acs]x#[default] Go to top",
"#[bold] Left, h #[default]#[acs]x#[default] Collapse %1", "#[fg=themelightgrey]"
"#[bold] Right, l #[default]#[acs]x#[default] Expand %1", " G #[#{E:tree-mode-border-style},acs]x#[default] Go to bottom",
"#[bold] M-- #[default]#[acs]x#[default] Collapse all %1s", "#[fg=themelightgrey]"
"#[bold] M-+ #[default]#[acs]x#[default] Expand all %1s", " PPage, C-b #[#{E:tree-mode-border-style},acs]x#[default] Page up",
"#[bold] t #[default]#[acs]x#[default] Toggle %1 tag", "#[fg=themelightgrey]"
"#[bold] T #[default]#[acs]x#[default] Untag all %1s", " NPage, C-f #[#{E:tree-mode-border-style},acs]x#[default] Page down",
"#[bold] C-t #[default]#[acs]x#[default] Tag all %1s", "#[fg=themelightgrey]"
"#[bold] C-s #[default]#[acs]x#[default] Search forward", " Left, h #[#{E:tree-mode-border-style},acs]x#[default] Collapse %1",
"#[bold] C-r #[default]#[acs]x#[default] Search backward", "#[fg=themelightgrey]"
"#[bold] n #[default]#[acs]x#[default] Repeat search forward", " Right, l #[#{E:tree-mode-border-style},acs]x#[default] Expand %1",
"#[bold] N #[default]#[acs]x#[default] Repeat search backward", "#[fg=themelightgrey]"
"#[bold] f #[default]#[acs]x#[default] Filter %1s", " M-- #[#{E:tree-mode-border-style},acs]x#[default] Collapse all %1s",
"#[bold] O #[default]#[acs]x#[default] Change sort order", "#[fg=themelightgrey]"
"#[bold] r #[default]#[acs]x#[default] Reverse sort order", " M-+ #[#{E:tree-mode-border-style},acs]x#[default] Expand all %1s",
"#[bold] v #[default]#[acs]x#[default] Toggle preview", "#[fg=themelightgrey]"
" t #[#{E:tree-mode-border-style},acs]x#[default] Toggle %1 tag",
"#[fg=themelightgrey]"
" T #[#{E:tree-mode-border-style},acs]x#[default] Untag all %1s",
"#[fg=themelightgrey]"
" C-t #[#{E:tree-mode-border-style},acs]x#[default] Tag all %1s",
"#[fg=themelightgrey]"
" C-s #[#{E:tree-mode-border-style},acs]x#[default] Search forward",
"#[fg=themelightgrey]"
" C-r #[#{E:tree-mode-border-style},acs]x#[default] Search backward",
"#[fg=themelightgrey]"
" n #[#{E:tree-mode-border-style},acs]x#[default] Repeat search forward",
"#[fg=themelightgrey]"
" N #[#{E:tree-mode-border-style},acs]x#[default] Repeat search backward",
"#[fg=themelightgrey]"
" f #[#{E:tree-mode-border-style},acs]x#[default] Filter %1s",
"#[fg=themelightgrey]"
" O #[#{E:tree-mode-border-style},acs]x#[default] Change sort order",
"#[fg=themelightgrey]"
" r #[#{E:tree-mode-border-style},acs]x#[default] Reverse sort order",
"#[fg=themelightgrey]"
" v #[#{E:tree-mode-border-style},acs]x#[default] Toggle preview",
NULL NULL
}; };
static const char* mode_tree_help_end[] = { static const char* mode_tree_help_end[] = {
"#[bold] q, Escape #[default]#[acs]x#[default] Exit mode", "#[fg=themelightgrey]"
" q, Escape #[#{E:tree-mode-border-style},acs]x#[default] Exit mode",
NULL NULL
}; };
#define MODE_TREE_HELP_DEFAULT_WIDTH 39 #define MODE_TREE_HELP_DEFAULT_WIDTH 39
@@ -784,12 +824,14 @@ mode_tree_draw(struct mode_tree_data *mtd)
struct mode_tree_item *mti; struct mode_tree_item *mti;
struct options *oo = wp->window->options; struct options *oo = wp->window->options;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
struct grid_cell gc0, gc; struct format_tree *ft;
u_int w, h, i, j, sy, box_x, box_y, width; struct grid_cell gc0, gc, box_gc;
char *text, *start, *key; u_int w, h, i, sy, box_x, box_y;
const char *tag, *symbol; u_int width, text_width, prefix_width, left;
size_t size, n; char *text, *prefix;
int keylen, pad, alignlen[mtd->maxdepth + 1]; const char *tag, *separator;
size_t n;
int keylen, alignlen[mtd->maxdepth + 1];
if (mtd->line_size == 0) if (mtd->line_size == 0)
return; return;
@@ -797,12 +839,15 @@ mode_tree_draw(struct mode_tree_data *mtd)
memcpy(&gc0, &grid_default_cell, sizeof gc0); memcpy(&gc0, &grid_default_cell, sizeof gc0);
memcpy(&gc, &grid_default_cell, sizeof gc); memcpy(&gc, &grid_default_cell, sizeof gc);
style_apply(&gc, oo, "mode-style", NULL); style_apply(&gc, oo, "mode-style", NULL);
memcpy(&box_gc, &grid_default_cell, sizeof box_gc);
style_apply(&box_gc, oo, "tree-mode-border-style", NULL);
w = mtd->width; w = mtd->width;
h = mtd->height; h = mtd->height;
screen_write_start(&ctx, s); screen_write_start(&ctx, s);
screen_write_clearscreen(&ctx, 8); screen_write_clearscreen(&ctx, 8);
ft = format_create_defaults(NULL, NULL, NULL, NULL, wp);
keylen = 0; keylen = 0;
for (i = 0; i < mtd->line_size; i++) { for (i = 0; i < mtd->line_size; i++) {
@@ -833,52 +878,53 @@ mode_tree_draw(struct mode_tree_data *mtd)
screen_write_cursormove(&ctx, 0, i - mtd->offset, 0); screen_write_cursormove(&ctx, 0, i - mtd->offset, 0);
pad = keylen - 2 - mti->keylen;
if (mti->key != KEYC_NONE) if (mti->key != KEYC_NONE)
xasprintf(&key, "(%s)%*s", mti->keystr, pad, ""); format_add(ft, "mode_tree_key", "%s", mti->keystr);
else else
key = xstrdup(""); format_add(ft, "mode_tree_key", "%s", "");
format_add(ft, "mode_tree_key_width", "%d", keylen);
if (line->flat) format_add(ft, "mode_tree_selected", "%d", i == mtd->current);
symbol = ""; if (line->depth == 0) {
else if (TAILQ_EMPTY(&mti->children)) format_add(ft, "mode_tree_repeat", "%u", 0);
symbol = " "; format_add(ft, "mode_tree_branch", "0");
else if (mti->expanded) format_add(ft, "mode_tree_parent_last", "0");
symbol = "- "; } else {
else format_add(ft, "mode_tree_repeat", "%u",
symbol = "+ "; line->depth - 1);
format_add(ft, "mode_tree_branch", "1");
if (line->depth == 0) if (mti->parent != NULL &&
start = xstrdup(symbol); mtd->line_list[mti->parent->line].last)
else { format_add(ft, "mode_tree_parent_last", "1");
size = (4 * line->depth) + 32;
start = xcalloc(1, size);
for (j = 1; j < line->depth; j++) {
if (mti->parent != NULL &&
mtd->line_list[mti->parent->line].last)
strlcat(start, " ", size);
else
strlcat(start, "\001x\001 ", size);
}
if (line->last)
strlcat(start, "\001mq\001> ", size);
else else
strlcat(start, "\001tq\001> ", size); format_add(ft, "mode_tree_parent_last", "0");
strlcat(start, symbol, size);
} }
if (TAILQ_EMPTY(&mti->children))
format_add(ft, "mode_tree_has_children", "0");
else
format_add(ft, "mode_tree_has_children", "1");
format_add(ft, "mode_tree_last", "%d", line->last);
format_add(ft, "mode_tree_expanded", "%d", mti->expanded);
format_add(ft, "mode_tree_flat", "%d", line->flat);
prefix = format_expand(ft, MODE_TREE_PREFIX_FORMAT);
prefix_width = format_width(prefix);
if (prefix_width > w)
prefix_width = w;
if (mti->tagged) if (mti->tagged)
tag = "*"; tag = "*";
else else
tag = ""; tag = "";
xasprintf(&text, "%-*s%s%*s%s%s", keylen, key, start, if (mti->text != NULL)
mti->align * alignlen[line->depth], mti->name, tag, separator = "#[fg=themelightgrey]: #[default]";
(mti->text != NULL) ? ": " : "" ); else
width = utf8_cstrwidth(text); separator = "";
if (width > w) xasprintf(&text, "%*s%s%s",
width = w; mti->align * alignlen[line->depth], mti->name, tag, separator);
free(start); text_width = format_width(text);
left = (prefix_width < w) ? (w - prefix_width) : 0;
if (text_width > left)
text_width = left;
width = prefix_width + text_width;
if (mti->tagged) { if (mti->tagged) {
gc.attr ^= GRID_ATTR_BRIGHT; gc.attr ^= GRID_ATTR_BRIGHT;
@@ -887,27 +933,43 @@ mode_tree_draw(struct mode_tree_data *mtd)
if (i != mtd->current) { if (i != mtd->current) {
screen_write_clearendofline(&ctx, 8); screen_write_clearendofline(&ctx, 8);
screen_write_nputs(&ctx, w, &gc0, "%s", text); format_draw(&ctx, &grid_default_cell, prefix_width,
if (mti->text != NULL) { prefix, NULL, 0);
format_draw(&ctx, &gc0, w - width, mti->text, if (left != 0) {
NULL, 0); screen_write_cursormove(&ctx, prefix_width,
i - mtd->offset, 0);
format_draw(&ctx, &gc0, left, text, NULL, 0);
if (mti->text != NULL && width < w) {
screen_write_cursormove(&ctx, width,
i - mtd->offset, 0);
format_draw(&ctx, &gc0, w - width,
mti->text, NULL, 0);
}
} }
} else { } else {
screen_write_clearendofline(&ctx, gc.bg); screen_write_clearendofline(&ctx, gc.bg);
screen_write_nputs(&ctx, w, &gc, "%s", text); format_draw(&ctx, &gc, prefix_width, prefix, NULL, 0);
if (mti->text != NULL) { if (left != 0) {
format_draw(&ctx, &gc, w - width, mti->text, screen_write_cursormove(&ctx, prefix_width,
NULL, 0); i - mtd->offset, 0);
format_draw(&ctx, &gc, left, text, NULL, 0);
if (mti->text != NULL && width < w) {
screen_write_cursormove(&ctx, width,
i - mtd->offset, 0);
format_draw(&ctx, &gc, w - width,
mti->text, NULL, 0);
}
} }
} }
free(text); free(text);
free(key); free(prefix);
if (mti->tagged) { if (mti->tagged) {
gc.attr ^= GRID_ATTR_BRIGHT; gc.attr ^= GRID_ATTR_BRIGHT;
gc0.attr ^= GRID_ATTR_BRIGHT; gc0.attr ^= GRID_ATTR_BRIGHT;
} }
} }
format_free(ft);
if (mtd->preview == MODE_TREE_PREVIEW_OFF) if (mtd->preview == MODE_TREE_PREVIEW_OFF)
goto done; goto done;
@@ -922,7 +984,7 @@ mode_tree_draw(struct mode_tree_data *mtd)
mti = mti->parent; mti = mti->parent;
screen_write_cursormove(&ctx, 0, h, 0); screen_write_cursormove(&ctx, 0, h, 0);
screen_write_box(&ctx, w, sy - h, BOX_LINES_DEFAULT, NULL, NULL); screen_write_box(&ctx, w, sy - h, BOX_LINES_DEFAULT, &box_gc, NULL);
if (mtd->sort_crit.order_seq != NULL) { if (mtd->sort_crit.order_seq != NULL) {
xasprintf(&text, " %s (sort: %s%s)%s%s%s", mti->name, xasprintf(&text, " %s (sort: %s%s)%s%s%s", mti->name,
@@ -935,21 +997,21 @@ mode_tree_draw(struct mode_tree_data *mtd)
xasprintf(&text, " %s", mti->name); xasprintf(&text, " %s", mti->name);
if (w - 2 >= strlen(text)) { if (w - 2 >= strlen(text)) {
screen_write_cursormove(&ctx, 1, h, 0); screen_write_cursormove(&ctx, 1, h, 0);
screen_write_puts(&ctx, &gc0, "%s", text); screen_write_puts(&ctx, &box_gc, "%s", text);
if (mtd->no_matches) if (mtd->no_matches)
n = (sizeof "no matches") - 1; n = (sizeof "no matches") - 1;
else else
n = (sizeof "active") - 1; n = (sizeof "active") - 1;
if (mtd->filter != NULL && w - 2 >= strlen(text) + 10 + n + 2) { if (mtd->filter != NULL && w - 2 >= strlen(text) + 10 + n + 2) {
screen_write_puts(&ctx, &gc0, " (filter: "); screen_write_puts(&ctx, &box_gc, " (filter: ");
if (mtd->no_matches) if (mtd->no_matches)
screen_write_puts(&ctx, &gc, "no matches"); screen_write_puts(&ctx, &box_gc, "no matches");
else else
screen_write_puts(&ctx, &gc0, "active"); screen_write_puts(&ctx, &box_gc, "active");
screen_write_puts(&ctx, &gc0, ") "); screen_write_puts(&ctx, &box_gc, ") ");
} else } else
screen_write_puts(&ctx, &gc0, " "); screen_write_puts(&ctx, &box_gc, " ");
} }
free(text); free(text);
@@ -1353,12 +1415,14 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x,
static void static void
mode_tree_draw_help_line(struct screen_write_ctx *ctx, mode_tree_draw_help_line(struct screen_write_ctx *ctx,
const struct grid_cell *gc, const char *line, const char *item, u_int x, const struct grid_cell *gc, struct format_tree *ft, const char *line,
u_int y, u_int w) const char *item, u_int x, u_int y, u_int w)
{ {
char *expanded; char *expanded, *replaced;
expanded = cmd_template_replace(line, item, 1); replaced = cmd_template_replace(line, item, 1);
expanded = format_expand(ft, replaced);
free(replaced);
screen_write_cursormove(ctx, x, y, 0); screen_write_cursormove(ctx, x, y, 0);
screen_write_clearcharacter(ctx, w, gc->bg); screen_write_clearcharacter(ctx, w, gc->bg);
screen_write_cursormove(ctx, x, y, 0); screen_write_cursormove(ctx, x, y, 0);
@@ -1370,7 +1434,9 @@ static void
mode_tree_draw_help(struct mode_tree_data *mtd, struct screen_write_ctx *ctx) mode_tree_draw_help(struct mode_tree_data *mtd, struct screen_write_ctx *ctx)
{ {
struct screen *s = &mtd->screen; struct screen *s = &mtd->screen;
struct grid_cell gc; struct options *oo = mtd->wp->window->options;
struct grid_cell box_gc, gc;
struct format_tree *ft;
const char **line, **lines = NULL, *item = "item"; const char **line, **lines = NULL, *item = "item";
u_int sx = screen_size_x(s), sy = screen_size_y(s); u_int sx = screen_size_x(s), sy = screen_size_y(s);
u_int x, y, w, h = 0, box_w, box_h; u_int x, y, w, h = 0, box_w, box_h;
@@ -1396,18 +1462,22 @@ mode_tree_draw_help(struct mode_tree_data *mtd, struct screen_write_ctx *ctx)
x = (sx - box_w) / 2; x = (sx - box_w) / 2;
y = (sy - box_h) / 2; y = (sy - box_h) / 2;
memcpy(&box_gc, &grid_default_cell, sizeof box_gc);
style_apply(&box_gc, oo, "tree-mode-border-style", NULL);
memcpy(&gc, &grid_default_cell, sizeof gc); memcpy(&gc, &grid_default_cell, sizeof gc);
ft = format_create_defaults(NULL, NULL, NULL, NULL, mtd->wp);
screen_write_cursormove(ctx, x, y, 0); screen_write_cursormove(ctx, x, y, 0);
screen_write_box(ctx, box_w, box_h, BOX_LINES_DEFAULT, &gc, NULL); screen_write_box(ctx, box_w, box_h, BOX_LINES_DEFAULT, &box_gc, NULL);
y++; y++;
x++; x++;
for (line = mode_tree_help_start; *line != NULL; line++, y++) for (line = mode_tree_help_start; *line != NULL; line++, y++)
mode_tree_draw_help_line(ctx, &gc, *line, item, x, y, w); mode_tree_draw_help_line(ctx, &gc, ft, *line, item, x, y, w);
for (line = lines; line != NULL && *line != NULL; line++, y++) for (line = lines; line != NULL && *line != NULL; line++, y++)
mode_tree_draw_help_line(ctx, &gc, *line, item, x, y, w); mode_tree_draw_help_line(ctx, &gc, ft, *line, item, x, y, w);
for (line = mode_tree_help_end; *line != NULL; line++, y++) for (line = mode_tree_help_end; *line != NULL; line++, y++)
mode_tree_draw_help_line(ctx, &gc, *line, item, x, y, w); mode_tree_draw_help_line(ctx, &gc, ft, *line, item, x, y, w);
format_free(ft);
} }
static void static void
@@ -1488,6 +1558,10 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
*key = KEYC_NONE; *key = KEYC_NONE;
return (0); return (0);
} }
if (*key == KEYC_FOCUS_IN || *key == KEYC_FOCUS_OUT) {
*key = KEYC_NONE;
return (0);
}
mtd->help = 0; mtd->help = 0;
mode_tree_draw(mtd); mode_tree_draw(mtd);
*key = KEYC_NONE; *key = KEYC_NONE;

View File

@@ -593,7 +593,7 @@ const struct options_table_entry options_table[] = {
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_SERVER, .scope = OPTIONS_TABLE_SERVER,
.flags = OPTIONS_TABLE_IS_COLOUR, .flags = OPTIONS_TABLE_IS_COLOUR,
.default_str = "#{?#{e|>=:#{client_colours},256},darkkhaki,yellow}", .default_str = "#{?#{e|>=:#{client_colours},256},darkgoldenrod,yellow}",
.text = "Dark theme colour for yellow." .text = "Dark theme colour for yellow."
}, },
@@ -1503,8 +1503,8 @@ const struct options_table_entry options_table[] = {
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_str = "fg=#{?pane_marked,thememagenta," .default_str = "fg=#{?pane_marked,thememagenta,"
"#{?synchronize-panes,themered," "#{?synchronize-panes,themered,"
"#{?pane_in_mode,themeyellow,themegreen}}}", "#{?pane_in_mode,themeyellow,themegreen}}}",
.flags = OPTIONS_TABLE_IS_STYLE, .flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",", .separator = ",",
.text = "Style of the active pane border." .text = "Style of the active pane border."
@@ -1614,7 +1614,7 @@ const struct options_table_entry options_table[] = {
{ .name = "popup-border-style", { .name = "popup-border-style",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,
.default_str = "fg=themelightgrey", .default_str = "bg=themedarkgrey,fg=themelightgrey",
.flags = OPTIONS_TABLE_IS_STYLE, .flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",", .separator = ",",
.text = "Default style of popup borders." .text = "Default style of popup borders."
@@ -1677,6 +1677,15 @@ const struct options_table_entry options_table[] = {
"A value of 0 means no limit." "A value of 0 means no limit."
}, },
{ .name = "tree-mode-border-style",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW,
.default_str = "bg=themedarkgrey,fg=themelightgrey",
.flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",",
.text = "Style of borders in tree mode."
},
{ .name = "tree-mode-preview-format", { .name = "tree-mode-preview-format",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,

View File

@@ -749,7 +749,8 @@ screen_write_hline(struct screen_write_ctx *ctx, u_int nx, int left, int right,
/* Draw a vertical line on screen. */ /* Draw a vertical line on screen. */
void void
screen_write_vline(struct screen_write_ctx *ctx, u_int ny, int top, int bottom) screen_write_vline(struct screen_write_ctx *ctx, u_int ny, int top, int bottom,
const struct grid_cell *gcp)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
struct grid_cell gc; struct grid_cell gc;
@@ -758,7 +759,10 @@ screen_write_vline(struct screen_write_ctx *ctx, u_int ny, int top, int bottom)
cx = s->cx; cx = s->cx;
cy = s->cy; cy = s->cy;
memcpy(&gc, &grid_default_cell, sizeof gc); if (gcp != NULL)
memcpy(&gc, gcp, sizeof gc);
else
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.attr |= GRID_ATTR_CHARSET; gc.attr |= GRID_ATTR_CHARSET;
screen_write_putc(ctx, &gc, top ? 'w' : 'x'); screen_write_putc(ctx, &gc, top ? 'w' : 'x');

8
tmux.1
View File

@@ -5853,6 +5853,14 @@ A value of 0 (the default) means no limit.
When a limit is set, panes are arranged to not exceed this number of columns, When a limit is set, panes are arranged to not exceed this number of columns,
with additional panes stacked in extra rows. with additional panes stacked in extra rows.
.Pp .Pp
.It Ic tree\-mode\-border\-style Ar style
Set the style of borders in tree mode.
For how to specify
.Ar style ,
see the
.Sx STYLES
section.
.Pp
.It Ic tree\-mode\-preview\-format Ar format .It Ic tree\-mode\-preview\-format Ar format
Format of the preview indicator in tree mode. Format of the preview indicator in tree mode.
.Pp .Pp

3
tmux.h
View File

@@ -3412,7 +3412,8 @@ void screen_write_fast_copy(struct screen_write_ctx *, struct screen *,
u_int, u_int, u_int, u_int); u_int, u_int, u_int, u_int);
void screen_write_hline(struct screen_write_ctx *, u_int, int, int, void screen_write_hline(struct screen_write_ctx *, u_int, int, int,
enum box_lines, const struct grid_cell *); enum box_lines, const struct grid_cell *);
void screen_write_vline(struct screen_write_ctx *, u_int, int, int); void screen_write_vline(struct screen_write_ctx *, u_int, int, int,
const struct grid_cell *);
void screen_write_menu(struct screen_write_ctx *, struct menu *, int, void screen_write_menu(struct screen_write_ctx *, struct menu *, int,
enum box_lines, const struct grid_cell *, const struct grid_cell *, enum box_lines, const struct grid_cell *, const struct grid_cell *,
const struct grid_cell *); const struct grid_cell *);

View File

@@ -336,13 +336,20 @@ window_buffer_sort(struct sort_criteria *sort_crit)
} }
static const char* window_buffer_help_lines[] = { static const char* window_buffer_help_lines[] = {
"#[bold] Enter #[default]#[acs]x#[default] Paste selected %1", "#[fg=themelightgrey]"
"#[bold] p #[default]#[acs]x#[default] Paste selected %1", " Enter #[#{E:tree-mode-border-style},acs]x#[default] Paste selected %1",
"#[bold] P #[default]#[acs]x#[default] Paste tagged %1s", "#[fg=themelightgrey]"
"#[bold] d #[default]#[acs]x#[default] Delete selected %1", " p #[#{E:tree-mode-border-style},acs]x#[default] Paste selected %1",
"#[bold] D #[default]#[acs]x#[default] Delete tagged %1s", "#[fg=themelightgrey]"
"#[bold] e #[default]#[acs]x#[default] Open %1 in editor", " P #[#{E:tree-mode-border-style},acs]x#[default] Paste tagged %1s",
"#[bold] f #[default]#[acs]x#[default] Enter a filter", "#[fg=themelightgrey]"
" d #[#{E:tree-mode-border-style},acs]x#[default] Delete selected %1",
"#[fg=themelightgrey]"
" D #[#{E:tree-mode-border-style},acs]x#[default] Delete tagged %1s",
"#[fg=themelightgrey]"
" e #[#{E:tree-mode-border-style},acs]x#[default] Open %1 in editor",
"#[fg=themelightgrey]"
" f #[#{E:tree-mode-border-style},acs]x#[default] Enter a filter",
NULL NULL
}; };

View File

@@ -38,7 +38,7 @@ static void window_client_key(struct window_mode_entry *,
#define WINDOW_CLIENT_DEFAULT_COMMAND "detach-client -t '%%'" #define WINDOW_CLIENT_DEFAULT_COMMAND "detach-client -t '%%'"
#define WINDOW_CLIENT_DEFAULT_FORMAT \ #define WINDOW_CLIENT_DEFAULT_FORMAT \
"#{t/p:client_activity}: session #{session_name}" "#[fg=themelightgrey]#{t/p:client_activity}: session #[default]#{session_name}"
#define WINDOW_CLIENT_DEFAULT_KEY_FORMAT \ #define WINDOW_CLIENT_DEFAULT_KEY_FORMAT \
"#{?#{e|<:#{line},10}," \ "#{?#{e|<:#{line},10}," \
@@ -49,87 +49,91 @@ static void window_client_key(struct window_mode_entry *,
#define WINDOW_CLIENT_FEATURE(f) \ #define WINDOW_CLIENT_FEATURE(f) \
"#{?#{I/f:" #f "}," \ "#{?#{I/f:" #f "}," \
"#[fg=green],#[dim]}#{p/15:#{l:" #f "}}" \ "#[fg=themegreen],#[fg=themelightgrey]}#{p/15:#{l:" #f "}}" \
"#[default]" "#[default]"
static const char *window_client_info_lines[] = { static const char *window_client_info_lines[] = {
"Client Name #[acs]x#[default] " "#[fg=themelightgrey]Client Name #[#{E:tree-mode-border-style},acs]x#[default] "
"#{client_name} " "#{client_name} #[fg=themelightgrey]"
"#[dim](PID #{client_pid})#[default]", "#[fg=themelightgrey](PID #{client_pid})#[default]",
"Session #[acs]x#[default] " "#[fg=themelightgrey]Session #[#{E:tree-mode-border-style},acs]x#[default] "
"#{session_name}", "#{session_name}",
"Attach Time #[acs]x#[default] " "#[fg=themelightgrey]Attach Time #[#{E:tree-mode-border-style},acs]x#[default] "
"#{t:client_created} " "#{t:client_created} "
"#[dim](#{t/r:client_created})#[default]", "#[fg=themelightgrey](#{t/r:client_created})#[default]",
"Activity Time #[acs]x#[default] " "#[fg=themelightgrey]Activity Time #[#{E:tree-mode-border-style},acs]x#[default] "
"#{t:client_activity} " "#{t:client_activity} "
"#[dim](#{t/r:client_activity})#[default]", "#[fg=themelightgrey](#{t/r:client_activity})#[default]",
"Terminal Type #[acs]x#[default] " "#[fg=themelightgrey]Terminal Type #[#{E:tree-mode-border-style},acs]x#[default] "
"#{?client_termtype,#{client_termtype},Unknown}", "#{?client_termtype,#{client_termtype},Unknown}",
"TERM #[acs]x#[default] " "#[fg=themelightgrey]TERM #[#{E:tree-mode-border-style},acs]x#[default] "
"#{client_termname}", "#{client_termname}",
"Size #[acs]x#[default] " "#[fg=themelightgrey]Size #[#{E:tree-mode-border-style},acs]x#[default] "
"#{client_width}x#{client_height} " "#{client_width}x#{client_height} "
"#[dim](cell #{client_cell_width}x#{client_cell_height})#[default]", "#[fg=themelightgrey](cell #{client_cell_width}x"
"Bytes Written #[acs]x#[default] " "#{client_cell_height})#[default]",
"#[fg=themelightgrey]Bytes Written #[#{E:tree-mode-border-style},acs]x#[default] "
"#{client_written} " "#{client_written} "
"#[dim](#{client_discarded} discarded)#[default]", "#[fg=themelightgrey](#{client_discarded} discarded)#[default]",
"Features #[acs]x#[default] " "#[fg=themelightgrey]Features #[#{E:tree-mode-border-style},acs]x#[default] "
WINDOW_CLIENT_FEATURE(256) " " WINDOW_CLIENT_FEATURE(256) " "
WINDOW_CLIENT_FEATURE(RGB) " " WINDOW_CLIENT_FEATURE(RGB) " "
WINDOW_CLIENT_FEATURE(bpaste) " " WINDOW_CLIENT_FEATURE(bpaste) " "
WINDOW_CLIENT_FEATURE(ccolour), WINDOW_CLIENT_FEATURE(ccolour),
" #[acs]x#[default] " " #[#{E:tree-mode-border-style},acs]x#[default] "
WINDOW_CLIENT_FEATURE(clipboard) " " WINDOW_CLIENT_FEATURE(clipboard) " "
WINDOW_CLIENT_FEATURE(cstyle) " " WINDOW_CLIENT_FEATURE(cstyle) " "
WINDOW_CLIENT_FEATURE(extkeys) " " WINDOW_CLIENT_FEATURE(extkeys) " "
WINDOW_CLIENT_FEATURE(focus), WINDOW_CLIENT_FEATURE(focus),
" #[acs]x#[default] " " #[#{E:tree-mode-border-style},acs]x#[default] "
WINDOW_CLIENT_FEATURE(hyperlinks) " " WINDOW_CLIENT_FEATURE(hyperlinks) " "
WINDOW_CLIENT_FEATURE(ignorefkeys) " " WINDOW_CLIENT_FEATURE(ignorefkeys) " "
WINDOW_CLIENT_FEATURE(margins) " " WINDOW_CLIENT_FEATURE(margins) " "
WINDOW_CLIENT_FEATURE(mouse), WINDOW_CLIENT_FEATURE(mouse),
" #[acs]x#[default] " " #[#{E:tree-mode-border-style},acs]x#[default] "
WINDOW_CLIENT_FEATURE(osc7) " " WINDOW_CLIENT_FEATURE(osc7) " "
WINDOW_CLIENT_FEATURE(overline) " " WINDOW_CLIENT_FEATURE(overline) " "
WINDOW_CLIENT_FEATURE(progressbar) " " WINDOW_CLIENT_FEATURE(progressbar) " "
WINDOW_CLIENT_FEATURE(rectfill), WINDOW_CLIENT_FEATURE(rectfill),
" #[acs]x#[default] " " #[#{E:tree-mode-border-style},acs]x#[default] "
WINDOW_CLIENT_FEATURE(sixel) " " WINDOW_CLIENT_FEATURE(sixel) " "
WINDOW_CLIENT_FEATURE(strikethrough) " " WINDOW_CLIENT_FEATURE(strikethrough) " "
WINDOW_CLIENT_FEATURE(sync) " " WINDOW_CLIENT_FEATURE(sync) " "
WINDOW_CLIENT_FEATURE(title), WINDOW_CLIENT_FEATURE(title),
" #[acs]x#[default] " " #[#{E:tree-mode-border-style},acs]x#[default] "
WINDOW_CLIENT_FEATURE(usstyle), WINDOW_CLIENT_FEATURE(usstyle),
"#[acs]qqqqqqqqqqqqqqn#{R:q,#{window_width}}#[default]", "#[#{E:tree-mode-border-style},acs]qqqqqqqqqqqqqqn#{R:q,#{window_width}}#[default]",
"prefix #[acs]x#[default] " "#[fg=themelightgrey]prefix #[#{E:tree-mode-border-style},acs]x#[default] "
"#{prefix}", "#{prefix}",
"mouse #[acs]x#[default] " "#[fg=themelightgrey]mouse #[#{E:tree-mode-border-style},acs]x#[default] "
"#{?mouse,#{?#{I/c:kmous},,#[fg=red]}on,#[dim]off} " "#{?mouse,#{?#{I/c:kmous},,#[fg=themered]}on,#[fg=themelightgrey]off} "
"#{?#{I/c:kmous},,#[align=right]unavailable: [kmous] missing}", "#{?#{I/c:kmous},,#[align=right]unavailable: [kmous] missing}",
"set-clipboard #[acs]x#[default] " "#[fg=themelightgrey]set-clipboard #[#{E:tree-mode-border-style},acs]x#[default] "
"#{?#{!=:#{set-clipboard},off},#{?#{I/f:clipboard},,#[fg=red]}#{set-clipboard},#[dim]off} " "#{?#{!=:#{set-clipboard},off},#{?#{I/f:clipboard},,"
"#[fg=themered]}#{set-clipboard},#[fg=themelightgrey]off} "
"#{?#{I/f:clipboard},,#[align=right]unavailable: [Ms] missing}", "#{?#{I/f:clipboard},,#[align=right]unavailable: [Ms] missing}",
"get-clipboard #[acs]x#[default] " "#[fg=themelightgrey]get-clipboard #[#{E:tree-mode-border-style},acs]x#[default] "
"#{?#{!=:#{get-clipboard},off},#{?#{I/f:clipboard},,#[fg=red]}#{get-clipboard},#[dim]off} " "#{?#{!=:#{get-clipboard},off},#{?#{I/f:clipboard},,"
"#[fg=themered]}#{get-clipboard},#[fg=themelightgrey]off} "
"#{?#{I/f:clipboard},,#[align=right]unavailable: [Ms] missing}", "#{?#{I/f:clipboard},,#[align=right]unavailable: [Ms] missing}",
"focus-events #[acs]x#[default] " "#[fg=themelightgrey]focus-events #[#{E:tree-mode-border-style},acs]x#[default] "
"#{?focus-events,#{?#{I/f:focus},,#[fg=red]}on,#[dim]off} " "#{?focus-events,#{?#{I/f:focus},,#[fg=themered]}on,#[fg=themelightgrey]off} "
"#{?#{I/f:focus},,#[align=right]unavailable: [Enfcs] or [Dcfcs] missing}", "#{?#{I/f:focus},,#[align=right]unavailable: [Enfcs] or [Dcfcs] missing}",
"extended-keys #[acs]x#[default] " "#[fg=themelightgrey]extended-keys #[#{E:tree-mode-border-style},acs]x#[default] "
"#{?#{!=:#{extended-keys},off},#{?#{I/f:extkeys},,#[fg=red]}#{extended-keys},#[dim]off} " "#{?#{!=:#{extended-keys},off},#{?#{I/f:extkeys},,"
"#[fg=themered]}#{extended-keys},#[fg=themelightgrey]off} "
"#{?#{I/f:extkeys},,#[align=right]unavailable: [Eneks] or [Dseks] missing}", "#{?#{I/f:extkeys},,#[align=right]unavailable: [Eneks] or [Dseks] missing}",
"set-titles #[acs]x#[default] " "#[fg=themelightgrey]set-titles #[#{E:tree-mode-border-style},acs]x#[default] "
"#{?set-titles,on,#[dim]off}", "#{?set-titles,on,#[fg=themelightgrey]off}",
"escape-time #[acs]x#[default] " "#[fg=themelightgrey]escape-time #[#{E:tree-mode-border-style},acs]x#[default] "
"#{escape-time} ms", "#{escape-time} ms",
}; };
@@ -258,6 +262,8 @@ window_client_draw_info(__unused void *modedata, void *itemdata,
struct window_client_itemdata *item = itemdata; struct window_client_itemdata *item = itemdata;
struct client *c = item->c; struct client *c = item->c;
struct screen *s = ctx->s; struct screen *s = ctx->s;
struct window *w = c->session->curw->window;
struct grid_cell gc;
u_int cx = s->cx, cy = s->cy, i; u_int cx = s->cx, cy = s->cy, i;
struct format_tree *ft; struct format_tree *ft;
char *expanded; char *expanded;
@@ -273,6 +279,12 @@ window_client_draw_info(__unused void *modedata, void *itemdata,
format_draw(ctx, &grid_default_cell, sx, expanded, NULL, 0); format_draw(ctx, &grid_default_cell, sx, expanded, NULL, 0);
free(expanded); free(expanded);
} }
if (sx > 14 && i < sy) {
memcpy(&gc, &grid_default_cell, sizeof gc);
style_apply(&gc, w->options, "tree-mode-border-style", NULL);
screen_write_cursormove(ctx, cx + 14, cy + i, 0);
screen_write_vline(ctx, sy - i, 0, 0, &gc);
}
format_free(ft); format_free(ft);
} }
@@ -284,20 +296,24 @@ window_client_draw(void *modedata, void *itemdata,
struct window_client_modedata *data = modedata; struct window_client_modedata *data = modedata;
struct window_client_itemdata *item = itemdata; struct window_client_itemdata *item = itemdata;
struct client *c = item->c; struct client *c = item->c;
struct session *session = c->session;
struct screen *s = ctx->s; struct screen *s = ctx->s;
struct window *w;
struct window_pane *wp; struct window_pane *wp;
struct grid_cell gc;
u_int cx = s->cx, cy = s->cy, lines, at; u_int cx = s->cx, cy = s->cy, lines, at;
if (c->session == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS)) if (session == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
return; return;
if (data->preview_is_info) { if (data->preview_is_info) {
window_client_draw_info(modedata, itemdata, ctx, sx, sy); window_client_draw_info(modedata, itemdata, ctx, sx, sy);
return; return;
} }
wp = c->session->curw->window->active; w = session->curw->window;
wp = w->active;
if (data->hide_preview_this_pane && wp == data->wp) { if (data->hide_preview_this_pane && wp == data->wp) {
if (!TAILQ_EMPTY(&c->session->curw->window->last_panes)) if (!TAILQ_EMPTY(&w->last_panes))
wp = TAILQ_FIRST(&c->session->curw->window->last_panes); wp = TAILQ_FIRST(&w->last_panes);
else else
wp = NULL; wp = NULL;
} }
@@ -318,7 +334,9 @@ window_client_draw(void *modedata, void *itemdata,
screen_write_cursormove(ctx, cx, cy + 2, 0); screen_write_cursormove(ctx, cx, cy + 2, 0);
else else
screen_write_cursormove(ctx, cx, cy + sy - 1 - lines, 0); screen_write_cursormove(ctx, cx, cy + sy - 1 - lines, 0);
screen_write_hline(ctx, sx, 0, 0, BOX_LINES_DEFAULT, NULL); memcpy(&gc, &grid_default_cell, sizeof gc);
style_apply(&gc, w->options, "tree-mode-border-style", NULL);
screen_write_hline(ctx, sx, 0, 0, BOX_LINES_DEFAULT, &gc);
if (at != 0) if (at != 0)
screen_write_cursormove(ctx, cx, cy, 0); screen_write_cursormove(ctx, cx, cy, 0);
@@ -369,15 +387,24 @@ window_client_sort(struct sort_criteria *sort_crit)
} }
static const char* window_client_help_lines[] = { static const char* window_client_help_lines[] = {
"#[bold] i #[default]#[acs]x#[default] Toggle info view", "#[fg=themelightgrey]"
"#[bold] Enter #[default]#[acs]x#[default] Choose selected %1", " i #[#{E:tree-mode-border-style},acs]x#[default] Toggle info view",
"#[bold] d #[default]#[acs]x#[default] Detach selected %1", "#[fg=themelightgrey]"
"#[bold] D #[default]#[acs]x#[default] Detach tagged %1s", " Enter #[#{E:tree-mode-border-style},acs]x#[default] Choose selected %1",
"#[bold] x #[default]#[acs]x#[default] Detach selected %1", "#[fg=themelightgrey]"
"#[bold] X #[default]#[acs]x#[default] Detach tagged %1s", " d #[#{E:tree-mode-border-style},acs]x#[default] Detach selected %1",
"#[bold] z #[default]#[acs]x#[default] Suspend selected %1", "#[fg=themelightgrey]"
"#[bold] Z #[default]#[acs]x#[default] Suspend tagged %1s", " D #[#{E:tree-mode-border-style},acs]x#[default] Detach tagged %1s",
"#[bold] f #[default]#[acs]x#[default] Enter a filter", "#[fg=themelightgrey]"
" x #[#{E:tree-mode-border-style},acs]x#[default] Detach selected %1",
"#[fg=themelightgrey]"
" X #[#{E:tree-mode-border-style},acs]x#[default] Detach tagged %1s",
"#[fg=themelightgrey]"
" z #[#{E:tree-mode-border-style},acs]x#[default] Suspend selected %1",
"#[fg=themelightgrey]"
" Z #[#{E:tree-mode-border-style},acs]x#[default] Suspend tagged %1s",
"#[fg=themelightgrey]"
" f #[#{E:tree-mode-border-style},acs]x#[default] Enter a filter",
NULL NULL
}; };

View File

@@ -36,8 +36,8 @@ static void window_customize_key(struct window_mode_entry *,
#define WINDOW_CUSTOMIZE_DEFAULT_FORMAT \ #define WINDOW_CUSTOMIZE_DEFAULT_FORMAT \
"#{?is_option," \ "#{?is_option," \
"#{?option_is_global,,#[reverse](#{option_scope})#[default] }" \ "#{?option_is_global,,#[reverse](#{option_scope})#[default] }" \
"#[ignore]" \ "#[fg=themelightgrey]#[ignore]#{option_value}" \
"#{option_value}#{?option_unit, #{option_unit},}" \ "#{?option_unit, #{option_unit},}" \
"," \ "," \
"#{key}" \ "#{key}" \
"}" "}"
@@ -881,15 +881,24 @@ window_customize_height(__unused void *modedata, __unused u_int height)
} }
static const char* window_customize_help_lines[] = { static const char* window_customize_help_lines[] = {
"#[bold] Enter, s #[default]#[acs]x#[default] Set %1 value", "#[fg=themelightgrey]"
"#[bold] S #[default]#[acs]x#[default] Set global %1 value", " Enter, s #[#{E:tree-mode-border-style},acs]x#[default] Set %1 value",
"#[bold] w #[default]#[acs]x#[default] Set window %1 value", "#[fg=themelightgrey]"
"#[bold] d #[default]#[acs]x#[default] Set to default value", " S #[#{E:tree-mode-border-style},acs]x#[default] Set global %1 value",
"#[bold] D #[default]#[acs]x#[default] Set tagged %1s to default value", "#[fg=themelightgrey]"
"#[bold] u #[default]#[acs]x#[default] Unset an %1", " w #[#{E:tree-mode-border-style},acs]x#[default] Set window %1 value",
"#[bold] U #[default]#[acs]x#[default] Unset tagged %1s", "#[fg=themelightgrey]"
"#[bold] f #[default]#[acs]x#[default] Enter a filter", " d #[#{E:tree-mode-border-style},acs]x#[default] Set to default value",
"#[bold] v #[default]#[acs]x#[default] Toggle information", "#[fg=themelightgrey]"
" D #[#{E:tree-mode-border-style},acs]x#[default] Set tagged %1s to default value",
"#[fg=themelightgrey]"
" u #[#{E:tree-mode-border-style},acs]x#[default] Unset an %1",
"#[fg=themelightgrey]"
" U #[#{E:tree-mode-border-style},acs]x#[default] Unset tagged %1s",
"#[fg=themelightgrey]"
" f #[#{E:tree-mode-border-style},acs]x#[default] Enter a filter",
"#[fg=themelightgrey]"
" v #[#{E:tree-mode-border-style},acs]x#[default] Toggle information",
NULL NULL
}; };

View File

@@ -39,14 +39,14 @@ static void window_tree_key(struct window_mode_entry *,
#define WINDOW_TREE_DEFAULT_FORMAT \ #define WINDOW_TREE_DEFAULT_FORMAT \
"#{?pane_format," \ "#{?pane_format," \
"#{?pane_marked,#[reverse],}#{?pane_floating_flag,#[italics],}" \ "#{?pane_marked,#[reverse],}#{?pane_floating_flag,#[italics],}" \
"#{pane_current_command}#{pane_flags}" \ "#{pane_current_command}#[fg=themelightgrey]#{pane_flags}" \
"#{?#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}},: \"#{pane_title}\",}" \ "#{?#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}},: \"#{pane_title}\",}" \
",window_format," \ ",window_format," \
"#{?window_marked_flag,#[reverse],}" \ "#{?window_marked_flag,#[reverse],}" \
"#{window_name}#{window_flags}" \ "#{window_name}#[fg=themelightgrey]#{window_flags}" \
"#{?#{&&:#{==:#{window_panes},1},#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}}},: \"#{pane_title}\",}" \ "#{?#{&&:#{==:#{window_panes},1},#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}}},: \"#{pane_title}\",}" \
"," \ "," \
"#{session_windows} windows" \ "#[fg=themelightgrey]#{session_windows} windows" \
"#{?session_grouped, " \ "#{?session_grouped, " \
"(group #{session_group}: " \ "(group #{session_group}: " \
"#{session_group_list})," \ "#{session_group_list})," \
@@ -401,7 +401,8 @@ window_tree_build(void *modedata, struct sort_criteria *sort_crit,
static void static void
window_tree_draw_label(struct screen_write_ctx *ctx, u_int px, u_int py, window_tree_draw_label(struct screen_write_ctx *ctx, u_int px, u_int py,
u_int sx, u_int sy, const struct grid_cell *gc, const char *label) u_int sx, u_int sy, const struct grid_cell *border_gc,
const struct grid_cell *label_gc, const char *label)
{ {
u_int width, ox, oy; u_int width, ox, oy;
char *new_label = NULL; char *new_label = NULL;
@@ -420,14 +421,22 @@ window_tree_draw_label(struct screen_write_ctx *ctx, u_int px, u_int py,
screen_write_cursormove(ctx, px + ox - 2, py + oy - 1, 0); screen_write_cursormove(ctx, px + ox - 2, py + oy - 1, 0);
screen_write_box(ctx, width + 4, 3, BOX_LINES_DEFAULT, screen_write_box(ctx, width + 4, 3, BOX_LINES_DEFAULT,
NULL, NULL); border_gc, NULL);
screen_write_cursormove(ctx, px + ox - 1, py + oy, 0); screen_write_cursormove(ctx, px + ox - 1, py + oy, 0);
screen_write_clearcharacter(ctx, width + 2, 8); screen_write_clearcharacter(ctx, width + 2, border_gc->bg);
screen_write_cursormove(ctx, px + ox, py + oy, 0); screen_write_cursormove(ctx, px + ox, py + oy, 0);
format_draw(ctx, gc, width, label, NULL, 0); format_draw(ctx, label_gc, width, label, NULL, 0);
free(new_label); free(new_label);
} }
static void
window_tree_border_cell(struct grid_cell *gc, struct options *oo,
struct format_tree *ft)
{
memcpy(gc, &grid_default_cell, sizeof *gc);
style_apply(gc, oo, "tree-mode-border-style", ft);
}
static void static void
window_tree_draw_session(struct window_tree_modedata *data, struct session *s, window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
struct screen_write_ctx *ctx, u_int sx, u_int sy) struct screen_write_ctx *ctx, u_int sx, u_int sy)
@@ -437,7 +446,7 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
u_int cx = ctx->s->cx, cy = ctx->s->cy; u_int cx = ctx->s->cx, cy = ctx->s->cy;
u_int loop, total, visible, each, width, offset; u_int loop, total, visible, each, width, offset;
u_int current, start, end, remaining, i; u_int current, start, end, remaining, i;
struct grid_cell gc; struct grid_cell gc, label_gc;
int left, right; int left, right;
char *label; char *label;
const char *format; const char *format;
@@ -495,20 +504,21 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
if (each == 0) if (each == 0)
return; return;
window_tree_border_cell(&gc, data->wp->window->options, NULL);
if (left) { if (left) {
data->left = cx + 2; data->left = cx + 2;
screen_write_cursormove(ctx, cx + 2, cy, 0); screen_write_cursormove(ctx, cx + 2, cy, 0);
screen_write_vline(ctx, sy, 0, 0); screen_write_vline(ctx, sy, 0, 0, &gc);
screen_write_cursormove(ctx, cx, cy + sy / 2, 0); screen_write_cursormove(ctx, cx, cy + sy / 2, 0);
screen_write_puts(ctx, &grid_default_cell, "<"); screen_write_puts(ctx, &gc, "<");
} else } else
data->left = -1; data->left = -1;
if (right) { if (right) {
data->right = cx + sx - 3; data->right = cx + sx - 3;
screen_write_cursormove(ctx, cx + sx - 3, cy, 0); screen_write_cursormove(ctx, cx + sx - 3, cy, 0);
screen_write_vline(ctx, sy, 0, 0); screen_write_vline(ctx, sy, 0, 0, &gc);
screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2, 0); screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2, 0);
screen_write_puts(ctx, &grid_default_cell, ">"); screen_write_puts(ctx, &gc, ">");
} else } else
data->right = -1; data->right = -1;
@@ -530,8 +540,10 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
ft = format_create(NULL, NULL, FORMAT_WINDOW|w->id, 0); ft = format_create(NULL, NULL, FORMAT_WINDOW|w->id, 0);
format_defaults(ft, NULL, s, wl, NULL); format_defaults(ft, NULL, s, wl, NULL);
memcpy(&gc, &grid_default_cell, sizeof gc); window_tree_border_cell(&gc, oo, ft);
style_apply(&gc, oo, "tree-mode-preview-style", ft); memcpy(&label_gc, &grid_default_cell, sizeof label_gc);
style_apply(&label_gc, oo, "tree-mode-preview-style", ft);
label_gc.bg = gc.bg;
if (left) if (left)
offset = 3 + (i * each); offset = 3 + (i * each);
@@ -550,7 +562,7 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
label = format_expand(ft, format); label = format_expand(ft, format);
if (*label != '\0') { if (*label != '\0') {
window_tree_draw_label(ctx, cx + offset, cy, window_tree_draw_label(ctx, cx + offset, cy,
width, sy, &gc, label); width, sy, &gc, &label_gc, label);
} }
free(label); free(label);
} }
@@ -558,7 +570,7 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
if (loop != end - 1) { if (loop != end - 1) {
screen_write_cursormove(ctx, cx + offset + width, cy, screen_write_cursormove(ctx, cx + offset + width, cy,
0); 0);
screen_write_vline(ctx, sy, 0, 0); screen_write_vline(ctx, sy, 0, 0, &gc);
} }
loop++; loop++;
@@ -575,7 +587,7 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
u_int cx = ctx->s->cx, cy = ctx->s->cy; u_int cx = ctx->s->cx, cy = ctx->s->cy;
u_int loop, total, visible, each, width, offset; u_int loop, total, visible, each, width, offset;
u_int current, start, end, remaining, i; u_int current, start, end, remaining, i;
struct grid_cell gc; struct grid_cell gc, label_gc;
int left, right; int left, right;
char *label; char *label;
const char *format; const char *format;
@@ -639,20 +651,21 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
if (each == 0) if (each == 0)
return; return;
window_tree_border_cell(&gc, data->wp->window->options, NULL);
if (left) { if (left) {
data->left = cx + 2; data->left = cx + 2;
screen_write_cursormove(ctx, cx + 2, cy, 0); screen_write_cursormove(ctx, cx + 2, cy, 0);
screen_write_vline(ctx, sy, 0, 0); screen_write_vline(ctx, sy, 0, 0, &gc);
screen_write_cursormove(ctx, cx, cy + sy / 2, 0); screen_write_cursormove(ctx, cx, cy + sy / 2, 0);
screen_write_puts(ctx, &grid_default_cell, "<"); screen_write_puts(ctx, &gc, "<");
} else } else
data->left = -1; data->left = -1;
if (right) { if (right) {
data->right = cx + sx - 3; data->right = cx + sx - 3;
screen_write_cursormove(ctx, cx + sx - 3, cy, 0); screen_write_cursormove(ctx, cx + sx - 3, cy, 0);
screen_write_vline(ctx, sy, 0, 0); screen_write_vline(ctx, sy, 0, 0, &gc);
screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2, 0); screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2, 0);
screen_write_puts(ctx, &grid_default_cell, ">"); screen_write_puts(ctx, &gc, ">");
} else } else
data->right = -1; data->right = -1;
@@ -675,8 +688,10 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
ft = format_create(NULL, NULL, FORMAT_PANE|wp->id, 0); ft = format_create(NULL, NULL, FORMAT_PANE|wp->id, 0);
format_defaults(ft, NULL, s, wl, wp); format_defaults(ft, NULL, s, wl, wp);
memcpy(&gc, &grid_default_cell, sizeof gc); window_tree_border_cell(&gc, oo, ft);
style_apply(&gc, oo, "tree-mode-preview-style", ft); memcpy(&label_gc, &grid_default_cell, sizeof label_gc);
style_apply(&label_gc, oo, "tree-mode-preview-style", ft);
label_gc.bg = gc.bg;
if (left) if (left)
offset = 3 + (i * each); offset = 3 + (i * each);
@@ -695,7 +710,7 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
label = format_expand(ft, format); label = format_expand(ft, format);
if (*label != '\0') { if (*label != '\0') {
window_tree_draw_label(ctx, cx + offset, cy, window_tree_draw_label(ctx, cx + offset, cy,
width, sy, &gc, label); width, sy, &gc, &label_gc, label);
} }
free(label); free(label);
} }
@@ -703,7 +718,7 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
if (loop != end - 1) { if (loop != end - 1) {
screen_write_cursormove(ctx, cx + offset + width, cy, screen_write_cursormove(ctx, cx + offset + width, cy,
0); 0);
screen_write_vline(ctx, sy, 0, 0); screen_write_vline(ctx, sy, 0, 0, &gc);
} }
loop++; loop++;
@@ -889,18 +904,30 @@ window_tree_sort(struct sort_criteria *sort_crit)
} }
static const char* window_tree_help_lines[] = { static const char* window_tree_help_lines[] = {
"#[bold] Enter #[default]#[acs]x#[default] Choose selected item", "#[fg=themelightgrey]"
"#[bold] S-Up #[default]#[acs]x#[default] Swap current and previous window", " Enter #[#{E:tree-mode-border-style},acs]x#[default] Choose selected item",
"#[bold] S-Down #[default]#[acs]x#[default] Swap current and next window", "#[fg=themelightgrey]"
"#[bold] x #[default]#[acs]x#[default] Kill selected item", " S-Up #[#{E:tree-mode-border-style},acs]x#[default] Swap current and previous window",
"#[bold] X #[default]#[acs]x#[default] Kill tagged items", "#[fg=themelightgrey]"
"#[bold] < #[default]#[acs]x#[default] Scroll previews left", " S-Down #[#{E:tree-mode-border-style},acs]x#[default] Swap current and next window",
"#[bold] > #[default]#[acs]x#[default] Scroll previews right", "#[fg=themelightgrey]"
"#[bold] m #[default]#[acs]x#[default] Set the marked pane", " x #[#{E:tree-mode-border-style},acs]x#[default] Kill selected item",
"#[bold] M #[default]#[acs]x#[default] Clear the marked pane", "#[fg=themelightgrey]"
"#[bold] : #[default]#[acs]x#[default] Run a command for each tagged item", " X #[#{E:tree-mode-border-style},acs]x#[default] Kill tagged items",
"#[bold] f #[default]#[acs]x#[default] Enter a format", "#[fg=themelightgrey]"
"#[bold] H #[default]#[acs]x#[default] Jump to the starting pane", " < #[#{E:tree-mode-border-style},acs]x#[default] Scroll previews left",
"#[fg=themelightgrey]"
" > #[#{E:tree-mode-border-style},acs]x#[default] Scroll previews right",
"#[fg=themelightgrey]"
" m #[#{E:tree-mode-border-style},acs]x#[default] Set the marked pane",
"#[fg=themelightgrey]"
" M #[#{E:tree-mode-border-style},acs]x#[default] Clear the marked pane",
"#[fg=themelightgrey]"
" : #[#{E:tree-mode-border-style},acs]x#[default] Run a command for each tagged item",
"#[fg=themelightgrey]"
" f #[#{E:tree-mode-border-style},acs]x#[default] Enter a format",
"#[fg=themelightgrey]"
" H #[#{E:tree-mode-border-style},acs]x#[default] Jump to the starting pane",
NULL NULL
}; };