I have a contacts.org file whose structure looks like this :

* Contacts
** John DOE
** Alicia PING
** Bob DELTA

I'd like to be able to :

  • quickly set up a link to, for instance, Alicia PING, from a different org file;

  • quickly navigate to Bob DELTA from anywhere in Emacs.

  • in both cases, be able to do this with autocompletion (because I might not remember John's surname...)

How could I achieve this?

1 Answer 1


I could not find a way to do this in the manual, so I programmed a solution in 3 steps:

  1. Retrieve the headings of the org file contacts.org. Although a very simple requirement, no function seems to do that in the manual, so here's mine:
(defun get-headers (org-filename)
  "Get the headers of the org-file located at <org-filename>"
  (with-current-buffer (find-file-noselect org-filename)
    (let ((parsetree (org-element-parse-buffer 'headline))) 
      (org-element-map parsetree 'headline 
                   (lambda (hl) (org-element-property :title hl)))))) 

which you would call, for instance, with (get-headers "~/contacts.org") :

("Contact" "John DOE" "Alicia PING" "Bob DELTA").

  1. Building from that, here's how to create a quick link to a contact, from an org-file:
(defun link-to-contact ()
"Quickly insert a link to one of the contacts in ~/contacts.org, with autocompletion."
  (let ((contact 
     (completing-read "Link to contact: " (cdr (get-headers "~/contacts.org")))))
    (insert (format "[[file:~/contacts.org::*%s][%s]]" contact contact))))
  1. And here's how to quickly go there:
(defun goto-contact ()
"Quickly navigate to a contact in ~/contacs.org"
  (let ((contact 
     (completing-read "Go to contact: " (cdr (get-headers "~/contacts.org")))))
    (pop-to-buffer (find-file-noselect "~/contacts.org"))
    (search-forward (format "** %s" contact))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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