Function: org-store-link

org-store-link is an autoloaded, interactive and byte-compiled function defined in ol.el.gz.

Signature

(org-store-link ARG &optional INTERACTIVE?)

Documentation

Store a link to the current location.

This link is added to org-stored-links and can later be inserted into an Org buffer with org-insert-link (C-c C-l (org-insert-link)). When optional argument INTERACTIVE? is nil, the link is not stored in org-stored-links, but returned as a string.

For some link types, a C-u (universal-argument) prefix ARG is interpreted. A single C-u (universal-argument) negates org-link-context-for-files for file links or org-gnus-prefer-web-links for links to Usenet articles.

A C-u (universal-argument) C-u (universal-argument) prefix ARG forces skipping storing functions that are not part of Org core.

A C-u (universal-argument) C-u (universal-argument) C-u (universal-argument) prefix ARG forces storing a link for each line in the active region.

Assume the function is called interactively if INTERACTIVE? is non-nil.

In Org buffers, an additional "human-readable" simple file link is stored as an alternative to persistent org-id or other links, if at a heading with a CUSTOM_ID property or an element with a NAME.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/org/ol.el.gz
;;;###autoload
(defun org-store-link (arg &optional interactive?)
  "Store a link to the current location.
\\<org-mode-map>
This link is added to `org-stored-links' and can later be inserted
into an Org buffer with `org-insert-link' (`\\[org-insert-link]').
When optional argument INTERACTIVE? is nil, the link is not stored in
`org-stored-links', but returned as a string.

For some link types, a `\\[universal-argument]' prefix ARG is interpreted.  \
A single
`\\[universal-argument]' negates `org-link-context-for-files' for file links or
`org-gnus-prefer-web-links' for links to Usenet articles.

A `\\[universal-argument] \\[universal-argument]' prefix ARG forces \
skipping storing functions that are not
part of Org core.

