Permit option values to be used in formats.

This commit is contained in:
nicm 2014-12-02 23:19:45 +00:00
parent e52d791212
commit 575fd1e322
3 changed files with 81 additions and 28 deletions

View File

@ -39,8 +39,26 @@ int format_replace(struct format_tree *, const char *, size_t, char **,
char *format_get_command(struct window_pane *); char *format_get_command(struct window_pane *);
void format_window_pane_tabs(struct format_tree *, struct window_pane *); void format_window_pane_tabs(struct format_tree *, struct window_pane *);
/* Entry in format tree. */
struct format_entry {
char *key;
char *value;
RB_ENTRY(format_entry) entry;
};
/* Tree of format entries. */
struct format_tree {
struct window *w;
struct session *s;
RB_HEAD(format_rb_tree, format_entry) tree;
};
/* Format key-value replacement entry. */ /* Format key-value replacement entry. */
RB_GENERATE(format_tree, format_entry, entry, format_cmp); int format_cmp(struct format_entry *, struct format_entry *);
RB_PROTOTYPE(format_rb_tree, format_entry, entry, format_cmp);
RB_GENERATE(format_rb_tree, format_entry, entry, format_cmp);
/* Format tree comparison function. */ /* Format tree comparison function. */
int int
@ -116,8 +134,8 @@ format_create(void)
struct format_tree *ft; struct format_tree *ft;
char host[MAXHOSTNAMELEN], *ptr; char host[MAXHOSTNAMELEN], *ptr;
ft = xmalloc(sizeof *ft); ft = xcalloc(1, sizeof *ft);
RB_INIT(ft); RB_INIT(&ft->tree);
if (gethostname(host, sizeof host) == 0) { if (gethostname(host, sizeof host) == 0) {
format_add(ft, "host", "%s", host); format_add(ft, "host", "%s", host);
@ -133,14 +151,10 @@ format_create(void)
void void
format_free(struct format_tree *ft) format_free(struct format_tree *ft)
{ {
struct format_entry *fe, *fe_next; struct format_entry *fe, *fe1;
fe_next = RB_MIN(format_tree, ft); RB_FOREACH_SAFE(fe, format_rb_tree, &ft->tree, fe1) {
while (fe_next != NULL) { RB_REMOVE(format_rb_tree, &ft->tree, fe);
fe = fe_next;
fe_next = RB_NEXT(format_tree, ft, fe);
RB_REMOVE(format_tree, ft, fe);
free(fe->value); free(fe->value);
free(fe->key); free(fe->key);
free(fe); free(fe);
@ -164,7 +178,7 @@ format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
xvasprintf(&fe->value, fmt, ap); xvasprintf(&fe->value, fmt, ap);
va_end(ap); va_end(ap);
fe_now = RB_INSERT(format_tree, ft, fe); fe_now = RB_INSERT(format_rb_tree, &ft->tree, fe);
if (fe_now != NULL) { if (fe_now != NULL) {
free(fe_now->value); free(fe_now->value);
fe_now->value = fe->value; fe_now->value = fe->value;
@ -178,9 +192,32 @@ const char *
format_find(struct format_tree *ft, const char *key) format_find(struct format_tree *ft, const char *key)
{ {
struct format_entry *fe, fe_find; struct format_entry *fe, fe_find;
struct options_entry *o;
static char s[16];
o = options_find(&global_options, key);
if (o == NULL && ft->w != NULL)
o = options_find(&ft->w->options, key);
if (o == NULL)
o = options_find(&global_w_options, key);
if (o == NULL && ft->s != NULL)
o = options_find(&ft->s->options, key);
if (o == NULL)
o = options_find(&global_s_options, key);
if (o != NULL) {
switch (o->type) {
case OPTIONS_STRING:
return (o->str);
case OPTIONS_NUMBER:
snprintf(s, sizeof s, "%lld", o->num);
return (s);
case OPTIONS_STYLE:
return (style_tostring(&o->style));
}
}
fe_find.key = (char *) key; fe_find.key = (char *) key;
fe = RB_FIND(format_tree, ft, &fe_find); fe = RB_FIND(format_rb_tree, &ft->tree, &fe_find);
if (fe == NULL) if (fe == NULL)
return (NULL); return (NULL);
return (fe->value); return (fe->value);
@ -205,7 +242,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
copy[keylen] = '\0'; copy[keylen] = '\0';
/* Is there a length limit or whatnot? */ /* Is there a length limit or whatnot? */
if (!islower((u_char) *copy) && *copy != '?') { if (!islower((u_char) *copy) && *copy != '@' && *copy != '?') {
while (*copy != ':' && *copy != '\0') { while (*copy != ':' && *copy != '\0') {
switch (*copy) { switch (*copy) {
case '=': case '=':
@ -388,6 +425,8 @@ format_session(struct format_tree *ft, struct session *s)
char *tim; char *tim;
time_t t; time_t t;
ft->s = s;
format_add(ft, "session_name", "%s", s->name); format_add(ft, "session_name", "%s", s->name);
format_add(ft, "session_windows", "%u", winlink_count(&s->windows)); format_add(ft, "session_windows", "%u", winlink_count(&s->windows));
format_add(ft, "session_width", "%u", s->sx); format_add(ft, "session_width", "%u", s->sx);
@ -417,6 +456,9 @@ format_client(struct format_tree *ft, struct client *c)
time_t t; time_t t;
struct session *s; struct session *s;
if (ft->s == NULL)
ft->s = c->session;
format_add(ft, "client_height", "%u", c->tty.sy); format_add(ft, "client_height", "%u", c->tty.sy);
format_add(ft, "client_width", "%u", c->tty.sx); format_add(ft, "client_width", "%u", c->tty.sx);
if (c->tty.path != NULL) if (c->tty.path != NULL)
@ -462,6 +504,8 @@ format_window(struct format_tree *ft, struct window *w)
{ {
char *layout; char *layout;
ft->w = w;
layout = layout_dump(w); layout = layout_dump(w);
format_add(ft, "window_id", "@%u", w->id); format_add(ft, "window_id", "@%u", w->id);
@ -483,6 +527,9 @@ format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl)
struct window *w = wl->window; struct window *w = wl->window;
char *flags; char *flags;
if (ft->w == NULL)
ft->w = wl->window;
flags = window_printable_flags(s, wl); flags = window_printable_flags(s, wl);
format_window(ft, w); format_window(ft, w);
@ -535,6 +582,9 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp)
u_int i, idx; u_int i, idx;
char *cmd; char *cmd;
if (ft->w == NULL)
ft->w = wp->window;
size = 0; size = 0;
for (i = 0; i < gd->hsize; i++) { for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i]; gl = &gd->linedata[i];

21
tmux.1
View File

@ -3039,12 +3039,17 @@ and
.Ql } , .Ql } ,
for example for example
.Ql #{session_name} . .Ql #{session_name} .
Some variables also have an shorter alias such as The possible variables are listed in the table below, or the name of a
.Ql #S . .Nm
option may be used for an option's value.
Some variables have a shorter alias such as
.Ql #S ,
and
.Ql ## .Ql ##
is replaced by a single is replaced by a single
.Ql # . .Ql # .
Conditionals are also accepted by prefixing with .Pp
Conditionals are available by prefixing with
.Ql \&? .Ql \&?
and separating two alternatives with a comma; and separating two alternatives with a comma;
if the specified variable exists and is not zero, the first alternative if the specified variable exists and is not zero, the first alternative
@ -3055,7 +3060,15 @@ will include the string
.Ql attached .Ql attached
if the session is attached and the string if the session is attached and the string
.Ql not attached .Ql not attached
if it is unattached. if it is unattached, or
.Ql #{?automatic-rename,yes,no}
will include
.Ql yes
if
.Ic automatic-rename
is enabled, or
.Ql no
if not.
A limit may be placed on the length of the resultant string by prefixing it A limit may be placed on the length of the resultant string by prefixing it
by an by an
.Ql = , .Ql = ,

12
tmux.h
View File

@ -1461,15 +1461,6 @@ struct options_table_entry {
const char *style; const char *style;
}; };
/* Tree of format entries. */
struct format_entry {
char *key;
char *value;
RB_ENTRY(format_entry) entry;
};
RB_HEAD(format_tree, format_entry);
/* Common command usages. */ /* Common command usages. */
#define CMD_TARGET_PANE_USAGE "[-t target-pane]" #define CMD_TARGET_PANE_USAGE "[-t target-pane]"
#define CMD_TARGET_WINDOW_USAGE "[-t target-window]" #define CMD_TARGET_WINDOW_USAGE "[-t target-window]"
@ -1513,8 +1504,7 @@ void cfg_print_causes(struct cmd_q *);
void cfg_show_causes(struct session *); void cfg_show_causes(struct session *);
/* format.c */ /* format.c */
int format_cmp(struct format_entry *, struct format_entry *); struct format_tree;
RB_PROTOTYPE(format_tree, format_entry, entry, format_cmp);
struct format_tree *format_create(void); struct format_tree *format_create(void);
void format_free(struct format_tree *); void format_free(struct format_tree *);
void printflike(3, 4) format_add(struct format_tree *, const char *, void printflike(3, 4) format_add(struct format_tree *, const char *,