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?
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)
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
(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:
#+FILETAGS: PROJ-NAME * 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
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) (:endgroup) ("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
(defun org-persist-new-tags () (interactive) (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.