63

I am using org-mode to write notes and org-agenda to organize all notes, especially to search some info. by keyword or tag.

C-c a m can search some files by tag inputed, C-c a s by keyword ,those functions from org-agenda are well to utilize, however, I need to add org-file into the agenda-list by hand.

I added some codes into .emacs, such as

(setq org-agenda-files (list "path/folder/*.org"))

or

(setq org-agenda-files (file-expand-wildcards "path/folder/*.org"))

but, both failed to add files under the folder specified into agenda-list automatically, so I can't search keyword or tag among those org-files, unless that I open a org-file and type C-c [ to add it into agenda-list.

How can I make all org-files under a folder automatically added in agenda?

Zoe Rowa
  • 1,329
  • 1
  • 11
  • 21
  • It looks like you're doing the right thing -- is this just a relative path issue? Can you try doing the same thing with the full path? Alternately, are you running a server and not re-evaluating the appropriate commands? – Craig Citro Jul 08 '12 at 16:33
  • I have tried that with both full path and relative path. now ,I know the cause resulting in this problem, owing to I want more than one folder to included the agenda-file. I made two case =setq org-agenda-file (...)= , giving rise to the function ineffective. Very thank your words. – Zoe Rowa Jul 09 '12 at 03:33

2 Answers2

92

Just naming the directory should be enough. For example this works for me very well:

(setq org-agenda-files '("~/org"))

Also take a look at org-agenda-text-search-extra-files; it lets you add extra files included only in text searches. A typical value might be,

(setq org-agenda-text-search-extra-files
      '(agenda-archives
        "~/org/subdir/textfile1.txt"
        "~/org/subdir/textfile1.txt"))

Caveat: If you add a file to the directory after you have started Emacs, it will not be included.

Edit: (2018) To include all files with a certain extension in the extra files list you can try the following function I wrote sometime back (a more recent version might be available here).

