summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Guerry <bzg@altern.org>2012-12-29 09:20:35 +0100
committerBastien Guerry <bzg@altern.org>2012-12-29 09:20:35 +0100
commit8477a4b215af642d64e51f23f8d1bb84e0253d40 (patch)
treeb3ebbdf6f213d2948803f039ecdd727d832599d4
parent43a242c44d6af058559b6d13fce3bb6c460edd1c (diff)
downloadorg-mode-8477a4b215af642d64e51f23f8d1bb84e0253d40.tar.gz
Allow to follow internal links from the agenda
* org-agenda.el (org-agenda-open-link): Allow to open an internal link by using the new `org-offer-links-in-entry' function. * org.el (org-offer-links-in-entry): Do not open the link directly through `org-open-link-from-string', only offer to select a link and return a cons with the link (as a string) and the end of entry. (org-open-at-point): Use `org-offer-links-in-entry' correctly. Thanks to Memnon Anon for reporting this.
-rw-r--r--lisp/org-agenda.el34
-rw-r--r--lisp/org.el127
2 files changed, 91 insertions, 70 deletions
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 68be0fe..2659a18 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -7892,23 +7892,39 @@ If this information is not given, the function uses the tree at point."
(unless no-update (org-agenda-redo))))
(defun org-agenda-open-link (&optional arg)
- "Follow the link in the current line, if any.
-This looks for a link in the displayed line in the agenda. It also looks
-at the text of the entry itself."
+ "Open the link(s) in the current entry, if any.
+This looks for a link in the displayed line in the agenda.
+It also looks at the text of the entry itself."
(interactive "P")
(let* ((marker (or (org-get-at-bol 'org-hd-marker)
(org-get-at-bol 'org-marker)))
(buffer (and marker (marker-buffer marker)))
(prefix (buffer-substring
- (point-at-bol) (point-at-eol))))
+ (point-at-bol) (point-at-eol)))
+ (lkall (org-offer-links-in-entry buffer marker arg prefix))
+ (lk (car lkall))
+ (lkend (cdr lkall))
+ trg)
(cond
(buffer
(with-current-buffer buffer
- (save-excursion
- (save-restriction
- (widen)
- (goto-char marker)
- (org-offer-links-in-entry arg prefix)))))
+ (setq trg (and (string-match org-bracket-link-regexp lk)
+ (match-string 1 lk)))
+ (if (or (not trg) (string-match org-any-link-re trg))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char marker)
+ (when (search-forward lk nil lkend)
+ (goto-char (match-beginning 0))
+ (org-open-at-point))))
+ ;; This is an internal link, widen the buffer
+ (switch-to-buffer-other-window buffer)
+ (widen)
+ (goto-char marker)
+ (when (search-forward lk nil lkend)
+ (goto-char (match-beginning 0))
+ (org-open-at-point)))))
((or (org-in-regexp (concat "\\(" org-bracket-link-regexp "\\)"))
(save-excursion
(beginning-of-line 1)
diff --git a/lisp/org.el b/lisp/org.el
index 6cf5b8d..14bb0d6 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -9648,7 +9648,13 @@ application the system uses for this file type."
org-angle-link-re "\\|"
"[ \t]:[^ \t\n]+:[ \t]*$")))
(not (get-text-property (point) 'org-linked-text)))
- (or (org-offer-links-in-entry arg)
+ (or (let* ((lkall (org-offer-links-in-entry (current-buffer) (point) arg))
+ (lk (car lkall))
+ (lkend (cdr lkall)))
+ (when lk
+ (prog1 (search-forward lk nil lkend)
+ (goto-char (match-beginning 0))
+ (org-open-at-point))))
(progn (require 'org-attach) (org-attach-reveal 'if-exists))))
((run-hook-with-args-until-success 'org-open-at-point-functions))
((and (org-at-timestamp-p t)
@@ -9844,68 +9850,67 @@ application the system uses for this file type."
(move-marker org-open-link-marker nil)
(run-hook-with-args 'org-follow-link-hook)))
-(defun org-offer-links-in-entry (&optional nth zero)
- "Offer links in the current entry and follow the selected link.
-If there is only one link, follow it immediately as well.
-If NTH is an integer, immediately pick the NTH link found.
+(defun org-offer-links-in-entry (buffer marker &optional nth zero)
+ "Offer links in the current entry and return the selected link.
+If there is only one link, return it.
+If NTH is an integer, return the NTH link found.
If ZERO is a string, check also this string for a link, and if
-there is one, offer it as link number zero."
- (let ((re (concat "\\(" org-bracket-link-regexp "\\)\\|"
- "\\(" org-angle-link-re "\\)\\|"
- "\\(" org-plain-link-re "\\)"))
- (cnt ?0)
- (in-emacs (if (integerp nth) nil nth))
- have-zero end links link c)
- (when (and (stringp zero) (string-match org-bracket-link-regexp zero))
- (push (match-string 0 zero) links)
- (setq cnt (1- cnt) have-zero t))
+there is one, return it."
+ (with-current-buffer buffer
(save-excursion
- (org-back-to-heading t)
- (setq end (save-excursion (outline-next-heading) (point)))
- (while (re-search-forward re end t)
- (push (match-string 0) links))
- (setq links (org-uniquify (reverse links))))
-
- (cond
- ((null links)
- (message "No links"))
- ((equal (length links) 1)
- (setq link (list (car links))))
- ((and (integerp nth) (>= (length links) (if have-zero (1+ nth) nth)))
- (setq link (list (nth (if have-zero nth (1- nth)) links))))
- (t ; we have to select a link
- (save-excursion
- (save-window-excursion
- (delete-other-windows)
- (with-output-to-temp-buffer "*Select Link*"
- (mapc (lambda (l)
- (if (not (string-match org-bracket-link-regexp l))
- (princ (format "[%c] %s\n" (incf cnt)
- (org-remove-angle-brackets l)))
- (if (match-end 3)
- (princ (format "[%c] %s (%s)\n" (incf cnt)
- (match-string 3 l) (match-string 1 l)))
- (princ (format "[%c] %s\n" (incf cnt)
- (match-string 1 l))))))
- links))
- (org-fit-window-to-buffer (get-buffer-window "*Select Link*"))
- (message "Select link to open, RET to open all:")
- (setq c (read-char-exclusive))
- (and (get-buffer "*Select Link*") (kill-buffer "*Select Link*"))))
- (when (equal c ?q) (error "Abort"))
- (if (equal c ?\C-m)
- (setq link links)
- (setq nth (- c ?0))
- (if have-zero (setq nth (1+ nth)))
- (unless (and (integerp nth) (>= (length links) nth))
- (error "Invalid link selection"))
- (setq link (list (nth (1- nth) links))))))
- (if link
- (let ((buf (current-buffer)))
- (dolist (l link)
- (org-open-link-from-string l in-emacs buf))
- t)
- nil)))
+ (save-restriction
+ (widen)
+ (goto-char marker)
+ (let ((re (concat "\\(" org-bracket-link-regexp "\\)\\|"
+ "\\(" org-angle-link-re "\\)\\|"
+ "\\(" org-plain-link-re "\\)"))
+ (cnt ?0)
+ (in-emacs (if (integerp nth) nil nth))
+ have-zero end links link c)
+ (when (and (stringp zero) (string-match org-bracket-link-regexp zero))
+ (push (match-string 0 zero) links)
+ (setq cnt (1- cnt) have-zero t))
+ (save-excursion
+ (org-back-to-heading t)
+ (setq end (save-excursion (outline-next-heading) (point)))
+ (while (re-search-forward re end t)
+ (push (match-string 0) links))
+ (setq links (org-uniquify (reverse links))))
+ (cond
+ ((null links)
+ (message "No links"))
+ ((equal (length links) 1)
+ (setq link (car links)))
+ ((and (integerp nth) (>= (length links) (if have-zero (1+ nth) nth)))
+ (setq link (nth (if have-zero nth (1- nth)) links)))
+ (t ; we have to select a link
+ (save-excursion
+ (save-window-excursion
+ (delete-other-windows)
+ (with-output-to-temp-buffer "*Select Link*"
+ (mapc (lambda (l)
+ (if (not (string-match org-bracket-link-regexp l))
+ (princ (format "[%c] %s\n" (incf cnt)
+ (org-remove-angle-brackets l)))
+ (if (match-end 3)
+ (princ (format "[%c] %s (%s)\n" (incf cnt)
+ (match-string 3 l) (match-string 1 l)))
+ (princ (format "[%c] %s\n" (incf cnt)
+ (match-string 1 l))))))
+ links))
+ (org-fit-window-to-buffer (get-buffer-window "*Select Link*"))
+ (message "Select link to open, RET to open all:")
+ (setq c (read-char-exclusive))
+ (and (get-buffer "*Select Link*") (kill-buffer "*Select Link*"))))
+ (when (equal c ?q) (error "Abort"))
+ (if (equal c ?\C-m)
+ (setq link links)
+ (setq nth (- c ?0))
+ (if have-zero (setq nth (1+ nth)))
+ (unless (and (integerp nth) (>= (length links) nth))
+ (error "Invalid link selection"))
+ (setq link (nth (1- nth) links)))))
+ (cons link end))))))
;; Add special file links that specify the way of opening