From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Kitchin Subject: links-9.0 v3 Date: Wed, 06 Jul 2016 10:41:35 -0400 Message-ID: Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:45642) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bKo1K-0000CK-EV for emacs-orgmode@gnu.org; Wed, 06 Jul 2016 10:41:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bKo1E-0007L7-J2 for emacs-orgmode@gnu.org; Wed, 06 Jul 2016 10:41:45 -0400 Received: from mail-qt0-x22c.google.com ([2607:f8b0:400d:c0d::22c]:36535) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bKo1E-0007L0-9U for emacs-orgmode@gnu.org; Wed, 06 Jul 2016 10:41:40 -0400 Received: by mail-qt0-x22c.google.com with SMTP id w59so117490757qtd.3 for ; Wed, 06 Jul 2016 07:41:40 -0700 (PDT) Received: from Johns-MacBook-Air.local (KITCHIN-TIMEMACHINE.CHEME.CMU.EDU. [128.2.54.215]) by smtp.gmail.com with ESMTPSA id i22sm1148711qtc.18.2016.07.06.07.41.37 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Jul 2016 07:41:37 -0700 (PDT) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: "emacs-orgmode@gnu.org" I found some difficulties with the org-link-set-parameters you suggested Nick. Your version doesn't let you add properties to links with no existing properties, e.g. ("http") and it also didn't work as expected to set properties to nil. The current function is one you didn't like earlier with setf and cl-getf, but it does exactly what it should as far as I can tell. I also modified the org-open-at-point function so the http type of links with no :follow function work with it. These diffs pass all the tests for me except the two that don't pass on master either. I think I have squashed everything together that makes sense. Let me know if you have further thoughts. commit 92db211ca9f95d5624b83615c83c62d8c703ca00 Author: John Kitchin Date: Tue Jul 5 10:38:42 2016 -0400 Update the contrib manual diff --git a/contrib/orgmanual.org b/contrib/orgmanual.org index e48ae97..4346083 100644 --- a/contrib/orgmanual.org +++ b/contrib/orgmanual.org @@ -3300,12 +3300,16 @@ can define them in the file with ,#+LINK: google http://www.google.com/search?q=%s #+end_src -{{{noindent}}} In-buffer completion (see [[Completion]]) can be used after -{{{samp([)}}} to complete link abbreviations. You may also define a -function ~org-PREFIX-complete-link~ that implements special (e.g., -completion) support for inserting such a link with {{{kbd(C-c C-l)}}}. -Such a function should not accept any arguments, and return the full -link with prefix. +{{{noindent}}} In-buffer completion (see [[Completion]]) can be used +after {{{samp([)}}} to complete link abbreviations. You may also +define a function that implements special (e.g., completion) support +for inserting such a link with {{{kbd(C-c C-l)}}}. Such a function +should not accept any arguments, and return the full link with +prefix. You can set the link completion function like this: + +#+BEGIN_SRC emacs-lisp +(org-link-set-parameter "type" :complete 'some-completion-function) +#+END_SRC ** Search options :PROPERTIES: @@ -16998,10 +17002,9 @@ description when the link is later inserted into an Org buffer with {{{kbd(C-c C-l)}}}. When it makes sense for your new link type, you may also define a -function ~org-PREFIX-complete-link~ that implements special (e.g., -completion) support for inserting such a link with {{{kbd(C-c C-l)}}}. -Such a function should not accept any arguments, and return the full -link with prefix. +function that implements special (e.g., completion) support for +inserting such a link with {{{kbd(C-c C-l)}}}. Such a function should +not accept any arguments, and return the full link with prefix. ** Context-sensitive commands :PROPERTIES: @@ -19181,8 +19184,8 @@ from the list of stored links. To keep it in the list later use, use a triple {{{kbd(C-u)}}} prefix argument to {{{kbd(C-c C-l)}}}, or configure the option ~org-keep-stored-link-after-insertion~. -[fn:37] This works by calling a special function -~org-PREFIX-complete-link~. +[fn:37] This works if a function has been defined in the :complete +property of a link in org-link-parameters. [fn:38] See the variable ~org-display-internal-link-with-indirect-buffer~. commit 895d48e4d11abdd5994c0ac2d0074e0e7efd7533 Author: John Kitchin Date: Tue Jul 5 10:31:30 2016 -0400 Update NEWS with link announcement diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 9909910..6ff7442 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -353,6 +353,8 @@ first footnote. *** The ~org-block~ face is inherited by ~src-blocks~ This works also when =org-src-fontify-natively= is non-nil. It is also possible to specify per-languages faces. See the manual for details. +*** Links are now customizable +Links can now have custom colors, tooltips, keymaps, display behavior, etc... Links are now centralized in ~org-link-parameters~. ** New functions *** ~org-next-line-empty-p~ It replaces the deprecated ~next~ argument to ~org-previous-line-empty-p~. commit c9f14fa9541139c5700ef0e7a522c837411fafc7 Author: John Kitchin Date: Tue Jul 5 10:29:07 2016 -0400 Update the texinfo for link parameters documentation diff --git a/doc/org.texi b/doc/org.texi index e92788f..aa552fc 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -3711,11 +3711,11 @@ them with @key{up} and @key{down} (or @kbd{M-p/n}). valid link prefixes like @samp{http:} or @samp{ftp:}, including the prefixes defined through link abbreviations (@pxref{Link abbreviations}). If you press @key{RET} after inserting only the @var{prefix}, Org will offer -specific completion support for some link types@footnote{This works by -calling a special function @code{org-PREFIX-complete-link}.} For -example, if you type @kbd{file @key{RET}}, file name completion (alternative -access: @kbd{C-u C-c C-l}, see below) will be offered, and after @kbd{bbdb -@key{RET}} you can complete contact names. +specific completion support for some link types@footnote{This works if a +completion function is defined in the :complete property of a link in +@var{org-link-parameters}.} For example, if you type @kbd{file @key{RET}}, +file name completion (alternative access: @kbd{C-u C-c C-l}, see below) will +be offered, and after @kbd{bbdb @key{RET}} you can complete contact names. @orgkey C-u C-c C-l @cindex file name completion @cindex completion, of file names @@ -3887,10 +3887,13 @@ can define them in the file with @noindent In-buffer completion (@pxref{Completion}) can be used after @samp{[} to -complete link abbreviations. You may also define a function -@code{org-PREFIX-complete-link} that implements special (e.g., completion) -support for inserting such a link with @kbd{C-c C-l}. Such a function should -not accept any arguments, and return the full link with prefix. +complete link abbreviations. You may also define a function that implements +special (e.g., completion) support for inserting such a link with @kbd{C-c +C-l}. Such a function should not accept any arguments, and return the full +link with prefix. You can add a completion function to a link like this: + +@code{(org-link-set-parameters ``type'' :complete 'some-function)} + @node Search options @section Search options in file links @@ -18005,9 +18008,9 @@ the link description when the link is later inserted into an Org buffer with @kbd{C-c C-l}. When it makes sense for your new link type, you may also define a function -@code{org-PREFIX-complete-link} that implements special (e.g., completion) -support for inserting such a link with @kbd{C-c C-l}. Such a function should -not accept any arguments, and return the full link with prefix. +that implements special (e.g., completion) support for inserting such a link +with @kbd{C-c C-l}. Such a function should not accept any arguments, and +return the full link with prefix. @node Adding export back-ends @section Adding export back-ends commit 8ccffad6875514c908f2aa34aed7b14117ecd4b4 Author: John Kitchin Date: Tue Jul 5 16:11:08 2016 -0400 Update the "id" link with org-link-set-parameters * lisp/org-id.el: diff --git a/lisp/org-id.el b/lisp/org-id.el index 2646c80..c517034 100644 --- a/lisp/org-id.el +++ b/lisp/org-id.el @@ -675,7 +675,7 @@ optional argument MARKERP, return the position as a new marker." (move-marker m nil) (org-show-context))) -(org-add-link-type "id" 'org-id-open) +(org-link-set-parameters "id" :follow 'org-id-open) (provide 'org-id) commit 92b5a3d5a0d95040d8790a531893eda04a100b87 Author: John Kitchin Date: Tue Jul 5 10:28:38 2016 -0400 Update w3m link definition * lisp/org-w3m.el ("w3m"): diff --git a/lisp/org-w3m.el b/lisp/org-w3m.el index 57ecafe..97b9841 100644 --- a/lisp/org-w3m.el +++ b/lisp/org-w3m.el @@ -46,7 +46,7 @@ (defvar w3m-current-url) (defvar w3m-current-title) -(add-hook 'org-store-link-functions 'org-w3m-store-link) +(org-link-set-parameters "w3m" :store 'org-w3m-store-link) (defun org-w3m-store-link () "Store a link to a w3m buffer." (when (eq major-mode 'w3m-mode) commit cbf9a8f841852debe3d30c98d8d0298a4344597f Author: John Kitchin Date: Tue Jul 5 10:28:09 2016 -0400 Update rmail link definition * lisp/org-rmail.el ("rmail"): Use org-link-set-parameters to define link. diff --git a/lisp/org-rmail.el b/lisp/org-rmail.el index 0bf44b8..7ceb972 100644 --- a/lisp/org-rmail.el +++ b/lisp/org-rmail.el @@ -43,8 +43,7 @@ (defvar rmail-file-name) ; From rmail.el ;; Install the link type -(org-add-link-type "rmail" 'org-rmail-open) -(add-hook 'org-store-link-functions 'org-rmail-store-link) +(org-link-set-parameters "rmail" :follow 'org-rmail-open :store 'org-rmail-store-link) ;; Implementation (defun org-rmail-store-link () commit e0f221ca4923dc90057a4e98f36e941af43eb754 Author: John Kitchin Date: Tue Jul 5 10:27:55 2016 -0400 Update mhe link definition. * lisp/org-mhe.el ("mhe"): Define link with org-link-set-parameters. diff --git a/lisp/org-mhe.el b/lisp/org-mhe.el index 2ee21de..773bcfd 100644 --- a/lisp/org-mhe.el +++ b/lisp/org-mhe.el @@ -74,8 +74,7 @@ supported by MH-E." (defvar mh-search-regexp-builder) ;; Install the link type -(org-add-link-type "mhe" 'org-mhe-open) -(add-hook 'org-store-link-functions 'org-mhe-store-link) +(org-link-set-parameters "mhe" :follow 'org-mhe-open :store 'org-mhe-store-link) ;; Implementation (defun org-mhe-store-link () commit 911d29e8f7e0c68dd9a48e4d1df335804ce10c0a Author: John Kitchin Date: Tue Jul 5 10:27:45 2016 -0400 Update irc link definition * lisp/org-irc.el ("irc"): Define link with org-link-set-parameters. diff --git a/lisp/org-irc.el b/lisp/org-irc.el index 81d0296..afb24c1 100644 --- a/lisp/org-irc.el +++ b/lisp/org-irc.el @@ -71,9 +71,7 @@ ;; Generic functions/config (extend these for other clients) -(add-to-list 'org-store-link-functions 'org-irc-store-link) - -(org-add-link-type "irc" 'org-irc-visit nil) +(org-link-set-parameters "irc" :follow 'org-irc-visit :store 'org-irc-store-link) (defun org-irc-visit (link) "Parse LINK and dispatch to the correct function based on the client found." commit e54fd15f09bf6f8f9ec1f959c04c57bf791ef9a8 Author: John Kitchin Date: Tue Jul 5 10:27:32 2016 -0400 Update info link definition * lisp/org-info.el ("info"): Update link definition with org-link-set-parameters and change a doc string to point to org-link-parameters. diff --git a/lisp/org-info.el b/lisp/org-info.el index 9e8fde0..0e9c43e 100644 --- a/lisp/org-info.el +++ b/lisp/org-info.el @@ -40,8 +40,8 @@ (defvar Info-current-node) ;; Install the link type -(org-add-link-type "info" 'org-info-open 'org-info-export) -(add-hook 'org-store-link-functions 'org-info-store-link) +(org-link-set-parameters "info" :follow 'org-info-open + :export 'org-info-export :store 'org-info-store-link) ;; Implementation (defun org-info-store-link () @@ -113,7 +113,7 @@ emacs related documents. See `org-info-official-gnu-document' and (defun org-info-export (path desc format) "Export an info link. -See `org-add-link-type' for details about PATH, DESC and FORMAT." +See `org-link-parameters' for details about PATH, DESC and FORMAT." (when (eq format 'html) (or (string-match "\\(.*\\)[#:]:?\\(.*\\)" path) (string-match "\\(.*\\)" path)) commit 8b6efc2cbed244f88d0c76857c0893ba8e5c1652 Author: John Kitchin Date: Tue Jul 5 10:27:14 2016 -0400 Update gnus link definition * lisp/org-gnus.el ("gnus"): Update link definition with org-link-set-parameters. diff --git a/lisp/org-gnus.el b/lisp/org-gnus.el index 386d6dc..8544f75 100644 --- a/lisp/org-gnus.el +++ b/lisp/org-gnus.el @@ -74,8 +74,7 @@ this variable to t." :type 'boolean) ;; Install the link type -(org-add-link-type "gnus" 'org-gnus-open) -(add-hook 'org-store-link-functions 'org-gnus-store-link) +(org-link-set-parameters "gnus" :follow 'org-gnus-open :store 'org-gnus-store-link) ;; Implementation commit 7b7d72a7ee8a5e7ffeac72c13299dc10c28700e4 Author: John Kitchin Date: Tue Jul 5 10:27:03 2016 -0400 Update eshell link definition * lisp/org-eshell.el ("eshell"): Update to use org-link-set-parameters. diff --git a/lisp/org-eshell.el b/lisp/org-eshell.el index 1919f6d..76b315e 100644 --- a/lisp/org-eshell.el +++ b/lisp/org-eshell.el @@ -27,8 +27,9 @@ (require 'eshell) (require 'esh-mode) -(org-add-link-type "eshell" 'org-eshell-open) -(add-hook 'org-store-link-functions 'org-eshell-store-link) +(org-link-set-parameters "eshell" + :follow 'org-eshell-open + :store 'org-eshell-store-link) (defun org-eshell-open (link) "Switch to am eshell buffer and execute a command line. commit 0e8e2bf92c80193871e21db14321b96747e66799 Author: John Kitchin Date: Tue Jul 5 10:26:28 2016 -0400 Update docview link definition * lisp/org-docview.el ("docview"): Update link definition with org-link-set-parameters. diff --git a/lisp/org-docview.el b/lisp/org-docview.el index fbc5551..e6404aa 100644 --- a/lisp/org-docview.el +++ b/lisp/org-docview.el @@ -49,8 +49,10 @@ (declare-function doc-view-goto-page "doc-view" (page)) (declare-function image-mode-window-get "image-mode" (prop &optional winprops)) -(org-add-link-type "docview" 'org-docview-open 'org-docview-export) -(add-hook 'org-store-link-functions 'org-docview-store-link) +(org-link-set-parameters "docview" + :follow 'org-docview-open + :export 'org-docview-export + :store 'org-docview-store-link) (defun org-docview-export (link description format) "Export a docview link from Org files." commit fcc50021304aafc0b4ee4beb2c4ad0a8c20a727f Author: John Kitchin Date: Tue Jul 5 10:26:04 2016 -0400 Update bibtex link definition * lisp/org-bibtex.el ("bibtex"): Change link definition to use org-link-set-parameters diff --git a/lisp/org-bibtex.el b/lisp/org-bibtex.el index 74e32f7..479422b 100644 --- a/lisp/org-bibtex.el +++ b/lisp/org-bibtex.el @@ -452,8 +452,7 @@ With optional argument OPTIONAL, also prompt for optional fields." ;;; Bibtex link functions -(org-add-link-type "bibtex" 'org-bibtex-open) -(add-hook 'org-store-link-functions 'org-bibtex-store-link) +(org-link-set-parameters "bibtex" :follow 'org-bibtex-open nil :store 'org-bibtex-store-link) (defun org-bibtex-open (path) "Visit the bibliography entry on PATH." commit 4d0ebc81021e967167c2453a1ce449b35487f87d Author: John Kitchin Date: Tue Jul 5 10:25:39 2016 -0400 Update bbdb link definition * lisp/org-bbdb.el ("bbdb"): Change link definition to org-link-set-parameters diff --git a/lisp/org-bbdb.el b/lisp/org-bbdb.el index 8d886cd..4af71fb 100644 --- a/lisp/org-bbdb.el +++ b/lisp/org-bbdb.el @@ -194,10 +194,10 @@ date year)." :group 'org-bbdb-anniversaries :require 'bbdb) - ;; Install the link type -(org-add-link-type "bbdb" 'org-bbdb-open 'org-bbdb-export) -(add-hook 'org-store-link-functions 'org-bbdb-store-link) +(org-link-set-parameters "bbdb" :follow 'org-bbdb-open :export 'org-bbdb-export + :complete 'org-bbdb-complete-link + :store 'org-bbdb-store-link) ;; Implementation (defun org-bbdb-store-link () commit bf2f7f346aa503395553f7b9cf7078419c688708 Author: John Kitchin Date: Tue Jul 5 10:22:24 2016 -0400 Make plain and bracketed link properties stick * lisp/org.el (org-set-font-lock-defaults): If t is after the face, than org-link clobbers everything from the activation functions. diff --git a/lisp/org.el b/lisp/org.el index 2c59012..cf39f79 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -6525,8 +6525,8 @@ needs to be inserted at a specific position in the font-lock sequence.") ;; Links (when (memq 'tag lk) '(org-activate-tags (1 'org-tag prepend))) (when (memq 'angle lk) '(org-activate-angle-links (0 'org-link t))) - (when (memq 'plain lk) '(org-activate-plain-links (0 'org-link t))) - (when (memq 'bracket lk) '(org-activate-bracket-links (0 'org-link t))) + (when (memq 'plain lk) '(org-activate-plain-links (0 'org-link))) + (when (memq 'bracket lk) '(org-activate-bracket-links (0 'org-link))) (when (memq 'radio lk) '(org-activate-target-links (1 'org-link t))) (when (memq 'date lk) '(org-activate-dates (0 'org-date t))) (when (memq 'footnote lk) '(org-activate-footnote-links)) commit 6f1fa7cd0200bc1f4c614f7e2522892ac751870f Author: John Kitchin Date: Tue Jul 5 10:21:50 2016 -0400 Update `org-activate-bracket-links' * lisp/org.el (org-activate-bracket-links): Use `org-link-parameters' to build link properties. diff --git a/lisp/org.el b/lisp/org.el index aafe1ec..2c59012 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -6170,14 +6170,69 @@ by a #." (when (and (re-search-forward org-bracket-link-regexp limit t) (not (org-in-src-block-p))) (let* ((hl (match-string-no-properties 1)) - (help (concat "LINK: " (save-match-data (org-link-unescape hl)))) - (ip (list 'invisible 'org-link - 'keymap org-mouse-map 'mouse-face 'highlight - 'font-lock-multiline t 'help-echo help - 'htmlize-link `(:uri ,hl))) - (vp (list 'keymap org-mouse-map 'mouse-face 'highlight - 'font-lock-multiline t 'help-echo help - 'htmlize-link `(:uri ,hl)))) + (type (save-match-data + (if (string-match org-plain-link-re hl) + (match-string-no-properties 1 hl) + nil))) + (path (save-match-data + (if (string-match org-plain-link-re hl) + (match-string-no-properties 2 hl) + nil))) + (link-start (match-beginning 0)) + (link-end (match-end 0)) + (bracketp t) + (help-echo (org-link-get-parameter type :help-echo)) + (help (cond + ((stringp help-echo) + help-echo) + ((functionp help-echo) + help-echo) + (t + (concat "LINK: " + (save-match-data + (org-link-unescape hl)))))) + (link-face (org-link-get-parameter type :face)) + (face (cond + ;; A function that returns a face + ((functionp link-face) + (funcall link-face path)) + ;; a face + ((facep link-face) + link-face) + ;; An anonymous face + ((consp link-face) + link-face) + ;; default + (t + 'org-link))) + (keymap (or (org-link-get-parameter type :keymap) + org-mouse-map)) + (mouse-face (or (org-link-get-parameter type :mouse-face) + 'highlight)) + (htmlize (org-link-get-parameter type :htmlize-link)) + (htmlize-link (cond + ((functionp htmlize) + (funcall htmlize)) + (t + `(:uri ,(format "%s:%s" type path))))) + (activate-func (org-link-get-parameter type :activate-func)) + ;; invisible part + (ip (list 'invisible (or + (org-link-get-parameter type :display) + 'org-link) + 'face face + 'keymap keymap + 'mouse-face mouse-face + 'font-lock-multiline t + 'help-echo help + 'htmlize-link htmlize-link)) + ;; visible part + (vp (list 'keymap keymap + 'face face + 'mouse-face mouse-face + 'font-lock-multiline t + 'help-echo help + 'htmlize-link htmlize-link))) ;; We need to remove the invisible property here. Table narrowing ;; may have made some of this invisible. (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0)) @@ -6197,6 +6252,8 @@ by a #." (org-rear-nonsticky-at (match-end 1)) (add-text-properties (match-end 1) (match-end 0) ip) (org-rear-nonsticky-at (match-end 0))) + (when activate-func + (funcall activate-func link-start link-end path bracketp)) t))) (defun org-activate-dates (limit) commit f68da27b80b50bd548123f906db15fb36fcf971b Author: John Kitchin Date: Tue Jul 5 10:21:08 2016 -0400 Update `org-activate-plain-links' * lisp/org.el (org-activate-plain-links): Use `org-link-parameters' to create the link properties. diff --git a/lisp/org.el b/lisp/org.el index d17cc3a..aafe1ec 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -5930,17 +5930,57 @@ prompted for." "Add link properties for plain links." (when (and (re-search-forward org-plain-link-re limit t) (not (org-in-src-block-p))) - (let ((face (get-text-property (max (1- (match-beginning 0)) (point-min)) - 'face)) - (link (match-string-no-properties 0))) + + (let* ((face (get-text-property (max (1- (match-beginning 0)) (point-min)) + 'face)) + (link (match-string-no-properties 0)) + (type (match-string-no-properties 1)) + (path (match-string-no-properties 2)) + (link-start (match-beginning 0)) + (link-end (match-end 0)) + (link-face (org-link-get-parameter type :face)) + (help-echo (org-link-get-parameter type :help-echo)) + (htmlize-link (org-link-get-parameter type :htmlize-link)) + (activate-func (org-link-get-parameter type :activate-func))) (unless (if (consp face) (memq 'org-tag face) (eq 'org-tag face)) (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0)) (add-text-properties (match-beginning 0) (match-end 0) - (list 'mouse-face 'highlight - 'face 'org-link - 'htmlize-link `(:uri ,link) - 'keymap org-mouse-map)) + (list + 'mouse-face (or (org-link-get-parameter type :mouse-face) + 'highlight) + 'face (cond + ;; A function that returns a face + ((functionp link-face) + (funcall link-face path)) + ;; a face + ((facep link-face) + link-face) + ;; An anonymous face + ((consp link-face) + link-face) + ;; default + (t + 'org-link)) + 'help-echo (cond + ((stringp help-echo) + help-echo) + ((functionp help-echo) + help-echo) + (t + (concat "LINK: " + (save-match-data + (org-link-unescape link))))) + 'htmlize-link (cond + ((functionp htmlize-link) + (funcall htmlize-link path)) + (t + `(:uri ,link))) + 'keymap (or (org-link-get-parameter type :keymap) + org-mouse-map) + 'org-link-start (match-beginning 0))) (org-rear-nonsticky-at (match-end 0)) + (when activate-func + (funcall activate-func link-start link-end path nil)) t)))) (defun org-activate-code (limit) commit 40335d32f1ce2031c3b2caf7c8d6ef400389f660 Author: John Kitchin Date: Tue Jul 5 10:20:23 2016 -0400 Get the complete function from org-link-parameters * lisp/org.el (org-link-try-special-completion): Get the follow function from org-link-parameters Only follow when a function is defined. * lisp/org.el (org-open-at-point): Some links don't have a :follow function, so we should not call nil in that case. diff --git a/lisp/org.el b/lisp/org.el index cd9a757..d17cc3a 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -10492,7 +10492,7 @@ Use TAB to complete link prefixes, then RET for type-specific completion support (defun org-link-try-special-completion (type) "If there is completion support for link type TYPE, offer it." - (let ((fun (intern (concat "org-" type "-complete-link")))) + (let ((fun (org-link-get-parameter type :complete))) (if (functionp fun) (funcall fun) (read-string "Link (no completion support): " (concat type ":"))))) @@ -10799,7 +10799,8 @@ link in a property drawer line." (list (string-to-number option))) (t (list nil (org-link-unescape option))))))))) - ((assoc type org-link-parameters) + ((and (assoc type org-link-parameters) + (functionp (org-link-get-parameter type :follow))) (funcall (org-link-get-parameter type :follow) path)) ((equal type "help") (let ((f-or-v (intern path))) commit 7d576c994c5ea20333837502aa4f2ef93df07f15 Author: John Kitchin Date: Tue Jul 5 10:19:52 2016 -0400 Replace org-store-link-functions variable with function * lisp/org.el: Replace the variable `org-store-link-functions' with a function by the same name. diff --git a/lisp/org.el b/lisp/org.el index 5d17319..cd9a757 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -9827,7 +9827,7 @@ active region." (delq nil (mapcar (lambda (f) (let (fs) (if (funcall f) (push f fs)))) - org-store-link-functions)) + (org-store-link-functions))) sfunsn (mapcar (lambda (fu) (symbol-name (car fu))) sfuns)) (or (and (cdr sfuns) (funcall (intern commit 0a9aa544b3766be615c5d931e6133e884334d014 Author: John Kitchin Date: Tue Jul 5 10:18:57 2016 -0400 Update org-add-link-type * lisp/org.el org-add-link-type: deprecated and now calls `org-link-add'. Create a new `org-link-add' function for making links. diff --git a/lisp/org-compat.el b/lisp/org-compat.el index 92fdb1c..a856ff7 100644 --- a/lisp/org-compat.el +++ b/lisp/org-compat.el @@ -374,6 +374,37 @@ Implements `define-error' for older emacsen." (put name 'error-conditions (copy-sequence (cons name (get 'error 'error-conditions)))))) +(defun org-add-link-type (type &optional follow export) + "Add a new TYPE link. +FOLLOW and EXPORT are two functions. + +FOLLOW should take the link path as the single argument and do whatever +is necessary to follow the link, for example find a file or display +a mail message. + +EXPORT should format the link path for export to one of the export formats. +It should be a function accepting three arguments: + + path the path of the link, the text after the prefix (like \"http:\") + desc the description of the link, if any + format the export format, a symbol like `html' or `latex' or `ascii'. + +The function may use the FORMAT information to return different values +depending on the format. The return value will be put literally into +the exported file. If the return value is nil, this means Org should +do what it normally does with links which do not have EXPORT defined. + +Org mode has a built-in default for exporting links. If you are happy with +this default, there is no need to define an export function for the link +type. For a simple example of an export function, see `org-bbdb.el'. + +If TYPE already exists, update it with the arguments. +See `org-link-parameters' for documentation on the other parameters." + (org-link-add type :follow follow :export export) + (message "Created %s link." type)) + +(make-obsolete 'org-add-link-type "org-link-add." "Org 9.0") + (provide 'org-compat) ;;; org-compat.el ends here diff --git a/lisp/org.el b/lisp/org.el index c5cefe9..5d17319 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -9752,37 +9752,37 @@ Special properties are: In addition to these, any additional properties can be specified and then used in capture templates.") -(defun org-add-link-type (type &optional follow export) - "Add TYPE to the list of `org-link-types'. -Re-compute all regular expressions depending on `org-link-types' - -FOLLOW and EXPORT are two functions. - -FOLLOW should take the link path as the single argument and do whatever -is necessary to follow the link, for example find a file or display -a mail message. - -EXPORT should format the link path for export to one of the export formats. -It should be a function accepting three arguments: - - path the path of the link, the text after the prefix (like \"http:\") - desc the description of the link, if any - format the export format, a symbol like `html' or `latex' or `ascii'. - -The function may use the FORMAT information to return different values -depending on the format. The return value will be put literally into -the exported file. If the return value is nil, this means Org should -do what it normally does with links which do not have EXPORT defined. - -Org mode has a built-in default for exporting links. If you are happy with -this default, there is no need to define an export function for the link -type. For a simple example of an export function, see `org-bbdb.el'." - (add-to-list 'org-link-types type t) - (org-make-link-regexps) - (org-element-update-syntax) - (if (assoc type org-link-protocols) - (setcdr (assoc type org-link-protocols) (list follow export)) - (push (list type follow export) org-link-protocols))) + +(defun org-store-link-functions () + "Returns a list of functions that are called to create and store a link. +The functions in the variable `org-store-link-functions' come +first. These may be user-defined for different contexts. Then +comes the functions defined in the :store property of +org-link-parameters. + +Each function will be called in turn until one returns a non-nil +value. Each function should check if it is responsible for +creating this link (for example by looking at the major mode). If +not, it must exit and return nil. If yes, it should return a +non-nil value after a calling `org-store-link-props' with a list +of properties and values. Special properties are: + +:type The link prefix, like \"http\". This must be given. +:link The link, like \"http://www.astro.uva.nl/~dominik\". + This is obligatory as well. +:description Optional default description for the second pair + of brackets in an Org-mode link. The user can still change + this when inserting this link into an Org-mode buffer. + +In addition to these, any additional properties can be specified +and then used in capture templates." + (append + org-store-link-functions + (cl-loop for link in org-link-parameters + with store-func + do (setq store-func (org-link-get-parameter (car link) :store)) + if store-func + collect store-func))) (defvar org-agenda-buffer-name) ; Defined in org-agenda.el (defvar org-id-link-to-org-use-id) ; Defined in org-id.el commit 99ca54d058d178d0e6d4cf67fe0016422ddf2254 Author: John Kitchin Date: Tue Jul 5 10:16:38 2016 -0400 Remove `org-link-protocols' * lisp/org.el (org-link-protocols): Remove variable. The data in this variable is now retrieved with org-link-get-parameter. diff --git a/lisp/org.el b/lisp/org.el index 3991179..c5cefe9 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -9732,9 +9732,6 @@ The refresh happens only for the current tree (not subtree)." (defvar org-store-link-plist nil "Plist with info about the most recently link created with `org-store-link'.") -(defvar org-link-protocols nil - "Link protocols added to Org-mode using `org-add-link-type'.") - (defvar org-store-link-functions nil "List of functions that are called to create and store a link. Each function will be called in turn until one returns a non-nil @@ -10773,7 +10770,7 @@ link in a property drawer line." ((equal type "file") (if (string-match "[*?{]" (file-name-nondirectory path)) (dired path) - ;; Look into `org-link-protocols' in order to find + ;; Look into `org-link-parameters' in order to find ;; a DEDICATED-FUNCTION to open file. The function ;; will be applied on raw link instead of parsed ;; link due to the limitation in `org-add-link-type' @@ -10787,7 +10784,7 @@ link in a property drawer line." (let* ((option (org-element-property :search-option link)) (app (org-element-property :application link)) (dedicated-function - (nth 1 (assoc app org-link-protocols)))) + (org-link-get-parameter type :follow))) (if dedicated-function (funcall dedicated-function (concat path @@ -10802,8 +10799,8 @@ link in a property drawer line." (list (string-to-number option))) (t (list nil (org-link-unescape option))))))))) - ((assoc type org-link-protocols) - (funcall (nth 1 (assoc type org-link-protocols)) path)) + ((assoc type org-link-parameters) + (funcall (org-link-get-parameter type :follow) path)) ((equal type "help") (let ((f-or-v (intern path))) (cond ((fboundp f-or-v) (describe-function f-or-v)) @@ -10852,7 +10849,7 @@ link in a property drawer line." (user-error "Abort")))) ((equal type "id") (require 'org-id) - (funcall (nth 1 (assoc "id" org-link-protocols)) path)) + (funcall (org-link-get-parameter type :follow) path)) ((member type '("coderef" "custom-id" "fuzzy" "radio")) (unless (run-hook-with-args-until-success 'org-open-link-functions path) diff --git a/lisp/ox.el b/lisp/ox.el index 3986ec3..8472e9d 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -4116,7 +4116,7 @@ The function ignores links with an implicit type (e.g., (let ((type (org-element-property :type link))) (unless (or (member type '("coderef" "custom-id" "fuzzy" "radio")) (not backend)) - (let ((protocol (nth 2 (assoc type org-link-protocols)))) + (let ((protocol (org-link-get-parameter type :export))) (and (functionp protocol) (funcall protocol (org-link-unescape (org-element-property :path link)) commit af23bca77b45ca13da9be0bece36e935b0f2c6d6 Author: John Kitchin Date: Tue Jul 5 10:08:14 2016 -0400 Add org-link-parameters * lisp/org.el (org-link-parameters): Add new centralized link variable. (org-link-get-parameter): A getter function to get link parameters. (org-link-set-parameters): A setter function to set link parameters or add new ones. (org-link-types): A function to return a list of link types. * lisp/ox.el: update comment for this new variable. * testing/lisp/test-ox.el :Update tests to take out org-link-types and use org-link-set-parameters. diff --git a/lisp/org.el b/lisp/org.el index c875d03..3991179 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -1758,6 +1758,75 @@ calls `table-recognize-table'." "Buffer-local version of `org-link-abbrev-alist', which see. The value of this is taken from the #+LINK lines.") +(defcustom org-link-parameters + '(("http") ("https") ("ftp") ("mailto") + ("file" :complete 'org-file-complete-link) + ("file+emacs") ("file+sys") + ("news") ("shell") ("elisp") + ("doi") ("message") ("help")) + "An alist of properties that defines all the links in Org mode. +The key in each association is a string of the link type. +Subsequent optional elements make up a p-list of link properties. + +:follow - A function that takes the link path as an argument. + +:export - A function that takes the link path, description and +export-backend as arguments. + +:store - A function responsible for storing the link. See the +variable `org-store-link-functions'. + +:complete - A function that inserts a link with completion. The +function takes one optional prefix arg. + +:face - A face for the link, or a function that returns a face. +The function takes one argument which is the link path. The +default face is `org-link'. + +:mouse-face - The mouse-face. The default is `highlight'. + +:display - `full' will not fold the link in descriptive +display. Default is `org-link'. + +:help-echo - A string or function that takes (window object position) +as args and returns a string. + +:keymap - A keymap that is active on the link. The default is +`org-mouse-map'. + +:htmlize-link - A function for the htmlize-link. Defaults +to (list :uri \"type:path\") + +:activate-func - A function to run at the end of font-lock +activation. The function must accept (link-start link-end path bracketp) +as arguments." + :group 'org-link + :type '(alist :tag "Link display paramters" + :value-type (plist))) + +(defun org-link-get-parameter (type key) + "Get TYPE link property for KEY." + (plist-get + (cdr (assoc type org-link-parameters)) + key)) + +(defun org-link-set-parameters (type &rest parameters) + "Set link TYPE properties to PARAMETERS. + PARAMETERS should be :key val pairs." + (let ((data (assoc type org-link-parameters))) + (if data + (cl-loop for (key val) on parameters by #'cddr + do + (setf (cl-getf (cdr data) key) + val)) + (push (cons type parameters) org-link-parameters) + (org-make-link-regexps) + (org-element-update-syntax)))) + +(defun org-link-types () + "Returns a list of known link types." + (mapcar #'car org-link-parameters)) + (defcustom org-link-abbrev-alist nil "Alist of link abbreviations. The car of each element is a string, to be replaced at the start of a link. @@ -5490,7 +5559,7 @@ The following commands are available: org-display-table 4 (vconcat (mapcar (lambda (c) (make-glyph-code c (and (not (stringp org-ellipsis)) - org-ellipsis))) + org-ellipsis))) (if (stringp org-ellipsis) org-ellipsis "...")))) (setq buffer-display-table org-display-table)) (org-set-regexps-and-options) @@ -7390,7 +7459,7 @@ a block. Return a non-nil value when toggling is successful." ;; Remove overlays when changing major mode (add-hook 'org-mode-hook (lambda () (add-hook 'change-major-mode-hook - 'org-show-block-all 'append 'local))) + 'org-show-block-all 'append 'local))) ;;; Org-goto diff --git a/lisp/ox.el b/lisp/ox.el index da985f3..3986ec3 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -4073,7 +4073,7 @@ meant to be translated with `org-export-data' or alike." ;;;; For Links ;; ;; `org-export-custom-protocol-maybe' handles custom protocol defined -;; with `org-add-link-type', which see. +;; in `org-link-parameters'. ;; ;; `org-export-get-coderef-format' returns an appropriate format ;; string for coderefs. diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index f1acc54..09d2e2a 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -2571,8 +2571,8 @@ Para2" (should (string-match "success" - (let ((org-link-types (org-link-types))) - (org-add-link-type "foo" nil (lambda (p d f) "success")) + (progn + (org-link-set-parameters "foo" :export (lambda (p d f) "success")) (org-export-string-as "[[foo:path]]" (org-export-create-backend @@ -2586,9 +2586,9 @@ Para2" (should-not (string-match "success" - (let ((org-link-types (org-link-types))) - (org-add-link-type - "foo" nil (lambda (p d f) (and (eq f 'test) "success"))) + (progn + (org-link-set-parameters + "foo" :export (lambda (p d f) (and (eq f 'test) "success"))) (org-export-string-as "[[foo:path]]" (org-export-create-backend @@ -2603,9 +2603,9 @@ Para2" (should-not (string-match "success" - (let ((org-link-types (org-link-types))) - (org-add-link-type - "foo" nil (lambda (p d f) (and (eq f 'test) "success"))) + (progn + (org-link-set-parameters + "foo" :export (lambda (p d f) (and (eq f 'test) "success"))) (org-export-string-as "[[foo:path]]" (org-export-create-backend commit a4b9ed7783437838f909f3516fb53f32598e803e Author: John Kitchin Date: Tue Jul 5 10:07:10 2016 -0400 Remove org-link-types * lisp/org.el (org-link-types): Remove this variable. * testing/lisp/test-ox.el (test-org-export/custom-protocol-maybe): Remove copy-sequence in the tests. Actually it seems like the let statement is no longer needed. I guess it was around to protect the list from extra links getting defined. A downside of this is the links may get added during tests. That does not seem like a big deal if those are run in batch mode. * lisp/org.el: The `org-link-types' variable was replaced with the `org-link-types' function everywhere. diff --git a/lisp/org-element.el b/lisp/org-element.el index 269bc7d..9452641 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -185,7 +185,7 @@ specially in `org-element--object-lex'.") "\\)\\)") org-element--object-regexp (mapconcat #'identity - (let ((link-types (regexp-opt org-link-types))) + (let ((link-types (regexp-opt (org-link-types)))) (list ;; Sub/superscript. "\\(?:[_^][-{(*+.,[:alnum:]]\\)" @@ -3108,7 +3108,7 @@ Assume point is at the beginning of the link." (string-match "\\`\\.\\.?/" raw-link)) (setq type "file") (setq path raw-link)) - ;; Explicit type (http, irc, bbdb...). See `org-link-types'. + ;; Explicit type (http, irc, bbdb...). ((string-match org-link-types-re raw-link) (setq type (match-string 1 raw-link)) (setq path (substring raw-link (match-end 0)))) diff --git a/lisp/org.el b/lisp/org.el index 2202d41..c875d03 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -5658,9 +5658,6 @@ the rounding returns a past time." (require 'font-lock) (defconst org-non-link-chars "]\t\n\r<>") -(defvar org-link-types '("http" "https" "ftp" "mailto" "file" "file+emacs" - "file+sys" "news" "shell" "elisp" "doi" "message" - "help")) (defvar org-link-types-re nil "Matches a link that has a url-like prefix like \"http:\"") (defvar org-link-re-with-space nil @@ -5727,8 +5724,8 @@ stacked delimiters is N. Escaping delimiters is not possible." (defun org-make-link-regexps () "Update the link regular expressions. -This should be called after the variable `org-link-types' has changed." - (let ((types-re (regexp-opt org-link-types t))) +This should be called after the variable `org-link-parameters' has changed." + (let ((types-re (regexp-opt (org-link-types) t))) (setq org-link-types-re (concat "\\`" types-re ":") org-link-re-with-space @@ -5766,7 +5763,7 @@ This should be called after the variable `org-link-types' has changed." org-bracket-link-analytic-regexp++ (concat "\\[\\[" - "\\(" (regexp-opt (cons "coderef" org-link-types) t) ":\\)?" + "\\(" (regexp-opt (cons "coderef" (org-link-types)) t) ":\\)?" "\\([^]]+\\)" "\\]" "\\(\\[" "\\([^]]+\\)" "\\]\\)?" @@ -10325,7 +10322,7 @@ Use TAB to complete link prefixes, then RET for type-specific completion support (and (window-live-p cw) (select-window cw))) (setq all-prefixes (append (mapcar 'car abbrevs) (mapcar 'car org-link-abbrev-alist) - org-link-types)) + (org-link-types))) (unwind-protect ;; Fake a link history, containing the stored links. (let ((org--links-history diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 8b07cca..f1acc54 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -2571,7 +2571,7 @@ Para2" (should (string-match "success" - (let ((org-link-types (copy-sequence org-link-types))) + (let ((org-link-types (org-link-types))) (org-add-link-type "foo" nil (lambda (p d f) "success")) (org-export-string-as "[[foo:path]]" @@ -2586,7 +2586,7 @@ Para2" (should-not (string-match "success" - (let ((org-link-types (copy-sequence org-link-types))) + (let ((org-link-types (org-link-types))) (org-add-link-type "foo" nil (lambda (p d f) (and (eq f 'test) "success"))) (org-export-string-as @@ -2603,7 +2603,7 @@ Para2" (should-not (string-match "success" - (let ((org-link-types (copy-sequence org-link-types))) + (let ((org-link-types (org-link-types))) (org-add-link-type "foo" nil (lambda (p d f) (and (eq f 'test) "success"))) (org-export-string-as -- Professor John Kitchin Doherty Hall A207F Department of Chemical Engineering Carnegie Mellon University Pittsburgh, PA 15213 412-268-7803 @johnkitchin http://kitchingroup.cheme.cmu.edu