org-clock-waybar/org-clock-waybar.el

136 lines
4.9 KiB
EmacsLisp
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; org-clock-waybar --- Summary
;; Copyright (C) 2021 Gergely Polonkai
;; Author: Gergely Polonkai <gergely@polonkai.eu>
;; Keywords: org, clocking, waybar
;; Version: 1.0
;; Package-Requires: ((emacs "26.1"))
;; URL: https://gitea.polonkai.eu/gergely/org-clock-waybar
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Export the currently clocked-in task in JSON format that Waybar can process
;;
;; To use it, customize the `org-clock-waybar-filename' variable (defaults to
;; $XDG_CONFIG_HOME/waybar-current-task.json) and add the following snippet to
;; your Waybar config:
;;
;; "custom/org": {
;; "format": " {}",
;; "return-type": "json",
;; "restart-interval": 5,
;; "exec": "cat /home/yourusername/.cache/waybar-current-task.json"
;; }
;;; Code:
(require 'xdg)
(require 'json)
(require 'org-clock)
(defgroup org-clock-waybar nil
"Send current clocked task to a JSON file for Waybar visualization"
:group 'emacs)
(defcustom org-clock-waybar-filename
(expand-file-name "waybar-current-task.json" (xdg-cache-home))
"Name of the file to save task data to."
:type 'string
:group 'org-clock-waybar)
(defcustom org-clock-waybar-not-clocked-in-text
"Not clocked in"
"Text to display when not clocked in on any task."
:type 'string
:group 'org-clock-waybar)
(defconst org-clock-waybar-filename-coding-system
(if (coding-system-p 'utf-8-emacs)
'utf-8-emacs
'emacs-mule)
"Coding system of the file `org-clock-waybar-filename'.")
(defun org-clock-waybar-tooltip ()
"The default tooltip to send to waybar."
(when org-clock-current-task
(let ((clocked-time (org-clock-get-clocked-time)))
(format "%s: %s (%s)"
(org-clock-waybar-alt)
(org-clock-waybar-text)
(org-duration-from-minutes clocked-time)))))
(defun org-clock-waybar--get-clocked-task-json (&optional clocking-out)
"Get the currently clocked-in tasks data as a stringified JSON object.
The output is in JSON format constructed in a way so Waybar can process it.
If there is no clocked in task, alt becomes empty and text will be set to the
value of `org-clock-waybar-not-clocked-in-text'.
If CLOCKING-OUT is non-nil, `org-clock-current-task' will be treated as if it
were nil; this is required because `org-clock-out' calls the hook functions
before setting `org-clock-current-task' to nil."
(let* ((task (if clocking-out nil org-clock-current-task))
(category (when task (get-text-property 0 'org-category task)))
(title (when task (substring-no-properties task)))
(tooltip (org-clock-waybar-tooltip))
(output (json-new-object)))
(setq output (json-add-to-object
output
"text"
(if title
title
org-clock-waybar-not-clocked-in-text)))
(setq output (json-add-to-object output "alt" (if category category "")))
(setq output (json-add-to-object output "tooltip" (if tooltip tooltip "")))
(setq output (json-add-to-object output "class" ""))
(setq output (json-add-to-object output "percentage" ""))
(json-encode output)))
(defun org-clock-waybar-save-task (&optional clocking-out)
"Save the current clocked in task to `org-clock-waybar-filename'.
If CLOCKING-OUT is non-nil, treat the current task as if it were nil."
(with-temp-buffer
(erase-buffer)
(set-buffer-file-coding-system org-clock-waybar-filename-coding-system)
(insert (org-clock-waybar--get-clocked-task-json clocking-out))
(write-file org-clock-waybar-filename)))
(defun org-clock-waybar-clear-task ()
"Clear the current task from `org-clock-waybar-filename'."
(org-clock-waybar-save-task t))
(defun org-clock-waybar-ouptut-task ()
"Output the current task in JSON format Waybar can understand.
This function is ought to be used via Emacsclient:
emacsclient --eval '(org-clock-waybar-output-task)'"
(org-clock-waybar--get-clocked-task-json))
(defun org-clock-waybar-setup ()
"Setup org-clock-waybar.
It adds `org-clock-waybar-save-task' to both `org-clock-in-hook' and
`org-clock-out-hook'."
(add-hook 'org-clock-in-hook #'org-clock-waybar-save-task)
(add-hook 'org-clock-out-hook #'org-clock-waybar-task)
(add-hook 'kill-emacs-hook #'org-clock-waybar-clear-task))
(provide 'org-clock-waybar)
;;; org-clock-waybar.el ends here