Monday, 15 April 2013

Byobu Bling with Unicode Custom Indicators

Introduction

In these heady times of almost daily advances in UI pizzazz, you could be forgiven for thinking the terminal is somewhat of a dead-zone when it comes to excitement. Oh how wrong you would be though...!

If you've never used ByobuDustin's awesome text-based window manage, sudo apt-get install it without delay to be bathed in pure terminal goodness. As shown below, byobu comes with a whole host of standard indicators, allowing the display of useful snippets of information.



The indicators are minimal out of terminal-width real estate necessity, but that's also their strength - they provide just the details you really care about in a tight ASCII format. And they're cute of course :-)

However, byobu has a well-kept secret: when running with the tmux backend, it supports Unicode indicators. So with the proviso that you are running "byobu-tmux" rather than "byobu-screen", you can squeeze down those indicators even further, saving precious onscreen characters and get extra bling at the same time! Intrigued? Then read on...

Background


A few years ago (yes, it's taken that long to get around to writing this up! ;-), I was playing around with Unicode and ended up writing a very simple C program to display the time in "binary" using the Braille Unicode Block. Assuming you were only displaying hours and minutes, that meant you could display any time in 2 onscreen characters - nice and compact :) I wanted to use this program as a byobu custom indicator but at the time byobu was only using GNU screen and alas even the latest version of screen did not have full UTF-8 support (for its status line atleast). However, tmux was fast becoming the worthy successor to screen and of course byobu now supports both backends. I ended up rewriting the C program as a shell script to fit in with the other byobu indicators. That shell script became the time_binary indicator shipped with byobu.

Here it is displaying the time (21:04) in 24-hour format:

T[⢄⠐]

Admittedly, it's kinda terse and somewhat difficult to read but that's half the fun right? :-) time_binary is slightly mis-named as it can also display the time in hexadecimal and octal.

But why stop there? I now wanted all sorts of Unicode indicators showing the level of things like sound, wifi signal strength, left/right speaker volumes, memory used, system load, etc. However, since UIs are very personal, I wanted to be able to write short custom indicators for each of the above but allow the choice of unicode indicators to be changed with minimal trouble as desired.

Enter byobu-ulevel

What I ended up doing is trawling through some of those myriad Unicode symbols looking for suitable groups and creating a small utility called byobu-ulevel. This takes a numeric value and converts it into an appropriate "level" symbol. This all sounds a bit vague, so here's an example:

$ byobu-ulevel 100
█

The above example has converted the value 100 to its default 100% value using the default theme. And here's the default 30% value:

$ byobu-ulevel 30
▂

Starting to make sense? If your data source doesn't provide values from 0% to 100%, fear not. Let's say your data source ranges from -123 to +456 and your value to display is 333.0:

$ byobu-ulevel -c 333 -m -123.45 -x +678.90
▄


This utility is generally only useful if your data has some specifiable bounded range. However, there is a "cheat mode" - if you are happy for values to overflow/underflow silently, you can specify "-p":

$ byobu-ulevel -c 999 -x 100
ERROR: value (999) > maximum (100)
$ byobu-ulevel -c 999 -x 100 -p
█

Template for a Byobu Unicode Custom Notification

We can create a Unicode custom notification:

$ mkdir -p ~/.byobu/bin
$ cd ~/.byobu/bin
$ cat >5_utest<<EOT

# XXX: rather than hard-coding the value, put your logic here
# XXX: to determine an actual value from some data source.
value=20

printf "U[%s]\n" $(byobu-ulevel $value)
EOT
$ chmod 755 5_utest

In fact, as you'll see once you finish this article, the example notification above is really a template for most of your Unicode notifications.

Once you've activated the custom notifications in byobu (F9 → Toggle status notifications → check the "custom" option), and waited for a few seconds (5 in the example above), you'll see the following on your byobu status line:

U[▁]

I've added a "U" to denote my Unicode test indicator and delimited the actual indicator value glyph between square brackets, but of course you can use whatever ornamentation you wish.

Themes


So, we now have an indicator that, assuming you add in some appropriate logic to set "$value" dynamically, will show a 1-character wide bar whose height varies depending on the magnitude of $value.

