Sync OpenBSD patchset 553:

Two new options, window-status-format and window-status-current-format, which
allow the format of each window in the status line window list to be controlled
using similar # sequences as status-left/right.

This diff also moves part of the way towards UTF-8 support in window names but
it isn't quite there yet.
pull/1/head
Tiago Cunha 2009-11-19 22:35:10 +00:00
parent 1feea926ed
commit f9451028c0
7 changed files with 138 additions and 49 deletions

View File

@ -1,4 +1,4 @@
/* $Id: cmd-display-message.c,v 1.5 2009-11-19 22:25:52 tcunha Exp $ */
/* $Id: cmd-display-message.c,v 1.6 2009-11-19 22:35:10 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@ -55,7 +55,7 @@ cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx)
else
template = data->arg;
msg = status_replace(c, template, time(NULL), 0);
msg = status_replace(c, NULL, template, time(NULL), 0);
status_message_set(c, "%s", msg);
xfree(msg);

View File

@ -1,4 +1,4 @@
/* $Id: cmd-set-window-option.c,v 1.41 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-set-window-option.c,v 1.42 2009-11-19 22:35:10 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -71,7 +71,9 @@ const struct set_option_entry set_window_option_table[] = {
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-format", SET_OPTION_STRING, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-format", SET_OPTION_STRING, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
@ -84,7 +86,10 @@ cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
struct client *c;
struct options *oo;
const struct set_option_entry *entry, *opt;
struct jobs *jobs;
struct job *job, *nextjob;
u_int i;
int try_again;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_w_options;
@ -166,5 +171,34 @@ cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_client(c);
}
/*
* Special-case: kill all persistent jobs if window-status-format has
* changed. Persistent jobs are only used by the status line at the
* moment so this works XXX.
*/
if (strcmp(entry->name, "window-status-format") == 0) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
jobs = &c->status_jobs;
do {
try_again = 0;
job = RB_ROOT(jobs);
while (job != NULL) {
nextjob = RB_NEXT(jobs, jobs, job);
if (job->flags & JOB_PERSIST) {
job_remove(jobs, job);
try_again = 1;
break;
}
job = nextjob;
}
} while (try_again);
server_redraw_client(c);
}
}
return (0);
}

View File

