Listing Org Tags

Chris over at the cpb83 blog solves a problem that many of us probably have. If you’re an Org mode user, you probably make use of the agenda and organize your data with tags. The problem is that if your agenda tracks several Org files, like mine does, and you use tags liberally, you’ll likely forget which tags you have. Was that tag “grocery” or “groceries?”

Swiper and similar utilities help with this a bit but, in the case of swiper, only the first tag for an entry. Chris shows us a bit of Elisp that goes through your agenda files and compiles a sorted list of all the tags in use. That’s a useful thing to have by itself but the code also demonstrates how to search Org files. Org has several functions, such as org-map-entries, that make the searching easier. Chris’ code shows how to do that and can serve as a template to search for something besides tags if you need to.

UPDATE [2017-04-26 Wed 09:19]: The cpb83 blog has been taken down but you can find Chris’ post and the code here.

This entry was posted in General and tagged , . Bookmark the permalink.
  • Not good: is no longer available.
    The authors have deleted this site.

    • I would really like to see the code. This is something I will need in a project I'm starting and it would be nice to see how someone else did it before I mangle it on my own....

      • Christoph Lange

        Hi, I once wrote a poor man's solution to this problem in Perl. Don't have the file handy right now but will share it today.

      • jcs

        The meat of it was something like

        (org-map-entries (lambda () org-scanner-tags) t 'agenda)

        with some function calls added to concatenate the lists, remove duplicates, and sort the results. There was also code to get the results in a buffer.

      • jcs

        Found it. The code is here.

  • NoonianAtall

    Unfortunately, org-map-entries is typically very slow, and org-scan-tags (which is used by it) is also very slow. Depending on the size and number of your org files, it may not be an issue. Here's some code that does the same thing but about 6 times faster:

    (defun c25l:org-tags-2 ()
    (with-current-buffer (get-buffer-create "*org-tags*")
    (delete-region (point-min) (point-max))
    (let ((tags (sort (delete-dups
    (cl-loop for buffer in (org-buffer-list 'agenda t)
    append (with-current-buffer buffer
    (goto-char (point-min))
    (cl-loop while (re-search-forward org-complex-heading-regexp nil t)
    when (match-string 5)
    append (split-string (substring-no-properties (match-string 5))
    ":" t "[[:space:]]+"))))))
    (dolist (tag tags)
    (insert (concat "[[elisp:(org-tags-view nil "" tag "")][" tag "]]n"))))
    (switch-to-buffer (current-buffer))))

  • c25l

    Hey. I just saw this and it absolutely made my day. Glad someone else enjoyed it, too! My only dissatisfaction with the code is it's basically set to run on a side effect of an interesting function, so without reading the help you could never figure out why it worked.