New session option, status-utf8, to control the interpretation of top-bit-set

characters in status-left and status-right (if on, they are treated as UTF-8;
otherwise passed through).
This commit is contained in:
Nicholas Marriott 2009-06-03 16:54:26 +00:00
parent 7d45e29683
commit 6521427a45
6 changed files with 51 additions and 23 deletions

View File

@ -73,6 +73,7 @@ const struct set_option_entry set_option_table[NSETOPTION] = {
{ "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, { "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-right", SET_OPTION_STRING, 0, 0, NULL }, { "status-right", SET_OPTION_STRING, 0, 0, NULL },
{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, { "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
}; };
int int

View File

@ -53,8 +53,8 @@ screen_write_putc(
} }
/* Calculate string length. */ /* Calculate string length. */
size_t printflike1 size_t printflike2
screen_write_strlen(const char *fmt, ...) screen_write_strlen(int utf8flag, const char *fmt, ...)
{ {
va_list ap; va_list ap;
char *msg; char *msg;
@ -67,7 +67,7 @@ screen_write_strlen(const char *fmt, ...)
ptr = msg; ptr = msg;
while (*ptr != '\0') { while (*ptr != '\0') {
if (*ptr > 0x7f) { /* Assume this is UTF-8. */ if (utf8flag && *ptr > 0x7f) {
memset(utf8buf, 0xff, sizeof utf8buf); memset(utf8buf, 0xff, sizeof utf8buf);
left = strlen(ptr); left = strlen(ptr);
@ -94,7 +94,7 @@ screen_write_strlen(const char *fmt, ...)
return (size); return (size);
} }
/* Write string. */ /* Write simple string (no UTF-8 or maximum length). */
void printflike3 void printflike3
screen_write_puts( screen_write_puts(
struct screen_write_ctx *ctx, struct grid_cell *gc, const char *fmt, ...) struct screen_write_ctx *ctx, struct grid_cell *gc, const char *fmt, ...)
@ -102,25 +102,25 @@ screen_write_puts(
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
screen_write_vnputs(ctx, -1, gc, fmt, ap); screen_write_vnputs(ctx, -1, gc, 0, fmt, ap);
va_end(ap); va_end(ap);
} }
/* Write string with length limit (-1 for unlimited). */ /* Write string with length limit (-1 for unlimited). */
void printflike4 void printflike5
screen_write_nputs(struct screen_write_ctx *ctx, screen_write_nputs(struct screen_write_ctx *ctx,
ssize_t maxlen, struct grid_cell *gc, const char *fmt, ...) ssize_t maxlen, struct grid_cell *gc, int utf8flag, const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
screen_write_vnputs(ctx, maxlen, gc, fmt, ap); screen_write_vnputs(ctx, maxlen, gc, utf8flag, fmt, ap);
va_end(ap); va_end(ap);
} }
void void
screen_write_vnputs(struct screen_write_ctx *ctx, screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
ssize_t maxlen, struct grid_cell *gc, const char *fmt, va_list ap) struct grid_cell *gc, int utf8flag, const char *fmt, va_list ap)
{ {
char *msg; char *msg;
u_char *ptr, utf8buf[4]; u_char *ptr, utf8buf[4];
@ -131,7 +131,7 @@ screen_write_vnputs(struct screen_write_ctx *ctx,
ptr = msg; ptr = msg;
while (*ptr != '\0') { while (*ptr != '\0') {
if (*ptr > 0x7f) { /* Assume this is UTF-8. */ if (utf8flag && *ptr > 0x7f) {
memset(utf8buf, 0xff, sizeof utf8buf); memset(utf8buf, 0xff, sizeof utf8buf);
left = strlen(ptr); left = strlen(ptr);

View File

@ -50,7 +50,7 @@ status_redraw(struct client *c)
size_t llen, llen2, rlen, rlen2, offset; size_t llen, llen2, rlen, rlen2, offset;
size_t xx, yy, sy, size, start, width; size_t xx, yy, sy, size, start, width;
struct grid_cell stdgc, gc; struct grid_cell stdgc, gc;
int larrow, rarrow; int larrow, rarrow, utf8flag;
left = right = NULL; left = right = NULL;
@ -74,18 +74,21 @@ status_redraw(struct client *c)
if (yy == 0) if (yy == 0)
goto blank; goto blank;
/* Caring about UTF-8 in status line? */
utf8flag = options_get_number(&s->options, "status-utf8");
/* Work out the left and right strings. */ /* Work out the left and right strings. */
left = status_replace(s, options_get_string( left = status_replace(s, options_get_string(
&s->options, "status-left"), c->status_timer.tv_sec); &s->options, "status-left"), c->status_timer.tv_sec);
llen = options_get_number(&s->options, "status-left-length"); llen = options_get_number(&s->options, "status-left-length");
llen2 = screen_write_strlen("%s", left); llen2 = screen_write_strlen(utf8flag, "%s", left);
if (llen2 < llen) if (llen2 < llen)
llen = llen2; llen = llen2;
right = status_replace(s, options_get_string( right = status_replace(s, options_get_string(
&s->options, "status-right"), c->status_timer.tv_sec); &s->options, "status-right"), c->status_timer.tv_sec);
rlen = options_get_number(&s->options, "status-right-length"); rlen = options_get_number(&s->options, "status-right-length");
rlen2 = screen_write_strlen("%s", right); rlen2 = screen_write_strlen(utf8flag, "%s", right);
if (rlen2 < rlen) if (rlen2 < rlen)
rlen = rlen2; rlen = rlen2;
right[rlen] = '\0'; right[rlen] = '\0';
@ -164,7 +167,8 @@ draw:
screen_write_start(&ctx, NULL, &c->status); screen_write_start(&ctx, NULL, &c->status);
if (llen != 0) { if (llen != 0) {
screen_write_cursormove(&ctx, 0, yy); screen_write_cursormove(&ctx, 0, yy);
screen_write_nputs(&ctx, llen + 1, &stdgc, "%s ", left); screen_write_nputs(
&ctx, llen + 1, &stdgc, utf8flag, "%s ", left);
if (larrow) if (larrow)
screen_write_putc(&ctx, &stdgc, ' '); screen_write_putc(&ctx, &stdgc, ' ');
} else { } else {
@ -221,7 +225,8 @@ draw:
/* Draw the last item. */ /* Draw the last item. */
if (rlen != 0) { if (rlen != 0) {
screen_write_cursormove(&ctx, c->tty.sx - rlen - 1, yy); screen_write_cursormove(&ctx, c->tty.sx - rlen - 1, yy);
screen_write_nputs(&ctx, rlen + 1, &stdgc, " %s", right); screen_write_nputs(
&ctx, rlen + 1, &stdgc, utf8flag, " %s", right);
} }
/* Draw the arrows. */ /* Draw the arrows. */

24
tmux.1
View File

@ -1133,6 +1133,12 @@ may contain any of the following special character pairs:
Where appropriate, these may be prefixed with a number to specify the maximum Where appropriate, these may be prefixed with a number to specify the maximum
length, for example length, for example
.Ql #24T . .Ql #24T .
.Pp
By default, UTF-8 in
.Ar string
is not interpreted, to enable UTF-8, use the
.Ic status-utf8
option.
.It Ic status-left-length Ar length .It Ic status-left-length Ar length
Set the maximum Set the maximum
.Ar length .Ar length
@ -1147,13 +1153,27 @@ As with
.Ic status-left , .Ic status-left ,
.Ar string .Ar string
will be passed to will be passed to
.Xr strftime 3 .Xr strftime 3 ,
and character pairs are replaced. character pairs are replaced, and UTF-8 is dependent on the
.Ic status-utf8
option.
.It Ic status-right-length Ar length .It Ic status-right-length Ar length
Set the maximum Set the maximum
.Ar length .Ar length
of the right component of the status bar. of the right component of the status bar.
The default is 40. The default is 40.
.Pp
.It Xo Ic status-utf8
.Op Ic on | Ic off
.Xc
Instruct
.Nm
to treat top-bit-set characters in the
.Ic status-left
and
.Ic status-right
strings as UTF-8; notably, this is important for wide characters.
This option defaults to off.
.El .El
.It Xo Ic set-password .It Xo Ic set-password
.Op Fl c .Op Fl c

1
tmux.c
View File

@ -299,6 +299,7 @@ main(int argc, char **argv)
options_set_string(&global_options, "status-left", "[#S]"); options_set_string(&global_options, "status-left", "[#S]");
options_set_string( options_set_string(
&global_options, "status-right", "\"#24T\" %%H:%%M %%d-%%b-%%y"); &global_options, "status-right", "\"#24T\" %%H:%%M %%d-%%b-%%y");
options_set_number(&global_options, "status-utf8", 0);
options_init(&global_window_options, NULL); options_init(&global_window_options, NULL);
options_set_number(&global_window_options, "aggressive-resize", 0); options_set_number(&global_window_options, "aggressive-resize", 0);

11
tmux.h
View File

@ -69,6 +69,7 @@ extern const char *__progname;
#define printflike2 __attribute__ ((format (printf, 2, 3))) #define printflike2 __attribute__ ((format (printf, 2, 3)))
#define printflike3 __attribute__ ((format (printf, 3, 4))) #define printflike3 __attribute__ ((format (printf, 3, 4)))
#define printflike4 __attribute__ ((format (printf, 4, 5))) #define printflike4 __attribute__ ((format (printf, 4, 5)))
#define printflike5 __attribute__ ((format (printf, 5, 6)))
/* Number of items in array. */ /* Number of items in array. */
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
@ -928,7 +929,7 @@ struct set_option_entry {
}; };
extern const struct set_option_entry set_option_table[]; extern const struct set_option_entry set_option_table[];
extern const struct set_option_entry set_window_option_table[]; extern const struct set_option_entry set_window_option_table[];
#define NSETOPTION 24 #define NSETOPTION 25
#define NSETWINDOWOPTION 19 #define NSETWINDOWOPTION 19
/* tmux.c */ /* tmux.c */
@ -1347,13 +1348,13 @@ void grid_view_delete_cells(struct grid *, u_int, u_int, u_int);
void screen_write_start( void screen_write_start(
struct screen_write_ctx *, struct window_pane *, struct screen *); struct screen_write_ctx *, struct window_pane *, struct screen *);
void screen_write_stop(struct screen_write_ctx *); void screen_write_stop(struct screen_write_ctx *);
size_t printflike1 screen_write_strlen(const char *, ...); size_t printflike2 screen_write_strlen(int, const char *, ...);
void printflike3 screen_write_puts(struct screen_write_ctx *, void printflike3 screen_write_puts(struct screen_write_ctx *,
struct grid_cell *, const char *, ...); struct grid_cell *, const char *, ...);
void printflike4 screen_write_nputs(struct screen_write_ctx *, void printflike5 screen_write_nputs(struct screen_write_ctx *,
ssize_t, struct grid_cell *, const char *, ...); ssize_t, struct grid_cell *, int, const char *, ...);
void screen_write_vnputs(struct screen_write_ctx *, void screen_write_vnputs(struct screen_write_ctx *,
ssize_t, struct grid_cell *, const char *, va_list); ssize_t, struct grid_cell *, int, const char *, va_list);
void screen_write_putc( void screen_write_putc(
struct screen_write_ctx *, struct grid_cell *, u_char); struct screen_write_ctx *, struct grid_cell *, u_char);
void screen_write_copy(struct screen_write_ctx *, void screen_write_copy(struct screen_write_ctx *,