@ -1,4 +1,4 @@
/* $Id: server-client.c,v 1.23 2009-11-19 22:25:52 tcunha Exp $ */
/* $Id: server-client.c,v 1.24 2009-11-19 22:35:10 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -488,7 +488,7 @@ server_client_set_title(struct client *c)
template = options_get_string(&s->options, "set-titles-string");
title = status_replace(c, template, time(NULL), 1);
title = status_replace(c, NULL, template, time(NULL), 1);
if (c->title == NULL || strcmp(title, c->title) != 0) {
if (c->title != NULL)
xfree(c->title);

109
status.c
View File

@ -1,4 +1,4 @@
/* $Id: status.c,v 1.131 2009-11-19 22:30:39 tcunha Exp $ */
/* $Id: status.c,v 1.132 2009-11-19 22:35:10 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -31,10 +31,11 @@
char *status_job(struct client *, char **);
void status_job_callback(struct job *);
size_t status_width(struct winlink *);
char *status_print(struct session *, struct winlink *, struct grid_cell *);
void status_replace1(
struct client *, char **, char **, char *, size_t, int);
size_t status_width(struct client *, struct winlink *, time_t);
char *status_print(
struct client *, struct winlink *, time_t, struct grid_cell *);
void status_replace1(struct client *,
struct winlink *, char **, char **, char *, size_t, int);
void status_message_callback(int, short, void *);
void status_prompt_add_history(struct client *);
@ -108,14 +109,14 @@ status_redraw(struct client *c)
utf8flag = options_get_number(&s->options, "status-utf8");
/* Work out the left and right strings. */
left = status_replace(c, options_get_string(
left = status_replace(c, NULL, options_get_string(
&s->options, "status-left"), c->status_timer.tv_sec, 1);
llen = options_get_number(&s->options, "status-left-length");
llen2 = screen_write_cstrlen(utf8flag, "%s", left);
if (llen2 < llen)
llen = llen2;
right = status_replace(c, options_get_string(
right = status_replace(c, NULL, options_get_string(
&s->options, "status-right"), c->status_timer.tv_sec, 1);
rlen = options_get_number(&s->options, "status-right-length");
rlen2 = screen_write_cstrlen(utf8flag, "%s", right);
@ -141,7 +142,7 @@ status_redraw(struct client *c)
*/
width = offset = 0;
RB_FOREACH(wl, winlinks, &s->windows) {
size = status_width(wl) + 1;
size = status_width(c, wl, c->status_timer.tv_sec) + 1;
if (wl == s->curw)
offset = width;
width += size;
@ -153,7 +154,7 @@ status_redraw(struct client *c)
goto draw;
/* Find size of current window text. */
size = status_width(s->curw);
size = status_width(c, s->curw, c->status_timer.tv_sec);
/*
* If the offset is already on screen, we're good to draw from the
@ -226,7 +227,7 @@ draw:
offset = 0;
RB_FOREACH(wl, winlinks, &s->windows) {
memcpy(&gc, &stdgc, sizeof gc);
text = status_print(s, wl, &gc);
text = status_print(c, wl, c->status_timer.tv_sec, &gc);
if (larrow == 1 && offset < start) {
if (session_alert_has(s, wl, WINDOW_ACTIVITY))
@ -237,10 +238,13 @@ draw:
larrow = -1;
}
for (ptr = text; *ptr != '\0'; ptr++) {
if (offset >= start && offset < start + width)
screen_write_putc(&ctx, &gc, *ptr);
offset++;
ptr = text;
for (; offset < start; offset++)
ptr++; /* XXX should skip UTF-8 characters */
if (offset < start + width) {
screen_write_cnputs(&ctx,
start + width - offset, &gc, utf8flag, "%s", text);
offset += screen_write_cstrlen(utf8flag, "%s", text);
}
if (rarrow == 1 && offset > start + width) {
@ -322,15 +326,17 @@ out:
/* Replace a single special sequence (prefixed by #). */
void
status_replace1(struct client *c,
status_replace1(struct client *c,struct winlink *wl,
char **iptr, char **optr, char *out, size_t outsize, int jobsflag)
{
struct session *s = c->session;
struct winlink *wl = s->curw;
char ch, tmp[256], *ptr, *endptr, *freeptr;
size_t ptrlen;
long limit;
if (wl == NULL)
wl = s->curw;
errno = 0;
limit = strtol(*iptr, &endptr, 10);
if ((limit == 0 && errno != EINVAL) ||
@ -376,6 +382,21 @@ status_replace1(struct client *c,
case 'W':
ptr = wl->window->name;
goto do_replace;
case 'F':
tmp[0] = ' ';
if (session_alert_has(s, wl, WINDOW_CONTENT))
tmp[0] = '+';
else if (session_alert_has(s, wl, WINDOW_BELL))
tmp[0] = '!';
else if (session_alert_has(s, wl, WINDOW_ACTIVITY))
tmp[0] = '#';
else if (wl == s->curw)
tmp[0] = '*';
else if (wl == TAILQ_FIRST(&s->lastw))
tmp[0] = '-';
tmp[1] = '\0';
ptr = tmp;
goto do_replace;
case '[':
/*
* Embedded style, handled at display time. Leave present and
@ -419,11 +440,12 @@ skip_to:
/* Replace special sequences in fmt. */
char *
status_replace(struct client *c, const char *fmt, time_t t, int jobsflag)
status_replace(struct client *c,
struct winlink *wl, const char *fmt, time_t t, int jobsflag)
{
static char out[BUFSIZ];
char in[BUFSIZ], ch, *iptr, *optr;
strftime(in, sizeof in, fmt, localtime(&t));
in[(sizeof in) - 1] = '\0';
@ -439,7 +461,7 @@ status_replace(struct client *c, const char *fmt, time_t t, int jobsflag)
*optr++ = ch;
continue;
}
status_replace1(c, &iptr, &optr, out, sizeof out, jobsflag);
status_replace1(c, wl, &iptr, &optr, out, sizeof out, jobsflag);
}
*optr = '\0';
@ -522,17 +544,37 @@ status_job_callback(struct job *job)
/* Calculate winlink status line entry width. */
size_t
status_width(struct winlink *wl)
status_width(struct client *c, struct winlink *wl, time_t t)
{
return (xsnprintf(NULL, 0, "%d:%s ", wl->idx, wl->window->name));
struct options *oo = &wl->window->options;
struct session *s = c->session;
const char *fmt;
char *text;
size_t size;
int utf8flag;
utf8flag = options_get_number(&s->options, "status-utf8");
fmt = options_get_string(&wl->window->options, "window-status-format");
if (wl == s->curw)
fmt = options_get_string(oo, "window-status-current-format");
text = status_replace(c, wl, fmt, t, 1);
size = screen_write_cstrlen(utf8flag, "%s", text);
xfree(text);
return (size);
}
/* Return winlink status line entry and adjust gc as necessary. */
char *
status_print(struct session *s, struct winlink *wl, struct grid_cell *gc)
status_print(
struct client *c, struct winlink *wl, time_t t, struct grid_cell *gc)
{
struct options *oo = &wl->window->options;
char *text, flag;
struct session *s = c->session;
const char *fmt;
char *text;
u_char fg, bg, attr;
fg = options_get_number(oo, "window-status-fg");
@ -544,10 +586,7 @@ status_print(struct session *s, struct winlink *wl, struct grid_cell *gc)
attr = options_get_number(oo, "window-status-attr");
if (attr != 0)
gc->attr = attr;
flag = ' ';
if (wl == TAILQ_FIRST(&s->lastw))
flag = '-';
fmt = options_get_string(oo, "window-status-format");
if (wl == s->curw) {
fg = options_get_number(oo, "window-status-current-fg");
if (fg != 8)
@ -558,21 +597,15 @@ status_print(struct session *s, struct winlink *wl, struct grid_cell *gc)
attr = options_get_number(oo, "window-status-current-attr");
if (attr != 0)
gc->attr = attr;
flag = '*';
fmt = options_get_string(oo, "window-status-current-format");
}
if (session_alert_has(s, wl, WINDOW_ACTIVITY)) {
flag = '#';
if (session_alert_has(s, wl, WINDOW_ACTIVITY) ||
session_alert_has(s, wl, WINDOW_BELL) ||
session_alert_has(s, wl, WINDOW_CONTENT))
gc->attr ^= GRID_ATTR_REVERSE;
} else if (session_alert_has(s, wl, WINDOW_BELL)) {
flag = '!';
gc->attr ^= GRID_ATTR_REVERSE;
} else if (session_alert_has(s, wl, WINDOW_CONTENT)) {
flag = '+';
gc->attr ^= GRID_ATTR_REVERSE;
}
xasprintf(&text, "%d:%s%c", wl->idx, wl->window->name, flag);
text = status_replace(c, wl, fmt, t, 1);
return (text);
}

25
tmux.1
View File

@ -1,4 +1,4 @@
.\" $Id: tmux.1,v 1.206 2009-11-19 22:32:12 tcunha Exp $
.\" $Id: tmux.1,v 1.207 2009-11-19 22:35:10 tcunha Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\"
@ -1477,6 +1477,7 @@ may contain any of the following special character sequences:
.It Li "#(command)" Ta "First line of command's output"
.It Li "#[attributes]" Ta "Colour or attribute change"
.It Li "#H" Ta "Hostname of local host"
.It Li "#F" Ta "Current window flag"
.It Li "#I" Ta "Current window index"
.It Li "#P" Ta "Current pane index"
.It Li "#S" Ta "Session name"
@ -1785,6 +1786,14 @@ Set status line background colour for a single window.
.It Ic window-status-fg Ar colour
Set status line foreground colour for a single window.
.Pp
.It Ic window-status-format Ar string
Set the format in which the window is displayed in the status line window list.
See the
.Ar status-left
option for details of special character sequences available.
The default is
.Ql #I:#W#F .
.Pp
.It Ic window-status-current-attr Ar attributes
Set status line attributes for the currently active window.
.Pp
@ -1794,6 +1803,11 @@ Set status line background colour for the currently active window.
.It Ic window-status-current-fg Ar colour
Set status line foreground colour for the currently active window.
.Pp
.It Ic window-status-current-format Ar string
Like
.Ar window-status-format ,
but is the format used when the window is the current window.
.Pp
.It Xo Ic xterm-keys
.Op Ic on | off
.Xc
@ -1900,8 +1914,13 @@ command, see the
and
.Ic status-right-length
options below), and a central window list.
The window list shows the index, name and (if any) flag of the windows
present in the current session in ascending numerical order.
By default, the window list shows the index, name and (if any) flag of the
windows present in the current session in ascending numerical order.
It may be customised with the
.Ar window-status-format
and
.Ar window-status-current-format
options.
The flag is one of the following symbols appended to the window name:
.Bl -column "Symbol" "Meaning" -offset indent
.It Sy "Symbol" Ta Sy "Meaning"

4
tmux.c
View File

@ -1,4 +1,4 @@
/* $Id: tmux.c,v 1.190 2009-11-19 22:31:27 tcunha Exp $ */
/* $Id: tmux.c,v 1.191 2009-11-19 22:35:10 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -394,6 +394,8 @@ main(int argc, char **argv)
options_set_number(wo, "window-status-current-bg", 8);
options_set_number(wo, "window-status-current-fg", 8);
options_set_number(wo, "window-status-fg", 8);
options_set_string(wo, "window-status-format", "#I:#W#F");
options_set_string(wo, "window-status-current-format", "#I:#W#F");
options_set_number(wo, "xterm-keys", 0);
options_set_number(wo, "remain-on-exit", 0);
options_set_number(wo, "synchronize-panes", 0);

5
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.520 2009-11-19 22:25:52 tcunha Exp $ */
/* $Id: tmux.h,v 1.521 2009-11-19 22:35:10 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -1616,7 +1616,8 @@ void server_update_event(struct client *);
/* status.c */
int status_redraw(struct client *);
char *status_replace(struct client *, const char *, time_t, int);
char *status_replace(
struct client *, struct winlink *, const char *, time_t, int);
void printflike2 status_message_set(struct client *, const char *, ...);
void status_message_clear(struct client *);
int status_message_redraw(struct client *);