I have a huge number of text files (.txt), in which I store notes. I would like to add tags to the start of each of these files in order to characterize their content. The best would be to be able to, either chose tags from a list of tags already used (that dynamically expands for each new tag used), or if none of these tags are useful add a new one (therby expanding the dynamic list with this new tag). Does it already exist such a dynamic tagging functionality, and if so, how to I implement it? How can I search over these multiple file?

  • Ideally, the dynamic list of tags should be stored alphabetically sorted in a text file. This file should be stored in the same folder as the file, or even better in the same parent folder that contains text files and subfolders also containing text files. – myotis Nov 8 '15 at 18:08
  • I already have a list of fixed tags that I use for my todo's, these are defined by the org-tag-alist. This list should be left undisturbed by the tags I use for the notes, because the notes will contain a huge number of tags over time. The tag list for todo's shoud be short and fixed. While the second list of tags, for the notes, will increase dynamically in size. – myotis Nov 12 '15 at 11:20

If using Org Mode

See answers to this question

If not using Org Mode

Look at Deft package for Emacs. It isn't exactly oriented to tagging approach, rather fulltext search, and it is recursive, i.e. contents of subfolders are included too


You may also try contacting author to provide missing functionality


This feature requires regex-like functions and a convention for tags (can be org-mode file tags)

  • Thanks, but the solutions you point me to does not help me building up dynamic tag lists to chose from when I need it – myotis Nov 11 '15 at 11:23

I think I use a similar method to what you're describing that I initially cribbed from http://doc.norang.ca/org-mode.html. Let me see if I can distill it to what you are looking for.

Firstly, have a directory that contains all of your note files (e.g. ~/org) and then set the org-agenda-files to that path and inside of that directory, I have a default notes file where everything that I capture goes into at first and then I can file it later in another file:

(setq org-agenda-files '("~/org"))
(setq org-default-notes-file "~/org/inbox.org")

To create a new note, I use org-capture which I bind to CTRL-C c:

(global-set-key (kbd "C-c c") 'org-capture)

You can setup templates for different capture tasks which I use for both my to-dos and my notes:

(setq org-capture-templates '(("t" "todo" entry (file "~/org/inbox.org")
                               "* TODO %?\n%U\n%a\n" :clock-in t :clock-resume t)
                              ("n" "note" entry (file "~/org/inbox.org")
                               "* %? :NOTE:\n%U\n%a\n" :clock-in t :clock-resume t)))

You can see the in template above that my to-do's have a TODO tag in front of them, which is made special through the org-todo-keywords variable while my note has the :NOTE: tag applied to it.

When I'm done creating the entry, I can then choose where I would like to file it. org-mode will give you all the headlines that exist in your org files. What I like to do is have a file per large project and inside of that file, I have the following structure:

* Notes
* Dates
* TODO Tasks

So for when I'm just creating notes for the project, I'll file them under the Notes heading but my to-do's are filed under the Tasks heading.

You can also see the FILETAGS header there which applies that tag to all of the items contained in the file. This achieves part of what you were asking but we still want to add tags to each individual note item. This can also be done and I do this as part of a GTD style system where I want to know the context of a particular item. Tags can be applied to each item by going to an org header and doing the key command CTRL-c CTRL-c. The choices for tags are given by the org-tag-alist variable which I currently have as:

(setq org-tag-alist '((:startgroup)
                      ("@errand" . ?e)
                      ("@office" . ?o)
                      ("@home" . ?H)
                      ("WAITING" . ?w)
                      ("HOLD" . ?h)
                      ("PERSONAL" . ?P)
                      ("ORG" . ?O)
                      ("crypt" . ?E)
                      ("NOTE" . ?n)
                      ("CANCELLED" . ?c)
                      ("FLAGGED" . ??))))

Each item in the list has a hot key that you can press immediately after the CTRL-c CTRL-c command to choose that tag. If you want to apply a different command than your hot keys, you can just hit TAB and then type in whatever tag you want to apply.

To search on these tags, you can use the org-agenda command, which I have set to the CTRL-c a key command:

(global-set-key "\C-ca" 'org-agenda)

Once that org-agenda is invoked, you can type "m" for matching on TAGS/PROP/TODO. So in the example above, if I wanted all of my PROJ-NAME items which were tagged as on hold, I could just type "PROJ-NAME HOLD" in my query and the appropriate items would be returned.

So this almost gets you where you want but the list of tags isn't dynamic. For that, you would need to add a function to the org-capture-before-finalize-hook that would scan the tags applied to the headline, add any missing tags to the org-tag-alist and then save that list out to a file which can then be read on initialisation to set the org-tag-plist file. I haven't finished that function but here's the beginnings of it (using the dash.el helper library for the -filter function):

(defun org-persist-new-tags ()
  (let ((known-tags (append org-tag-persistent-alist org-tag-alist))
        (item-tags (split-string (org-get-tags))))
    (setq org-tag-alist
          (append org-tag-alist
                  (-filter (lambda (tag) (assoc tag known-tags)) item-tags)))
    ;; TODO: write out to a file the org-tag-alist

Sorry I can't finish the whole function right now but I wanted to at least see if this is a direction you think is interesting.

  • Thanks for your thorough answer! The hook function you mentioned will add the new tags to the list of tags allready defined by the org-tag-alist, right? This is not practical, see my second comment above. – myotis Nov 12 '15 at 11:21
  • Correct, the org-persist-new-tags' that I created would modify the org-tag-alist'. In many ways, I think what you're asking for is exactly what is already provided behind the free tagging done by pressing TAB instead of a hot key for tag selection and the org-tags-history' variable. You would just need to persist the org-tags-history' variable between sessions to get what you're looking for then. – Aaron Nov 12 '15 at 12:12
  • When I store my notes within a single file or within files that are defined as agenda files, then pressing tab twice during tagging, will give me a list of all fixed tags (defined in org-tag-alist) plus all the tags defined freely inside that file. But my notes file (several hundred) are not defined as agenda files. – myotis Nov 12 '15 at 12:53
  • What du you mean by "persist org-tags-history" ? do you mean manually run your "org-persist-new-tags" file? Thans for using time on this ! :) – myotis Nov 12 '15 at 12:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.