17 Commits

Author SHA1 Message Date
3779adda25 Make different parts of the output configurable by setting user functions 2025-03-31 17:33:35 +02:00
3301967d3d Factor out clocked-out title generation to get-task-title 2025-03-31 17:33:35 +02:00
82faddc8c3 Rename most functions to remove the double dashes
This naming convention denotes “private” functions; however, if we want to introduce more
customization, we should make these available and documented well.
2025-03-31 17:33:34 +02:00
1c922fd4b4 Some more tweaks 2025-02-27 12:03:42 +00:00
d5a776c761 fix typo 2025-02-27 11:53:10 +00:00
c327eb18c6 Make the xdg dependency optional
We now default to using `~/.cache/waybar-current-task.json` if the `xdg` package is not present.
2023-01-31 08:47:36 +01:00
754fd9d2fa Merge pull request '[Bugfix] Make sure we remove all text properties before outputting JSON data' (#8) from remove-text-properties into main
Reviewed-on: gergely/org-clock-waybar#8
2021-10-16 10:24:06 +00:00
a144ee13c0 [Bugfix] Make sure we remove all text properties before outputting JSON data 2021-10-16 06:25:34 +02:00
612c0d1e31 Do not use org-clock-goto to get tags 2021-03-29 10:20:01 +01:00
lh@hrdl.eu
3e71766f85 Add-hook org-clock-cancel-hook 2021-03-13 16:01:43 +01:00
e4987c99ad Add installation instructions for quelpa/quelpa-use-package 2021-03-12 16:55:51 +00:00
c92eeff06e Fix the file header
It missed the .el extension, which is required if you want to install it via Quelpa (and probably
with `package.el` later.
2021-03-12 16:55:51 +00:00
dc3a934d62 Fix title and category 2021-03-12 09:11:13 +00:00
f90fee167f Get the tags of the currently clocked-in task and expose it in the class key 2021-03-12 05:48:15 +01:00
7648b9629c Make getting task data more error prone (and actually working) 2021-03-12 05:42:26 +01:00
c6caa3276f [Bugfix] Fix org-clock-waybar--get-tooltip
The functions it calls don’texist.
2021-03-11 17:55:47 +01:00
eb03af79d9 Factor out the title and category queries to separate functions 2021-03-11 17:47:35 +01:00
2 changed files with 147 additions and 41 deletions

View File

@@ -10,6 +10,27 @@ You can set the file to be written by customizing `org-clock-waybar-filename`; i
`$XDG_CACHE_HOME/waybar-current-task.json` (`$XDG_CACHE_HOME` defaults to `$HOME/.cache` on XDG `$XDG_CACHE_HOME/waybar-current-task.json` (`$XDG_CACHE_HOME` defaults to `$HOME/.cache` on XDG
compatible systems, like Linux.) compatible systems, like Linux.)
### Quelpa
If you only have [`quelpa`](https://github.com/quelpa/quelpa) installed:
```elisp
(quelpa
'(org-clock-waybar
:fetcher git
:url "https://gitea.polonkai.eu/gergely/org-clock-waybar.git"))
```
or, if you have [`quelpa-use-package`](https://github.com/quelpa/quelpa-use-package) installed,
too:
```elisp
(quelpa-use-package org-clock-waybar
:quelpa (org-clock-waybar
:fetcher git
:url "https://gitea.polonkai.eu/gergely/org-clock-waybar.git"))
```
## Waybar configuration ## Waybar configuration
To add the current task to Waybar, add this snippet to your config: To add the current task to Waybar, add this snippet to your config:

View File

@@ -1,4 +1,5 @@
;;; org-clock-waybar --- Summary ;;; ... -*- lexical-binding: t -*-
;;; org-clock-waybar.el --- Summary
;; Copyright (C) 2021 Gergely Polonkai ;; Copyright (C) 2021 Gergely Polonkai
@@ -38,7 +39,7 @@
;;; Code: ;;; Code:
(require 'xdg) (require 'xdg nil t)
(require 'json) (require 'json)
(require 'org-clock) (require 'org-clock)
@@ -47,7 +48,9 @@
:group 'emacs) :group 'emacs)
(defcustom org-clock-waybar-filename (defcustom org-clock-waybar-filename
(expand-file-name "waybar-current-task.json" (xdg-cache-home)) (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." "Name of the file to save task data to."
:type 'string :type 'string
:group 'org-clock-waybar) :group 'org-clock-waybar)
@@ -58,78 +61,160 @@
:type 'string :type 'string
:group 'org-clock-waybar) :group 'org-clock-waybar)
(defcustom org-clock-waybar-text-function
nil
"Function to generate the title text.
The function must return a single string.
When nil, `org-clock-waybar-get-task-title' is used."
:type 'function
:group 'org-clock-waybar)
(defcustom org-clock-waybar-alt-function
nil
"Function to generate the alternative text.
The function must return a single string.
When nil, `org-clock-waybar-get-task-category' is used."
:type 'function
:group 'org-clock-waybar)
(defcustom org-clock-waybar-class-function
nil
"Function to generate the class.
The function must either return a string, or a list of strings.
When nil, `org-clock-waybar-get-tags' is used."
:type 'function
:group 'org-clock-waybar)
(defcustom org-clock-waybar-tooltip-function
nil
"Function to generate the tooltip.
The function must return a string.
When nil, `org-clock-waybar-get-tooltip' is used."
:type 'function
:group 'org-clock-waybar)
(defcustom org-clock-waybar-percentage-function
nil
"Function to generate the percentage text.
When nil, the percentage text will be an empty string."
:type 'function
:group 'org-clock-waybar)
(defconst org-clock-waybar-filename-coding-system (defconst org-clock-waybar-filename-coding-system
(if (coding-system-p 'utf-8-emacs) (if (coding-system-p 'utf-8-emacs)
'utf-8-emacs 'utf-8-emacs
'emacs-mule) 'emacs-mule)
"Coding system of the file `org-clock-waybar-filename'.") "Coding system of the file `org-clock-waybar-filename'.")
(defun org-clock-waybar-tooltip () (defsubst org-clock-waybar-get-task-title ()
"Get the title of TASK."
(if (org-clocking-p)
(substring-no-properties org-clock-current-task)
org-clock-waybar-not-clocked-in-text))
(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--list-of-strings-p (object)
"Return t if OBJECT is a list of strings."
(not (null (delq nil
(mapcar (lambda (x) (and (stringp x) x)) object)))))
(defun org-clock-waybar-get-tooltip ()
"The default tooltip to send to waybar." "The default tooltip to send to waybar."
(when org-clock-current-task (when (org-clocking-p)
(let ((clocked-time (org-clock-get-clocked-time))) (let ((clocked-time (org-clock-get-clocked-time)))
(format "%s: %s (%s)" (format "%s: %s (%s)"
(org-clock-waybar-alt) (org-clock-waybar-get-task-category)
(org-clock-waybar-text) (org-clock-waybar-get-task-title)
(org-duration-from-minutes clocked-time))))) (org-duration-from-minutes clocked-time)))))
(defun org-clock-waybar--get-clocked-task-json (&optional clocking-out) (defun org-clock-waybar-get-tags ()
"Get the currently clocked-in tasks data as a stringified JSON object. "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. 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 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'. value of `org-clock-waybar-not-clocked-in-text'."
(let* ((text-func (or 'org-clock-waybar-text-function
If CLOCKING-OUT is non-nil, `org-clock-current-task' will be treated as if it 'org-clock-waybar-get-task-title))
were nil; this is required because `org-clock-out' calls the hook functions (text (funcall text-func))
before setting `org-clock-current-task' to nil." (alt-func (or 'org-clock-waybar-alt-function
(let* ((task (if clocking-out nil org-clock-current-task)) 'org-clock-waybar-get-task-category))
(category (when task (get-text-property 0 'org-category task))) (alt (funcall alt-func))
(title (when task (substring-no-properties task))) (tooltip-func (or 'org-clock-waybar-tooltip-function
(tooltip (org-clock-waybar-tooltip)) 'org-clock-waybar-get-tooltip))
(tooltip (funcall tooltip-func))
(class-func (or 'org-clock-waybar-class-function
'org-clock-waybar-get-tags))
(class (funcall class-func))
(percentage (when (fboundp 'org-clock-waybar-percentage-function)
(funcall 'org-clock-waybar-percentage-function)))
(output (json-new-object))) (output (json-new-object)))
(setq output (json-add-to-object (or (null title)
output (stringp title)
"text" (error "Title must be a string (org-clock-waybar)!"))
(if title (or (null alt)
title (stringp alt)
org-clock-waybar-not-clocked-in-text))) (error "Alt text must be a string (org-clock-waybar)!"))
(setq output (json-add-to-object output "alt" (if category category ""))) (or (null tooltip)
(setq output (json-add-to-object output "tooltip" (if tooltip tooltip ""))) (stringp tooltip)
(setq output (json-add-to-object output "class" "")) (error "Tooltip must be a string (org-clock-waybar)!"))
(setq output (json-add-to-object output "percentage" "")) (or (null class)
(stringp class)
(org-clock-waybar--list-of-strings-p class)
(error "Class must be a string or a list of strings (org-clock-waybar)!"))
(or (null percentage)
(stringp percentage)
(error "Percentage must be a string (org-clock-waybar)!"))
(setq output (json-add-to-object output "text" (or text "")))
(setq output (json-add-to-object output "alt" (or alt "")))
(setq output (json-add-to-object output "tooltip" (or tooltip "")))
(setq output (json-add-to-object output "class" (or class "")))
(setq output (json-add-to-object output "percentage" (or percentage "")))
(json-encode output))) (json-encode output)))
(defun org-clock-waybar-save-task (&optional clocking-out) (defun org-clock-waybar-save-task ()
"Save the current clocked in task to `org-clock-waybar-filename'. "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 (with-temp-buffer
(erase-buffer) (erase-buffer)
(set-buffer-file-coding-system org-clock-waybar-filename-coding-system) (set-buffer-file-coding-system org-clock-waybar-filename-coding-system)
(insert (org-clock-waybar--get-clocked-task-json clocking-out)) (insert (org-clock-waybar--get-clocked-task-json))
(write-file org-clock-waybar-filename))) (write-file org-clock-waybar-filename)))
(defun org-clock-waybar-clear-task () (defun org-clock-waybar-output-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. "Output the current task in JSON format Waybar can understand.
This function is ought to be used via Emacsclient: This function is ought to be used via Emacsclient:
emacsclient --eval '(org-clock-waybar-output-task)'" emacsclient --eval '(org-clock-waybar-output-task)'"
(org-clock-waybar--get-clocked-task-json)) (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 () (defun org-clock-waybar-setup ()
"Setup org-clock-waybar. "Setup org-clock-waybar.
It adds `org-clock-waybar-save-task' to both `org-clock-in-hook' and It adds `org-clock-waybar-save-task' to both `org-clock-in-hook' and
`org-clock-out-hook'." `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-in-hook #'org-clock-waybar-save-task)
(add-hook 'org-clock-out-hook #'org-clock-waybar-task) (add-hook 'org-clock-out-hook #'org-clock-waybar-save-task)
(add-hook 'kill-emacs-hook #'org-clock-waybar-clear-task)) (add-hook 'kill-emacs-hook #'org-clock-waybar-save-task))
(provide 'org-clock-waybar) (provide 'org-clock-waybar)
;;; org-clock-waybar.el ends here ;;; org-clock-waybar.el ends here