16

Currently to insert internal org-mode org-id links, I navigate to a heading or pull it up in agenda view (C-a s heading test search RET), store the link with C-l (org-store-link), going back to where I want to insert the link, then insert the link with C-c C-l (org-insert-link).

Instead, I would prefer to map a key that allows me to insert a link at the current point using tab completion similar to org-refile (C-c C-w). The intended result would be an org-id internal link in the form:

[[id:d7534b2f-c221-4dea-8566-d5ce3e4e1b78][Example Link]]

Looking through org-id.el, it seems like org-id-get-with-outline-path-completion was designed for this purpose. I tried:

(global-set-key "\C-ci" (lambda () (interactive) (org-id-get-with-outline-path-completion)))

but it didn't work as intended.

I have the following in my init.el file:

;; Use global IDs
(require 'org-id)
(setq org-id-link-to-org-use-id t)

;; Update ID file .org-id-locations on startup
(org-id-update-id-locations)

;; Refile options
(setq org-refile-targets (quote ((nil :maxlevel . 9) (org-agenda-files :maxlevel . 9))))
(setq org-refile-use-outline-path 'file)
(setq org-outline-path-complete-in-steps t)
(setq org-refile-allow-creating-parent-nodes t)
6
  • You're missing a "-" in org-id-get-with outline-path-completion. Is that the problem?
    – erikstokes
    May 14, 2015 at 3:00
  • Unfortunately not--it was just a typographical error. I've updated the question.
    – sk8ingdom
    May 14, 2015 at 5:16
  • Too bad. How is it failing? It works when I try it.
    – erikstokes
    May 14, 2015 at 11:55
  • The function is definitely called. It prompts me for the entry, allows me to navigate via tab completion (which is great and works as intended), but when I hit enter, instead of pasting the link, it just moves the cursor to the the current headline, similar to C-c C-u (outline-up-heading).
    – sk8ingdom
    May 14, 2015 at 14:19
  • I thought this may have been caused by an outdated org version, but tried the most recent in Emacs 24.5 so it must be something in my configuration. Can anyone confirm that my code above actually inserts a link for them?
    – sk8ingdom
    May 14, 2015 at 18:18

1 Answer 1

12

I poked around in the org-mode source and found a minimally documented feature. If you define a function org-TYPE-complete-link, it will be used to provide completion for links of type TYPE. So we just need to define a function org-id-complete-link that does our completion and returns the link (including the "id:" prefix).

(defun org-id-complete-link (&optional arg)
  "Create an id: link using completion"
  (concat "id:"
          (org-id-get-with-outline-path-completion)))

Insert the link the normal way (with C-c C-l), select "id:" as the type and the completion function will fire.

EDIT: As of org-mode version 9.0 just defining the function as above above no longer works (ref). Instead you have to add the completion function to org-link-parameters using

(org-link-set-parameters "id"
                         :complete 'org-id-complete-link)
3
  • This is excellent and works as intended! The only modification I made was to add org-refile-targets as an argument to org-id-get-with-outline-path-completion. That way, I can can grab links from ANY of my org files. Thanks for your help!
    – sk8ingdom
    May 15, 2015 at 19:29
  • @sk8ingdom Can you update the question to include your final solution? I'm not sure what the doc means by TARGETS may be a setting for ‘org-refile-targets’ to define eligible headlines.
    – kshenoy
    Jan 14, 2018 at 16:08
  • 1
    The final solution is just to define the function above and also call org-link-set-parameters if you're using org-mode 9. The extra argument to org-id-get-with-outline-path-completion let's you limit the headlines you chose from just like org-refile-targets does when you refile. See the help for everything, but a common setting is ((org-agenda-files :maxlevel . 3) (nil :maxlevel . 2)) which limits to 3 levels deep in agenda files and 2 in the current buffer.
    – erikstokes
    Jan 14, 2018 at 16:42

Your Answer

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

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