A `\\[universal-argument] \\[universal-argument] \\[universal-argument]' \
prefix ARG forces storing a link for each line in the
active region.

Assume the function is called interactively if INTERACTIVE? is
non-nil.

In Org buffers, an additional \"human-readable\" simple file link
is stored as an alternative to persistent org-id or other links,
if at a heading with a CUSTOM_ID property or an element with a
NAME."
  (interactive "P\np")
  (org-load-modules-maybe)
  (if (and (equal arg '(64)) (org-region-active-p))
      (save-excursion
	(let ((end (region-end)))
	  (goto-char (region-beginning))
	  (set-mark (point))
          (while (< (line-end-position) end)
	    (move-end-of-line 1) (activate-mark)
	    (let (current-prefix-arg)
	      (call-interactively 'org-store-link))
	    (move-beginning-of-line 2)
	    (set-mark (point)))))
    (setq org-store-link-plist nil)
    ;; Negate `org-context-in-file-links' when given a single universal arg.
    (let ((org-link-context-for-files (org-xor org-link-context-for-files
                                               (equal arg '(4))))
          link desc search agenda-link) ;; description
      (cond
       ;; Store a link using an external link type, if any function is
       ;; available, unless external link types are skipped for this
       ;; call using two universal args.  If more than one function
       ;; can generate a link from current location, ask the user
       ;; which one to use.
       ((and (not (equal arg '(16)))
             (org-link--try-link-store-functions interactive?))
        (setq link (plist-get org-store-link-plist :link))
        ;; If store function actually set `:description' property, use
        ;; it, even if it is nil.  Otherwise, fallback to nil (ask user).
	(setq desc (plist-get org-store-link-plist :description)))

       ;; Store a link from a remote editing buffer.
       ((org-src-edit-buffer-p)
	(let ((coderef-format (org-src-coderef-format))
	      (format-link
	       (lambda (label)
		 (if org-src-source-file-name
		     (format "file:%s::(%s)" org-src-source-file-name label)
		   (format "(%s)" label)))))
	  (cond
	   ;; Code references do not exist in this type of buffer.
	   ;; Pretend we're linking from the source buffer directly.
	   ((not (memq (org-src-source-type) '(example-block src-block)))
	    (with-current-buffer (org-src-source-buffer)
	      (org-store-link arg interactive?))
	    (setq link nil))
	   ;; A code reference exists.  Use it.
	   ((save-excursion
	      (forward-line 0)
	      (re-search-forward (org-src-coderef-regexp coderef-format)
				 (line-end-position)
				 t))
	    (setq link (funcall format-link (match-string-no-properties 3))))
	   ;; No code reference.  Create a new one then store the link
	   ;; to it, but only in the function is called interactively.
	   (interactive?
	    (end-of-line)
	    (let* ((label (read-string "Code line label: "))
		   (reference (format coderef-format label))
		   (gc (- 79 (length reference))))
	      (if (< (current-column) gc)
		  (org-move-to-column gc t)
		(insert " "))
	      (insert reference)
	      (setq link (funcall format-link label))))
	   ;; No code reference, and non-interactive call.  Don't know
	   ;; what to do.  Give up.
	   (t (setq link nil)))))

       ;; We are in the agenda, link to referenced location
       ((eq major-mode 'org-agenda-mode)
	(let ((m (or (get-text-property (point) 'org-hd-marker)
		     (get-text-property (point) 'org-marker))))
	  (when m
	    (org-with-point-at m
	      (setq agenda-link (org-store-link nil interactive?))))))

       ;; Calendar mode
       ((eq major-mode 'calendar-mode)
	(let ((cd (calendar-cursor-to-date)))
	  (setq link
		(format-time-string
                 (org-time-stamp-format)
		 (org-encode-time 0 0 0 (nth 1 cd) (nth 0 cd) (nth 2 cd))))
	  (org-link-store-props :type "calendar" :date cd)))

       ;; Image mode
       ((eq major-mode 'image-mode)
	(setq link (concat "file:"
                           (abbreviate-file-name buffer-file-name)))
	(org-link-store-props :type "image" :file buffer-file-name))

       ;; In dired, store a link to the file of the current line
       ((derived-mode-p 'dired-mode)
	(let ((file (dired-get-filename nil t)))
	  (setq file (if file
			 (abbreviate-file-name
			  (expand-file-name (dired-get-filename nil t)))
		       ;; Otherwise, no file so use current directory.
		       default-directory))
	  (setq link (concat "file:" file))))

       ;; Try `org-create-file-search-functions`.  If any are
       ;; successful, create a file link to the current buffer with
       ;; the provided search string.
       ((setq search (run-hook-with-args-until-success
		      'org-create-file-search-functions))
	(setq link (concat "file:" (abbreviate-file-name buffer-file-name)
			   "::" search)
              desc (plist-get org-store-link-plist :description)))

       ;; Main logic for storing built-in link types in org-mode
       ;; buffers
       ((and (buffer-file-name (buffer-base-buffer)) (derived-mode-p 'org-mode))
	(org-with-limited-levels
	 (cond
	  ;; Store a link using the target at point
	  ((org-in-regexp "[^<]<<\\([^<>]+\\)>>[^>]" 1)
	   (setq link
		 (concat "file:"
			 (abbreviate-file-name
			  (buffer-file-name (buffer-base-buffer)))
			 "::" (match-string 1))
                 ;; Target may be shortened when link is inserted.
                 ;; Avoid [[target][file:~/org/test.org::target]]
                 ;; links.  Maybe the case of identical target and
                 ;; description should be handled by `org-insert-link'.
                 desc nil))
          (t
	   ;; Just link to current headline.
           (let ((here (org-link--file-link-to-here)))
             (setq link (car here))
             (setq desc (cdr here)))))))

       ;; Buffer linked to file, but not an org-mode buffer.
       ((buffer-file-name (buffer-base-buffer))
	;; Just link to this file here.
        (let ((here (org-link--file-link-to-here)))
          (setq link (car here))
          (setq desc (cdr here))))

       (interactive?
	(user-error "No method for storing a link from this buffer"))

       (t (setq link nil)))

      ;; We're done setting link and desc, clean up
      (when (consp link) (setq link (or (cdr link) (car link))))
      (cond ((not desc))
	    ((equal desc "NONE") (setq desc nil))
	    (t (setq desc (org-link-display-format desc))))
      ;; Store and return the link
      (if (not (and interactive? link))
	  (or agenda-link (and link (org-link-make-string link desc)))
        (org-link--add-to-stored-links link desc)
        ;; In org buffers, store an additional "human-readable" link
        ;; using custom id, if available.
        (when (and (buffer-file-name (buffer-base-buffer))
                   (derived-mode-p 'org-mode)
                   (org-entry-get nil "CUSTOM_ID"))
          (let ((here (org-link--file-link-to-here)))
            (setq link (car here))
            (setq desc (cdr here)))
          (unless (equal (list link desc) (car org-stored-links))
            (org-link--add-to-stored-links link desc)))
        (car org-stored-links)))))