But what if you don't like that bar much? No problem because byobu-ulevel comes with a set of built-in "themes" and since we haven't specified one, we get the default (vbars_8). Let's list the available themes by asking byobu-ulevel to display them:

$ byobu-ulevel -l
circles_2
diamonds_2
flags_2
hearts_2
squares_2
squares_small_2
stars_2
vdots_thick_4
vdots_thin_4
fractions_4
quadrants_4
shades_4
circles_5
dice_6
hbars_8
vbars_8
circle_number_10
solid_numbers_a_10
solid_numbers_b_10

So now we know the theme names, let's take a look at them:


$ for theme in $(byobu-ulevel -l); do byobu-ulevel -l -t "$theme"; done
Listing theme 'circles_2'

○ ● 

Listing theme 'diamonds_2'

◇ ◆ 

Listing theme 'flags_2'

⚐ ⚑ 

Listing theme 'hearts_2'

♡ ♥ 

Listing theme 'squares_2'

◻ ◼ 

Listing theme 'squares_small_2'

◽ ◾ 

Listing theme 'stars_2'

☆ ★ 

Listing theme 'vdots_thick_4'

⣀ ⣤ ⣶ ⣿ 

Listing theme 'vdots_thin_4'

⢀ ⢠ ⢰ ⢸ 

Listing theme 'fractions_4'

¼ ½ ¾ ¹ 

Listing theme 'quadrants_4'

◔ ◑ ◕ ● 

Listing theme 'shades_4'

░ ▒ ▓ █ 

Listing theme 'circles_5'

◦ ○ ◎ ◉ ● 

Listing theme 'dice_6'

⚀ ⚁ ⚂ ⚃ ⚄ ⚅ 

Listing theme 'hbars_8'

▏ ▎ ▍ ▌ ▋ ▊ ▉ █ 

Listing theme 'vbars_8'

▁ ▂ ▃ ▄ ▅ ▆ ▇ █ 

Listing theme 'circle_number_10'

➀ ➁ ➂ ➃ ➄ ➅ ➆ ➇ ➈ ➉ 

Listing theme 'solid_numbers_a_10'

➊ ➋ ➌ ➍ ➎ ➏ ➐ ➑ ➒ ➓ 

Listing theme 'solid_numbers_b_10'

❶ ❷ ❸ ❹ ❺ ❻ ❼ ❽ ❾ ❿ 

So how do you use these themes? Easy, just choose the one you like the look of and specify it using "-t $theme". Let's try out the stars_2 theme:

$ byobu-ulevel -c 60 -t stars_2
★★★☆☆

All themes ending with "_2" contain two glyphs and are called "rating themes" (for obvious reasons I hope). The first glyph in a rating theme represents the "unused" part of the range and the second glyph represents the "used" part. So, here we see that 60% (equating to 3 solid stars) is "used" since the value is 60 and the default range is 0-100%. Obviously, we can't display half glyphs so for this theme for example the value provided is "rounded to the nearest star" :-)

By default rating themes are displayed left-to-right. However, you can change that using the "-r" option:

$ byobu-ulevel -c 60 -t stars_2 -r
☆☆★★★

Or you can invert the theme such that the first glyph will represent the "used" part and the second the "unused" using the "-i" option:

$ byobu-ulevel -c 60 -t stars_2 -i
☆☆☆★★

But maybe 5 stars isn't enough for you? No problem, use the width option ("-w"):

$ byobu-ulevel -c 60 -t stars_2  -w 10
★★★★★★☆☆☆☆

Themes with more than 2 glyph values are different to rating themes in that rather than using a combination of the "used" and "unused" glyphs to show the value, only a single glyph is selected. For example, here's our 60% again using the circle_number_10 theme:

$ byobu-ulevel -c 60 -t circle_number_10
➅

Since I'm bound to have missed out your favourite Unicode glyphs, you can of course make your own theme trivially too. Let's create a rating theme:

$ byobu-ulevel -c 60 -u "· ☢"
☢☢☢··

And now a normal theme with, in this example, 10 values:

$ byobu-ulevel -c 60 -u "a b c d e f g h i j"
f

You could even use utfout to construct your theme:

