3

Assume that I have a hyperlink to a file in org-mode

- [[file:~/Documents/one_document.txt][this is a link to one file]]

And then for some reason I want to update the linked file to some other file using org-store-link.

After using C-c l, I move back to my org file(pre-existent link), I hit C-c C-l and would hope that UP, DOWN or M-p would show me stored links--but it doesn't! Even if I delete the pre-existent link I never get to see the *Org links* buffer.

From reading the documentation it seems that I should be able to see the stored links. If so, does anyone knows why I can't? Thank you in advance.

1 Answer 1

1

Unfortunately, org-insert-link (C-c C-l) on an existing link does not use org-stored-links, as you can see in its source:

;; Answers note: code taken from `org-insert-link' on commit ff8683aa35
    ...
    (cond
     (link-location)              ; specified by arg, just use it.
     ((org-in-regexp org-link-bracket-re 1)
      ;; We do have a link at point, and we are going to edit it.
      (setq remove (list (match-beginning 0) (match-end 0)))
      (setq desc (when (match-end 2) (match-string-no-properties 2)))
      (setq link (read-string "Link: "
                  (org-link-unescape
                   (match-string-no-properties 1)))))
    ...

Instead org-insert-link only uses read-string with your current link. However, we can use an advice to modify both org-stored-links as well as the current link:

(defun remove-link-and-mark-description (&rest args)
  "Removes the link at point and marks the description.

The previous link gets stored into `org-stored-links'. ARGS is unused"
  (cond
   ((org-in-regexp org-link-bracket-re 1)
    (let* ((link (match-string-no-properties 1))
           (desc (if (match-end 2) (match-string-no-properties 2) link))
           (deactivate-mark))
      (push (list (org-link-unescape link) desc) org-stored-links)
      (replace-match desc)
      (push-mark (match-beginning 0) t t)))
   (t nil)))

(advice-add 'org-insert-link :before #'remove-link-and-mark-description)

However, the code above is merely a proof of concept. There are some bugs, e.g. the stored link doesn't follow Org's usual file:... format if used on files, and push should probably get replaced by add-to-list.

6
  • I am surprised that this is not implemented by default. Your solution returned an error, so it might have to be slightly changed. I will give feedback as soon as possible.
    – Ajned
    Nov 15, 2020 at 14:18
  • @Ajned Which emacs-version and org-version do you use?
    – Zeta
    Nov 15, 2020 at 14:37
  • Indeed, I should have stated that right at the beginning. Emacs v26.3, Org mode v9.4. and the error is "Wrong number of arguments: (lambda nil "Removes the link at point and marks the description. The previous link gets stored into org-stored-links'." (cond ((org-in-regexp org-link-bracket-re 1) (let* ((link (match-string-no-properties 1)) (desc (if (match-end 2) (match-string-no-properties 2) link)) (deactivate-mark)) (setq org-stored-links (cons (list (org-link-unescape link) desc) org-stored-links)) (replace-match desc) (push-mark (match-beginning 0) t t))) (t nil))), 1"`
    – Ajned
    Nov 15, 2020 at 14:45
  • I can reproduce the error with Emacs v26.3, Org mode v9.1. It works fine on Emacs 27.1. There might have been some changes with advice-add. I'll check the NEWS.
    – Zeta
    Nov 15, 2020 at 14:47
  • @Ajned I'm not entirely sure why it's necessary in Emacs 26.3, but apparently remove-link-and-mark-description must take an argument in 26.3. &rest args makes sure that it works in both 26.3 and 27.1.
    – Zeta
    Nov 15, 2020 at 14:56

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.