summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2009-09-07 10:49:33 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2009-09-07 10:49:33 +0000
commit098fdbf528d23bfdfc87a25ef8596184ea9e37d9 (patch)
tree45e49ae2b3fdff96428ce9874b720fd6d094fc84 /usr.bin
parent7c92b6f5b2780bbb057203c76c0a26460a715451 (diff)
Permit embedded colour and attributes in status-left and status-right using new
#[] special characters, for example #[fg=red,bg=blue,blink].
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/tmux/screen-write.c174
-rw-r--r--usr.bin/tmux/status.c24
-rw-r--r--usr.bin/tmux/tmux.124
-rw-r--r--usr.bin/tmux/tmux.h7
4 files changed, 219 insertions, 10 deletions
diff --git a/usr.bin/tmux/screen-write.c b/usr.bin/tmux/screen-write.c
index ec26f94c940..233a93fe306 100644
--- a/usr.bin/tmux/screen-write.c
+++ b/usr.bin/tmux/screen-write.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen-write.c,v 1.23 2009/08/21 08:12:05 nicm Exp $ */
+/* $OpenBSD: screen-write.c,v 1.24 2009/09/07 10:49:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -52,6 +52,41 @@ screen_write_putc(
screen_write_cell(ctx, gc, NULL);
}
+/* Calculate string length, with embedded formatting. */
+size_t printflike2
+screen_write_cstrlen(int utf8flag, const char *fmt, ...)
+{
+ va_list ap;
+ char *msg, *msg2, *ptr, *ptr2;
+ size_t size;
+
+ va_start(ap, fmt);
+ xvasprintf(&msg, fmt, ap);
+ va_end(ap);
+ msg2 = xmalloc(strlen(msg) + 1);
+
+ ptr = msg;
+ ptr2 = msg2;
+ while (*ptr != '\0') {
+ if (ptr[0] == '#' && ptr[1] == '[') {
+ while (*ptr != ']' && *ptr != '\0')
+ ptr++;
+ if (*ptr == ']')
+ ptr++;
+ continue;
+ }
+ *ptr2++ = *ptr++;
+ }
+ *ptr2 = '\0';
+
+ size = screen_write_strlen(utf8flag, "%s", msg2);
+
+ xfree(msg);
+ xfree(msg2);
+
+ return (size);
+}
+
/* Calculate string length. */
size_t printflike2
screen_write_strlen(int utf8flag, const char *fmt, ...)
@@ -177,6 +212,143 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
xfree(msg);
}
+/* Write string, similar to nputs, but with embedded formatting (#[]). */
+void printflike5
+screen_write_cnputs(struct screen_write_ctx *ctx,
+ ssize_t maxlen, struct grid_cell *gc, int utf8flag, const char *fmt, ...)
+{
+ struct grid_cell lgc;
+ va_list ap;
+ char *msg;
+ u_char *ptr, *last, utf8buf[4];
+ size_t left, size = 0;
+ int width;
+
+ va_start(ap, fmt);
+ xvasprintf(&msg, fmt, ap);
+ va_end(ap);
+
+ memcpy(&lgc, gc, sizeof lgc);
+
+ ptr = msg;
+ while (*ptr != '\0') {
+ if (ptr[0] == '#' && ptr[1] == '[') {
+ ptr += 2;
+ last = ptr + strcspn(ptr, "]");
+ if (*last == '\0') {
+ /* No ]. Not much point in doing anything. */
+ break;
+ }
+ *last = '\0';
+
+ screen_write_parsestyle(gc, &lgc, ptr);
+ ptr = last + 1;
+ continue;
+ }
+
+ if (utf8flag && *ptr > 0x7f) {
+ memset(utf8buf, 0xff, sizeof utf8buf);
+
+ left = strlen(ptr);
+ if (*ptr >= 0xc2 && *ptr <= 0xdf && left >= 2) {
+ memcpy(utf8buf, ptr, 2);
+ ptr += 2;
+ } else if (*ptr >= 0xe0 && *ptr <= 0xef && left >= 3) {
+ memcpy(utf8buf, ptr, 3);
+ ptr += 3;
+ } else if (*ptr >= 0xf0 && *ptr <= 0xf4 && left >= 4) {
+ memcpy(utf8buf, ptr, 4);
+ ptr += 4;
+ } else {
+ *utf8buf = *ptr;
+ ptr++;
+ }
+
+ width = utf8_width(utf8buf);
+ if (maxlen > 0 && size + width > (size_t) maxlen) {
+ while (size < (size_t) maxlen) {
+ screen_write_putc(ctx, gc, ' ');
+ size++;
+ }
+ break;
+ }
+ size += width;
+
+ lgc.flags |= GRID_FLAG_UTF8;
+ screen_write_cell(ctx, &lgc, utf8buf);
+ lgc.flags &= ~GRID_FLAG_UTF8;
+
+ } else {
+ if (maxlen > 0 && size + 1 > (size_t) maxlen)
+ break;
+
+ size++;
+ screen_write_putc(ctx, &lgc, *ptr);
+ ptr++;
+ }
+ }
+
+ xfree(msg);
+}
+
+/* Parse an embedded style of the form "fg=colour,bg=colour,bright,...". */
+void
+screen_write_parsestyle(
+ struct grid_cell *defgc, struct grid_cell *gc, const char *in)
+{
+ const char delimiters[] = " ,";
+ char tmp[32];
+ int val;
+ size_t end;
+ u_char fg, bg, attr;
+
+ if (*in == '\0')
+ return;
+ if (strchr(delimiters, in[strlen(in) - 1]) != NULL)
+ return;
+
+ fg = gc->fg;
+ bg = gc->bg;
+ attr = 0;
+ do {
+ end = strcspn(in, delimiters);
+ if (end > (sizeof tmp) - 1)
+ return;
+ memcpy(tmp, in, end);
+ tmp[end] = '\0';
+
+ if (strcasecmp(tmp, "default") == 0) {
+ fg = defgc->fg;
+ bg = defgc->bg;
+ attr = defgc->attr;
+ } else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) {
+ if ((val = colour_fromstring(tmp + 3)) == -1)
+ return;
+ if (*in == 'f' || *in == 'F') {
+ if (val != 8)
+ fg = val;
+ else
+ fg = defgc->fg;
+ } else if (*in == 'b' || *in == 'B') {
+ if (val != 8)
+ bg = val;
+ else
+ bg = defgc->bg;
+ } else
+ return;
+ } else {
+ if ((val = attributes_fromstring(tmp)) == -1)
+ return;
+ attr |= val;
+ }
+
+ in += end + strspn(in + end, delimiters);
+ } while (*in != '\0');
+ gc->fg = fg;
+ gc->bg = bg;
+ gc->attr = attr;
+}
+
/* Copy from another screen. */
void
screen_write_copy(struct screen_write_ctx *ctx,
diff --git a/usr.bin/tmux/status.c b/usr.bin/tmux/status.c
index 4ce1d006070..a6469dee67e 100644
--- a/usr.bin/tmux/status.c
+++ b/usr.bin/tmux/status.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: status.c,v 1.30 2009/09/02 06:33:20 nicm Exp $ */
+/* $OpenBSD: status.c,v 1.31 2009/09/07 10:49:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -107,14 +107,14 @@ status_redraw(struct client *c)
left = status_replace(s, options_get_string(
&s->options, "status-left"), c->status_timer.tv_sec);
llen = options_get_number(&s->options, "status-left-length");
- llen2 = screen_write_strlen(utf8flag, "%s", left);
+ llen2 = screen_write_cstrlen(utf8flag, "%s", left);
if (llen2 < llen)
llen = llen2;
right = status_replace(s, options_get_string(
&s->options, "status-right"), c->status_timer.tv_sec);
rlen = options_get_number(&s->options, "status-right-length");
- rlen2 = screen_write_strlen(utf8flag, "%s", right);
+ rlen2 = screen_write_cstrlen(utf8flag, "%s", right);
if (rlen2 < rlen)
rlen = rlen2;
@@ -192,7 +192,7 @@ draw:
screen_write_start(&ctx, NULL, &c->status);
if (llen != 0) {
screen_write_cursormove(&ctx, 0, yy);
- screen_write_nputs(&ctx, llen, &sl_stdgc, utf8flag, "%s", left);
+ screen_write_cnputs(&ctx, llen, &sl_stdgc, utf8flag, "%s", left);
screen_write_putc(&ctx, &stdgc, ' ');
if (larrow)
screen_write_putc(&ctx, &stdgc, ' ');
@@ -266,7 +266,7 @@ draw:
if (rlen != 0) {
screen_write_cursormove(&ctx, c->tty.sx - rlen - 1, yy);
screen_write_putc(&ctx, &stdgc, ' ');
- screen_write_nputs(&ctx, rlen, &sr_stdgc, utf8flag, "%s", right);
+ screen_write_cnputs(&ctx, rlen, &sr_stdgc, utf8flag, "%s", right);
}
/* Draw the arrows. */
@@ -400,6 +400,20 @@ status_replace(struct session *s, const char *fmt, time_t t)
len--;
}
break;
+ case '[':
+ /*
+ * Embedded style, handled at display time.
+ * Leave present and skip input until ].
+ */
+ *optr++ = '#';
+
+ iptr--; /* include [ */
+ while (*iptr != ']' && *iptr != '\0') {
+ if (optr >= out + (sizeof out) - 1)
+ break;
+ *optr++ = *iptr++;
+ }
+ break;
case '#':
*optr++ = '#';
break;
diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1
index f6e91c60bf0..cdff7b508ca 100644
--- a/usr.bin/tmux/tmux.1
+++ b/usr.bin/tmux/tmux.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.82 2009/09/02 17:34:57 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.83 2009/09/07 10:49:32 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\"
@@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 2 2009 $
+.Dd $Mdocdate: September 7 2009 $
.Dt TMUX 1
.Os
.Sh NAME
@@ -1316,10 +1316,11 @@ will be passed through
before being used.
By default, the session name is shown.
.Ar string
-may contain any of the following special character pairs:
+may contain any of the following special character sequences:
.Bl -column "Character pair" "Replaced with" -offset indent
.It Sy "Character pair" Ta Sy "Replaced with"
.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 "#I" Ta "Current window index"
.It Li "#P" Ta "Current pane index"
@@ -1329,6 +1330,23 @@ may contain any of the following special character pairs:
.It Li "##" Ta "A literal" Ql #
.El
.Pp
+The #(command) form executes
+.Ql command
+as a shell command and inserts the first line of its output.
+#[attributes] allows a comma-separated list of attributes to be specified,
+these may be
+.Ql fg=colour
+to set the foreground colour,
+.Ql bg=colour
+to set the background colour, or one of the attributes described under the
+.Ic message-attr
+option.
+Examples are:
+.Bd -literal -offset indent
+#(sysctl vm.loadavg)
+#[fg=yellow,bold]#(apm -l)%%#[default] [#S]
+.Ed
+.Pp
Where appropriate, these may be prefixed with a number to specify the maximum
length, for example
.Ql #24T .
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 69013fb3fed..e4df68a3091 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.98 2009/09/02 20:15:49 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.99 2009/09/07 10:49:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -1533,6 +1533,9 @@ char *grid_view_string_cells(struct grid *, u_int, u_int, u_int);
void screen_write_start(
struct screen_write_ctx *, struct window_pane *, struct screen *);
void screen_write_stop(struct screen_write_ctx *);
+size_t printflike2 screen_write_cstrlen(int, const char *, ...);
+void printflike5 screen_write_cnputs(struct screen_write_ctx *,
+ ssize_t, struct grid_cell *, int, const char *, ...);
size_t printflike2 screen_write_strlen(int, const char *, ...);
void printflike3 screen_write_puts(struct screen_write_ctx *,
struct grid_cell *, const char *, ...);
@@ -1540,6 +1543,8 @@ void printflike5 screen_write_nputs(struct screen_write_ctx *,
ssize_t, struct grid_cell *, int, const char *, ...);
void screen_write_vnputs(struct screen_write_ctx *,
ssize_t, struct grid_cell *, int, const char *, va_list);
+void screen_write_parsestyle(
+ struct grid_cell *, struct grid_cell *, const char *);
void screen_write_putc(
struct screen_write_ctx *, struct grid_cell *, u_char);
void screen_write_copy(struct screen_write_ctx *,