ZSH: Emoji Analog Clock

Just about any example of a of customized ZSH prompt that you’ll find on the internet has time shown.

PROMPT='time: %T > '

I can’t recall the last time I noticed or gained any advantage of having the time printed in the terminal.

Lots of other customized ZSH prompts also have some emoji characters to spice things up. Skulls đź’€, ghost đź‘», etc. That’s easy enough to add.

ghost=$'\U1F47B'
PROMPT='time: %T $ghost >

Screenshot from 2018-06-30 15-04-03

You can also directly paste an emoji into your configuration file, but I didn’t like the idea of having none regular text in my configuration files. Also, I’d like to make the emoji on my prompt a little more dynamic. And this is where the discussion of putting time into your custom prompt comes back.

The full set of o’clock emojis are defined between 0x1F550 to 0x1F567 and looks like this.

Screenshot from 2018-06-30 15-25-58

It first defines top of the hour from 1 to 12 then the half hours from 1 to 12. So with a little bit of script we can get the command line to show us an analog clock of the current time by simple getting the hour and increment from the first hex value.

current_clock_emoji() {
    hour=$(date +"%l")
    echo -n '\U'$(([##16] 0x1F550 + hour - 1))
}

A couple of note about this code: The %l gets the hour from 1-12 without padding, the #16 tells ZSH that you want to do hexadecimal arithmetic, and the extra pound(#) symbol says to not output the base prefix (ZSH arithmetic).

Now call the method when setting up your prompt. Pretty straight forward.

PROMPT='time: %T $(current_clock_emoji) > '

Here is what my final prompt looks like.

Screenshot from 2018-06-30 15-39-05

I didn’t bother changing the clock for every half hour because that sort of granularity probably won’t be helpful. Here is a solution that changes the emoji on the quarter hours.

Extra

Below is the code I used to display out all the clocks.

display_clocks(){
    for i in `seq 0 $((0x1F567 - 0x1F550))`;
    do
        echo -n ' \U'$(([##16] 0x1F550 + $i))
    done
}

ZSH: How Deep Am I

If you are on unix and you haven’t tried zsh, I would recommend it. If you use zsh and haven’t tried oh-my-zsh,  I would recommend it. I won’t go into too much detail on oh-my-zsh and how it helps manage your zsh configuration, but, it provides two features that make command line work more pleasant. 1) Plugins for integration with things like git, gulp, ruby, etc and 2) a number of different themes.

One of the plugins I use is Gradle. I noticed that it hadn’t been updated for a while because it was missing some switches from newer versions of Gradle, so I updated it. It was a trivial update and while I was there I noticed that the plugin lacked the ability to auto-complete the gradle init command. That is a more complex patch and required me to start learning zsh scripting.

Writing zsh and testing various functions is pretty straight forward–write a function in a file or directly on the command line. Updating configurations (which is what oh-my-zsh manages) is slightly harder to test. The best recommendation that I found, was to just open zsh in zsh.

Screenshot from 2015-12-02 20-00-07

I would open up zsh nested, let oh-my-zsh do its work with my changes and then test. Now I have a shell inside a shell, if I type exit then I’m back to my base shell. If I type exit again then whatever terminal I’m in will shut down. If I got distracted and forgot what level I was at in my nested zsh, and exited, then I had to started my terminal all over again. This is slightly annoying, so I added a little script to my .zshrc file to help me track where I’m at.

export ZSH_LEVEL
let "ZSH_LEVEL++"
print -Pn "\e]2;${ZSH_LEVEL}\a"

function zshexit_shelllevel() {
let "ZSH_LEVEL--"
print -Pn "\e]2;${ZSH_LEVEL}\a"
}
zshexit_functions+=(zshexit_shelllevel)

Let me explain this real quick. Line 3 and 7 will allow us to change the the window title (that’s what the 2 is saying). zshexit_functions is a zsh builtin function that will get called when zsh is exited. So, when the .zshrc get source on start up it increments ZSH_LEVEL and when the zshexit_shelllevel gets called it decrements the ZSH_LEVEL, changing the window title every time.

It looks like this:

levelzsh

See that little “2” in the bottom right-hand corner.

I’m sure there are simpler/better ways to do this, but I got a kick out of learning some simple zsh builtins and display preferences, both of which are used heavily in oh-my-zsh.


 

Edit (March 19, 2016):

As expected, there is a built-in solution for this problem. Check out nath_schwarz solution on reddit.