org-super-agenda
org-super-agenda copied to clipboard
Org Group tags are not recognized
I'm using Org Group-Tags as described here: Org Tag hierarchy.
This lets me search for for a main Group-Tag via org-tags-view
and it then displays all members of the group and any subgroups.
However super-agenda
doesn't match the tags correctly. I'm not quite sure how that could be achieved as I didn't find a way to actually get the group tags. When I had a quick look at the org-tags-view defun
it seems like it uses org-make-tags-matcher
to match the group tags: See source code here
Anyway my Lisp is not very good so I'm not sure if that's even correct or if this can be used to make super-agenda
match Group-Tags.
I would really appreciate if there was a way for it to work.
Yeah, I don't use group tags, and it seems that not many people do. Since it's not a feature I use, I probably won't work on it anytime soon.
I don't know how they're implemented internally. Whether we can easily support them depends on whether the agenda sets group tags in text-properties--if not, we'll have to write code to get them from the source buffers, and whether that's difficult depends on how Org implements them. If it's just a simple function call, it probably wouldn't be too difficult.
For anyone who wants to investigate this, here's what I recommend:
As a first step, pull up an agenda view that shows items that have group tags set, and use C-u C-x =
to view the text properties of one of the items, to see if you can find the group tags in the properties.
If not, see if Org has a function to get specifically group tags from an item at point (in an Org buffer, not an Agenda buffer).
If not, then see if the standard Org tag-getting functions work with group tags.
And if the group tags aren't available in text properties, then we'll probably need to define a group-tags-specific selector in this package, to avoid making the regular one slower.
It seems like tags are not part of the text properties. Instead they are are expanded as regular expressions when searching: Matching tags
There is the function org-tags-expand
which returns a regular expression matching all corresponding group tags.
So when having defined a "maingroup" and "subgroup 1" + "subgroup 2", (org-tags-expand "maingroup")
returns "{\\<\\(?:maingroup\\|subgroup [12]\\)\\>}"
I couldn't really figure out how org-super-agenda--defgroup tag
works, but maybe this can help.
Thanks. It looks like it may not be too difficult after all. Please try evaluating this code and then running one of your views that should work with group tags:
(org-super-agenda--defgroup tag
"Group items that match any of the given tags.
Argument may be a string or list of strings."
:let* ((target-tags (->> args (--map (org-group-tags it t)) -flatten)))
:section-name (concat "Tags: " (s-join " OR " target-tags))
:test (seq-intersection (org-super-agenda--get-tags item) target-tags 'cl-equalp))
Unfortunately it doesn't work. "Symbol’s function definition is void: org-group-tags"
is thrown when I try running an agenda view.
This seems to work for me:
(org-super-agenda--defgroup tag
"Group items that match any of the given tags.
Argument may be a string or list of strings."
:let* ((target-tags (-flatten (cons args (org-tags-expand (car args) t)))))
:section-name (concat "Tags: " (s-join " OR " args))
:test (seq-intersection (org-super-agenda--get-tags item) target-tags 'cl-equalp))
The previous code only worked while matching a single tag. This should also work with multiple tags:
(org-super-agenda--defgroup tag
"Group items that match any of the given tags.
Argument may be a string or list of strings."
:let* ((target-tags (-flatten (cons args (mapcar (lambda (arg) (funcall #'org-tags-expand arg t)) args)))))
:section-name (concat "Tags: " (s-join " OR " args))
:test (seq-intersection (org-super-agenda--get-tags item) target-tags 'cl-equalp))
The previous code only worked while matching a single tag. This should also work with multiple tags:
(org-super-agenda--defgroup tag "Group items that match any of the given tags. Argument may be a string or list of strings." :let* ((target-tags (-flatten (cons args (mapcar (lambda (arg) (funcall #'org-tags-expand arg t)) args))))) :section-name (concat "Tags: " (s-join " OR " args)) :test (seq-intersection (org-super-agenda--get-tags item) target-tags 'cl-equalp))
This works :) except for tag grouping with regular expressions such as Project : {P@.+} do you have any ideas, how to solve that as well?
@ugurbolat This PR implementing group-tags support for org-ql shows how it can be done: https://github.com/alphapapa/org-ql/pull/146
Not sure what the status is on this or if @alphapapa is going to add it but using @k-jell suggestion. You can get all the parent tags like this:
;; You could use cl-flet but prob overkill (nconc final `()) is fine for now.
(org-super-agenda-groups
(seq-map-indexed (lambda (x idx)
(let* ((count (+ idx 1))
(parent (car x))
(ph '(:underline t :foreground "green"))
(h2 '(:inherit org-level-2))
(final `( :name ,parent :tag ,parent )))
(pcase parent
((pred (equal "Personal"))
(nconc final `(:order 0 :face ,h2) ))
((pred (equal "Linux")) (nconc final `(:order 5)) )
((pred (equal "Emacs"))(nconc final `(:order 3 )) )
;; defaults
(_ (nconc final `(:order ,idx))))
final))
(org-tag-alist-to-groups org-tag-alist)))