;; recursively find .org files in provided directory
;; modified from an Emacs Lisp Intro example
(defun sa-find-org-file-recursively (&optional directory filext)
  "Return .org and .org_archive files recursively from DIRECTORY.
If FILEXT is provided, return files with extension FILEXT instead."
  (interactive "DDirectory: ")
  (let* (org-file-list
         (case-fold-search t)         ; filesystems are case sensitive
         (file-name-regex "^[^.#].*") ; exclude dot, autosave, and backupfiles
         (filext (or filext "org$\\\|org_archive"))
         (fileregex (format "%s\\.\\(%s$\\)" file-name-regex filext))
         (cur-dir-list (directory-files directory t file-name-regex)))
    ;; loop over directory listing
    (dolist (file-or-dir cur-dir-list org-file-list) ; returns org-file-list
      (cond
       ((file-regular-p file-or-dir)             ; regular files
        (if (string-match fileregex file-or-dir) ; org files
            (add-to-list 'org-file-list file-or-dir)))
       ((file-directory-p file-or-dir)
        (dolist (org-file (sa-find-org-file-recursively file-or-dir filext)
                          org-file-list) ; add files found to result
          (add-to-list 'org-file-list org-file)))))))

You can use it like this:

(setq org-agenda-text-search-extra-files
      (append (sa-find-org-file-recursively "~/org/dir1/" "txt")
              (sa-find-org-file-recursively "~/org/dir2/" "tex")))

Edit: (2019) As mentioned in the answer by @mingwei-zhang and the comment by @xiaobing, find-lisp-find-files from find-lisp and directory-files-recursively also provides this functionality. However, please note in these cases the file name argument is a (greedy) regex. So something like (directory-files-recursively "~/my-dir" "org") will give you all Org files including backup files (*.org~). To include only *.org files, you may use (directory-files-recursively "~/my-dir" "org$").

suvayu
  • 4,271
  • 2
  • 29
  • 35
  • 2
    wow~ eaxtly! Specifying the directory is enough. at present, I know what mistake I made as to cause the problem. Properly .emacs permits one case of **(setq org-agenda-files ..)** , if more than one folder want to be added in agenda-files, it should add the directory next to the first one, all directories put together on the unique codes, like this **(setq org-agenda-files "** =directory1= **" "** =directory2= **" ..)** thank you very much. – Zoe Rowa Jul 09 '12 at 03:50
  • More, I really like to organize all types text files with emacs, your code is work also, seemingly those text files other than .org only can be added in agenda-file after we have assigned them in .emacs one by one. *Is there a convenient way to point tall of tex -files, .txt;.doc;.tex under the folder to agenda-file? like the case of org-file we told above?* – Zoe Rowa Jul 09 '12 at 03:50
  • Thank you for your guide again. I have tried your code, but the emacs showed the error message, **Symbol's function definition is void: find-org-file-recursuvely** I added a `'` before `(append`, `(setq org-agenda-text-search-extra-files '(append (find-org-file-recursively....` the error message disappeared, I searched the keyword by **C-c /** , the emacs responded: **Wrong typ argument: arrayp, append** Is there something important I omitted ? – Zoe Rowa Jul 10 '12 at 13:29
  • yes I restart my Emacs after amending the **.emacs** file everytime. – Zoe Rowa Jul 10 '12 at 13:32
  • @x7x7 There is no need for the single quote. Did you put the function definition for `find-org-file-recursively` in your init file? I linked to the page on github, just copy paste to your .emacs and restart Emacs. – suvayu Jul 10 '12 at 21:07
  • very sorry, here is the feedback. I copied all your codes from your link in **.emacs**, there is no error message after restarting, but it's can't work. – Zoe Rowa Jul 11 '12 at 06:46
  • 2
    I have checked it numerous times on my setup and it works very well. You must be doing something wrong. You don't give enough info for me to make an educated guess either. – suvayu Jul 11 '12 at 15:58
  • hi it's long time I left here, but I always hold this problem within my mind, here are those codes I added into **.emacs** This is to recognize all org-type files `(setq org-agenda-files '("~/Documents" "~/Documents/melancholy"))` – Zoe Rowa Jan 24 '13 at 15:04
  • And I pasted those codes are you taught me ,such as you mentioned above and your link, After restarting emacs ,no error is reported, but when I do _C-c a s_ emacs shows me `Agenda file ~/Documents/test.txt is not in 'org-mode'` and if I deleted the file `test.txt` emacs will show another tet-file to meet the same problem. I extremely want to handle this problem, thank you again and again.... – Zoe Rowa Jan 24 '13 at 15:16
  • I found that use **C-c a s** can't search any keyword in non-org file, but **C-c a /**, it works well. I think this's OK enough if there is no more effective way to cope with. thank you. – Zoe Rowa Jan 24 '13 at 15:55
  • You should add it to `org-agenda-text-search-extra-files`, not `org-agenda-files`. Agenda files should always be org-mode files. Extra files can be any text file. – suvayu Jan 27 '13 at 13:09
  • Nice function. Though shouldn't that be `sa-find-org-file-recursively` instead of `find-org-file-recursively` in your example? – xji May 07 '15 at 05:02
  • 1
    @XiangJi Thanks. And indeed it should be `sa-*`. I changed my functions a few times. I guess I did not update the SO answer. – suvayu May 07 '15 at 09:29
  • avoid dot files and so "^[[:alnum:]].*\\.org\\'" is what you're looking for. – RichieHH Sep 03 '20 at 19:59
42

There is a simpler way of doing recursive search of org files (courtesy @xiaobing):

(setq org-agenda-files (directory-files-recursively "~/org/" "\\.org$"))

EDIT: You can also filter out certain directory from lookup by adding a array filter. Example, filtering out all org files in xxxx/xxx/daily/ directory:

(setq org-agenda-files 
      (seq-filter (lambda(x) (not (string-match "/daily/"(file-name-directory x)))) 
       (directory-files-recursively "~/Notes/roam" "\\.org$")
       ))

For Emacs <25, you can use find-lisp-find-files:

(load-library "find-lisp")
(setq org-agenda-files
   (find-lisp-find-files "FOLDERNAME" "\.org$"))
Mingwei Zhang
  • 663
  • 7
  • 15
  • 19
    found a similar way: `(setq org-agenda-files (directory-files-recursively "~/org/" "\.org$"))` , don't need `load-library` – xiaobing Jul 24 '18 at 03:11
  • 6
    +1 for @xiaobing's answer, with emacs 25 the directory-files-recursively works great. But CAUTION: the regexp for org files has a typo, so don't just copy and paste! Naturally, it should be "\\.org$"... – Nandan Rao Oct 31 '18 at 14:47
  • avoid dot files/backup files and so "^[[:alnum:]].*\\.org\\'" – RichieHH Sep 03 '20 at 19:59
  • I found your answer to be very helpful. Is it possible though to exclude a specific directory from being added to org-agena? I have a journal directory that contains a lot of files without any todo items in them, which slows down opening the agenda view significantly (multiple minutes of loading). – pfincent Jan 13 '21 at 01:30
  • 1
    @pfincent I have updated the answer to include a short snippet to hopefully resolve your issue. – Mingwei Zhang Jan 13 '21 at 13:46
  • this is the correct answer. a single line not an entirely new function – Andrew Luhring Jul 29 '21 at 05:18
  • This does not work if you create symbolic links. Any idea how to make org files that are symbolically linked? – rambalachandran Feb 06 '22 at 02:21