Show current org clock and task in sway bar
Written by Sebastian Dümcke on
Tags: emacs guix silverblue
The emacs mode-line is quite crowded, with the currently clocked task appearing at the very right side in my case. Whenever I open a second vertical frame, it covers that part of the mode-line leaving me without indication whether I am currently clocked into a task, which task that is and how much time I already spent on the task. This had me run org-current-clock regularly just to check this.
Changing or adapting the mode-line would only partially solve this, because there will always be a certain screen size or amount of additional frames that will eventually cover up the information. One evening I had the realisation that I might be able to show this information in the status bar of my window manager (sway bar). It is prime screen real-estate that currently is underused by me.
On the emacs side, getting the information to show is easy, you simply evaluate the function org-clock-get-clock-string. Wrapped in a few guardrails to account for the org package being loaded and the presence of an active clock and a default string in case of no clock we end up with the following expression:
emacsclient -e "(if (and (fboundp 'org-clocking-p) (org-clocking-p)) (substring-no-properties (org-clock-get-clock-string)) \"💤\")"
This code then goes into whatever script you call to generate the text to be shown in the bar.
The difficult part for me was integrating this into my personal setup. I run guix package manager on Fedora Silverblue with only sway as layered package and that setup required a few peculiarities. First off, for the above to work one must ensure that the emacs server is running (and that you use an emacsclient connected to the same server to clock your time). For this the emacs package contains a systemd service unit that can be run as a service. Since in guix that service is in the store, we need to copy it to the right path:
guix locate emacs.serive #returns the paths to all emacs service units in the store, choose the correct one cp /gnu/store/c6qvzq6zf3apwmdh5q9k8204yfxx0cr1-emacs-30.2/lib/systemd/user/emacs.service ~/.config/systemd/user #then activate the unit and start it immediately systemctl --user enable --now emacs
However, it turns out, that the emacs is not in PATH when systemd starts the service, because the guix profile is only activated on login or in .bashrc. To propagate the environment to systemd and sway on should create a file in ~/.config/environment.d with the following content (name is irrelevant):
PATH=$HOME/.guix-profile/bin:${PATH}
This will then allow binaries (such as emacs and emacsclient) from your main guix profile to be available to systemd and inside your sway config. The relevant part of my sway config for the bar is:
bar {
position bottom
# When the status_command prints a new line to stdout, swaybar updates.
status_command $HOME/.config/sway/bar.sh
}
and the complete content of the bar.sh file (including showing the currently connected network, battery status and the date+time:
#!/usr/bin/env sh while echo $(emacsclient -e "(if (and (fboundp 'org-clocking-p) (org-clocking-p)) (substring-no-properties (org-clock-get-clock-string)) \"💤\")" | tr -d '"';nmcli con show --active | head -n 2 | tail -n 1 | cut -f 1 -d ' ' | tr '\n' ' ';cat /sys/class/power_supply/BAT0/capacity | tr '\n' ' '; date +'%Y-%m-%d %H:%M') do sleep 5 done
There you have it. We the bar always shown at the bottom of the screen without any overlapping windows, I can now always check if and which task is active and how much time was spent on it (currently 45 minutes writing this blog post).