$ byobu-ulevel -c 45 -u "$(utfout -a ' ' '\{α..ω}')"
λ

Accessibility

But what about accessibility? What about users who cannot display some of these characters? byobu-ulevel provides for these folk too: either specify "-a" or set the BYOBU_A11Y environment variable to any value, and byobu-ulevel will display purely numeric (floating point) values rather than Unicode bling. You can specify the number of decimal places too with the "-e" option.

Multiple Values



Great, but byobu-ulevel only handles a single value - what if you want to display multiple values? For example a range of values over time? No problem because along with byobu-ulevel we have byobu-ugraph which takes a series of values and uses byobu-ulevel to display them. The canonical example being the load average display. Let's create a rolling load average showing 5 data points by creating ~/.byobu/bin/5_uload and making it executable:


file=/tmp/load.dat
awk '{print $1}' /proc/loadavg >> $file
printf "L[%s]\n" $(byobu-ugraph -p 5 -x 3 -f $file)

Leave it to run for a few iterations (to generate the 5 data points we've specified we want and we get something like this:

L[▁▄▇▇▇]












Like byobu-ulevel, byobu-ugraph assumes all data values range from 0 to 100 so assuming your system load is somewhat more manageable than that, you'll want to specify a "reasonable" maximum value as I have with "-x 3" to allow byobu-ugraph to scale the values appropriately.

Again, you can specify a theme to pass through to byobu-ulevel. Here's the same data using the solid_numbers_b_10 theme:

L[❷❺❾❾❾]

... And the same data again this time using the vdots_thick_4 theme:

L[⣀⣤⣶⣶⣶]






 
Can console bliss get any better than this? Of course it can - we haven't introduced colours yet!

This part is still rather a work-in-progress as my current unreleased colour utility is rather basic. I'm hoping to expand it and potentially merge it into byobu-ulevel "Real Soon Now". However, my latest versions of byobu-ulevel and byobu-ugraph now accept a "-y" option to enable colour. This allow us to bling up that original load example rather trivially:


file=/tmp/load.dat
awk '{print $1}' /proc/loadavg >> $file
printf "L[%s]\n" $(byobu-ugraph -p 5 -x 3 -f $file -y)

All I've done is add that "-y" to produce:

L[▇▇▇]






The colour script currently takes current, minimum and maximum values but also allows thresholds to be specified along with colours for each threshold. By default, two thresholds are specified: "low" (0-15%) and "high" (85-100%). If the value is within the low threshold, it will be coloured red, if in the high threshold it gets coloured green, and yellow if in the middle. The threshold colours can also be inverted so that for example an indicator showing 95% disk usage will default to displaying in red when inverted (as that's a bad scenario), whilst an indicator showing 95% free memory will show in green when not inverted (as that's good :-)

Obligatory Screenshot


Here's an example of the sorts of indicators you can create with just a few lines of shell script for your custom indicators:



As you can see, it's pretty sparse - just the way I like it.

The indicators, from left to right (ignoring the "0:*" byobu window number) are:

  • Time (23:01) in binary ("T[...]")
  • Free disk ("D[...]")
  • Some sort of rating (you decide :-) using hearts ("R[...]")
  • Free memory ("M[...]")
  • Another rating this time using stars ("R[...]")
  • Load average with 5 values ("L[...]")
  • Wifi signal strengh ("W[...]")

Tips and Observations

  • Sometimes, you may find that an indicator doesn't appear. This appears to be an issue with either tmux or the terminal emulator you are using (gnome-terminal, rxvt, urxvt, xterm, etc). The solution seems to be to exit byobu, close the tab/window and restart byobu.
  • When writing custom indicators, ensure that the output ends with a newline character ('\n') - without it, byobu won't display the indicator.
  • Performance can be an issue if you specify a large (10+ say) number of values to byobu-ugraph or if you have more than a few byobu-ulevel and/or byobu-ugraph indicators on-screen at once.
  • byobu-ulevel and byobu-ugraph can run in a terminal as long as you don't enable colour mode (which outputs not colour escape sequences but tmux colour commands).
  • For extra fun, you could have your indicator script call byobu-ulevel specifying a random theme. Here's an indicator which will use a random theme to display the value (80) each time it is called:
  • # change this to by the value you want to display
    num=80
    
    count=$(byobu-ulevel -l | wc -l)
    selected=$(((RANDOM % count)+1))
    theme=$(byobu-ulevel -l | sed -n ${selected}p)
    printf "X[%s]\n" $(byobu-ulevel -c $num -t $theme)
    

Planned Future Work

  • Finish the colour script and potentially merge with byobu-ulevel. New features that could be added to the colour script:
    • ability to specify arbitrary thresholds with arbitrary colours and attributes (bold, etc).
    • ability to invert the colour applied to a value from a colour theme.
  • Improve performance (probably by rewriting in C).
  • Improve accessibility support.
  • Finish another utility I've half-written that shows sound levels (with individual left and right speaker channels all in a single on-screen character!)

Contribute

There are lots of other Unicode possibilities. Just browse through the wikipedia Unicode page for inspiration.
For example, I'd love it for example if someone would write a Unicode weather app that downloaded the current weather for my location and then displayed it using suitable glyphs like: ⁂ ※ ⁑   ⁕ ⁖  ⁜ ⁛ ☀ ☁ ☂ ☔  ☃.
Find an excuse to get involved!

Conclusion


With minimal effort, you can now add custom Unicode indicators to your byobu session saving you precious onscreen space whilst also offering a dash of visual spice.



13 comments:

  1. Here are some more Unicode levels:

    ����������
    ����������
    ��������
    ������������
    ����������
    ����������
    ⓪①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳
    ⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇
    ������������������
    ⚀⚁⚂⚃⚄⚅

    Also, please keep in mind that the Unicode blocks for Mathmatical Alphanumeric Symbols contains alternative Latin glyphs, which can be used as alternative English fonts for titles in textmode. ☺

    ReplyDelete
    Replies
    1. I am very sorry, but it seems that Blogger doesn't like my 4 bytes characters… ��

      Delete
    2. Thanks Tomer. The dice are already available (see the 'dice_6' theme above) but I'll add the 2 remaining themes you've listed that I can see :-) You might want to raise a bug on byobu itself with the details of the other themes (launchpad handles unicode rather well I believe :-):

      https://bugs.launchpad.net/byobu/+filebug

      Delete
  2. Could you share the scripts you're using?

    I can't find a link in the article, and it's not in the 'byobu' package in Raring either.

    ReplyDelete
  3. byobu-ulevel and byobu-ugraph live in the byobu source package below, but are not yet in the binary package (I think(?) Dustin is in the process of converting some of the other indicators to display Unicode icons but you may want to ping him on that):

    http://bazaar.launchpad.net/~kirkland/byobu/trunk/files/head:/usr/bin/

    The binary clock *is* in the package as /usr/lib/byobu/time_binary.

    ReplyDelete
    Replies
    1. I'll post the latest versions of the scripts later though...

      Delete
    2. The latest versions of the scripts are below, along with the test custom indicators used for the blog post:

      http://people.canonical.com/~jhunt/byobu/

      Delete
  4. Nice article, thanks for the information. It's very complete information. I will bookmark for next reference
    jaring futsal | jaring golf | jaring pengaman proyek |
    jaring pengaman bangunan | jaring pengaman gedung
    http://www.jual-jaring.blogspot.com/
    http://www.agen-jaring.blogspot.com/
    http://www.pancasamudera-safetynet.blogspot.com/
    http://www.toko-jaring.blogspot.com/
    http://www.pusat-jaring.blogspot.com/
    http://jualjaringpengaman.blogspot.com/
    https://pancasamudera.wordpress.com/
    https://pasangjaringfutsal.wordpress.com/
    https://jualtambangmurah.wordpress.com/
    https://tokojaring.wordpress.com/
    https://jualjaringfutsal.wordpress.com/
    https://jaringfutsal.wordpress.com/


    ReplyDelete
  5. It is really very helpful for us and I have gathered some important information from this blog.

    123 hp oj2620 setup

    ReplyDelete
  6. Great blog! I really love how it is easy on my eyes and the information are well written.123 HP Officejet Pro 8748 Printer Setup

    ReplyDelete