forked from gergely/org-clock-waybar
		
	We now default to using `~/.cache/waybar-current-task.json` if the `xdg` package is not present.
		
			
				
	
	
		
			145 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
| ;;; org-clock-waybar.el --- 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 nil t)
 | ||
| (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
 | ||
|   (if (fboundp 'xdg-cache-home)
 | ||
|       (expand-file-name "waybar-current-task.json" (xdg-cache-home))
 | ||
|     (expand-file-name "~/.cache/waybar-current-task.json"))
 | ||
|   "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'.")
 | ||
| 
 | ||
| (defsubst org-clock-waybar--get-task-title ()
 | ||
|   "Get the title of TASK."
 | ||
|   (when (org-clocking-p) (substring-no-properties org-clock-current-task)))
 | ||
| 
 | ||
| (defsubst org-clock-waybar--get-task-category ()
 | ||
|   "Get the category of TASK."
 | ||
|   (when (org-clocking-p) (get-text-property 0 'org-category org-clock-current-task)))
 | ||
| 
 | ||
| (defun org-clock-waybar--get-tooltip ()
 | ||
|   "The default tooltip to send to waybar."
 | ||
|   (when (org-clocking-p)
 | ||
|     (let ((clocked-time (org-clock-get-clocked-time)))
 | ||
|       (format "%s: %s (%s)"
 | ||
|               (org-clock-waybar--get-task-category)
 | ||
|               (org-clock-waybar--get-task-title)
 | ||
|               (org-duration-from-minutes clocked-time)))))
 | ||
| 
 | ||
| (defun org-clock-waybar--get-tags ()
 | ||
|   "Get the tags of the currently clocked-in task."
 | ||
|   (when (org-clocking-p)
 | ||
|     (or (org-with-point-at org-clock-marker (org-get-tags))
 | ||
|         "")
 | ||
|     ))
 | ||
| 
 | ||
| (defun org-clock-waybar--get-clocked-task-json ()
 | ||
|   "Get the currently clocked-in task’s 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'."
 | ||
|   (let* ((category (org-clock-waybar--get-task-category))
 | ||
|          (title (org-clock-waybar--get-task-title))
 | ||
|          (tooltip (org-clock-waybar--get-tooltip))
 | ||
|          (output (json-new-object)))
 | ||
|     (setq output (json-add-to-object
 | ||
|                   output
 | ||
|                   "text"
 | ||
|                   (or title org-clock-waybar-not-clocked-in-text)))
 | ||
|     (setq output (json-add-to-object output "alt" (or category "")))
 | ||
|     (setq output (json-add-to-object output "tooltip" (or tooltip "")))
 | ||
|     (setq output (json-add-to-object output "class" (or (org-clock-waybar--get-tags) "")))
 | ||
|     (setq output (json-add-to-object output "percentage" ""))
 | ||
|     (json-encode output)))
 | ||
| 
 | ||
| (defun org-clock-waybar-save-task ()
 | ||
|   "Save the current clocked in task to `org-clock-waybar-filename'."
 | ||
|   (with-temp-buffer
 | ||
|     (erase-buffer)
 | ||
|     (set-buffer-file-coding-system org-clock-waybar-filename-coding-system)
 | ||
|     (insert (org-clock-waybar--get-clocked-task-json))
 | ||
|     (write-file org-clock-waybar-filename)))
 | ||
| 
 | ||
| (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)'"
 | ||
|   (let* ((output (org-clock-waybar--get-clocked-task-json))
 | ||
|          (start 0)
 | ||
|          (end (length output)))
 | ||
|     (set-text-properties start end nil output)
 | ||
|     output))
 | ||
| 
 | ||
| (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-cancel-hook #'org-clock-waybar-save-task)
 | ||
|   (add-hook 'org-clock-in-hook #'org-clock-waybar-save-task)
 | ||
|   (add-hook 'org-clock-out-hook #'org-clock-waybar-save-task)
 | ||
|   (add-hook 'kill-emacs-hook #'org-clock-waybar-save-task))
 | ||
| 
 | ||
| (provide 'org-clock-waybar)
 | ||
| ;;; org-clock-waybar.el ends here
 |