shithub: bar

Download patch

ref: 73e4e2d06233632508f9f430faa0f93c7f1e8078
parent: 473836c5ff5a94d1cd9cba0edb9d96f46a54be49
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Mon Jan 25 06:04:16 EST 2021

add information read from stdin

--- a/README.md
+++ b/README.md
@@ -7,4 +7,7 @@
 the left top of the screen.  Bar is centered horizontally if no "top"
 or "bottom" specified for its position.
 
+`bar` reads additional data from standard input and displays it along
+with other information.
+
 ![screenshot](scr.png)
--- a/bar.c
+++ b/bar.c
@@ -13,13 +13,20 @@
 	Off = 3,
 };
 
-static int wctl, width, bottom, bat, minheight;
+static int wctl, owidth, width, twidth, bottom, bat, minheight;
 static Image *cback, *ctext;
+static char sep[16], bats[16], *aux;
 static char *pos = "rb";
-static char bats[16];
 static Tzone *local;
 static Font *f;
 
+#pragma varargck type "|" char*
+static int
+sepfmt(Fmt *f)
+{
+	return fmtstrcpy(f, va_arg(f->args, char*)[0] ? sep : "");
+}
+
 /*
  * nsec() is wallclock and can be adjusted by timesync
  * so need to use cycles() instead, but fall back to
@@ -70,7 +77,7 @@
 	w = atoi(a[3]);
 	h = atoi(a[4]);
 
-	if(ow != w || oh != h){
+	if(ow != w || oh != h || owidth != width){
 		if(pos[0] == 't' || pos[1] == 't'){
 			miny = 0;
 			maxy = minheight;
@@ -93,6 +100,7 @@
 			fprint(2, "%s: %r\n", t);
 		ow = w;
 		oh = h;
+		owidth = width;
 	}
 }
 
@@ -111,24 +119,26 @@
 	draw(screen, r, cback, nil, ZP);
 
 	tf = tmfmt(tmnow(&tm, local), "YYYY/MM/DD WW hh:mm:ss");
+	p.x = r.min.x + Off;
+	p.y = (pos[0] == 't' || pos[1] == 't') ? r.max.y - (f->height + Off) : r.min.y + Off;
 	if(pos[0] == 'l' || pos[1] == 'l'){
-		snprint(s, sizeof(s), "%τ%s", tf, bats);
-		p.x = r.min.x + Off;
-	}else if(pos[0] == 'r' || pos[1] == 'r'){
-		snprint(s, sizeof(s), "%s%τ", bats, tf);
-		p.x = r.max.x - (stringwidth(f, s) + Off);
-	}else{
-		snprint(s, sizeof(s), "%s%τ", bats, tf);
-		p.x = r.min.x + Off;
+		snprint(s, sizeof(s), "%τ%|%s%|%s", tf, bats, bats, aux, aux);
+	}else{
+		snprint(s, sizeof(s), "%s%|%s%|%τ", aux, aux, bats, bats, tf);
+		if(pos[0] == 'r' || pos[1] == 'r')
+			p.x = r.max.x - (stringwidth(f, s) + Off);
 	}
-	p.y = (pos[0] == 't' || pos[1] == 't') ? r.max.y - (f->height + Off) : r.min.y + Off;
 	string(screen, p, ctext, ZP, f, s);
 
 	flushimage(display, 1);
 	unlockdisplay(display);
 
-	snprint(s, sizeof(s), "%s%τ", bats[0] ? "100% │ " : "", tf);
-	width = stringwidth(f, s);
+	snprint(s, sizeof(s), "%τ", tf);
+	twidth = MAX(twidth, stringwidth(f, s));
+	snprint(s, sizeof(s), "%|%s%|%s", bats, bats[0] ? "100%" : "", aux, aux);
+	width = twidth + stringwidth(f, s);
+	if(owidth != width)
+		place();
 }
 
 static void
@@ -139,7 +149,7 @@
 	s = bat < 0 || pread(bat, tmp, 4, 0) < 4 ? nil : strchr(tmp, ' ');
 	if(s != nil){
 		*s = 0;
-		snprint(bats, sizeof(bats), pos[0] == 'l' || pos[1] == 'l' ? " │ %s%%" : "%s%% │ ", tmp);
+		snprint(bats, sizeof(bats), "%s%%", tmp);
 	}else{
 		bats[0] = 0;
 	}
@@ -174,9 +184,33 @@
 }
 
 static void
+auxproc(void *)
+{
+	Biobuf b;
+	char *s;
+
+	Binit(&b, 0, OREAD);
+	for(;;){
+		s = Brdstr(&b, '\n', 1);
+		lockdisplay(display);
+		free(aux);
+		aux = s ? s : strdup("");
+		unlockdisplay(display);
+		redraw();
+		if(wctl >= 0)
+			fprint(wctl, bottom ? "bottom" : "top");
+		if(s == nil)
+			break;
+	}
+	Bterm(&b);
+
+	threadexits(nil);
+}
+
+static void
 usage(void)
 {
-	fprint(2, "usage: %s [-b] [-p lt|t|rt|lb|b|rb]\n", argv0);
+	fprint(2, "usage: %s [-b] [-p lt|t|rt|lb|b|rb] [-s separator]\n", argv0);
 	threadexitsall("usage");
 }
 
@@ -190,25 +224,35 @@
 	Biobuf *b;
 	Rune key;
 	Mouse m;
-	Alt a[] =
-	{
-		{ nil, &m, CHANRCV },
-		{ nil, nil, CHANRCV },
-		{ nil, &key, CHANRCV },
-		{ nil, nil, CHANEND },
+	enum {
+		Emouse,
+		Eresize,
+		Ekeyboard,
+		Eend,
 	};
+	Alt a[] = {
+		[Emouse] = { nil, &m, CHANRCV },
+		[Eresize] = { nil, nil, CHANRCV },
+		[Ekeyboard] = { nil, &key, CHANRCV },
+		[Eend] = { nil, nil, CHANEND },
+	};
 
+	strcpy(sep, " │ ");
 	ARGBEGIN{
+	case 'b':
+		bottom = 1;
+		break;
 	case 'p':
 		pos = EARGF(usage());
 		break;
-	case 'b':
-		bottom = 1;
+	case 's':
+		snprint(sep, sizeof(sep), "%s", EARGF(usage()));
 		break;
 	default:
 		usage();
 	}ARGEND
 
+	fmtinstall('|', sepfmt);
 	tmfmtinstall();
 	if((local = tzload("local")) == nil)
 		sysfatal("zone: %r");
@@ -246,17 +290,18 @@
 	brgb = brgb<<8 | brgb<<16 | brgb<<24 | 0xff;
 	ctext = allocimage(display, Rect(0,0,1,1), RGB24, 1, brgb);
 
+	aux = strdup("");
 	readbattery();
 	redraw();
-	place();
 	proccreate(updateproc, nil, 4096);
+	proccreate(auxproc, nil, 16384);
 
 	for(;;){
 		switch(alt(a)){
-		case 0:
+		case Emouse:
 			break;
 
-		case 1:
+		case Eresize:
 			if(getwindow(display, Refnone) < 0)
 				sysfatal("getwindow: %r");
 			redraw();
@@ -263,7 +308,7 @@
 			place();
 			break;
 
-		case 2:
+		case Ekeyboard:
 			if(key == Kdel){
 				close(wctl);
 				wctl = -1;