From 8562bd09ec9045c4823d037114573359c2e629ba Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gustav=20Wikstr=C3=B6m?= Date: Sat, 24 Jan 2015 02:47:47 +0100 Subject: [PATCH] org: Nesting grouptags * lisp/org.el (org-tags-expand): Nesting grouptags. Allowing subtags to be defined as groups themselves. : #+TAGS: [ Group : SubOne(1) SubTwo ] : #+TAGS: [ SubOne : SubOne1 SubOne2 ] : #+TAGS: [ SubTwo : SubTwo1 SubTwo2 ] Should be seen as a tree of tags: - Group - SubOne - SubOne1 - SubOne2 - SubTwo - SubTwo1 - SubTwo2 Searching for "Group" should return all tags defined above. --- lisp/org.el | 29 +++++++++++++++++++++++++++-- testing/lisp/test-org.el | 10 ++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index da0932007..b1999dcda 100755 --- a/lisp/org.el +++ b/lisp/org.el @@ -14530,7 +14530,7 @@ See also `org-scan-tags'. matcher))) (cons match0 matcher))) -(defun org-tags-expand (match &optional single-as-list downcased) +(defun org-tags-expand (match &optional single-as-list downcased tags-already-expanded) "Expand group tags in MATCH. This replaces every group tag in MATCH with a regexp tag search. @@ -14571,6 +14571,7 @@ When DOWNCASE is non-nil, expand downcased TAGS." (taggroups-keys (mapcar #'car taggroups)) (return-match (if downcased (downcase match) match)) (count 0) + (work-already-expanded tags-already-expanded) regexps-in-match tags-in-group regexp-in-group regexp-in-group-escaped) ;; @ and _ are allowed as word-components in tags. (modify-syntax-entry ?@ "w" stable) @@ -14588,8 +14589,32 @@ When DOWNCASE is non-nil, expand downcased TAGS." (let* ((dir (match-string 1 return-match)) (tag (match-string 2 return-match)) (tag (if downcased (downcase tag) tag))) - (when (not (get-text-property 0 'grouptag (match-string 2 return-match))) + (unless (or (get-text-property 0 'grouptag (match-string 2 return-match)) + (member tag work-already-expanded)) (setq tags-in-group (assoc tag taggroups)) + (push tag work-already-expanded) + ;; Recursively expand each tag in the group, if the tag hasn't + ;; already been expanded. Restore the match-data after all recursive calls. + (save-match-data + (let (tags-expanded) + (dolist (x (cdr tags-in-group)) + (if (and (member x taggroups-keys) + (not (member x work-already-expanded))) + (setq tags-expanded + (delete-dups + (append + (org-tags-expand x t downcased + work-already-expanded) + tags-expanded))) + (setq tags-expanded + (append (list x) tags-expanded))) + (setq work-already-expanded + (delete-dups + (append tags-expanded + work-already-expanded)))) + (setq tags-in-group + (delete-dups (cons (car tags-in-group) + tags-expanded))))) ;; Filter tag-regexps from tags. (setq regexp-in-group-escaped (delq nil (mapcar (lambda (x) diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 36df1d3e1..c624b7319 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -3174,6 +3174,16 @@ Text. (org-match-sparse-tree nil "work") (search-forward "H2") (org-invisible-p2))) + ;; Match tags in hierarchies + (should-not + (org-test-with-temp-text + "#+TAGS: [ Lev_1 : Lev_2 ]\n +#+TAGS: [ Lev_2 : Lev_3 ]\n +#+TAGS: { Lev_3 : Lev_4 }\n +* H\n** H1 :Lev_1:\n** H2 :Lev_2:\n** H3 :Lev_3:\n** H4 :Lev_4:" + (org-match-sparse-tree nil "Lev_1") + (search-forward "H4") + (org-invisible-p2))) ;; Match regular expressions in tags (should-not (org-test-with-temp-text -- 2.11.4.GIT