Change format callback to return value rather than storing it in the entry.

pull/2270/head
nicm 2020-06-01 19:39:25 +00:00
parent 674ec410b7
commit 9819470058
2 changed files with 170 additions and 153 deletions

321
format.c
View File

@ -38,13 +38,9 @@
* string. * string.
*/ */
struct format_entry;
typedef void (*format_cb)(struct format_tree *, struct format_entry *);
static char *format_job_get(struct format_tree *, const char *); static char *format_job_get(struct format_tree *, const char *);
static void format_job_timer(int, short, void *); static void format_job_timer(int, short, void *);
static void format_add_cb(struct format_tree *, const char *, format_cb);
static int format_replace(struct format_tree *, const char *, size_t, static int format_replace(struct format_tree *, const char *, size_t,
char **, size_t *, size_t *); char **, size_t *, size_t *);
static void format_defaults_session(struct format_tree *, static void format_defaults_session(struct format_tree *,
@ -421,50 +417,51 @@ format_job_timer(__unused int fd, __unused short events, __unused void *arg)
} }
/* Callback for host. */ /* Callback for host. */
static void static char *
format_cb_host(__unused struct format_tree *ft, struct format_entry *fe) format_cb_host(__unused struct format_tree *ft)
{ {
char host[HOST_NAME_MAX + 1]; char host[HOST_NAME_MAX + 1];
if (gethostname(host, sizeof host) != 0) if (gethostname(host, sizeof host) != 0)
fe->value = xstrdup(""); return (xstrdup(""));
else return (xstrdup(host));
fe->value = xstrdup(host);
} }
/* Callback for host_short. */ /* Callback for host_short. */
static void static char *
format_cb_host_short(__unused struct format_tree *ft, struct format_entry *fe) format_cb_host_short(__unused struct format_tree *ft)
{ {
char host[HOST_NAME_MAX + 1], *cp; char host[HOST_NAME_MAX + 1], *cp;
if (gethostname(host, sizeof host) != 0) if (gethostname(host, sizeof host) != 0)
fe->value = xstrdup(""); return (xstrdup(""));
else { if ((cp = strchr(host, '.')) != NULL)
if ((cp = strchr(host, '.')) != NULL) *cp = '\0';
*cp = '\0'; return (xstrdup(host));
fe->value = xstrdup(host);
}
} }
/* Callback for pid. */ /* Callback for pid. */
static void static char *
format_cb_pid(__unused struct format_tree *ft, struct format_entry *fe) format_cb_pid(__unused struct format_tree *ft)
{ {
xasprintf(&fe->value, "%ld", (long)getpid()); char *value;
xasprintf(&value, "%ld", (long)getpid());
return (value);
} }
/* Callback for session_attached_list. */ /* Callback for session_attached_list. */
static void static char *
format_cb_session_attached_list(struct format_tree *ft, struct format_entry *fe) format_cb_session_attached_list(struct format_tree *ft)
{ {
struct session *s = ft->s; struct session *s = ft->s;
struct client *loop; struct client *loop;
struct evbuffer *buffer; struct evbuffer *buffer;
int size; int size;
char *value = NULL;
if (s == NULL) if (s == NULL)
return; return (NULL);
buffer = evbuffer_new(); buffer = evbuffer_new();
if (buffer == NULL) if (buffer == NULL)
@ -479,20 +476,21 @@ format_cb_session_attached_list(struct format_tree *ft, struct format_entry *fe)
} }
if ((size = EVBUFFER_LENGTH(buffer)) != 0) if ((size = EVBUFFER_LENGTH(buffer)) != 0)
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer)); xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
evbuffer_free(buffer); evbuffer_free(buffer);
return (value);
} }
/* Callback for session_alerts. */ /* Callback for session_alerts. */
static void static char *
format_cb_session_alerts(struct format_tree *ft, struct format_entry *fe) format_cb_session_alerts(struct format_tree *ft)
{ {
struct session *s = ft->s; struct session *s = ft->s;
struct winlink *wl; struct winlink *wl;
char alerts[1024], tmp[16]; char alerts[1024], tmp[16];
if (s == NULL) if (s == NULL)
return; return (NULL);
*alerts = '\0'; *alerts = '\0';
RB_FOREACH(wl, winlinks, &s->windows) { RB_FOREACH(wl, winlinks, &s->windows) {
@ -510,19 +508,19 @@ format_cb_session_alerts(struct format_tree *ft, struct format_entry *fe)
if (wl->flags & WINLINK_SILENCE) if (wl->flags & WINLINK_SILENCE)
strlcat(alerts, "~", sizeof alerts); strlcat(alerts, "~", sizeof alerts);
} }
fe->value = xstrdup(alerts); return (xstrdup(alerts));
} }
/* Callback for session_stack. */ /* Callback for session_stack. */
static void static char *
format_cb_session_stack(struct format_tree *ft, struct format_entry *fe) format_cb_session_stack(struct format_tree *ft)
{ {
struct session *s = ft->s; struct session *s = ft->s;
struct winlink *wl; struct winlink *wl;
char result[1024], tmp[16]; char result[1024], tmp[16];
if (s == NULL) if (s == NULL)
return; return (NULL);
xsnprintf(result, sizeof result, "%u", s->curw->idx); xsnprintf(result, sizeof result, "%u", s->curw->idx);
TAILQ_FOREACH(wl, &s->lastw, sentry) { TAILQ_FOREACH(wl, &s->lastw, sentry) {
@ -532,16 +530,17 @@ format_cb_session_stack(struct format_tree *ft, struct format_entry *fe)
strlcat(result, ",", sizeof result); strlcat(result, ",", sizeof result);
strlcat(result, tmp, sizeof result); strlcat(result, tmp, sizeof result);
} }
fe->value = xstrdup(result); return (xstrdup(result));
} }
/* Callback for window_stack_index. */ /* Callback for window_stack_index. */
static void static char *
format_cb_window_stack_index(struct format_tree *ft, struct format_entry *fe) format_cb_window_stack_index(struct format_tree *ft)
{ {
struct session *s = ft->wl->session; struct session *s = ft->wl->session;
struct winlink *wl; struct winlink *wl;
u_int idx; u_int idx;
char *value = NULL;
idx = 0; idx = 0;
TAILQ_FOREACH(wl, &s->lastw, sentry) { TAILQ_FOREACH(wl, &s->lastw, sentry) {
@ -549,21 +548,21 @@ format_cb_window_stack_index(struct format_tree *ft, struct format_entry *fe)
if (wl == ft->wl) if (wl == ft->wl)
break; break;
} }
if (wl != NULL) if (wl == NULL)
xasprintf(&fe->value, "%u", idx); return (xstrdup("0"));
else xasprintf(&value, "%u", idx);
fe->value = xstrdup("0"); return (value);
} }
/* Callback for window_linked_sessions_list. */ /* Callback for window_linked_sessions_list. */
static void static char *
format_cb_window_linked_sessions_list(struct format_tree *ft, format_cb_window_linked_sessions_list(struct format_tree *ft)
struct format_entry *fe)
{ {
struct window *w = ft->wl->window; struct window *w = ft->wl->window;
struct winlink *wl; struct winlink *wl;
struct evbuffer *buffer; struct evbuffer *buffer;
int size; int size;
char *value = NULL;
buffer = evbuffer_new(); buffer = evbuffer_new();
if (buffer == NULL) if (buffer == NULL)
@ -576,36 +575,38 @@ format_cb_window_linked_sessions_list(struct format_tree *ft,
} }
if ((size = EVBUFFER_LENGTH(buffer)) != 0) if ((size = EVBUFFER_LENGTH(buffer)) != 0)
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer)); xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
evbuffer_free(buffer); evbuffer_free(buffer);
return (value);
} }
/* Callback for window_active_sessions. */ /* Callback for window_active_sessions. */
static void static char *
format_cb_window_active_sessions(struct format_tree *ft, format_cb_window_active_sessions(struct format_tree *ft)
struct format_entry *fe)
{ {
struct window *w = ft->wl->window; struct window *w = ft->wl->window;
struct winlink *wl; struct winlink *wl;
u_int n = 0; u_int n = 0;
char *value;
TAILQ_FOREACH(wl, &w->winlinks, wentry) { TAILQ_FOREACH(wl, &w->winlinks, wentry) {
if (wl->session->curw == wl) if (wl->session->curw == wl)
n++; n++;
} }
xasprintf(&fe->value, "%u", n); xasprintf(&value, "%u", n);
return (value);
} }
/* Callback for window_active_sessions_list. */ /* Callback for window_active_sessions_list. */
static void static char *
format_cb_window_active_sessions_list(struct format_tree *ft, format_cb_window_active_sessions_list(struct format_tree *ft)
struct format_entry *fe)
{ {
struct window *w = ft->wl->window; struct window *w = ft->wl->window;
struct winlink *wl; struct winlink *wl;
struct evbuffer *buffer; struct evbuffer *buffer;
int size; int size;
char *value = NULL;
buffer = evbuffer_new(); buffer = evbuffer_new();
if (buffer == NULL) if (buffer == NULL)
@ -620,18 +621,20 @@ format_cb_window_active_sessions_list(struct format_tree *ft,
} }
if ((size = EVBUFFER_LENGTH(buffer)) != 0) if ((size = EVBUFFER_LENGTH(buffer)) != 0)
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer)); xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
evbuffer_free(buffer); evbuffer_free(buffer);
return (value);
} }
/* Callback for window_active_clients. */ /* Callback for window_active_clients. */
static void static char *
format_cb_window_active_clients(struct format_tree *ft, struct format_entry *fe) format_cb_window_active_clients(struct format_tree *ft)
{ {
struct window *w = ft->wl->window; struct window *w = ft->wl->window;
struct client *loop; struct client *loop;
struct session *client_session; struct session *client_session;
u_int n = 0; u_int n = 0;
char *value;
TAILQ_FOREACH(loop, &clients, entry) { TAILQ_FOREACH(loop, &clients, entry) {
client_session = loop->session; client_session = loop->session;
@ -642,19 +645,20 @@ format_cb_window_active_clients(struct format_tree *ft, struct format_entry *fe)
n++; n++;
} }
xasprintf(&fe->value, "%u", n); xasprintf(&value, "%u", n);
return (value);
} }
/* Callback for window_active_clients_list. */ /* Callback for window_active_clients_list. */
static void static char *
format_cb_window_active_clients_list(struct format_tree *ft, format_cb_window_active_clients_list(struct format_tree *ft)
struct format_entry *fe)
{ {
struct window *w = ft->wl->window; struct window *w = ft->wl->window;
struct client *loop; struct client *loop;
struct session *client_session; struct session *client_session;
struct evbuffer *buffer; struct evbuffer *buffer;
int size; int size;
char *value = NULL;
buffer = evbuffer_new(); buffer = evbuffer_new();
if (buffer == NULL) if (buffer == NULL)
@ -673,58 +677,58 @@ format_cb_window_active_clients_list(struct format_tree *ft,
} }
if ((size = EVBUFFER_LENGTH(buffer)) != 0) if ((size = EVBUFFER_LENGTH(buffer)) != 0)
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer)); xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
evbuffer_free(buffer); evbuffer_free(buffer);
return (value);
} }
/* Callback for window_layout. */ /* Callback for window_layout. */
static void static char *
format_cb_window_layout(struct format_tree *ft, struct format_entry *fe) format_cb_window_layout(struct format_tree *ft)
{ {
struct window *w = ft->w; struct window *w = ft->w;
if (w == NULL) if (w == NULL)
return; return (NULL);
if (w->saved_layout_root != NULL) if (w->saved_layout_root != NULL)
fe->value = layout_dump(w->saved_layout_root); return (layout_dump(w->saved_layout_root));
else return (layout_dump(w->layout_root));
fe->value = layout_dump(w->layout_root);
} }
/* Callback for window_visible_layout. */ /* Callback for window_visible_layout. */
static void static char *
format_cb_window_visible_layout(struct format_tree *ft, struct format_entry *fe) format_cb_window_visible_layout(struct format_tree *ft)
{ {
struct window *w = ft->w; struct window *w = ft->w;
if (w == NULL) if (w == NULL)
return; return (NULL);
fe->value = layout_dump(w->layout_root); return (layout_dump(w->layout_root));
} }
/* Callback for pane_start_command. */ /* Callback for pane_start_command. */
static void static char *
format_cb_start_command(struct format_tree *ft, struct format_entry *fe) format_cb_start_command(struct format_tree *ft)
{ {
struct window_pane *wp = ft->wp; struct window_pane *wp = ft->wp;
if (wp == NULL) if (wp == NULL)
return; return (NULL);
fe->value = cmd_stringify_argv(wp->argc, wp->argv); return (cmd_stringify_argv(wp->argc, wp->argv));
} }
/* Callback for pane_current_command. */ /* Callback for pane_current_command. */
static void static char *
format_cb_current_command(struct format_tree *ft, struct format_entry *fe) format_cb_current_command(struct format_tree *ft)
{ {
struct window_pane *wp = ft->wp; struct window_pane *wp = ft->wp;
char *cmd; char *cmd, *value;
if (wp == NULL || wp->shell == NULL) if (wp == NULL || wp->shell == NULL)
return; return (NULL);
cmd = get_proc_name(wp->fd, wp->tty); cmd = get_proc_name(wp->fd, wp->tty);
if (cmd == NULL || *cmd == '\0') { if (cmd == NULL || *cmd == '\0') {
@ -735,37 +739,40 @@ format_cb_current_command(struct format_tree *ft, struct format_entry *fe)
cmd = xstrdup(wp->shell); cmd = xstrdup(wp->shell);
} }
} }
fe->value = parse_window_name(cmd); value = parse_window_name(cmd);
free(cmd); free(cmd);
return (value);
} }
/* Callback for pane_current_path. */ /* Callback for pane_current_path. */
static void static char *
format_cb_current_path(struct format_tree *ft, struct format_entry *fe) format_cb_current_path(struct format_tree *ft)
{ {
struct window_pane *wp = ft->wp; struct window_pane *wp = ft->wp;
char *cwd; char *cwd;
if (wp == NULL) if (wp == NULL)
return; return (NULL);
cwd = get_proc_cwd(wp->fd); cwd = get_proc_cwd(wp->fd);
if (cwd != NULL) if (cwd == NULL)
fe->value = xstrdup(cwd); return (NULL);
return (xstrdup(cwd));
} }
/* Callback for history_bytes. */ /* Callback for history_bytes. */
static void static char *
format_cb_history_bytes(struct format_tree *ft, struct format_entry *fe) format_cb_history_bytes(struct format_tree *ft)
{ {
struct window_pane *wp = ft->wp; struct window_pane *wp = ft->wp;
struct grid *gd; struct grid *gd;
struct grid_line *gl; struct grid_line *gl;
size_t size = 0; size_t size = 0;
u_int i; u_int i;
char *value;
if (wp == NULL) if (wp == NULL)
return; return (NULL);
gd = wp->base.grid; gd = wp->base.grid;
for (i = 0; i < gd->hsize + gd->sy; i++) { for (i = 0; i < gd->hsize + gd->sy; i++) {
@ -775,20 +782,22 @@ format_cb_history_bytes(struct format_tree *ft, struct format_entry *fe)
} }
size += (gd->hsize + gd->sy) * sizeof *gl; size += (gd->hsize + gd->sy) * sizeof *gl;
xasprintf(&fe->value, "%zu", size); xasprintf(&value, "%zu", size);
return (value);
} }
/* Callback for history_all_bytes. */ /* Callback for history_all_bytes. */
static void static char *
format_cb_history_all_bytes(struct format_tree *ft, struct format_entry *fe) format_cb_history_all_bytes(struct format_tree *ft)
{ {
struct window_pane *wp = ft->wp; struct window_pane *wp = ft->wp;
struct grid *gd; struct grid *gd;
struct grid_line *gl; struct grid_line *gl;
u_int i, lines, cells = 0, extended_cells = 0; u_int i, lines, cells = 0, extended_cells = 0;
char *value;
if (wp == NULL) if (wp == NULL)
return; return (NULL);
gd = wp->base.grid; gd = wp->base.grid;
lines = gd->hsize + gd->sy; lines = gd->hsize + gd->sy;
@ -798,22 +807,24 @@ format_cb_history_all_bytes(struct format_tree *ft, struct format_entry *fe)
extended_cells += gl->extdsize; extended_cells += gl->extdsize;
} }
xasprintf(&fe->value, "%u,%zu,%u,%zu,%u,%zu", lines, xasprintf(&value, "%u,%zu,%u,%zu,%u,%zu", lines,
lines * sizeof *gl, cells, cells * sizeof *gl->celldata, lines * sizeof *gl, cells, cells * sizeof *gl->celldata,
extended_cells, extended_cells * sizeof *gl->extddata); extended_cells, extended_cells * sizeof *gl->extddata);
return (value);
} }
/* Callback for pane_tabs. */ /* Callback for pane_tabs. */
static void static char *
format_cb_pane_tabs(struct format_tree *ft, struct format_entry *fe) format_cb_pane_tabs(struct format_tree *ft)
{ {
struct window_pane *wp = ft->wp; struct window_pane *wp = ft->wp;
struct evbuffer *buffer; struct evbuffer *buffer;
u_int i; u_int i;
int size; int size;
char *value = NULL;
if (wp == NULL) if (wp == NULL)
return; return (NULL);
buffer = evbuffer_new(); buffer = evbuffer_new();
if (buffer == NULL) if (buffer == NULL)
@ -827,25 +838,27 @@ format_cb_pane_tabs(struct format_tree *ft, struct format_entry *fe)
evbuffer_add_printf(buffer, "%u", i); evbuffer_add_printf(buffer, "%u", i);
} }
if ((size = EVBUFFER_LENGTH(buffer)) != 0) if ((size = EVBUFFER_LENGTH(buffer)) != 0)
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer)); xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
evbuffer_free(buffer); evbuffer_free(buffer);
return (value);
} }
/* Callback for session_group_list. */ /* Callback for session_group_list. */
static void static char *
format_cb_session_group_list(struct format_tree *ft, struct format_entry *fe) format_cb_session_group_list(struct format_tree *ft)
{ {
struct session *s = ft->s; struct session *s = ft->s;
struct session_group *sg; struct session_group *sg;
struct session *loop; struct session *loop;
struct evbuffer *buffer; struct evbuffer *buffer;
int size; int size;
char *value = NULL;
if (s == NULL) if (s == NULL)
return; return (NULL);
sg = session_group_contains(s); sg = session_group_contains(s);
if (sg == NULL) if (sg == NULL)
return; return (NULL);
buffer = evbuffer_new(); buffer = evbuffer_new();
if (buffer == NULL) if (buffer == NULL)
@ -858,26 +871,27 @@ format_cb_session_group_list(struct format_tree *ft, struct format_entry *fe)
} }
if ((size = EVBUFFER_LENGTH(buffer)) != 0) if ((size = EVBUFFER_LENGTH(buffer)) != 0)
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer)); xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
evbuffer_free(buffer); evbuffer_free(buffer);
return (value);
} }
/* Callback for session_group_attached_list. */ /* Callback for session_group_attached_list. */
static void static char *
format_cb_session_group_attached_list(struct format_tree *ft, format_cb_session_group_attached_list(struct format_tree *ft)
struct format_entry *fe)
{ {
struct session *s = ft->s, *client_session, *session_loop; struct session *s = ft->s, *client_session, *session_loop;
struct session_group *sg; struct session_group *sg;
struct client *loop; struct client *loop;
struct evbuffer *buffer; struct evbuffer *buffer;
int size; int size;
char *value = NULL;
if (s == NULL) if (s == NULL)
return; return (NULL);
sg = session_group_contains(s); sg = session_group_contains(s);
if (sg == NULL) if (sg == NULL)
return; return (NULL);
buffer = evbuffer_new(); buffer = evbuffer_new();
if (buffer == NULL) if (buffer == NULL)
@ -897,36 +911,40 @@ format_cb_session_group_attached_list(struct format_tree *ft,
} }
if ((size = EVBUFFER_LENGTH(buffer)) != 0) if ((size = EVBUFFER_LENGTH(buffer)) != 0)
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer)); xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
evbuffer_free(buffer); evbuffer_free(buffer);
return (value);
} }
/* Callback for pane_in_mode. */ /* Callback for pane_in_mode. */
static void static char *
format_cb_pane_in_mode(struct format_tree *ft, struct format_entry *fe) format_cb_pane_in_mode(struct format_tree *ft)
{ {
struct window_pane *wp = ft->wp; struct window_pane *wp = ft->wp;
u_int n = 0; u_int n = 0;
struct window_mode_entry *wme; struct window_mode_entry *wme;
char *value;
if (wp == NULL) if (wp == NULL)
return; return (NULL);
TAILQ_FOREACH(wme, &wp->modes, entry) TAILQ_FOREACH(wme, &wp->modes, entry)
n++; n++;
xasprintf(&fe->value, "%u", n); xasprintf(&value, "%u", n);
return (value);
} }
/* Callback for pane_at_top. */ /* Callback for pane_at_top. */
static void static char *
format_cb_pane_at_top(struct format_tree *ft, struct format_entry *fe) format_cb_pane_at_top(struct format_tree *ft)
{ {
struct window_pane *wp = ft->wp; struct window_pane *wp = ft->wp;
struct window *w; struct window *w;
int status, flag; int status, flag;
char *value;
if (wp == NULL) if (wp == NULL)
return; return (NULL);
w = wp->window; w = wp->window;
status = options_get_number(w->options, "pane-border-status"); status = options_get_number(w->options, "pane-border-status");
@ -934,19 +952,21 @@ format_cb_pane_at_top(struct format_tree *ft, struct format_entry *fe)
flag = (wp->yoff == 1); flag = (wp->yoff == 1);
else else
flag = (wp->yoff == 0); flag = (wp->yoff == 0);
xasprintf(&fe->value, "%d", flag); xasprintf(&value, "%d", flag);
return (value);
} }
/* Callback for pane_at_bottom. */ /* Callback for pane_at_bottom. */
static void static char *
format_cb_pane_at_bottom(struct format_tree *ft, struct format_entry *fe) format_cb_pane_at_bottom(struct format_tree *ft)
{ {
struct window_pane *wp = ft->wp; struct window_pane *wp = ft->wp;
struct window *w; struct window *w;
int status, flag; int status, flag;
char *value;
if (wp == NULL) if (wp == NULL)
return; return (NULL);
w = wp->window; w = wp->window;
status = options_get_number(w->options, "pane-border-status"); status = options_get_number(w->options, "pane-border-status");
@ -954,22 +974,25 @@ format_cb_pane_at_bottom(struct format_tree *ft, struct format_entry *fe)
flag = (wp->yoff + wp->sy == w->sy - 1); flag = (wp->yoff + wp->sy == w->sy - 1);
else else
flag = (wp->yoff + wp->sy == w->sy); flag = (wp->yoff + wp->sy == w->sy);
xasprintf(&fe->value, "%d", flag); xasprintf(&value, "%d", flag);
return (value);
} }
/* Callback for cursor_character. */ /* Callback for cursor_character. */
static void static char *
format_cb_cursor_character(struct format_tree *ft, struct format_entry *fe) format_cb_cursor_character(struct format_tree *ft)
{ {
struct window_pane *wp = ft->wp; struct window_pane *wp = ft->wp;
struct grid_cell gc; struct grid_cell gc;
char *value = NULL;
if (wp == NULL) if (wp == NULL)
return; return (NULL);
grid_view_get_cell(wp->base.grid, wp->base.cx, wp->base.cy, &gc); grid_view_get_cell(wp->base.grid, wp->base.cx, wp->base.cy, &gc);
if (~gc.flags & GRID_FLAG_PADDING) if (~gc.flags & GRID_FLAG_PADDING)
xasprintf(&fe->value, "%.*s", (int)gc.data.size, gc.data.data); xasprintf(&value, "%.*s", (int)gc.data.size, gc.data.data);
return (value);
} }
/* Return word at given coordinates. Caller frees. */ /* Return word at given coordinates. Caller frees. */
@ -1043,8 +1066,8 @@ format_grid_word(struct grid *gd, u_int x, u_int y)
} }
/* Callback for mouse_word. */ /* Callback for mouse_word. */
static void static char *
format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe) format_cb_mouse_word(struct format_tree *ft)
{ {
struct window_pane *wp; struct window_pane *wp;
struct grid *gd; struct grid *gd;
@ -1052,25 +1075,21 @@ format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe)
char *s; char *s;
if (!ft->m.valid) if (!ft->m.valid)
return; return (NULL);
wp = cmd_mouse_pane(&ft->m, NULL, NULL); wp = cmd_mouse_pane(&ft->m, NULL, NULL);
if (wp == NULL) if (wp == NULL)
return; return (NULL);
if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0) if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
return; return (NULL);
if (!TAILQ_EMPTY(&wp->modes)) { if (!TAILQ_EMPTY(&wp->modes)) {
if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode || if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
TAILQ_FIRST(&wp->modes)->mode == &window_view_mode) TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
s = window_copy_get_word(wp, x, y); return (s = window_copy_get_word(wp, x, y));
else return (NULL);
s = NULL;
} else {
gd = wp->base.grid;
s = format_grid_word(gd, x, gd->hsize + y);
} }
if (s != NULL) gd = wp->base.grid;
fe->value = s; return (format_grid_word(gd, x, gd->hsize + y));
} }
/* Return line at given coordinates. Caller frees. */ /* Return line at given coordinates. Caller frees. */
@ -1100,34 +1119,29 @@ format_grid_line(struct grid *gd, u_int y)
} }
/* Callback for mouse_line. */ /* Callback for mouse_line. */
static void static char *
format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe) format_cb_mouse_line(struct format_tree *ft)
{ {
struct window_pane *wp; struct window_pane *wp;
struct grid *gd; struct grid *gd;
u_int x, y; u_int x, y;
char *s;
if (!ft->m.valid) if (!ft->m.valid)
return; return (NULL);
wp = cmd_mouse_pane(&ft->m, NULL, NULL); wp = cmd_mouse_pane(&ft->m, NULL, NULL);
if (wp == NULL) if (wp == NULL)
return; return (NULL);
if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0) if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
return; return (NULL);
if (!TAILQ_EMPTY(&wp->modes)) { if (!TAILQ_EMPTY(&wp->modes)) {
if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode || if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
TAILQ_FIRST(&wp->modes)->mode == &window_view_mode) TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
s = window_copy_get_line(wp, y); return (window_copy_get_line(wp, y));
else return (NULL);
s = NULL;
} else {
gd = wp->base.grid;
s = format_grid_line(gd, gd->hsize + y);
} }
if (s != NULL) gd = wp->base.grid;
fe->value = s; return (format_grid_line(gd, gd->hsize + y));
} }
/* Merge one format tree into another. */ /* Merge one format tree into another. */
@ -1244,7 +1258,7 @@ format_each(struct format_tree *ft, void (*cb)(const char *, const char *,
cb(fe->key, s, arg); cb(fe->key, s, arg);
} else { } else {
if (fe->value == NULL && fe->cb != NULL) { if (fe->value == NULL && fe->cb != NULL) {
fe->cb(ft, fe); fe->value = fe->cb(ft);
if (fe->value == NULL) if (fe->value == NULL)
fe->value = xstrdup(""); fe->value = xstrdup("");
} }
@ -1304,7 +1318,7 @@ format_add_tv(struct format_tree *ft, const char *key, struct timeval *tv)
} }
/* Add a key and function. */ /* Add a key and function. */
static void void
format_add_cb(struct format_tree *ft, const char *key, format_cb cb) format_add_cb(struct format_tree *ft, const char *key, format_cb cb)
{ {
struct format_entry *fe; struct format_entry *fe;
@ -1427,10 +1441,11 @@ format_find(struct format_tree *ft, const char *key, int modifiers,
t = fe->t; t = fe->t;
goto found; goto found;
} }
if (fe->value == NULL && fe->cb != NULL) if (fe->value == NULL && fe->cb != NULL) {
fe->cb(ft, fe); fe->value = fe->cb(ft);
if (fe->value == NULL) if (fe->value == NULL)
fe->value = xstrdup(""); fe->value = xstrdup("");
}
found = xstrdup(fe->value); found = xstrdup(fe->value);
goto found; goto found;
} }

2
tmux.h
View File

@ -1912,6 +1912,7 @@ char *paste_make_sample(struct paste_buffer *);
#define FORMAT_WINDOW 0x40000000U #define FORMAT_WINDOW 0x40000000U
struct format_tree; struct format_tree;
struct format_modifier; struct format_modifier;
typedef char *(*format_cb)(struct format_tree *);
const char *format_skip(const char *, const char *); const char *format_skip(const char *, const char *);
int format_true(const char *); int format_true(const char *);
struct format_tree *format_create(struct client *, struct cmdq_item *, int, struct format_tree *format_create(struct client *, struct cmdq_item *, int,
@ -1922,6 +1923,7 @@ void printflike(3, 4) format_add(struct format_tree *, const char *,
const char *, ...); const char *, ...);
void format_add_tv(struct format_tree *, const char *, void format_add_tv(struct format_tree *, const char *,
struct timeval *); struct timeval *);
void format_add_cb(struct format_tree *, const char *, format_cb);
void format_each(struct format_tree *, void (*)(const char *, void format_each(struct format_tree *, void (*)(const char *,
const char *, void *), void *); const char *, void *), void *);
char *format_expand_time(struct format_tree *, const char *); char *format_expand_time(struct format_tree *, const char *);