Integrating org-pomodoro to polybar

I like to use the pomodoro technique. Initially I built myself for fun a simple daemon in Rust to handle the pomodoro cycles and I would display it’s output periodically in my status bar to be able to keep track of said cycles at a glance. But after a while of using that I switched to the most excellent org-pomodoro as it integrated better with my existing workflow. I wanted to keep my status bar indicator though as I’m not always in Emacs so I had to write a script to get the current pomodoro status.

UPDATE : You can find a more recent and featureful version of the script here.

This is what it looks like : org-pomodoro-polybar.png You can toggle the amount of information shown.

For this I’ll assume you’re running Emacs as a daemon. You’ll also need the pomicons font installed on your system. If you’re only interested in the code you can find it here but for this article I’ll go over the process of creating the script.

First we have to get from Emacs the current org-pomodoro status. To do so we will use the following command :

emacsclient --eval '(if (org-pomodoro-active-p) org-pomodoro-state -1)'

Emacsclient --eval sends a command to the daemon and gives us it’s return. (if (org-pomodoro-active-p) org-pomodoro-state -1) returns the pomodoro state if org-pomodoro is active. Otherwise it returns -1.

Let’s put the result of that command in a variable and print a different icon depending on the state :

#!/usr/bin/env bash

STATE=$(emacsclient --eval '(if (org-pomodoro-active-p) org-pomodoro-state -1)')
case "$STATE" in
    ":pomodoro")
        echo -e "%{F#B77A76}\ue003";;
    ":short-break")
        echo -e "%{F#958090}\ue005";;
    ":long-break")
        echo -e "%{F#7DAEA9}\ue006";;
    *)
        echo -e "\ue007";;
esac

This will print a different icon depending on the state (pomodoro, short break or long break) or print a ghost icon if no pomodoro state is found (that includes errors). The \ue003 is used to print the corresponding unicode. The %{F#hexcolor} part is a polybar format tag, you can change them to the colors of your choice.

The polybar config looks like the following :

[bar/mybar]
;; setting up the bar so that it uses the correct font
font-1 = "Pomicons:size=8;1"

[module/pomodoro]
type = custom/script
exec = /path/to/the/script.sh
interval = 5

The interval is 5 seconds to avoid using too much resources.

We could stop there but I wanted it to be able to optionally show the time and the current task, meaning I wanted to be able to switch between different output formats. To do so, we need to have some way to keep track of a state. Environment variables aren’t an option as the script is called as a child and therefor cannot modify the environment of the parent. This means we have to use a file instead, like so :

OUTPUT_STYLE_FILE="/tmp/pomodoro-polybar-output-style"

# If the file doesn't exist, default to SIMPLE output style
if test -e "$OUTPUT_STYLE_FILE"
then
    OUTPUT_STYLE=$(cat "$OUTPUT_STYLE_FILE")
else
    OUTPUT_STYLE="SIMPLE"
fi

if [ "$#" == "0" ]; then
    case "$1" in
        "SIMPLE")
            print_pomodoro_state_simple;;
        "LONG")
            print_pomodoro_state_long;;
        *)
            print_pomodoro_state_full;;
    esac
fi

# Toggle env variable to know what kind of output to show
if [ "$1" == "toggle" ]; then
    case "$OUTPUT_STYLE" in
        "SIMPLE")
            NEW_OUTPUT_STYLE="LONG";;
        "LONG")
            NEW_OUTPUT_STYLE="FULL";;
        *)
            NEW_OUTPUT_STYLE="SIMPLE";;
    esac
    echo $NEW_OUTPUT_STYLE > /tmp/pomodoro-polybar-output-style
fi

So now the output style depends on the content of the /tmp/pomodoro-polybar-output-style file if it exists and defaults to simple otherwise. If the script is called with the toggle argument it will toggle between the different output styles and if called without it will output the pomodoro state depending on the set output style.

All we have to do now is implement the different print functions. For starters we can get the remaining time.

set_remaining_time() {
    TIME_REMAINING=$(emacsclient --eval '(org-pomodoro-format-seconds)')
    TIME_REMAINING="${TIME_REMAINING%\"}"
    TIME_REMAINING="${TIME_REMAINING#\"}"
}

Emacs output is between quotes, i.e. "25:00", so we have to remove them, here using bash built-ins. Same for the current task :

set_task_at_hand() {
    TASK_AT_HAND=$(emacsclient --eval '(org-no-properties org-clock-current-task)')
    TASK_AT_HAND="${TASK_AT_HAND%\"}"
    TASK_AT_HAND="${TASK_AT_HAND#\"}"
}

I’ll just go over one of the 3 print functions :

print_pomodoro_state_full() {
    set_state_and_pomodoro_icon
    if [ $STATE = ":pomodoro" ]; then
        set_remaining_time
        set_task_at_hand
        echo -e "$ICON $TIME_REMAINING $TASK_AT_HAND"
    elif [ $STATE = ":short-break" -o $STATE = ":long-break" ]; then #No current task to print
        set_remaining_time
        echo -e "$ICON $TIME_REMAINING"
    else # Org-pomodoro not running, nothing else to print
        echo -e "$ICON"
        exit
    fi
    exit
}

set_state_and_pomodoro_icon is just a modified version of the first version of the script that populates a variable ICON with the color and icon to print instead of echoing it. We have 3 cases :

Putting it all together, you can find the end result here.