emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* links-9.0 v3
@ 2016-07-06 14:41 John Kitchin
  2016-07-06 22:10 ` Nicolas Goaziou
  0 siblings, 1 reply; 26+ messages in thread
From: John Kitchin @ 2016-07-06 14:41 UTC (permalink / raw)
  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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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."
 
 \f
 ;;; 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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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 <jkitchin@andrew.cmu.edu>
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

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-06 14:41 links-9.0 v3 John Kitchin
@ 2016-07-06 22:10 ` Nicolas Goaziou
  2016-07-06 23:06   ` John Kitchin
  2016-07-07  1:55   ` John Kitchin
  0 siblings, 2 replies; 26+ messages in thread
From: Nicolas Goaziou @ 2016-07-06 22:10 UTC (permalink / raw)
  To: John Kitchin; +Cc: emacs-orgmode@gnu.org

Hello,

John Kitchin <jkitchin@andrew.cmu.edu> writes:

> Your version doesn't let you add properties to links with no
> existing properties, e.g. ("http")

There was a typo (spurious `cdr'), the correct version is

  (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 (setcdr data (org-combine-plists (cdr data) parameters))
        (push (cons type parameters) org-link-parameters)
        (org-make-link-regexps)
        (org-element-update-syntax))))

> and it also didn't work as expected to set properties to nil.

Not sure to understand what you mean here. Could you give an example?

> I think I have squashed everything together that makes sense. Let me
> know if you have further thoughts.

OK. Some comments follow.

> +{{{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:

Mind the spaces after sentences.

In any case, updating contrib manual is not top priority, since many
section needs to be updated anyway.

> +[fn:37] This works if a function has been defined in the :complete
> +property of a link in org-link-parameters.

~org-link-parameters~

> -(org-add-link-type "id" 'org-id-open)
> +(org-link-set-parameters "id" :follow 'org-id-open)

Nitpick: #'org-id-open

> -(add-hook 'org-store-link-functions 'org-w3m-store-link)
> +(org-link-set-parameters "w3m" :store 'org-w3m-store-link)

#'org-w3m-store-link

You get the idea, I will not comment the other occurrences.

> +	   (type (save-match-data
> +		   (if (string-match org-plain-link-re hl)
> +		       (match-string-no-properties 1 hl)
> +		     nil)))

Nitpick

  (save-match-data
    (and (string-match org-plain-link-re hl)
         (match-string-no-properties 1 hl)))

> +	   (path (save-match-data
> +		   (if (string-match org-plain-link-re hl)
> +		       (match-string-no-properties 2 hl)
> +		     nil)))

Ditto.

> -	       ((assoc type org-link-parameters)
> +	       ((and (assoc type org-link-parameters)
> +		     (functionp (org-link-get-parameter type :follow)))

I think (functionp ...) is sufficient, no need for the `and' and 
(assoc type org-link-parameters), which `org-link-get-parameters'
already takes case of.  So

  ((functionp (org-link-get-parameters type :follow)
   ...)

>     * lisp/org.el: Replace the variable `org-store-link-functions' with a
>       function by the same name.

You need to add the name of the function being modified.

>     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.

You probably mean `org-link-set-parameters', since `org-link-add' would
be but a lesser version of the former.

> +  (org-link-add type :follow follow :export export)

See above.

> +(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:

Mind the spaces between sentences.

I don't understand why we need to both preserve
`org-store-link-functions' and use :store property. Wouldn't one
location be enough?

> +: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.

Org-mode -> Org mode

> +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)))

The above looks dubious. You seem to be collection :store values for
every link type, in addition to user-defined functions. It doesn't make
sense to run unrelated store functions.

> -	       ((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))

(assoc type org-link-parameters) -> (functionp (org-link-get-parameter type :follow))

> +(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)))

Isn't it plist instead of (plist)?

> +(defun org-link-get-parameter (type key)
> +  "Get TYPE link property for KEY."

We could add that TYPE is string and KEY a keyword.

> +(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))))

See at the beginning of the message, I didn't give up yet ;)

> commit a4b9ed7783437838f909f3516fb53f32598e803e
> Author: John Kitchin <jkitchin@andrew.cmu.edu>
> 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.

The copy-sequence was used to prevent modifying `org-link-types' by
side-effect. It is not needed anymore since (org-link-types) generates
a new list every time.

I think we're almost there, barring my stubbornness about
`org-link-set-parameters'. Thank you for this work.

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-06 22:10 ` Nicolas Goaziou
@ 2016-07-06 23:06   ` John Kitchin
  2016-07-07  1:55   ` John Kitchin
  1 sibling, 0 replies; 26+ messages in thread
From: John Kitchin @ 2016-07-06 23:06 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode@gnu.org

Thanks. I responded to some below. I didn't respond to all of them. I
will revise the commits accordingly and send a new version.

Nicolas Goaziou writes:

> Hello,
>
> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
>> Your version doesn't let you add properties to links with no
>> existing properties, e.g. ("http")
>
> There was a typo (spurious `cdr'), the correct version is
>
>   (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 (setcdr data (org-combine-plists (cdr data) parameters))
>         (push (cons type parameters) org-link-parameters)
>         (org-make-link-regexps)
>         (org-element-update-syntax))))
>
>> and it also didn't work as expected to set properties to nil.

I will give this a try.
>
> Not sure to understand what you mean here. Could you give an example?

If I ran the previous function a few times like this

(org-link-set-parameters "http" :follow nil)

I would get
("http" :follow :follow nil nil nil...)

probably because of the bug. I will let you know if it works.

>> I think I have squashed everything together that makes sense. Let me
>> know if you have further thoughts.
>
> OK. Some comments follow.
>
>> +{{{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:
>
> Mind the spaces after sentences.
I will fix these.

>
> In any case, updating contrib manual is not top priority, since many
> section needs to be updated anyway.
>
>> +[fn:37] This works if a function has been defined in the :complete
>> +property of a link in org-link-parameters.
>
> ~org-link-parameters~
>
>> -(org-add-link-type "id" 'org-id-open)
>> +(org-link-set-parameters "id" :follow 'org-id-open)
>
> Nitpick: #'org-id-open
>
>> -(add-hook 'org-store-link-functions 'org-w3m-store-link)
>> +(org-link-set-parameters "w3m" :store 'org-w3m-store-link)
>
> #'org-w3m-store-link
>
> You get the idea, I will not comment the other occurrences.

Just to make sure I get it, all functions should be sharp quoted like this?

>
>> +	   (type (save-match-data
>> +		   (if (string-match org-plain-link-re hl)
>> +		       (match-string-no-properties 1 hl)
>> +		     nil)))
>
> Nitpick
>
>   (save-match-data
>     (and (string-match org-plain-link-re hl)
>          (match-string-no-properties 1 hl)))
>
>> +	   (path (save-match-data
>> +		   (if (string-match org-plain-link-re hl)
>> +		       (match-string-no-properties 2 hl)
>> +		     nil)))
>
> Ditto.

ok

>
>> -	       ((assoc type org-link-parameters)
>> +	       ((and (assoc type org-link-parameters)
>> +		     (functionp (org-link-get-parameter type :follow)))
>
> I think (functionp ...) is sufficient, no need for the `and' and 
> (assoc type org-link-parameters), which `org-link-get-parameters'
> already takes case of.  So
>
>   ((functionp (org-link-get-parameters type :follow)
>    ...)
>
>>     * lisp/org.el: Replace the variable `org-store-link-functions' with a
>>       function by the same name.
>
> You need to add the name of the function being modified.
>
>>     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.
>
> You probably mean `org-link-set-parameters', since `org-link-add' would
> be but a lesser version of the former.
>
>> +  (org-link-add type :follow follow :export export)
>
> See above.
>
>> +(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:
>
> Mind the spaces between sentences.
>
> I don't understand why we need to both preserve
> `org-store-link-functions' and use :store property. Wouldn't one
> location be enough?
>

It probably isn't necessary. I will take it out.

>> +: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.
>
> Org-mode -> Org mode
>
>> +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)))
>
> The above looks dubious. You seem to be collection :store values for
> every link type, in addition to user-defined functions. It doesn't make
> sense to run unrelated store functions.

see above.

>
>> -	       ((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))
>
> (assoc type org-link-parameters) -> (functionp (org-link-get-parameter type :follow))
>
>> +(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)))
>
> Isn't it plist instead of (plist)?
>
>> +(defun org-link-get-parameter (type key)
>> +  "Get TYPE link property for KEY."
>
> We could add that TYPE is string and KEY a keyword.
>
>> +(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))))
>
> See at the beginning of the message, I didn't give up yet ;)
>
>> commit a4b9ed7783437838f909f3516fb53f32598e803e
>> Author: John Kitchin <jkitchin@andrew.cmu.edu>
>> 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.
>
> The copy-sequence was used to prevent modifying `org-link-types' by
> side-effect. It is not needed anymore since (org-link-types) generates
> a new list every time.
>
> I think we're almost there, barring my stubbornness about
> `org-link-set-parameters'. Thank you for this work.

No problem, thanks for the detailed feedback and tips! I will send a new
set of revised diffs later.

>
> Regards,


-- 
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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-06 22:10 ` Nicolas Goaziou
  2016-07-06 23:06   ` John Kitchin
@ 2016-07-07  1:55   ` John Kitchin
  2016-07-07  8:20     ` Nicolas Goaziou
  1 sibling, 1 reply; 26+ messages in thread
From: John Kitchin @ 2016-07-07  1:55 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode@gnu.org

I think I have addressed these. Revised commits appended and at https://github.com/jkitchin/org-mode/tree/link-9.0-v3.

The new org-link-set-parameters function you suggested works fine as far
as I can tell. WDYT?

commit f8bb180150514b92535506601c747001da305610
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..07d9e8d 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 d5db3a80b3e6eab98935a329d8633a85f398ee3a
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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 74d6817ea942b9b20b9a15f47d259ef71ddb83a3
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..f962a58 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 c8301849750a3f6590fe3f7bc9ddf79e835b9d1c
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..5ad7f00 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 ee4a5b043b0fedcdb1c47fdd2c4b20ccab499faf
Author: John Kitchin <jkitchin@andrew.cmu.edu>
Date:   Tue Jul 5 10:28:38 2016 -0400

    Update w3m link definition
    
    * lisp/org-w3m.el ("w3m"):
    Update to use org-link-set-parameters.

diff --git a/lisp/org-w3m.el b/lisp/org-w3m.el
index 57ecafe..28bc492 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 f5af65a2cd9fe352014e4badf20bee89b79882e8
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..35bf073 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 dc902d132a2a05a44f98e454681f9030464713a1
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..c793eed 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 a27489a2ae414399730ca76ae8703c8ae1971623
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..5b9c839 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 4f07b7d6beb8b79b2f73ce3aa074b9efa88725c5
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..8765c53 100644
--- a/lisp/org-info.el
+++ b/lisp/org-info.el
@@ -40,8 +40,10 @@
 (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 +115,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 fbcd5a394f42ebdf2b322d0ddb62fd269cdfff7a
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..13e28cc 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 e20a185f461f53391368812a152efe0ecc2d53a7
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..6f9a18a 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 d00ff860b602287eedf4ba573fae6df494476ce6
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..3d4df40 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 dfae434d21995d36d69aea3c5bec2a2d4ae72b05
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..e740353 100644
--- a/lisp/org-bibtex.el
+++ b/lisp/org-bibtex.el
@@ -452,8 +452,9 @@ With optional argument OPTIONAL, also prompt for optional fields."
 
 \f
 ;;; 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
+			 :store #'org-bibtex-store-link)
 
 (defun org-bibtex-open (path)
   "Visit the bibliography entry on PATH."

commit a35516ec1a10bcaa85a9d02846ed69ed1eb86ba8
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..5f3971b 100644
--- a/lisp/org-bbdb.el
+++ b/lisp/org-bbdb.el
@@ -194,10 +194,12 @@ 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 60ee24064afad1c054fd4c50ddecef9f58eb19c6
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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 9340b87..d7bb5fc 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6520,8 +6520,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 7d764309e1d00fd5e0092f5c5ea264fe1e7929a2
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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 760db41..9340b87 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6167,14 +6167,67 @@ 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
+		   (and (string-match org-plain-link-re hl)
+			(match-string-no-properties 1 hl))))
+	   (path (save-match-data
+		   (and (string-match org-plain-link-re hl)
+			(match-string-no-properties 2 hl))))
+	   (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))
@@ -6194,6 +6247,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 8567e2e2ef7e3ba53dda05aaa134e3636524b4a0
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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 85af56b..760db41 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -5927,17 +5927,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 81c5b375315166f14a3c2bf73d07621bc655ab02
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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 9660856..85af56b 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -10464,7 +10464,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 ":")))))

commit f9d0ca3244570d7289742bc2976a10b00e7d7fbd
Author: John Kitchin <jkitchin@andrew.cmu.edu>
Date:   Tue Jul 5 10:16:38 2016 -0400

    Remove `org-link-protocols'
    
    * lisp/org.el (org-link-protocols): Remove variable org-link-protocols.
    The data in this variable is now retrieved with org-link-get-parameter.

diff --git a/lisp/org.el b/lisp/org.el
index 6f3e931..9660856 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -10742,7 +10742,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'
@@ -10756,7 +10756,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
@@ -10771,8 +10771,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))
+	       ((functionp (org-link-get-parameter type :follow))
+		(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))
@@ -10821,7 +10821,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 838bbb08082170042867682444c771b546498d70
Author: John Kitchin <jkitchin@andrew.cmu.edu>
Date:   Tue Jul 5 10:07:10 2016 -0400

    Remove `org-link-types' variable
    
    * lisp/org.el (org-link-types): Remove this variable.
    
    * 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 5fbffd0..6f3e931 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -1802,10 +1802,11 @@ 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)))
+		:value-type plist))
 
 (defun org-link-get-parameter (type key)
-  "Get TYPE link property for KEY."
+  "Get TYPE link property for KEY.
+TYPE is a string and KEY is a plist keyword."
   (plist-get
    (cdr (assoc type org-link-parameters))
    key))
@@ -1814,11 +1815,7 @@ as arguments."
   "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))
+    (if data (setcdr data (org-combine-plists (cdr data) parameters))
       (push (cons type parameters) org-link-parameters)
       (org-make-link-regexps)
       (org-element-update-syntax))))
@@ -5727,9 +5724,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
@@ -5796,8 +5790,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
@@ -5835,7 +5829,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) ":\\)?"
 	   "\\([^]]+\\)"
 	   "\\]"
 	   "\\(\\[" "\\([^]]+\\)" "\\]\\)?"
@@ -10366,7 +10360,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

commit 28f43b0ba61db603bb0db39ac5c281fc8bcdf61e
Author: John Kitchin <jkitchin@andrew.cmu.edu>
Date:   Tue Jul 5 10:08:14 2016 -0400

    Add `org-link-parameters' variable and functions
    
    * 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/org.el org-add-link-type: deprecated and now calls
      `org-link-set-parameters'. `org-link-add-type' was moved to
      org-compat.el
    
    * lisp/org.el (org-store-link-functions):
       Add `org-store-link-functions'  to return list of store functions.
    
    * lisp/org.el: Replace the variable `org-store-link-functions' with a
      function `org-store-link-functions'.
    
    * lisp/ox.el: change reference in a comment.
    
    * testing/lisp/test-ox.el (test-org-export/custom-protocol-maybe):
    Remove references to org-link-types and use org-link-set-parameters instead.

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 2202d41..5fbffd0 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)
@@ -7393,7 +7462,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
 
@@ -9666,60 +9735,32 @@ 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'.")
+(defun org-store-link-functions ()
+  "Returns a list of functions that are called to create and store a link.
+The functions defined in the :store property of
+`org-link-parameters'.
 
-(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
-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:
+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.
+              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.")
-
-(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)))
+and then used in capture templates."
+  (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
@@ -9764,7 +9805,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
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 8b07cca..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 (copy-sequence 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 (copy-sequence 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 (copy-sequence 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


Nicolas Goaziou writes:

> Hello,
>
> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
>> Your version doesn't let you add properties to links with no
>> existing properties, e.g. ("http")
>
> There was a typo (spurious `cdr'), the correct version is
>
>   (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 (setcdr data (org-combine-plists (cdr data) parameters))
>         (push (cons type parameters) org-link-parameters)
>         (org-make-link-regexps)
>         (org-element-update-syntax))))
>
>> and it also didn't work as expected to set properties to nil.
>
> Not sure to understand what you mean here. Could you give an example?
>
>> I think I have squashed everything together that makes sense. Let me
>> know if you have further thoughts.
>
> OK. Some comments follow.
>
>> +{{{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:
>
> Mind the spaces after sentences.
>
> In any case, updating contrib manual is not top priority, since many
> section needs to be updated anyway.
>
>> +[fn:37] This works if a function has been defined in the :complete
>> +property of a link in org-link-parameters.
>
> ~org-link-parameters~
>
>> -(org-add-link-type "id" 'org-id-open)
>> +(org-link-set-parameters "id" :follow 'org-id-open)
>
> Nitpick: #'org-id-open
>
>> -(add-hook 'org-store-link-functions 'org-w3m-store-link)
>> +(org-link-set-parameters "w3m" :store 'org-w3m-store-link)
>
> #'org-w3m-store-link
>
> You get the idea, I will not comment the other occurrences.
>
>> +	   (type (save-match-data
>> +		   (if (string-match org-plain-link-re hl)
>> +		       (match-string-no-properties 1 hl)
>> +		     nil)))
>
> Nitpick
>
>   (save-match-data
>     (and (string-match org-plain-link-re hl)
>          (match-string-no-properties 1 hl)))
>
>> +	   (path (save-match-data
>> +		   (if (string-match org-plain-link-re hl)
>> +		       (match-string-no-properties 2 hl)
>> +		     nil)))
>
> Ditto.
>
>> -	       ((assoc type org-link-parameters)
>> +	       ((and (assoc type org-link-parameters)
>> +		     (functionp (org-link-get-parameter type :follow)))
>
> I think (functionp ...) is sufficient, no need for the `and' and 
> (assoc type org-link-parameters), which `org-link-get-parameters'
> already takes case of.  So
>
>   ((functionp (org-link-get-parameters type :follow)
>    ...)
>
>>     * lisp/org.el: Replace the variable `org-store-link-functions' with a
>>       function by the same name.
>
> You need to add the name of the function being modified.
>
>>     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.
>
> You probably mean `org-link-set-parameters', since `org-link-add' would
> be but a lesser version of the former.
>
>> +  (org-link-add type :follow follow :export export)
>
> See above.
>
>> +(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:
>
> Mind the spaces between sentences.
>
> I don't understand why we need to both preserve
> `org-store-link-functions' and use :store property. Wouldn't one
> location be enough?
>
>> +: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.
>
> Org-mode -> Org mode
>
>> +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)))
>
> The above looks dubious. You seem to be collection :store values for
> every link type, in addition to user-defined functions. It doesn't make
> sense to run unrelated store functions.
>
>> -	       ((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))
>
> (assoc type org-link-parameters) -> (functionp (org-link-get-parameter type :follow))
>
>> +(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)))
>
> Isn't it plist instead of (plist)?
>
>> +(defun org-link-get-parameter (type key)
>> +  "Get TYPE link property for KEY."
>
> We could add that TYPE is string and KEY a keyword.
>
>> +(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))))
>
> See at the beginning of the message, I didn't give up yet ;)
>
>> commit a4b9ed7783437838f909f3516fb53f32598e803e
>> Author: John Kitchin <jkitchin@andrew.cmu.edu>
>> 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.
>
> The copy-sequence was used to prevent modifying `org-link-types' by
> side-effect. It is not needed anymore since (org-link-types) generates
> a new list every time.
>
> I think we're almost there, barring my stubbornness about
> `org-link-set-parameters'. Thank you for this work.
>
> Regards,


-- 
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

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-07  1:55   ` John Kitchin
@ 2016-07-07  8:20     ` Nicolas Goaziou
  2016-07-07 13:27       ` John Kitchin
  0 siblings, 1 reply; 26+ messages in thread
From: Nicolas Goaziou @ 2016-07-07  8:20 UTC (permalink / raw)
  To: John Kitchin; +Cc: emacs-orgmode@gnu.org

Hello,

John Kitchin <jkitchin@andrew.cmu.edu> writes:

> I think I have addressed these. Revised commits appended and at https://github.com/jkitchin/org-mode/tree/link-9.0-v3.
>
> The new org-link-set-parameters function you suggested works fine as far
> as I can tell. WDYT?

That's great. I realized there's one gotcha left.

>  		  (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

Here is the gotcha. `type' is "file", not "file+sys" or "file+emacs",
so, when checking `dedicated-function' first, we cannot tell the
difference between "file+sys" and "file+emacs".

One solution is to swap the logic order. First, if app is non-nil, we
use it. If it isn't, we look after `dedicated-function'.

Another solution is to add an optional parameter to the signature of
the :follow function, which would be the "app" (e.g. "emacs", "sys",
"docview"...) to use. I tend to think this solution is slightly better,
since it doesn't require to hard-code logic in `org-open-at-point'.

WDYT?

>    (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))
> +    (if data (setcdr data (org-combine-plists (cdr data) parameters))
>        (push (cons type parameters) org-link-parameters)
>        (org-make-link-regexps)
>        (org-element-update-syntax))))

This change can be merged with `org-link-set-parameters' definition.

> +(defcustom org-link-parameters
> +  '(("http") ("https") ("ftp") ("mailto")
> +    ("file" :complete 'org-file-complete-link)
> +    ("file+emacs") ("file+sys")
> +    ("news") ("shell") ("elisp")
> +    ("doi") ("message") ("help"))

See above about "file+emacs" and "file+sys", which are not valid types.

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-07  8:20     ` Nicolas Goaziou
@ 2016-07-07 13:27       ` John Kitchin
  2016-07-07 14:56         ` Nicolas Goaziou
  0 siblings, 1 reply; 26+ messages in thread
From: John Kitchin @ 2016-07-07 13:27 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode@gnu.org

>
> That's great. I realized there's one gotcha left.
>
>>  		  (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
>
> Here is the gotcha. `type' is "file", not "file+sys" or "file+emacs",
> so, when checking `dedicated-function' first, we cannot tell the
> difference between "file+sys" and "file+emacs".

I don't follow this. Why can't these be three types? They
define 3 different follow actions right? Those are basically equal to
pressing RET, C-u RET and C-u C-u RET on a link. We could just define
three :follow functions, and one :export function for them.

With the patches I sent, the three types actually work as they used to,
e.g. file:some.pptx opens the powerpoint file in emacs (not convenient
;), file+sys:some.pptx opens it in powerpoint. This seems to be because
org-element-context (via org-element-link-parser) sees file+sys and
file+emacs as a file type.

Overall, this is an inconsistency to me. On one hand, we need file+sys
and file+emacs in org-link-parameters so that they are built into the
link regexps (or they would have to be hard-coded in the function that
makes the regexp. E.g. (cons "coderef" (org-link-types)) is already done
that way for some reason). On the other hand, the org-open-at-point
function bypasses the link properties, so it is not possible to change
the :follow function for file+sys and file+emacs.

> One solution is to swap the logic order. First, if app is non-nil, we
> use it. If it isn't, we look after `dedicated-function'.
>
> Another solution is to add an optional parameter to the signature of
> the :follow function, which would be the "app" (e.g. "emacs", "sys",
> "docview"...) to use. I tend to think this solution is slightly better,
> since it doesn't require to hard-code logic in `org-open-at-point'.
>
> WDYT?

I am not crazy about this solution, since it only applies to one type of
link, and I can't see how to use it for other follow functions. It would be
better IMO to define :follow functions maybe like this:

"file" :follow #'org-open-at-point
"file+sys" :follow (lambda (_) (org-open-at-point '(4)))
"file+emacs" :follow (lambda (_) (org-open-at-point '(16)))

and make them be honored in org-open-at-point. Then we could eliminate
the logic code in org-open-at-point.

>
>>    (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))
>> +    (if data (setcdr data (org-combine-plists (cdr data) parameters))
>>        (push (cons type parameters) org-link-parameters)
>>        (org-make-link-regexps)
>>        (org-element-update-syntax))))
>
> This change can be merged with `org-link-set-parameters' definition.

I am not sure how to do that. It is like a hunk in one commit that I
want to move to another commit.

>
>> +(defcustom org-link-parameters
>> +  '(("http") ("https") ("ftp") ("mailto")
>> +    ("file" :complete 'org-file-complete-link)
>> +    ("file+emacs") ("file+sys")
>> +    ("news") ("shell") ("elisp")
>> +    ("doi") ("message") ("help"))
>
> See above about "file+emacs" and "file+sys", which are not valid types.

Those either need to be here for link regexps, or hard-coded somewhere
else though. Speaking of which, should coderef be a link type, so it can
be removed as a hard-coded string that I referenced above?

> Regards,


-- 
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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-07 13:27       ` John Kitchin
@ 2016-07-07 14:56         ` Nicolas Goaziou
  2016-07-07 19:17           ` John Kitchin
  2016-07-07 19:21           ` John Kitchin
  0 siblings, 2 replies; 26+ messages in thread
From: Nicolas Goaziou @ 2016-07-07 14:56 UTC (permalink / raw)
  To: John Kitchin; +Cc: emacs-orgmode@gnu.org

John Kitchin <jkitchin@andrew.cmu.edu> writes:

>> Here is the gotcha. `type' is "file", not "file+sys" or "file+emacs",
>> so, when checking `dedicated-function' first, we cannot tell the
>> difference between "file+sys" and "file+emacs".
>
> I don't follow this. Why can't these be three types?

The type is "file". "sys" or "emacs" are indications about how to follow
them. "docview" is also an indication, but it really points to a "file".

> They define 3 different follow actions right? Those are basically
> equal to pressing RET, C-u RET and C-u C-u RET on a link. We could
> just define three :follow functions, and one :export function for
> them.

It doesn't mean they cannot have an entry in `org-link-parameters'.
Actually they should.

However `org-link-protocols' keys are applications, not types. So

  (org-link-get-parameter type :follow)

is not a drop-in replacement for

  (nth 1 (assoc app org-link-protocols))

> With the patches I sent, the three types actually work as they used to,
> e.g. file:some.pptx opens the powerpoint file in emacs (not convenient
> ;), file+sys:some.pptx opens it in powerpoint. This seems to be because
> org-element-context (via org-element-link-parser) sees file+sys and
> file+emacs as a file type.

Which is correct.

> Overall, this is an inconsistency to me. On one hand, we need file+sys
> and file+emacs in org-link-parameters so that they are built into the
> link regexps (or they would have to be hard-coded in the function that
> makes the regexp.

[...]

> On the other hand, the org-open-at-point
> function bypasses the link properties, so it is not possible to change
> the :follow function for file+sys and file+emacs.

Of course it is possible. I suggested two solutions already.

>> One solution is to swap the logic order. First, if app is non-nil, we
>> use it. If it isn't, we look after `dedicated-function'.
>>
>> Another solution is to add an optional parameter to the signature of
>> the :follow function, which would be the "app" (e.g. "emacs", "sys",
>> "docview"...) to use. I tend to think this solution is slightly better,
>> since it doesn't require to hard-code logic in `org-open-at-point'.
>>
>> WDYT?
>
> I am not crazy about this solution,

Which one? I suggested two of them.

> since it only applies to one type of link,

Does it? Every type can benefit from this change, i.e. instead of
calling follow function with a single argument, it is called with two,
the second one being the application (e.g., "sys", "emacs"...) or nil.

> and I can't see how to use it for other follow functions. It would be
> better IMO to define :follow functions maybe like this:
>
> "file" :follow #'org-open-at-point
> "file+sys" :follow (lambda (_) (org-open-at-point '(4)))
> "file+emacs" :follow (lambda (_) (org-open-at-point '(16)))
>
> and make them be honored in org-open-at-point. Then we could eliminate
> the logic code in org-open-at-point.

You may be misunderstanding the problem. 

The issue is that `org-open-at-point', at the moment, cannot call
the :follow function for "file+emacs" or "file+sys" since the common
type is "file", even if `org-link-parameters' distinguish them. IOW the
first :follow function would always be called.

Also, `org-open-at-point' shouldn't be part of a follow function, since
`org-open-at-point' calls follow functions. It can call `org-open-file',
tho, as currently done in `org-open-at-point'.

Actually, I can think of a third solution, which may well follow the
path of least resistance. Instead of calling

  (org-link-get-parameter type :follow)

we would call

  (org-link-get-parameter (if app (concat type "+" app) type) :follow)

and get the appropriate follow function. This solution is local to
`org-open-at-point', but I don't think other places need :follow
function.

>>>    (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))
>>> +    (if data (setcdr data (org-combine-plists (cdr data) parameters))
>>>        (push (cons type parameters) org-link-parameters)
>>>        (org-make-link-regexps)
>>>        (org-element-update-syntax))))
>>
>> This change can be merged with `org-link-set-parameters' definition.
>
> I am not sure how to do that. It is like a hunk in one commit that I
> want to move to another commit.

I would edit the commit defining `org-link-set-parameters' and install
that change there. Then, upon rebasing, I would make sure this change is
preserved.

>>> +(defcustom org-link-parameters
>>> +  '(("http") ("https") ("ftp") ("mailto")
>>> +    ("file" :complete 'org-file-complete-link)
>>> +    ("file+emacs") ("file+sys")
>>> +    ("news") ("shell") ("elisp")
>>> +    ("doi") ("message") ("help"))
>>
>> See above about "file+emacs" and "file+sys", which are not valid types.
>
> Those either need to be here for link regexps, or hard-coded somewhere
> else though.

You're right, they need to be here, but there is still an issue.

>Speaking of which, should coderef be a link type, so it can
> be removed as a hard-coded string that I referenced above?

No it cannot. "coderef" is not a valid link type, since there is no
[[coderef:something]]. It shouldn't belong to the link regexp.

Regards,

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-07 14:56         ` Nicolas Goaziou
@ 2016-07-07 19:17           ` John Kitchin
  2016-07-08 21:32             ` Nicolas Goaziou
  2016-07-07 19:21           ` John Kitchin
  1 sibling, 1 reply; 26+ messages in thread
From: John Kitchin @ 2016-07-07 19:17 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode@gnu.org

Let me preface my reply that I think your last suggestion:

>   (org-link-get-parameter (if app (concat type "+" app) type) :follow)

Is the thing to do for this set of changes for now. I think it would
wrap up this set of changes. I will send a new set of diffs that
implement this shortly after this mail.

I have some other responses below because there are some things I don't
totally understand yet.

Nicolas Goaziou writes:

> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
>>> Here is the gotcha. `type' is "file", not "file+sys" or "file+emacs",
>>> so, when checking `dedicated-function' first, we cannot tell the
>>> difference between "file+sys" and "file+emacs".
>>
>> I don't follow this. Why can't these be three types?
>
> The type is "file". "sys" or "emacs" are indications about how to follow
> them. "docview" is also an indication, but it really points to a "file".
>
>> They define 3 different follow actions right? Those are basically
>> equal to pressing RET, C-u RET and C-u C-u RET on a link. We could
>> just define three :follow functions, and one :export function for
>> them.
>
> It doesn't mean they cannot have an entry in `org-link-parameters'.
> Actually they should.
>
> However `org-link-protocols' keys are applications, not types. So

I don't understand what you mean here. The contents of org-link
protocols (in master) looks a lot like a list of (link-type :follow
:export), e.g.

#+BEGIN_SRC emacs-lisp :results code
(assoc "bbdb" org-link-protocols)
#+END_SRC

#+RESULTS:
#+BEGIN_SRC emacs-lisp
("bbdb" org-bbdb-open org-bbdb-export)
#+END_SRC

There doesn't seem to be a "sys" or "emacs" defined in
org-link-protocols in master. So there is no dedicated function being
called as far as I can tell.

#+BEGIN_SRC emacs-lisp :results code
(assoc "sys" org-link-protocols)
#+END_SRC

#+RESULTS:
#+BEGIN_SRC emacs-lisp
nil
#+END_SRC

>  (org-link-get-parameter type :follow)
>
> is not a drop-in replacement for
>
>   (nth 1 (assoc app org-link-protocols))

I see that these are not the same, since type != app.

With app, this would try to look up (org-link-get-parameter "sys"
:follow), which currently would return nil. That seems consistent with
what is currently in master too. I concede that if a "sys" link was
defined it would do something, but that isn't currently the case AFAICT.
Your solution solves this nicely though.

>> With the patches I sent, the three types actually work as they used to,
>> e.g. file:some.pptx opens the powerpoint file in emacs (not convenient
>> ;), file+sys:some.pptx opens it in powerpoint. This seems to be because
>> org-element-context (via org-element-link-parser) sees file+sys and
>> file+emacs as a file type.
>
> Which is correct.
>
>> Overall, this is an inconsistency to me. On one hand, we need file+sys
>> and file+emacs in org-link-parameters so that they are built into the
>> link regexps (or they would have to be hard-coded in the function that
>> makes the regexp.
>
> [...]
>
>> On the other hand, the org-open-at-point
>> function bypasses the link properties, so it is not possible to change
>> the :follow function for file+sys and file+emacs.
>
> Of course it is possible. I suggested two solutions already.
>
>>> One solution is to swap the logic order. First, if app is non-nil, we
>>> use it. If it isn't, we look after `dedicated-function'.
>>>
>>> Another solution is to add an optional parameter to the signature of
>>> the :follow function, which would be the "app" (e.g. "emacs", "sys",
>>> "docview"...) to use. I tend to think this solution is slightly better,
>>> since it doesn't require to hard-code logic in `org-open-at-point'.
>>>
>>> WDYT?
>>
>> I am not crazy about this solution,
>
> Which one? I suggested two of them.
I was referring to the optional parameter, although I reconsider it
here.  I don't understand how does the "application" get to the
follow functions of links other than file+sys and file+emacs. It seems
like we would need to allow type+application:path as a link syntax and
extend the link-parser to get the application. Right now it looks like
the parser only adds application properties to file type links.

>
>> since it only applies to one type of link,
>
> Does it? Every type can benefit from this change, i.e. instead of
> calling follow function with a single argument, it is called with two,
> the second one being the application (e.g., "sys", "emacs"...) or nil.

I don't mind this (it makes links more flexible after all ;) OTOH, we
would have to "register" each type+application for the link regexp, and
then each type can have its own follow function, so it seems unnecessary
to me.

I would leave this on the table for future consideration, but consider
it outside the current scope of this set of changes. I think with your
final suggestion it isn't necessary to consider this now. 

>
>> and I can't see how to use it for other follow functions. It would be
>> better IMO to define :follow functions maybe like this:
>>
>> "file" :follow #'org-open-at-point
>> "file+sys" :follow (lambda (_) (org-open-at-point '(4)))
>> "file+emacs" :follow (lambda (_) (org-open-at-point '(16)))
>>
>> and make them be honored in org-open-at-point. Then we could eliminate
>> the logic code in org-open-at-point.
>
> You may be misunderstanding the problem.

My understanding of your statement of the problem is that the
link-parser recognizes file:path, file+sys:path, and file+emacs:path as
links of type "file", with different "application" properties. In the
implementation of org-open-at-point on master, there is a cond branch
for the "file" type link, and inside that the application is checked.
Hence, without your suggestion at the end, there is not a way to access
the :follow function of file+sys or file+emacs.

To me this seems to be an unnecessary distinction from a link point of
view since those three file links could just be defined as regular links
with different follow/export functions. OTOH, perhaps there are other
places in org-mode that rely on being able to tell when a link is a
file, even if they are labeled file+sys or file+emacs that I am not
aware of?

If I compare this to what exists in org-ref, for example, there
are close to 40 different types of citations one can use, but they are
all fundamentally "cite" types. They all share a common follow action,
but have different export functions. When defined as separate links, I
use them like cite:key citenum:key, citet:key, autocite:key, etc...

Even here while I can see some utility for an application, e.g. perhaps
to open the key in zotero, or mendeley or bibtex, I would normally
associate that action with the :follow function. Am I missing something?


> The issue is that `org-open-at-point', at the moment, cannot call
> the :follow function for "file+emacs" or "file+sys" since the common
> type is "file", even if `org-link-parameters' distinguish them. IOW the
> first :follow function would always be called.
>
> Also, `org-open-at-point' shouldn't be part of a follow function, since
> `org-open-at-point' calls follow functions. It can call `org-open-file',
> tho, as currently done in `org-open-at-point'.

> Actually, I can think of a third solution, which may well follow the
> path of least resistance. Instead of calling
>
>   (org-link-get-parameter type :follow)
>
> we would call
>
>   (org-link-get-parameter (if app (concat type "+" app) type) :follow)

This seems like a good solution to me. The next revision of patches
implements this, along with follow functions for file+sys and file+emacs
that use org-open-file.

> and get the appropriate follow function. This solution is local to
> `org-open-at-point', but I don't think other places need :follow
> function.

It sounds good to me.

>
>>>>    (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))
>>>> +    (if data (setcdr data (org-combine-plists (cdr data) parameters))
>>>>        (push (cons type parameters) org-link-parameters)
>>>>        (org-make-link-regexps)
>>>>        (org-element-update-syntax))))
>>>
>>> This change can be merged with `org-link-set-parameters' definition.
>>
>> I am not sure how to do that. It is like a hunk in one commit that I
>> want to move to another commit.
>
> I would edit the commit defining `org-link-set-parameters' and install
> that change there. Then, upon rebasing, I would make sure this change is
> preserved.

I think I figured this out. 

>
>>>> +(defcustom org-link-parameters
>>>> +  '(("http") ("https") ("ftp") ("mailto")
>>>> +    ("file" :complete 'org-file-complete-link)
>>>> +    ("file+emacs") ("file+sys")
>>>> +    ("news") ("shell") ("elisp")
>>>> +    ("doi") ("message") ("help"))
>>>
>>> See above about "file+emacs" and "file+sys", which are not valid types.
>>
>> Those either need to be here for link regexps, or hard-coded somewhere
>> else though.
>
> You're right, they need to be here, but there is still an issue.

hopefully it is solved in the next version.

>
>>Speaking of which, should coderef be a link type, so it can
>> be removed as a hard-coded string that I referenced above?
>
> No it cannot. "coderef" is not a valid link type, since there is no
> [[coderef:something]]. It shouldn't belong to the link regexp.

I only mentioned it because it seems to be in there in master via this line:

(regexp-opt (cons "coderef" org-link-types)

but it looks like it is in there in a different sort of way. It doesn't
seem important here.

Ok, that's it. Thanks for reading down this far!

>
> Regards,


-- 
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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-07 14:56         ` Nicolas Goaziou
  2016-07-07 19:17           ` John Kitchin
@ 2016-07-07 19:21           ` John Kitchin
  2016-07-08 21:48             ` Nicolas Goaziou
  1 sibling, 1 reply; 26+ messages in thread
From: John Kitchin @ 2016-07-07 19:21 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode@gnu.org

Here are the new revisions that implement the previous solution you
suggested and that incorporate the commit merges as far as I can see.
WDYT?


commit 290213ef3eee86175d5a6b15c7b6173afd0c1616
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..07d9e8d 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 8e51c2ff4b37524dcc489d58a6769fd8430c5593
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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 246539109bac10f8de227adbc491bdeb94e80ba0
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..f962a58 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 d7ae43598f8d2a048e262a3d5e7ae9d2bbc7c3f7
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..5ad7f00 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 a9c73838f7ddfc531ae3d2a80cab56fb5c9941b6
Author: John Kitchin <jkitchin@andrew.cmu.edu>
Date:   Tue Jul 5 10:28:38 2016 -0400

    Update w3m link definition
    
    * lisp/org-w3m.el ("w3m"):
    Update to use org-link-set-parameters.

diff --git a/lisp/org-w3m.el b/lisp/org-w3m.el
index 57ecafe..28bc492 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 61c2f48e332d60305608af56c326efade1f8f3b1
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..35bf073 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 c25ee02c40a548df817b36edbc630161a468e0df
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..c793eed 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 f061f028266cf3f2b779d9926ff3e7d71e0fa905
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..5b9c839 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 936bcb0a77d7c63eed9da2ff8cb54d9133d0f736
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..8765c53 100644
--- a/lisp/org-info.el
+++ b/lisp/org-info.el
@@ -40,8 +40,10 @@
 (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 +115,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 78a9e11c45a939442a46e25f664770dc9897bc87
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..13e28cc 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 38a53ccde0f90a37b6372cf2a4d7d56172e572b0
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..6f9a18a 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 b0f73dfc0cabc111fe5a9e81a160282e4c7d9bbe
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..3d4df40 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 426bff005b948c36440025efdf61bd383c4daac3
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..e740353 100644
--- a/lisp/org-bibtex.el
+++ b/lisp/org-bibtex.el
@@ -452,8 +452,9 @@ With optional argument OPTIONAL, also prompt for optional fields."
 
 \f
 ;;; 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
+			 :store #'org-bibtex-store-link)
 
 (defun org-bibtex-open (path)
   "Visit the bibliography entry on PATH."

commit 582918948b413cc75e0ccec4f9e921ef0bcf447b
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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..5f3971b 100644
--- a/lisp/org-bbdb.el
+++ b/lisp/org-bbdb.el
@@ -194,10 +194,12 @@ 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 ee988cdbe05d93e39b1cf1700a553d9897b42e47
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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 580986d..a772792 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6521,8 +6521,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 7dba21b34910ff8fdbb95c39e659694e5312ff84
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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 37daa82..580986d 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6168,14 +6168,67 @@ 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
+		   (and (string-match org-plain-link-re hl)
+			(match-string-no-properties 1 hl))))
+	   (path (save-match-data
+		   (and (string-match org-plain-link-re hl)
+			(match-string-no-properties 2 hl))))
+	   (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))
@@ -6195,6 +6248,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 7fd0b5651d4876b27a5e7381be8204cc196d2822
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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 1f5e891..37daa82 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -5928,17 +5928,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 0d6f1ece1ae509aca01e94c60bec537dc0582596
Author: John Kitchin <jkitchin@andrew.cmu.edu>
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 80f3973..1f5e891 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -10465,7 +10465,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 ":")))))

commit a0c8dba24e330ca3998a70806eec57e6b869212d
Author: John Kitchin <jkitchin@andrew.cmu.edu>
Date:   Thu Jul 7 10:02:29 2016 -0400

    Remove `org-link-protocols' variable
    
    * lisp/org.el (org-link-protocols): Remove variable org-link-protocols.
    The data in this variable is now retrieved with org-link-get-parameter.
    
    * lisp/org.el: Enable file links to use the application link property to
      determine the follow action. Also add a space after let*.

diff --git a/lisp/org.el b/lisp/org.el
index c6bf218..80f3973 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -10732,10 +10732,10 @@ link in a property drawer line."
 	  ;; When link is located within the description of another
 	  ;; link (e.g., an inline image), always open the parent
 	  ;; link.
-	  (let*((link (let ((up (org-element-property :parent context)))
-			(if (eq (org-element-type up) 'link) up context)))
-		(type (org-element-property :type link))
-		(path (org-link-unescape (org-element-property :path link))))
+	  (let* ((link (let ((up (org-element-property :parent context)))
+			 (if (eq (org-element-type up) 'link) up context)))
+		 (type (org-element-property :type link))
+		 (path (org-link-unescape (org-element-property :path link))))
 	    ;; Switch back to REFERENCE-BUFFER needed when called in
 	    ;; a temporary buffer through `org-open-link-from-string'.
 	    (with-current-buffer (or reference-buffer (current-buffer))
@@ -10743,7 +10743,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'
@@ -10757,7 +10757,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 (if app (concat type "+" app) type) :follow)))
 		    (if dedicated-function
 			(funcall dedicated-function
 				 (concat path
@@ -10772,8 +10772,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))
+	       ((functionp (org-link-get-parameter type :follow))
+		(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))
@@ -10822,7 +10822,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 ab27cd1a3889a383572e634c0e980465daba1256
Author: John Kitchin <jkitchin@andrew.cmu.edu>
Date:   Thu Jul 7 09:58:29 2016 -0400

    Create `org-link-parameters'
    
    * lisp/org-element.el: Replace `org-link-types' variable with
      `org-link-types' function.
    
    * lisp/org.el: Replace the `org-link-types' variable with
      `org-link-types' function. Create `org-link-get-parameter' and
      `org-link-set-parameters' functions. Remove `org-add-link-type'. Add
      `org-store-link-functions' function and remove
      `org-store-link-functions' variable.
    
    * testing/lisp/test-ox.el: Remove usage of the `org-link-types'
      variable.
    
    * lisp/org-compat.el: Move `org-add-link-type' and mark it as obsolete.
    
    * lisp/ox.el: Change org-add-link-type comment in ox.el.

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-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..c6bf218 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -1758,6 +1758,73 @@ 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
+  '(("file"  :complete 'org-file-complete-link)
+    ("file+emacs" :follow (lambda (path) (org-open-file path '(4))))
+    ("file+sys" :follow (lambda (path) (org-open-file path 'system)))
+    ("http") ("https") ("ftp") ("mailto")
+    ("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
+function `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 arguments 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 parameters"
+		:value-type plist))
+
+(defun org-link-get-parameter (type key)
+  "Get TYPE link property for KEY.
+TYPE is a string and KEY is a plist keyword."
+  (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 (setcdr data (org-combine-plists (cdr data) parameters))
+      (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.
@@ -5658,9 +5725,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 +5791,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 +5830,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) ":\\)?"
 	   "\\([^]]+\\)"
 	   "\\]"
 	   "\\(\\[" "\\([^]]+\\)" "\\]\\)?"
@@ -7393,7 +7457,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
 
@@ -9666,60 +9730,32 @@ 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'.")
+(defun org-store-link-functions ()
+  "Returns a list of functions that are called to create and store a link.
+The functions defined in the :store property of
+`org-link-parameters'.
 
-(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
-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:
+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.
+              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.")
-
-(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)))
+and then used in capture templates."
+  (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
@@ -9764,7 +9800,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
@@ -10325,7 +10361,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/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 8b07cca..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 (copy-sequence 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 (copy-sequence 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 (copy-sequence 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


Nicolas Goaziou writes:

> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
>>> Here is the gotcha. `type' is "file", not "file+sys" or "file+emacs",
>>> so, when checking `dedicated-function' first, we cannot tell the
>>> difference between "file+sys" and "file+emacs".
>>
>> I don't follow this. Why can't these be three types?
>
> The type is "file". "sys" or "emacs" are indications about how to follow
> them. "docview" is also an indication, but it really points to a "file".
>
>> They define 3 different follow actions right? Those are basically
>> equal to pressing RET, C-u RET and C-u C-u RET on a link. We could
>> just define three :follow functions, and one :export function for
>> them.
>
> It doesn't mean they cannot have an entry in `org-link-parameters'.
> Actually they should.
>
> However `org-link-protocols' keys are applications, not types. So
>
>   (org-link-get-parameter type :follow)
>
> is not a drop-in replacement for
>
>   (nth 1 (assoc app org-link-protocols))
>
>> With the patches I sent, the three types actually work as they used to,
>> e.g. file:some.pptx opens the powerpoint file in emacs (not convenient
>> ;), file+sys:some.pptx opens it in powerpoint. This seems to be because
>> org-element-context (via org-element-link-parser) sees file+sys and
>> file+emacs as a file type.
>
> Which is correct.
>
>> Overall, this is an inconsistency to me. On one hand, we need file+sys
>> and file+emacs in org-link-parameters so that they are built into the
>> link regexps (or they would have to be hard-coded in the function that
>> makes the regexp.
>
> [...]
>
>> On the other hand, the org-open-at-point
>> function bypasses the link properties, so it is not possible to change
>> the :follow function for file+sys and file+emacs.
>
> Of course it is possible. I suggested two solutions already.
>
>>> One solution is to swap the logic order. First, if app is non-nil, we
>>> use it. If it isn't, we look after `dedicated-function'.
>>>
>>> Another solution is to add an optional parameter to the signature of
>>> the :follow function, which would be the "app" (e.g. "emacs", "sys",
>>> "docview"...) to use. I tend to think this solution is slightly better,
>>> since it doesn't require to hard-code logic in `org-open-at-point'.
>>>
>>> WDYT?
>>
>> I am not crazy about this solution,
>
> Which one? I suggested two of them.
>
>> since it only applies to one type of link,
>
> Does it? Every type can benefit from this change, i.e. instead of
> calling follow function with a single argument, it is called with two,
> the second one being the application (e.g., "sys", "emacs"...) or nil.
>
>> and I can't see how to use it for other follow functions. It would be
>> better IMO to define :follow functions maybe like this:
>>
>> "file" :follow #'org-open-at-point
>> "file+sys" :follow (lambda (_) (org-open-at-point '(4)))
>> "file+emacs" :follow (lambda (_) (org-open-at-point '(16)))
>>
>> and make them be honored in org-open-at-point. Then we could eliminate
>> the logic code in org-open-at-point.
>
> You may be misunderstanding the problem. 
>
> The issue is that `org-open-at-point', at the moment, cannot call
> the :follow function for "file+emacs" or "file+sys" since the common
> type is "file", even if `org-link-parameters' distinguish them. IOW the
> first :follow function would always be called.
>
> Also, `org-open-at-point' shouldn't be part of a follow function, since
> `org-open-at-point' calls follow functions. It can call `org-open-file',
> tho, as currently done in `org-open-at-point'.
>
> Actually, I can think of a third solution, which may well follow the
> path of least resistance. Instead of calling
>
>   (org-link-get-parameter type :follow)
>
> we would call
>
>   (org-link-get-parameter (if app (concat type "+" app) type) :follow)
>
> and get the appropriate follow function. This solution is local to
> `org-open-at-point', but I don't think other places need :follow
> function.
>
>>>>    (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))
>>>> +    (if data (setcdr data (org-combine-plists (cdr data) parameters))
>>>>        (push (cons type parameters) org-link-parameters)
>>>>        (org-make-link-regexps)
>>>>        (org-element-update-syntax))))
>>>
>>> This change can be merged with `org-link-set-parameters' definition.
>>
>> I am not sure how to do that. It is like a hunk in one commit that I
>> want to move to another commit.
>
> I would edit the commit defining `org-link-set-parameters' and install
> that change there. Then, upon rebasing, I would make sure this change is
> preserved.
>
>>>> +(defcustom org-link-parameters
>>>> +  '(("http") ("https") ("ftp") ("mailto")
>>>> +    ("file" :complete 'org-file-complete-link)
>>>> +    ("file+emacs") ("file+sys")
>>>> +    ("news") ("shell") ("elisp")
>>>> +    ("doi") ("message") ("help"))
>>>
>>> See above about "file+emacs" and "file+sys", which are not valid types.
>>
>> Those either need to be here for link regexps, or hard-coded somewhere
>> else though.
>
> You're right, they need to be here, but there is still an issue.
>
>>Speaking of which, should coderef be a link type, so it can
>> be removed as a hard-coded string that I referenced above?
>
> No it cannot. "coderef" is not a valid link type, since there is no
> [[coderef:something]]. It shouldn't belong to the link regexp.
>
> Regards,


-- 
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

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-07 19:17           ` John Kitchin
@ 2016-07-08 21:32             ` Nicolas Goaziou
  0 siblings, 0 replies; 26+ messages in thread
From: Nicolas Goaziou @ 2016-07-08 21:32 UTC (permalink / raw)
  To: John Kitchin; +Cc: emacs-orgmode@gnu.org

Hello,

John Kitchin <jkitchin@andrew.cmu.edu> writes:

> I don't understand what you mean here. The contents of org-link
> protocols (in master) looks a lot like a list of (link-type :follow
> :export), e.g.

You're right. Keys in `org-link-protocols' are types.

>>   (nth 1 (assoc app org-link-protocols))
>
> I see that these are not the same, since type != app.

Per the above, this snippet from `org-open-at-point' is suspicious.

> I was referring to the optional parameter, although I reconsider it
> here.  I don't understand how does the "application" get to the
> follow functions of links other than file+sys and file+emacs. It seems
> like we would need to allow type+application:path as a link syntax and
> extend the link-parser to get the application. Right now it looks like
> the parser only adds application properties to file type links.

file+sys and file+emacs predate the parser. Since the manual doesn't
seem to generalize them, parser support for them is rather minimalist.

I really hope this syntax is not going to be extended, because it
doesn't sound right to define the application opening a link at the
syntax level.

> I don't mind this (it makes links more flexible after all ;) OTOH, we
> would have to "register" each type+application for the link regexp, and
> then each type can have its own follow function, so it seems unnecessary
> to me.

I agree. As long as we need the regexp (because of plain links,
actually), my suggestion is a false good idea.

> My understanding of your statement of the problem is that the
> link-parser recognizes file:path, file+sys:path, and file+emacs:path as
> links of type "file", with different "application" properties. In the
> implementation of org-open-at-point on master, there is a cond branch
> for the "file" type link, and inside that the application is checked.
> Hence, without your suggestion at the end, there is not a way to access
> the :follow function of file+sys or file+emacs.
>
> To me this seems to be an unnecessary distinction from a link point of
> view since those three file links could just be defined as regular links
> with different follow/export functions. OTOH, perhaps there are other
> places in org-mode that rely on being able to tell when a link is a
> file, even if they are labeled file+sys or file+emacs that I am not
> aware of?

Any use not relying on :follow does not care above "+sys" or "+emacs".
E.g., during export, file+sys and file+emacs are treated the same.

> If I compare this to what exists in org-ref, for example, there
> are close to 40 different types of citations one can use, but they are
> all fundamentally "cite" types. They all share a common follow action,
> but have different export functions. When defined as separate links, I
> use them like cite:key citenum:key, citet:key, autocite:key, etc...
>
> Even here while I can see some utility for an application, e.g. perhaps
> to open the key in zotero, or mendeley or bibtex, I would normally
> associate that action with the :follow function. Am I missing
> something?

I think file+app was designed to override :follow function, so
associating the action with the :follow function wouldn't help.

> I only mentioned it because it seems to be in there in master via this line:
>
> (regexp-opt (cons "coderef" org-link-types)
>
> but it looks like it is in there in a different sort of way. It doesn't
> seem important here.

The line above creates a regexp matching types, as stored by the parser,
as returned by (org-element-property :type link). This can be "coderef".

OTOH (regexp-opt org-link-types) is meant to match links in an Org
buffer, where there is no "coderef".

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-07 19:21           ` John Kitchin
@ 2016-07-08 21:48             ` Nicolas Goaziou
  2016-07-08 22:04               ` John Kitchin
                                 ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Nicolas Goaziou @ 2016-07-08 21:48 UTC (permalink / raw)
  To: John Kitchin; +Cc: emacs-orgmode@gnu.org

John Kitchin <jkitchin@andrew.cmu.edu> writes:

> Here are the new revisions that implement the previous solution you
> suggested and that incorporate the commit merges as far as I can see.

Thank you.

> +(defcustom org-link-parameters
> +  '(("file"  :complete 'org-file-complete-link)

#'org-file-complete-link

> +    ("file+emacs" :follow (lambda (path) (org-open-file path '(4))))
> +    ("file+sys" :follow (lambda (path) (org-open-file path 'system)))

This will ignore so-called "option" part, e.g.

  [[file:test.org::3]]

:follow functions need to extract it somehow.

Once this issue is resolved, I think the whole change-set can be pushed
to master, AFAIC.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-08 21:48             ` Nicolas Goaziou
@ 2016-07-08 22:04               ` John Kitchin
  2016-07-09 13:27               ` John Kitchin
  2016-07-15  1:12               ` John Kitchin
  2 siblings, 0 replies; 26+ messages in thread
From: John Kitchin @ 2016-07-08 22:04 UTC (permalink / raw)
  To: John Kitchin, emacs-orgmode@gnu.org

[-- Attachment #1: Type: text/plain, Size: 1090 bytes --]

K

On Friday, July 8, 2016, Nicolas Goaziou <mail@nicolasgoaziou.fr> wrote:

> John Kitchin <jkitchin@andrew.cmu.edu <javascript:;>> writes:
>
> > Here are the new revisions that implement the previous solution you
> > suggested and that incorporate the commit merges as far as I can see.
>
> Thank you.
>
> > +(defcustom org-link-parameters
> > +  '(("file"  :complete 'org-file-complete-link)
>
> #'org-file-complete-link
>
> > +    ("file+emacs" :follow (lambda (path) (org-open-file path '(4))))
> > +    ("file+sys" :follow (lambda (path) (org-open-file path 'system)))
>
> This will ignore so-called "option" part, e.g.
>
>   [[file:test.org::3]]
>
> :follow functions need to extract it somehow.


Good catch. I can probably do that tomorrow. Thanks!

>
> Once this issue is resolved, I think the whole change-set can be pushed
> to master, AFAIC.
>


-- 
John

-----------------------------------
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

[-- Attachment #2: Type: text/html, Size: 1849 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-08 21:48             ` Nicolas Goaziou
  2016-07-08 22:04               ` John Kitchin
@ 2016-07-09 13:27               ` John Kitchin
  2016-07-18 12:02                 ` Nicolas Goaziou
  2016-07-15  1:12               ` John Kitchin
  2 siblings, 1 reply; 26+ messages in thread
From: John Kitchin @ 2016-07-09 13:27 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode@gnu.org

What do you think of this approach:

 (defcustom org-link-parameters
-  '(("file"  :complete 'org-file-complete-link)
-    ("file+emacs" :follow (lambda (path) (org-open-file path '(4))))
-    ("file+sys" :follow (lambda (path) (org-open-file path 'system)))
+  '(("file"  :complete #'org-file-complete-link)
+    ("file+emacs" :follow (lambda (path) (org-open-file-link path '(4))))
+    ("file+sys" :follow (lambda (path) (org-open-file-link path 'system)))
     ("http") ("https") ("ftp") ("mailto")
     ("news") ("shell") ("elisp")
     ("doi") ("message") ("help"))
@@ -10732,6 +10732,30 @@ they must return nil.")
 
 (defvar org-link-search-inhibit-query nil) ;; dynamically scoped
 (defvar clean-buffer-list-kill-buffer-names) ; Defined in midnight.el
+
+(defun org-open-file-link (path app)
+  "Open PATH using APP.
+
+PATH is from a file link, and can have the following 
+     [[file:~/code/main.c::255]]
+     [[file:~/xx.org::My Target]]
+     [[file:~/xx.org::*My Target]]
+     [[file:~/xx.org::#my-custom-id]]
+     [[file:~/xx.org::/regexp/]]
+
+APP is '(4) to open the PATH in Emacs, or 'system to use a system application."
+  (let* ((fields (split-string path "::"))	   
+	 (option (when (cdr fields)
+		   (mapconcat 'identity (cdr fields) ""))))
+    (apply #'org-open-file
+	   (car fields)
+	   app
+	   (cond ((not option) nil)
+		 ((org-string-match-p "\\`[0-9]+\\'" option)
+		  (list (string-to-number option)))
+		 (t (list nil
+			  (org-link-unescape option)))))))
+
 (defun org-open-at-point (&optional arg reference-buffer)
   "Open link, timestamp, footnote or tags at point.


Nicolas Goaziou writes:

> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
>> Here are the new revisions that implement the previous solution you
>> suggested and that incorporate the commit merges as far as I can see.
>
> Thank you.
>
>> +(defcustom org-link-parameters
>> +  '(("file"  :complete 'org-file-complete-link)
>
> #'org-file-complete-link
>
>> +    ("file+emacs" :follow (lambda (path) (org-open-file path '(4))))
>> +    ("file+sys" :follow (lambda (path) (org-open-file path 'system)))
>
> This will ignore so-called "option" part, e.g.
>
>   [[file:test.org::3]]
>
> :follow functions need to extract it somehow.
>
> Once this issue is resolved, I think the whole change-set can be pushed
> to master, AFAIC.


-- 
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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-08 21:48             ` Nicolas Goaziou
  2016-07-08 22:04               ` John Kitchin
  2016-07-09 13:27               ` John Kitchin
@ 2016-07-15  1:12               ` John Kitchin
  2016-07-18 11:48                 ` Nicolas Goaziou
  2 siblings, 1 reply; 26+ messages in thread
From: John Kitchin @ 2016-07-15  1:12 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode@gnu.org

Here are my current suggestions for the org-link 9.0. Let me know what
the best way to send these might be. It looks like it might be 21
patches right now. Thanks,

17 files changed, 187 insertions(+), 87 deletions(-)
contrib/orgmanual.org |  27 +++++----
doc/org.texi          |  27 +++++----
etc/ORG-NEWS          |   2 +
lisp/org-bbdb.el      |   8 ++-
lisp/org-bibtex.el    |   5 +-
lisp/org-docview.el   |   6 +-
lisp/org-element.el   |   4 +-
lisp/org-eshell.el    |   5 +-
lisp/org-gnus.el      |   3 +-
lisp/org-id.el        |   2 +-
lisp/org-info.el      |   8 ++-
lisp/org-irc.el       |   4 +-
lisp/org-mhe.el       |   3 +-
lisp/org-rmail.el     |   3 +-
lisp/org-w3m.el       |   2 +-
lisp/org.el           | 163 ++++++++++++++++++++++++++++++++++++++------------
lisp/ox.el            |   2 +-

modified   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~.
 
modified   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
modified   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~.
modified   lisp/org-bbdb.el
@@ -194,10 +194,12 @@ 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 ()
modified   lisp/org-bibtex.el
@@ -452,8 +452,9 @@ With optional argument OPTIONAL, also prompt for optional fields."
 
 \f
 ;;; 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
+			 :store #'org-bibtex-store-link)
 
 (defun org-bibtex-open (path)
   "Visit the bibliography entry on PATH."
modified   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."
modified   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))))
modified   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.
modified   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
 
modified   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)
 
modified   lisp/org-info.el
@@ -40,8 +40,10 @@
 (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 +115,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))
modified   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."
modified   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 ()
modified   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 ()
modified   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)
modified   lisp/org.el
@@ -1803,10 +1803,11 @@ 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)))
+		:value-type plist))
 
 (defun org-link-get-parameter (type key)
-  "Get TYPE link property for KEY."
+  "Get TYPE link property for KEY.
+TYPE is a string and KEY is a plist keyword."
   (plist-get
    (cdr (assoc type org-link-parameters))
    key))
@@ -1815,11 +1816,7 @@ as arguments."
   "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))
+    (if data (setcdr data (org-combine-plists (cdr data) parameters))
       (push (cons type parameters) org-link-parameters)
       (org-make-link-regexps)
       (org-element-update-syntax))))
@@ -5728,9 +5725,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
@@ -5797,8 +5791,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
@@ -5836,7 +5830,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) ":\\)?"
 	   "\\([^]]+\\)"
 	   "\\]"
 	   "\\(\\[" "\\([^]]+\\)" "\\]\\)?"
@@ -5934,17 +5928,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)
@@ -6134,14 +6168,67 @@ 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
+		   (and (string-match org-plain-link-re hl)
+			(match-string-no-properties 1 hl))))
+	   (path (save-match-data
+		   (and (string-match org-plain-link-re hl)
+			(match-string-no-properties 2 hl))))
+	   (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))
@@ -6161,6 +6248,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)
@@ -6432,8 +6521,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))
@@ -10367,7 +10456,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
@@ -10471,7 +10560,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 ":")))))
@@ -10773,7 +10862,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 +10876,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 +10891,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))
+	       ((functionp (org-link-get-parameter type :follow))
+		(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 +10941,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)
modified   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))

[back]


Nicolas Goaziou writes:

> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
>> Here are the new revisions that implement the previous solution you
>> suggested and that incorporate the commit merges as far as I can see.
>
> Thank you.
>
>> +(defcustom org-link-parameters
>> +  '(("file"  :complete 'org-file-complete-link)
>
> #'org-file-complete-link
>
>> +    ("file+emacs" :follow (lambda (path) (org-open-file path '(4))))
>> +    ("file+sys" :follow (lambda (path) (org-open-file path 'system)))
>
> This will ignore so-called "option" part, e.g.
>
>   [[file:test.org::3]]
>
> :follow functions need to extract it somehow.
>
> Once this issue is resolved, I think the whole change-set can be pushed
> to master, AFAIC.


-- 
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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-15  1:12               ` John Kitchin
@ 2016-07-18 11:48                 ` Nicolas Goaziou
  2016-07-18 15:20                   ` John Kitchin
  0 siblings, 1 reply; 26+ messages in thread
From: Nicolas Goaziou @ 2016-07-18 11:48 UTC (permalink / raw)
  To: John Kitchin; +Cc: emacs-orgmode@gnu.org

Hello,

John Kitchin <jkitchin@andrew.cmu.edu> writes:

> Here are my current suggestions for the org-link 9.0.

Thank you.

> Let me know what the best way to send these might be. It looks like it
> might be 21 patches right now.

AFAIU, many among them introduce code that no longer exists in the final
draft. It would be nice to make them disappear, using interactive
rebasing, as suggested earlier in this thread.

If that's not possible, just send them over here, I'll apply them.

BTW sent patch doesn't seem to include an option handler. Am I missing something?

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-09 13:27               ` John Kitchin
@ 2016-07-18 12:02                 ` Nicolas Goaziou
  0 siblings, 0 replies; 26+ messages in thread
From: Nicolas Goaziou @ 2016-07-18 12:02 UTC (permalink / raw)
  To: John Kitchin; +Cc: emacs-orgmode@gnu.org

John Kitchin <jkitchin@andrew.cmu.edu> writes:

> What do you think of this approach:
>
>  (defcustom org-link-parameters
> -  '(("file"  :complete 'org-file-complete-link)
> -    ("file+emacs" :follow (lambda (path) (org-open-file path '(4))))
> -    ("file+sys" :follow (lambda (path) (org-open-file path 'system)))
> +  '(("file"  :complete #'org-file-complete-link)
> +    ("file+emacs" :follow (lambda (path) (org-open-file-link path '(4))))
> +    ("file+sys" :follow (lambda (path) (org-open-file-link path 'system)))

It could work, but I suggest to rename it `org--open-file-link' or some
such, i.e., make it an internal function, because it could be confusing
with `org-open-link-from-string'.

>      ("http") ("https") ("ftp") ("mailto")
>      ("news") ("shell") ("elisp")
>      ("doi") ("message") ("help"))
> @@ -10732,6 +10732,30 @@ they must return nil.")
>  
>  (defvar org-link-search-inhibit-query nil) ;; dynamically scoped
>  (defvar clean-buffer-list-kill-buffer-names) ; Defined in midnight.el
> +
> +(defun org-open-file-link (path app)
> +  "Open PATH using APP.
> +
> +PATH is from a file link, and can have the following

missing "syntax"?

> +     [[file:~/code/main.c::255]]
> +     [[file:~/xx.org::My Target]]
> +     [[file:~/xx.org::*My Target]]
> +     [[file:~/xx.org::#my-custom-id]]
> +     [[file:~/xx.org::/regexp/]]
> +
> +APP is '(4) to open the PATH in Emacs, or 'system to use a system application."
> +  (let* ((fields (split-string path "::"))	   
> +	 (option (when (cdr fields)
> +		   (mapconcat 'identity (cdr fields) ""))))

(and (cdr field)
     (mapconcat #'identity (cdr fields) ""))
     
> +    (apply #'org-open-file
> +	   (car fields)
> +	   app
> +	   (cond ((not option) nil)
> +		 ((org-string-match-p "\\`[0-9]+\\'" option)

org-string-match-p -> string-match-p


Regards,

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-18 11:48                 ` Nicolas Goaziou
@ 2016-07-18 15:20                   ` John Kitchin
  2016-07-18 16:05                     ` Nicolas Goaziou
  0 siblings, 1 reply; 26+ messages in thread
From: John Kitchin @ 2016-07-18 15:20 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode@gnu.org

[-- Attachment #1: Type: text/plain, Size: 1744 bytes --]


Nicolas Goaziou writes:

> Hello,
>
> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
>> Here are my current suggestions for the org-link 9.0.
>
> Thank you.

I think I fixed the points you made in the previous email.

>
>> Let me know what the best way to send these might be. It looks like it
>> might be 21 patches right now.
>
> AFAIU, many among them introduce code that no longer exists in the final
> draft. It would be nice to make them disappear, using interactive
> rebasing, as suggested earlier in this thread.

I am not sure what you mean for this. Let me know if it isn't fixed in
the attached patches. I thought I had squashed everything into a concise
history. 

>
> If that's not possible, just send them over here, I'll apply them.
>
> BTW sent patch doesn't seem to include an option handler. Am I missing
> something?

What do you mean by an option handler?

Do you mean for this file:path::option

I think this code below (which should be in the patches) handles the
option correctly.

(defun org--open-file-link (path app)
  "Open PATH using APP.

PATH is from a file link, and can have the following syntax:
     [[file:~/code/main.c::255]]
     [[file:~/xx.org::My Target]]
     [[file:~/xx.org::*My Target]]
     [[file:~/xx.org::#my-custom-id]]
     [[file:~/xx.org::/regexp/]]

APP is '(4) to open the PATH in Emacs, or 'system to use a system application."
  (let* ((fields (split-string path "::"))	   
	 (option (and (cdr fields)
		      (mapconcat #'identity (cdr fields) ""))))
    (apply #'org-open-file
	   (car fields)
	   app
	   (cond ((not option) nil)
		 ((string-match-p "\\`[0-9]+\\'" option)
		  (list (string-to-number option)))
		 (t (list nil
			  (org-link-unescape option)))))))


>
> Regards,


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Create-org-link-parameters.patch --]
[-- Type: text/x-patch, Size: 16031 bytes --]

From ddc863fc16b8fe4b430e2f86b7ad96a0e90219cc Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Thu, 7 Jul 2016 09:58:29 -0400
Subject: [PATCH 01/20] Create `org-link-parameters'

* lisp/org-element.el: Replace `org-link-types' variable with
  `org-link-types' function.

* lisp/org.el: Replace the `org-link-types' variable with
  `org-link-types' function. Create `org-link-get-parameter' and
  `org-link-set-parameters' functions. Remove `org-add-link-type'. Add
  `org-store-link-functions' function and remove
  `org-store-link-functions' variable. Add `org--open-file-link' for use
  as a :follow function for file type links.

* lisp/org.el: Set :follow functions for file links in `org-link-parameters.
Define `org-open-file-link' that opens a file link with an app.

* testing/lisp/test-ox.el: Remove usage of the `org-link-types'
  variable.

* lisp/org-compat.el: Move `org-add-link-type' and mark it as obsolete.

* lisp/ox.el: Change org-add-link-type comment in ox.el.
---
 lisp/org-compat.el      |  31 +++++++++
 lisp/org-element.el     |   4 +-
 lisp/org.el             | 167 ++++++++++++++++++++++++++++++++----------------
 lisp/ox.el              |   2 +-
 testing/lisp/test-ox.el |  16 ++---
 5 files changed, 155 insertions(+), 65 deletions(-)

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-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..5b92e12 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -1758,6 +1758,73 @@ 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
+  '(("file"  :complete #'org-file-complete-link)
+    ("file+emacs" :follow (lambda (path) (org--open-file-link path '(4))))
+    ("file+sys" :follow (lambda (path) (org--open-file-link path 'system)))
+    ("http") ("https") ("ftp") ("mailto")
+    ("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
+function `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 arguments 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 parameters"
+		:value-type plist))
+
+(defun org-link-get-parameter (type key)
+  "Get TYPE link property for KEY.
+TYPE is a string and KEY is a plist keyword."
+  (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 (setcdr data (org-combine-plists (cdr data) parameters))
+      (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 +5557,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)
@@ -5658,9 +5725,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 +5791,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 +5830,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) ":\\)?"
 	   "\\([^]]+\\)"
 	   "\\]"
 	   "\\(\\[" "\\([^]]+\\)" "\\]\\)?"
@@ -7393,7 +7457,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
 
@@ -9666,60 +9730,32 @@ 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'.")
+(defun org-store-link-functions ()
+  "Returns a list of functions that are called to create and store a link.
+The functions defined in the :store property of
+`org-link-parameters'.
 
-(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
-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:
+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.
+              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.")
-
-(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)))
+and then used in capture templates."
+  (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
@@ -9764,7 +9800,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
@@ -10325,7 +10361,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
@@ -10601,6 +10637,29 @@ they must return nil.")
 
 (defvar org-link-search-inhibit-query nil) ;; dynamically scoped
 (defvar clean-buffer-list-kill-buffer-names) ; Defined in midnight.el
+(defun org--open-file-link (path app)
+  "Open PATH using APP.
+
+PATH is from a file link, and can have the following syntax:
+     [[file:~/code/main.c::255]]
+     [[file:~/xx.org::My Target]]
+     [[file:~/xx.org::*My Target]]
+     [[file:~/xx.org::#my-custom-id]]
+     [[file:~/xx.org::/regexp/]]
+
+APP is '(4) to open the PATH in Emacs, or 'system to use a system application."
+  (let* ((fields (split-string path "::"))	   
+	 (option (and (cdr fields)
+		      (mapconcat #'identity (cdr fields) ""))))
+    (apply #'org-open-file
+	   (car fields)
+	   app
+	   (cond ((not option) nil)
+		 ((string-match-p "\\`[0-9]+\\'" option)
+		  (list (string-to-number option)))
+		 (t (list nil
+			  (org-link-unescape option)))))))
+
 (defun org-open-at-point (&optional arg reference-buffer)
   "Open link, timestamp, footnote or tags at point.
 
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 8b07cca..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 (copy-sequence 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 (copy-sequence 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 (copy-sequence 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
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Remove-org-link-protocols-variable.patch --]
[-- Type: text/x-patch, Size: 3896 bytes --]

From 8225a3b630de05bb507dea2b85b10af5a8776afc Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Thu, 7 Jul 2016 10:02:29 -0400
Subject: [PATCH 02/20] Remove `org-link-protocols' variable

* lisp/org.el (org-link-protocols): Remove variable org-link-protocols.
The data in this variable is now retrieved with org-link-get-parameter.

* lisp/org.el: Enable file links to use the application link property to
  determine the follow action. Also add a space after let*.
---
 lisp/org.el | 18 +++++++++---------
 lisp/ox.el  |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index 5b92e12..13f794a 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -10755,10 +10755,10 @@ link in a property drawer line."
 	  ;; When link is located within the description of another
 	  ;; link (e.g., an inline image), always open the parent
 	  ;; link.
-	  (let*((link (let ((up (org-element-property :parent context)))
-			(if (eq (org-element-type up) 'link) up context)))
-		(type (org-element-property :type link))
-		(path (org-link-unescape (org-element-property :path link))))
+	  (let* ((link (let ((up (org-element-property :parent context)))
+			 (if (eq (org-element-type up) 'link) up context)))
+		 (type (org-element-property :type link))
+		 (path (org-link-unescape (org-element-property :path link))))
 	    ;; Switch back to REFERENCE-BUFFER needed when called in
 	    ;; a temporary buffer through `org-open-link-from-string'.
 	    (with-current-buffer (or reference-buffer (current-buffer))
@@ -10766,7 +10766,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'
@@ -10780,7 +10780,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 (if app (concat type "+" app) type) :follow)))
 		    (if dedicated-function
 			(funcall dedicated-function
 				 (concat path
@@ -10795,8 +10795,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))
+	       ((functionp (org-link-get-parameter type :follow))
+		(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))
@@ -10845,7 +10845,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))
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-Get-the-complete-function-from-org-link-parameters.patch --]
[-- Type: text/x-patch, Size: 1134 bytes --]

From 5f2f09643d1c79ce83c2b990700227f90c262bfe Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:20:23 -0400
Subject: [PATCH 03/20] 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.
---
 lisp/org.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/org.el b/lisp/org.el
index 13f794a..5448bdb 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -10465,7 +10465,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 ":")))))
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-Update-org-activate-plain-links.patch --]
[-- Type: text/x-patch, Size: 2872 bytes --]

From f4dcf689de2c0091597fd07d2b88c194e12eb873 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:21:08 -0400
Subject: [PATCH 04/20] Update `org-activate-plain-links'

* lisp/org.el (org-activate-plain-links): Use `org-link-parameters' to
  create the link properties.
---
 lisp/org.el | 54 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 7 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index 5448bdb..886c288 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -5928,17 +5928,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)
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0005-Update-org-activate-bracket-links.patch --]
[-- Type: text/x-patch, Size: 3436 bytes --]

From 0aaa52eefc8022b8b62fe9ab7134b8f9c38b3737 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:21:50 -0400
Subject: [PATCH 05/20] Update `org-activate-bracket-links'

* lisp/org.el (org-activate-bracket-links): Use `org-link-parameters' to
  build link properties.
---
 lisp/org.el | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 63 insertions(+), 8 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index 886c288..a7aa4ee 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6168,14 +6168,67 @@ 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
+		   (and (string-match org-plain-link-re hl)
+			(match-string-no-properties 1 hl))))
+	   (path (save-match-data
+		   (and (string-match org-plain-link-re hl)
+			(match-string-no-properties 2 hl))))
+	   (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))
@@ -6195,6 +6248,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)
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #7: 0006-Make-plain-and-bracketed-link-properties-stick.patch --]
[-- Type: text/x-patch, Size: 1301 bytes --]

From 8be88f99413786a38f358b0901a2a1ffaa9651f7 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:22:24 -0400
Subject: [PATCH 06/20] 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.
---
 lisp/org.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index a7aa4ee..3843dab 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6521,8 +6521,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))
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #8: 0007-Update-bbdb-link-definition.patch --]
[-- Type: text/x-patch, Size: 963 bytes --]

From d2142696b4da3a262dc550c0cbadbcec324023fb Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:25:39 -0400
Subject: [PATCH 07/20] Update bbdb link definition

* lisp/org-bbdb.el ("bbdb"):

Change link definition to org-link-set-parameters
---
 lisp/org-bbdb.el | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lisp/org-bbdb.el b/lisp/org-bbdb.el
index 8d886cd..5f3971b 100644
--- a/lisp/org-bbdb.el
+++ b/lisp/org-bbdb.el
@@ -194,10 +194,12 @@ 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 ()
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #9: 0008-Update-bibtex-link-definition.patch --]
[-- Type: text/x-patch, Size: 929 bytes --]

From f1be7da9a58afc8ee8109738758eefa67e3c724e Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:26:04 -0400
Subject: [PATCH 08/20] Update bibtex link definition

* lisp/org-bibtex.el ("bibtex"):

Change link definition to use org-link-set-parameters
---
 lisp/org-bibtex.el | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lisp/org-bibtex.el b/lisp/org-bibtex.el
index 74e32f7..e740353 100644
--- a/lisp/org-bibtex.el
+++ b/lisp/org-bibtex.el
@@ -452,8 +452,9 @@ With optional argument OPTIONAL, also prompt for optional fields."
 
 \f
 ;;; 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
+			 :store #'org-bibtex-store-link)
 
 (defun org-bibtex-open (path)
   "Visit the bibliography entry on PATH."
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #10: 0009-Update-docview-link-definition.patch --]
[-- Type: text/x-patch, Size: 1059 bytes --]

From db83d9940464171936bc2f04cf5827fc33003990 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:26:28 -0400
Subject: [PATCH 09/20] Update docview link definition

* lisp/org-docview.el ("docview"):

Update link definition with org-link-set-parameters.
---
 lisp/org-docview.el | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lisp/org-docview.el b/lisp/org-docview.el
index fbc5551..3d4df40 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."
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #11: 0010-Update-eshell-link-definition.patch --]
[-- Type: text/x-patch, Size: 871 bytes --]

From 199678c0007461b7a57cc4e6b251792d1cae9663 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:27:03 -0400
Subject: [PATCH 10/20] Update eshell link definition

* lisp/org-eshell.el ("eshell"):

Update to use org-link-set-parameters.
---
 lisp/org-eshell.el | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lisp/org-eshell.el b/lisp/org-eshell.el
index 1919f6d..6f9a18a 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.
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #12: 0011-Update-gnus-link-definition.patch --]
[-- Type: text/x-patch, Size: 800 bytes --]

From 25a9106eb4d29f9996a599ff9fdee980ef9ef785 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:27:14 -0400
Subject: [PATCH 11/20] Update gnus link definition

* lisp/org-gnus.el ("gnus"):
Update link definition with org-link-set-parameters.
---
 lisp/org-gnus.el | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lisp/org-gnus.el b/lisp/org-gnus.el
index 386d6dc..13e28cc 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
 
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #13: 0012-Update-info-link-definition.patch --]
[-- Type: text/x-patch, Size: 1345 bytes --]

From b285b6d04d85f13e6d7612e7c39635e99178d1cb Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:27:32 -0400
Subject: [PATCH 12/20] 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.
---
 lisp/org-info.el | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lisp/org-info.el b/lisp/org-info.el
index 9e8fde0..8765c53 100644
--- a/lisp/org-info.el
+++ b/lisp/org-info.el
@@ -40,8 +40,10 @@
 (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 +115,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))
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #14: 0013-Update-irc-link-definition.patch --]
[-- Type: text/x-patch, Size: 873 bytes --]

From 5148d0b901aed5a773dbacf0e5149fd56578787c Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:27:45 -0400
Subject: [PATCH 13/20] Update irc link definition

* lisp/org-irc.el ("irc"):
Define link with org-link-set-parameters.
---
 lisp/org-irc.el | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lisp/org-irc.el b/lisp/org-irc.el
index 81d0296..5b9c839 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."
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #15: 0014-Update-mhe-link-definition.patch --]
[-- Type: text/x-patch, Size: 819 bytes --]

From 9556cf43dc421abce0d51632c08fcc2abfc90ab2 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:27:55 -0400
Subject: [PATCH 14/20] Update mhe link definition.

* lisp/org-mhe.el ("mhe"):
Define link with org-link-set-parameters.
---
 lisp/org-mhe.el | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lisp/org-mhe.el b/lisp/org-mhe.el
index 2ee21de..c793eed 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 ()
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #16: 0015-Update-rmail-link-definition.patch --]
[-- Type: text/x-patch, Size: 844 bytes --]

From 6ec1112fcef7f93292125b578a3ee8f88a250d2b Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:28:09 -0400
Subject: [PATCH 15/20] Update rmail link definition

* lisp/org-rmail.el ("rmail"):
Use org-link-set-parameters to define link.
---
 lisp/org-rmail.el | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lisp/org-rmail.el b/lisp/org-rmail.el
index 0bf44b8..35bf073 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 ()
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #17: 0016-Update-w3m-link-definition.patch --]
[-- Type: text/x-patch, Size: 771 bytes --]

From 484349af5e3c751672d3ac5fe29cab7638ab5f8f Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:28:38 -0400
Subject: [PATCH 16/20] Update w3m link definition

* lisp/org-w3m.el ("w3m"):
Update to use org-link-set-parameters.
---
 lisp/org-w3m.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/org-w3m.el b/lisp/org-w3m.el
index 57ecafe..28bc492 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)
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #18: 0017-Update-the-id-link-with-org-link-set-parameters.patch --]
[-- Type: text/x-patch, Size: 702 bytes --]

From c57fb8d7741362c3583844c6eb9ae8ed40732eb0 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 16:11:08 -0400
Subject: [PATCH 17/20] Update the "id" link with org-link-set-parameters

* lisp/org-id.el:
---
 lisp/org-id.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/org-id.el b/lisp/org-id.el
index 2646c80..5ad7f00 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)
 
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #19: 0018-Update-the-texinfo-for-link-parameters-documentation.patch --]
[-- Type: text/x-patch, Size: 3088 bytes --]

From 52a2fa192ec2f2ce5e5138b97cf695abf2aeffaf Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:29:07 -0400
Subject: [PATCH 18/20] Update the texinfo for link parameters documentation

---
 doc/org.texi | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/doc/org.texi b/doc/org.texi
index e92788f..f962a58 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
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #20: 0019-Update-NEWS-with-link-announcement.patch --]
[-- Type: text/x-patch, Size: 912 bytes --]

From b60f795819c1294be2315c9208f4ac64d89088e4 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:31:30 -0400
Subject: [PATCH 19/20] Update NEWS with link announcement

---
 etc/ORG-NEWS | 2 ++
 1 file changed, 2 insertions(+)

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~.
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #21: 0020-Update-the-contrib-manual.patch --]
[-- Type: text/x-patch, Size: 2681 bytes --]

From ea975f48749776e1d7b3a84d1ed3598c059bf9a6 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:38:42 -0400
Subject: [PATCH 20/20] Update the contrib manual

---
 contrib/orgmanual.org | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/contrib/orgmanual.org b/contrib/orgmanual.org
index e48ae97..07d9e8d 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~.
 
-- 
2.9.0


[-- Attachment #22: Type: text/plain, Size: 192 bytes --]




-- 
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

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-18 15:20                   ` John Kitchin
@ 2016-07-18 16:05                     ` Nicolas Goaziou
  2016-07-18 16:55                       ` John Kitchin
  0 siblings, 1 reply; 26+ messages in thread
From: Nicolas Goaziou @ 2016-07-18 16:05 UTC (permalink / raw)
  To: John Kitchin; +Cc: emacs-orgmode@gnu.org

John Kitchin <jkitchin@andrew.cmu.edu> writes:

> I am not sure what you mean for this. Let me know if it isn't fixed in
> the attached patches. I thought I had squashed everything into a concise
> history.

No worries. Let's just apply the 21 patches.

> I think this code below (which should be in the patches) handles the
> option correctly.
>
> (defun org--open-file-link (path app)

It should, but I didn't see it in the previous patch, hence my remark.

> -(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
> -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:
> +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:

Missing a space after the full stop above.

> +(defun org--open-file-link (path app)
> +  "Open PATH using APP.
> +
> +PATH is from a file link, and can have the following syntax:
> +     [[file:~/code/main.c::255]]
> +     [[file:~/xx.org::My Target]]
> +     [[file:~/xx.org::*My Target]]
> +     [[file:~/xx.org::#my-custom-id]]
> +     [[file:~/xx.org::/regexp/]]
> +
> +APP is '(4) to open the PATH in Emacs, or 'system to use a system
> application."

Maybe something like:

  Called it with \\[universal-argument] to open PATH in Emacs. If ARG is
  `system', use a system application instead.


Regards,

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-18 16:05                     ` Nicolas Goaziou
@ 2016-07-18 16:55                       ` John Kitchin
  2016-07-18 21:59                         ` Nicolas Goaziou
  2016-08-06  1:14                         ` [PATCH] " Matt Lundin
  0 siblings, 2 replies; 26+ messages in thread
From: John Kitchin @ 2016-07-18 16:55 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode@gnu.org

[-- Attachment #1: Type: text/plain, Size: 2030 bytes --]


Nicolas Goaziou writes:

> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
>> I am not sure what you mean for this. Let me know if it isn't fixed in
>> the attached patches. I thought I had squashed everything into a concise
>> history.
>
> No worries. Let's just apply the 21 patches.

Ok. I have attached 20 patches with the updates below.

>
>> I think this code below (which should be in the patches) handles the
>> option correctly.
>>
>> (defun org--open-file-link (path app)
>
> It should, but I didn't see it in the previous patch, hence my remark.
>
>> -(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
>> -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:
>> +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:
>
> Missing a space after the full stop above.
>
>> +(defun org--open-file-link (path app)
>> +  "Open PATH using APP.
>> +
>> +PATH is from a file link, and can have the following syntax:
>> +     [[file:~/code/main.c::255]]
>> +     [[file:~/xx.org::My Target]]
>> +     [[file:~/xx.org::*My Target]]
>> +     [[file:~/xx.org::#my-custom-id]]
>> +     [[file:~/xx.org::/regexp/]]
>> +
>> +APP is '(4) to open the PATH in Emacs, or 'system to use a system
>> application."
>
> Maybe something like:
>
>   Called it with \\[universal-argument] to open PATH in Emacs. If ARG is
>   `system', use a system application instead.
>
>
> Regards,

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Create-org-link-parameters.patch --]
[-- Type: text/x-patch, Size: 16070 bytes --]

From 9255b7f7b5462a82fb720720fc10eb5a1bd17297 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Thu, 7 Jul 2016 09:58:29 -0400
Subject: [PATCH 01/20] Create `org-link-parameters'

* lisp/org-element.el: Replace `org-link-types' variable with
  `org-link-types' function.

* lisp/org.el: Replace the `org-link-types' variable with
  `org-link-types' function. Create `org-link-get-parameter' and
  `org-link-set-parameters' functions. Remove `org-add-link-type'. Add
  `org-store-link-functions' function and remove
  `org-store-link-functions' variable. Add `org--open-file-link' for use
  as a :follow function for file type links.

* lisp/org.el: Set :follow functions for file links in `org-link-parameters.
Define `org-open-file-link' that opens a file link with an app.

* testing/lisp/test-ox.el: Remove usage of the `org-link-types'
  variable.

* lisp/org-compat.el: Move `org-add-link-type' and mark it as obsolete.

* lisp/ox.el: Change org-add-link-type comment in ox.el.
---
 lisp/org-compat.el      |  31 +++++++++
 lisp/org-element.el     |   4 +-
 lisp/org.el             | 168 ++++++++++++++++++++++++++++++++----------------
 lisp/ox.el              |   2 +-
 testing/lisp/test-ox.el |  16 ++---
 5 files changed, 156 insertions(+), 65 deletions(-)

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-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..7b12404 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -1758,6 +1758,73 @@ 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
+  '(("file"  :complete #'org-file-complete-link)
+    ("file+emacs" :follow (lambda (path) (org--open-file-link path '(4))))
+    ("file+sys" :follow (lambda (path) (org--open-file-link path 'system)))
+    ("http") ("https") ("ftp") ("mailto")
+    ("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
+function `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 arguments 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 parameters"
+		:value-type plist))
+
+(defun org-link-get-parameter (type key)
+  "Get TYPE link property for KEY.
+TYPE is a string and KEY is a plist keyword."
+  (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 (setcdr data (org-combine-plists (cdr data) parameters))
+      (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 +5557,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)
@@ -5658,9 +5725,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 +5791,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 +5830,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) ":\\)?"
 	   "\\([^]]+\\)"
 	   "\\]"
 	   "\\(\\[" "\\([^]]+\\)" "\\]\\)?"
@@ -7393,7 +7457,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
 
@@ -9666,60 +9730,32 @@ 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'.")
+(defun org-store-link-functions ()
+  "Returns a list of functions that are called to create and store a link.
+The functions defined in the :store property of
+`org-link-parameters'.
 
-(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
-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:
+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.
+              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.")
-
-(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)))
+and then used in capture templates."
+  (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
@@ -9764,7 +9800,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
@@ -10325,7 +10361,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
@@ -10601,6 +10637,30 @@ they must return nil.")
 
 (defvar org-link-search-inhibit-query nil) ;; dynamically scoped
 (defvar clean-buffer-list-kill-buffer-names) ; Defined in midnight.el
+(defun org--open-file-link (path app)
+  "Open PATH using APP.
+
+PATH is from a file link, and can have the following syntax:
+     [[file:~/code/main.c::255]]
+     [[file:~/xx.org::My Target]]
+     [[file:~/xx.org::*My Target]]
+     [[file:~/xx.org::#my-custom-id]]
+     [[file:~/xx.org::/regexp/]]
+
+Call it with \\[universal-argument] to open PATH in Emacs.  If ARG is
+  `system', use a system application instead."
+  (let* ((fields (split-string path "::"))	   
+	 (option (and (cdr fields)
+		      (mapconcat #'identity (cdr fields) ""))))
+    (apply #'org-open-file
+	   (car fields)
+	   app
+	   (cond ((not option) nil)
+		 ((string-match-p "\\`[0-9]+\\'" option)
+		  (list (string-to-number option)))
+		 (t (list nil
+			  (org-link-unescape option)))))))
+
 (defun org-open-at-point (&optional arg reference-buffer)
   "Open link, timestamp, footnote or tags at point.
 
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 8b07cca..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 (copy-sequence 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 (copy-sequence 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 (copy-sequence 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
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Remove-org-link-protocols-variable.patch --]
[-- Type: text/x-patch, Size: 3896 bytes --]

From e056405efe7b98b7f6575b18daa8671194851763 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Thu, 7 Jul 2016 10:02:29 -0400
Subject: [PATCH 02/20] Remove `org-link-protocols' variable

* lisp/org.el (org-link-protocols): Remove variable org-link-protocols.
The data in this variable is now retrieved with org-link-get-parameter.

* lisp/org.el: Enable file links to use the application link property to
  determine the follow action. Also add a space after let*.
---
 lisp/org.el | 18 +++++++++---------
 lisp/ox.el  |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index 7b12404..4ed4503 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -10756,10 +10756,10 @@ link in a property drawer line."
 	  ;; When link is located within the description of another
 	  ;; link (e.g., an inline image), always open the parent
 	  ;; link.
-	  (let*((link (let ((up (org-element-property :parent context)))
-			(if (eq (org-element-type up) 'link) up context)))
-		(type (org-element-property :type link))
-		(path (org-link-unescape (org-element-property :path link))))
+	  (let* ((link (let ((up (org-element-property :parent context)))
+			 (if (eq (org-element-type up) 'link) up context)))
+		 (type (org-element-property :type link))
+		 (path (org-link-unescape (org-element-property :path link))))
 	    ;; Switch back to REFERENCE-BUFFER needed when called in
 	    ;; a temporary buffer through `org-open-link-from-string'.
 	    (with-current-buffer (or reference-buffer (current-buffer))
@@ -10767,7 +10767,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'
@@ -10781,7 +10781,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 (if app (concat type "+" app) type) :follow)))
 		    (if dedicated-function
 			(funcall dedicated-function
 				 (concat path
@@ -10796,8 +10796,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))
+	       ((functionp (org-link-get-parameter type :follow))
+		(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))
@@ -10846,7 +10846,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))
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-Get-the-complete-function-from-org-link-parameters.patch --]
[-- Type: text/x-patch, Size: 1134 bytes --]

From 2a1f35cce3a2472ccfabab6a7ac21381e065a407 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:20:23 -0400
Subject: [PATCH 03/20] 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.
---
 lisp/org.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/org.el b/lisp/org.el
index 4ed4503..11a70d8 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -10465,7 +10465,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 ":")))))
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-Update-org-activate-plain-links.patch --]
[-- Type: text/x-patch, Size: 2872 bytes --]

From 25cabb65ad30ad1e61dad242cce29f9c2aed6650 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:21:08 -0400
Subject: [PATCH 04/20] Update `org-activate-plain-links'

* lisp/org.el (org-activate-plain-links): Use `org-link-parameters' to
  create the link properties.
---
 lisp/org.el | 54 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 7 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index 11a70d8..ae724ce 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -5928,17 +5928,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)
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0005-Update-org-activate-bracket-links.patch --]
[-- Type: text/x-patch, Size: 3436 bytes --]

From 387d54acf37c60092b5e7c643fd1dec4a6fbf661 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:21:50 -0400
Subject: [PATCH 05/20] Update `org-activate-bracket-links'

* lisp/org.el (org-activate-bracket-links): Use `org-link-parameters' to
  build link properties.
---
 lisp/org.el | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 63 insertions(+), 8 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index ae724ce..60bf052 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6168,14 +6168,67 @@ 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
+		   (and (string-match org-plain-link-re hl)
+			(match-string-no-properties 1 hl))))
+	   (path (save-match-data
+		   (and (string-match org-plain-link-re hl)
+			(match-string-no-properties 2 hl))))
+	   (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))
@@ -6195,6 +6248,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)
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #7: 0006-Make-plain-and-bracketed-link-properties-stick.patch --]
[-- Type: text/x-patch, Size: 1301 bytes --]

From 1cb67213dc794324583717a866f0783456c538b4 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:22:24 -0400
Subject: [PATCH 06/20] 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.
---
 lisp/org.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index 60bf052..24ed97e 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -6521,8 +6521,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))
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #8: 0007-Update-bbdb-link-definition.patch --]
[-- Type: text/x-patch, Size: 963 bytes --]

From b2c85eabafa20525ead669e33e65fdf0831b42ba Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:25:39 -0400
Subject: [PATCH 07/20] Update bbdb link definition

* lisp/org-bbdb.el ("bbdb"):

Change link definition to org-link-set-parameters
---
 lisp/org-bbdb.el | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lisp/org-bbdb.el b/lisp/org-bbdb.el
index 8d886cd..5f3971b 100644
--- a/lisp/org-bbdb.el
+++ b/lisp/org-bbdb.el
@@ -194,10 +194,12 @@ 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 ()
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #9: 0008-Update-bibtex-link-definition.patch --]
[-- Type: text/x-patch, Size: 929 bytes --]

From 5ab89ffb7227cd5d4016b6da778b1d1318dd81b1 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:26:04 -0400
Subject: [PATCH 08/20] Update bibtex link definition

* lisp/org-bibtex.el ("bibtex"):

Change link definition to use org-link-set-parameters
---
 lisp/org-bibtex.el | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lisp/org-bibtex.el b/lisp/org-bibtex.el
index 74e32f7..e740353 100644
--- a/lisp/org-bibtex.el
+++ b/lisp/org-bibtex.el
@@ -452,8 +452,9 @@ With optional argument OPTIONAL, also prompt for optional fields."
 
 \f
 ;;; 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
+			 :store #'org-bibtex-store-link)
 
 (defun org-bibtex-open (path)
   "Visit the bibliography entry on PATH."
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #10: 0009-Update-docview-link-definition.patch --]
[-- Type: text/x-patch, Size: 1059 bytes --]

From 473f9a7eb1b314ac9a7d95a052a8dc7daed05e93 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:26:28 -0400
Subject: [PATCH 09/20] Update docview link definition

* lisp/org-docview.el ("docview"):

Update link definition with org-link-set-parameters.
---
 lisp/org-docview.el | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lisp/org-docview.el b/lisp/org-docview.el
index fbc5551..3d4df40 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."
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #11: 0010-Update-eshell-link-definition.patch --]
[-- Type: text/x-patch, Size: 871 bytes --]

From b04729fe42adab6d7ad4e29086e6d38adcadcb6b Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:27:03 -0400
Subject: [PATCH 10/20] Update eshell link definition

* lisp/org-eshell.el ("eshell"):

Update to use org-link-set-parameters.
---
 lisp/org-eshell.el | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lisp/org-eshell.el b/lisp/org-eshell.el
index 1919f6d..6f9a18a 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.
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #12: 0011-Update-gnus-link-definition.patch --]
[-- Type: text/x-patch, Size: 800 bytes --]

From a0c738986b1acd25d08527133cd009a4bb25cd4c Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:27:14 -0400
Subject: [PATCH 11/20] Update gnus link definition

* lisp/org-gnus.el ("gnus"):
Update link definition with org-link-set-parameters.
---
 lisp/org-gnus.el | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lisp/org-gnus.el b/lisp/org-gnus.el
index 386d6dc..13e28cc 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
 
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #13: 0012-Update-info-link-definition.patch --]
[-- Type: text/x-patch, Size: 1345 bytes --]

From a9fa32d50f099d25517904792e089b93a24f8f6e Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:27:32 -0400
Subject: [PATCH 12/20] 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.
---
 lisp/org-info.el | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lisp/org-info.el b/lisp/org-info.el
index 9e8fde0..8765c53 100644
--- a/lisp/org-info.el
+++ b/lisp/org-info.el
@@ -40,8 +40,10 @@
 (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 +115,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))
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #14: 0013-Update-irc-link-definition.patch --]
[-- Type: text/x-patch, Size: 873 bytes --]

From 104a4b6787393d8097e375572e7ff2f9759962b0 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:27:45 -0400
Subject: [PATCH 13/20] Update irc link definition

* lisp/org-irc.el ("irc"):
Define link with org-link-set-parameters.
---
 lisp/org-irc.el | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lisp/org-irc.el b/lisp/org-irc.el
index 81d0296..5b9c839 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."
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #15: 0014-Update-mhe-link-definition.patch --]
[-- Type: text/x-patch, Size: 819 bytes --]

From bb9548a0e212151517f75756e16df80f7be82336 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:27:55 -0400
Subject: [PATCH 14/20] Update mhe link definition.

* lisp/org-mhe.el ("mhe"):
Define link with org-link-set-parameters.
---
 lisp/org-mhe.el | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lisp/org-mhe.el b/lisp/org-mhe.el
index 2ee21de..c793eed 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 ()
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #16: 0015-Update-rmail-link-definition.patch --]
[-- Type: text/x-patch, Size: 844 bytes --]

From 75a33fc8858c194993e4d7b292114e7075831d48 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:28:09 -0400
Subject: [PATCH 15/20] Update rmail link definition

* lisp/org-rmail.el ("rmail"):
Use org-link-set-parameters to define link.
---
 lisp/org-rmail.el | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lisp/org-rmail.el b/lisp/org-rmail.el
index 0bf44b8..35bf073 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 ()
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #17: 0016-Update-w3m-link-definition.patch --]
[-- Type: text/x-patch, Size: 771 bytes --]

From 6e1737f360684112c8f464c5602624d10ab89583 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:28:38 -0400
Subject: [PATCH 16/20] Update w3m link definition

* lisp/org-w3m.el ("w3m"):
Update to use org-link-set-parameters.
---
 lisp/org-w3m.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/org-w3m.el b/lisp/org-w3m.el
index 57ecafe..28bc492 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)
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #18: 0017-Update-the-id-link-with-org-link-set-parameters.patch --]
[-- Type: text/x-patch, Size: 702 bytes --]

From daf983946eabf5dcc50ade84ed7648057611ce53 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 16:11:08 -0400
Subject: [PATCH 17/20] Update the "id" link with org-link-set-parameters

* lisp/org-id.el:
---
 lisp/org-id.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/org-id.el b/lisp/org-id.el
index 2646c80..5ad7f00 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)
 
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #19: 0018-Update-the-texinfo-for-link-parameters-documentation.patch --]
[-- Type: text/x-patch, Size: 3088 bytes --]

From 90ef2774b8022f7e482ffc149cf23a7da7f886e3 Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:29:07 -0400
Subject: [PATCH 18/20] Update the texinfo for link parameters documentation

---
 doc/org.texi | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/doc/org.texi b/doc/org.texi
index e92788f..f962a58 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
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #20: 0019-Update-NEWS-with-link-announcement.patch --]
[-- Type: text/x-patch, Size: 912 bytes --]

From 737d8f95eeafbb2b85bbbd8cc485035cbc11b97a Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:31:30 -0400
Subject: [PATCH 19/20] Update NEWS with link announcement

---
 etc/ORG-NEWS | 2 ++
 1 file changed, 2 insertions(+)

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~.
-- 
2.9.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #21: 0020-Update-the-contrib-manual.patch --]
[-- Type: text/x-patch, Size: 2681 bytes --]

From 42ce0fc0b07c5ac8227cb86268fb13b9d52e1c9d Mon Sep 17 00:00:00 2001
From: John Kitchin <jkitchin@andrew.cmu.edu>
Date: Tue, 5 Jul 2016 10:38:42 -0400
Subject: [PATCH 20/20] Update the contrib manual

---
 contrib/orgmanual.org | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/contrib/orgmanual.org b/contrib/orgmanual.org
index e48ae97..07d9e8d 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~.
 
-- 
2.9.0


[-- Attachment #22: Type: text/plain, Size: 190 bytes --]


-- 
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

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-18 16:55                       ` John Kitchin
@ 2016-07-18 21:59                         ` Nicolas Goaziou
  2016-07-18 23:37                           ` John Kitchin
  2016-08-06  1:14                         ` [PATCH] " Matt Lundin
  1 sibling, 1 reply; 26+ messages in thread
From: Nicolas Goaziou @ 2016-07-18 21:59 UTC (permalink / raw)
  To: John Kitchin; +Cc: emacs-orgmode@gnu.org

John Kitchin <jkitchin@andrew.cmu.edu> writes:

> Ok. I have attached 20 patches with the updates below.

Applied, with minor tweaks (trailing white spaces and too wide lines).
Thank you for all this work.

Ultimately, I removed `org--open-file-link' altogether since default
behaviour for file+apps links DTRT. I also started to deprecate
file+apps links, i.e., they are still supported but we start suggesting
to use plain "file" links instead.

Regards,

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: links-9.0 v3
  2016-07-18 21:59                         ` Nicolas Goaziou
@ 2016-07-18 23:37                           ` John Kitchin
  0 siblings, 0 replies; 26+ messages in thread
From: John Kitchin @ 2016-07-18 23:37 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: emacs-orgmode@gnu.org

Sounds good. Thanks for your patience, I learned a lot doing this! I
look forward to using it in the wild ;)

Nicolas Goaziou writes:

> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
>> Ok. I have attached 20 patches with the updates below.
>
> Applied, with minor tweaks (trailing white spaces and too wide lines).
> Thank you for all this work.
>
> Ultimately, I removed `org--open-file-link' altogether since default
> behaviour for file+apps links DTRT. I also started to deprecate
> file+apps links, i.e., they are still supported but we start suggesting
> to use plain "file" links instead.
>
> Regards,


-- 
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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH] Re: links-9.0 v3
  2016-07-18 16:55                       ` John Kitchin
  2016-07-18 21:59                         ` Nicolas Goaziou
@ 2016-08-06  1:14                         ` Matt Lundin
  2016-08-08  0:12                           ` John Kitchin
  2016-08-08  9:08                           ` Nicolas Goaziou
  1 sibling, 2 replies; 26+ messages in thread
From: Matt Lundin @ 2016-08-06  1:14 UTC (permalink / raw)
  To: John Kitchin; +Cc: emacs-orgmode@gnu.org, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 388 bytes --]

Thanks, John, for improving link functionality in org-mode!

I just discovered that this change breaks the contrib files that use
org-store-link-functions and org-add-link-type.

I'm not familiar enough with the details of org-link-set-parameters to
fix all of the contrib files, but I am including a simple patch to
update a contrib file that I use regularly: org-eww.el.

Thanks,
Matt


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Update-org-eww-to-use-new-link-api.patch --]
[-- Type: text/x-diff, Size: 865 bytes --]

From d473260956493dafd1e37c5f3680813fbf63434e Mon Sep 17 00:00:00 2001
From: Matt Lundin <mdl@imapmail.org>
Date: Fri, 5 Aug 2016 20:07:40 -0500
Subject: [PATCH] Update org-eww to use new link api

* contrib/lisp/org-eww.el: org-store-link-functions: Remove obsolete
  hook.
  (org-link-set-parameters) Use new api for links.
---
 contrib/lisp/org-eww.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/lisp/org-eww.el b/contrib/lisp/org-eww.el
index 11ccb68..a443255 100644
--- a/contrib/lisp/org-eww.el
+++ b/contrib/lisp/org-eww.el
@@ -48,7 +48,7 @@
 
 \f
 ;; Store Org-link in eww-mode buffer
-(add-hook 'org-store-link-functions 'org-eww-store-link)
+(org-link-set-parameters "eww" :store #'org-eww-store-link)
 (defun org-eww-store-link ()
   "Store a link to the url of a eww buffer."
   (when (eq major-mode 'eww-mode)
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH] Re: links-9.0 v3
  2016-08-06  1:14                         ` [PATCH] " Matt Lundin
@ 2016-08-08  0:12                           ` John Kitchin
  2016-08-08  5:30                             ` Robert Klein
  2016-08-08  9:08                           ` Nicolas Goaziou
  1 sibling, 1 reply; 26+ messages in thread
From: John Kitchin @ 2016-08-08  0:12 UTC (permalink / raw)
  To: Matt Lundin; +Cc: emacs-orgmode@gnu.org, Nicolas Goaziou

That looks like the correct fix for org-eww.el.

What is the protocol for fixing the contrib packages? I can take a pass
at doing it if it is ok.



Matt Lundin writes:

> Thanks, John, for improving link functionality in org-mode!
>
> I just discovered that this change breaks the contrib files that use
> org-store-link-functions and org-add-link-type.
>
> I'm not familiar enough with the details of org-link-set-parameters to
> fix all of the contrib files, but I am including a simple patch to
> update a contrib file that I use regularly: org-eww.el.
>
> Thanks,
> Matt


-- 
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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH] Re: links-9.0 v3
  2016-08-08  0:12                           ` John Kitchin
@ 2016-08-08  5:30                             ` Robert Klein
  2016-08-08  9:21                               ` Nicolas Goaziou
  0 siblings, 1 reply; 26+ messages in thread
From: Robert Klein @ 2016-08-08  5:30 UTC (permalink / raw)
  To: John Kitchin; +Cc: Matt Lundin, emacs-orgmode@gnu.org, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 1127 bytes --]

Hi,

attached are Patches for contrib except ox-bibtex.el and
org-velocity.el.

Some files are spitting out errors during compile, some of those
probably vanish if you require the stuff they depend on.

I modified Matt's patch to also open eww links with eww (but this could
also be something with `browse-url').

The last patch also updates the replacement for org-add-link-type in
org-compat.el.

Best regards
Robert

On Sun, 07 Aug 2016 20:12:21 -0400
John Kitchin <jkitchin@andrew.cmu.edu> wrote:

> That looks like the correct fix for org-eww.el.
> 
> What is the protocol for fixing the contrib packages? I can take a
> pass at doing it if it is ok.
> 
> 
> 
> Matt Lundin writes:
> 
> > Thanks, John, for improving link functionality in org-mode!
> >
> > I just discovered that this change breaks the contrib files that use
> > org-store-link-functions and org-add-link-type.
> >
> > I'm not familiar enough with the details of org-link-set-parameters
> > to fix all of the contrib files, but I am including a simple patch
> > to update a contrib file that I use regularly: org-eww.el.
> >
> > Thanks,
> > Matt  
> 
> 


[-- Attachment #2: 0001-Update-bookmark-link-definition.patch --]
[-- Type: text/x-patch, Size: 984 bytes --]

From 5c56aab31caff84241856cb019d496bee2376937 Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:09 +0200
Subject: [PATCH 01/14] Update bookmark link definition

* contrib/lisp/org-bookmark.el ("bookmark"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-bookmark.el | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/contrib/lisp/org-bookmark.el b/contrib/lisp/org-bookmark.el
index 40c7cd0..f042467 100644
--- a/contrib/lisp/org-bookmark.el
+++ b/contrib/lisp/org-bookmark.el
@@ -47,8 +47,9 @@ Otherwise prompt the user for the right bookmark to use."
   :group 'org-bookmark
   :type 'boolean)
 
-(org-add-link-type "bookmark" 'org-bookmark-open)
-(add-hook 'org-store-link-functions 'org-bookmark-store-link)
+(org-link-set-parameters "bookmark"
+			 :follow #'org-bookmark-open
+			 :store #'org-bookmark-store-link)
 
 (defun org-bookmark-open (bookmark)
   "Visit the bookmark BOOKMARK."
-- 
2.9.2


[-- Attachment #3: 0002-Update-tel-link-definition.patch --]
[-- Type: text/x-patch, Size: 922 bytes --]

From 76518d2668e274b48c5b67ad698cb6c5d1659627 Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 02/14] Update tel link definition

* contrib/lisp/org-contacts.el ("contacts"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-contacts.el | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/contrib/lisp/org-contacts.el b/contrib/lisp/org-contacts.el
index 309b9b9..2cadd1d 100644
--- a/contrib/lisp/org-contacts.el
+++ b/contrib/lisp/org-contacts.el
@@ -1107,8 +1107,7 @@ link string and return the pure link target."
 
 ;; Add the link type supported by org-contacts-strip-link
 ;; so everything is in order for its use in Org files
-(org-add-link-type "tel")
-
+(org-link-set-parameters "tel")
 
 (defun org-contacts-split-property (string &optional separators omit-nulls)
   "Custom version of `split-string'.
-- 
2.9.2


[-- Attachment #4: 0003-Update-ebib-link-definition.patch --]
[-- Type: text/x-patch, Size: 837 bytes --]

From a1d89751290a6594d559dd3ccf5ac957f31c30e0 Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 03/14] Update ebib link definition

* contrib/lisp/org-ebib.el ("ebib"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-ebib.el | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/contrib/lisp/org-ebib.el b/contrib/lisp/org-ebib.el
index 2136a13..4ed5e50 100644
--- a/contrib/lisp/org-ebib.el
+++ b/contrib/lisp/org-ebib.el
@@ -22,9 +22,9 @@
 
 (require 'org)
 
-(org-add-link-type "ebib" 'org-ebib-open)
-
-(add-hook 'org-store-link-functions 'org-ebib-store-link)
+(org-link-set-parameters "ebib"
+			 :follow #'org-ebib-open
+			 :store #'org-ebib-store-link)
 
 (defun org-ebib-open (key)
   "Open Ebib and jump to KEY."
-- 
2.9.2


[-- Attachment #5: 0004-Update-elisp-symbol-link-definition.patch --]
[-- Type: text/x-patch, Size: 971 bytes --]

From aafd21ba551dd87959eba47e89b402ef7e53826f Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 04/14] Update elisp-symbol link definition

* contrib/lisp/org-elisp-symbol.el ("elisp-symbol"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-elisp-symbol.el | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/contrib/lisp/org-elisp-symbol.el b/contrib/lisp/org-elisp-symbol.el
index cdf868b..7c98962 100644
--- a/contrib/lisp/org-elisp-symbol.el
+++ b/contrib/lisp/org-elisp-symbol.el
@@ -78,8 +78,9 @@
 
 (require 'org)
 
-(org-add-link-type "elisp-symbol" 'org-elisp-symbol-open)
-(add-hook 'org-store-link-functions 'org-elisp-symbol-store-link)
+(org-link-set-parameters "elisp-symbol"
+			 :follow #'org-elisp-symbol-open
+			 :store #'org-elisp-symbol-store-link)
 
 (defun org-elisp-symbol-open (path)
   "Visit the emacs-lisp elisp-symbol at PATH."
-- 
2.9.2


[-- Attachment #6: 0005-Update-eww-link-definition.patch --]
[-- Type: text/x-patch, Size: 831 bytes --]

From 6bae91b2ddfe6691c7615c16bb1cab3722f9625a Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 05/14] Update eww link definition

* contrib/lisp/org-eww.el ("eww"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-eww.el | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/contrib/lisp/org-eww.el b/contrib/lisp/org-eww.el
index 11ccb68..822aba5 100644
--- a/contrib/lisp/org-eww.el
+++ b/contrib/lisp/org-eww.el
@@ -48,7 +48,8 @@
 
 \f
 ;; Store Org-link in eww-mode buffer
-(add-hook 'org-store-link-functions 'org-eww-store-link)
+(org-link-set-parameters "eww" :follow #'eww :store #'org-eww-store-link)
+
 (defun org-eww-store-link ()
   "Store a link to the url of a eww buffer."
   (when (eq major-mode 'eww-mode)
-- 
2.9.2


[-- Attachment #7: 0006-Update-git-gitbare-link-definitions.patch --]
[-- Type: text/x-patch, Size: 1554 bytes --]

From f1e36266438122ef7a0555e5334dfbfed86f083f Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 06/14] Update git, gitbare link definitions

* contrib/lisp/org-git-link.el ("git-link"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-git-link.el | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/contrib/lisp/org-git-link.el b/contrib/lisp/org-git-link.el
index d3ba848..9d3ff32 100644
--- a/contrib/lisp/org-git-link.el
+++ b/contrib/lisp/org-git-link.el
@@ -69,7 +69,7 @@
 
 ;; org link functions
 ;; bare git link
-(org-add-link-type "gitbare" 'org-gitbare-open)
+(org-link-set-parameters "gitbare" :follow #'org-gitbare-open)
 
 (defun org-gitbare-open (str)
   (let* ((strlist (org-git-split-string str))
@@ -92,7 +92,7 @@
     (setq buffer-read-only t)))
 
 ;; user friendly link
-(org-add-link-type "git" 'org-git-open)
+(org-link-set-parameters "git" :follow #'org-git-open :store #'org-git-store-link)
 
 (defun org-git-open (str)
   (let* ((strlist (org-git-split-string str))
@@ -190,8 +190,6 @@ than two double colons, str2 and/or str3 may be set the empty string."
 	 :type "git"
 	 :link (org-git-create-git-link file line))))))
 
-(add-hook 'org-store-link-functions 'org-git-store-link)
-
 (defun org-git-insert-link-interactively (file searchstring &optional description)
   (interactive "FFile: \nsSearch string: \nsDescription: ")
   (insert (org-make-link-string (concat "git:" file "::" searchstring) description)))
-- 
2.9.2


[-- Attachment #8: 0007-Update-misc-mac-link-definitions.patch --]
[-- Type: text/x-patch, Size: 3323 bytes --]

From ddb707a985e1caf21e6c7eb9cf798b20d3bffb73 Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 07/14] Update misc mac link definitions

* contrib/lisp/org-mac-link.el ("mac-link"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-mac-link.el | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/contrib/lisp/org-mac-link.el b/contrib/lisp/org-mac-link.el
index 076483c..ae2def3 100644
--- a/contrib/lisp/org-mac-link.el
+++ b/contrib/lisp/org-mac-link.el
@@ -442,8 +442,7 @@ The links are of the form <link>::split::<name>."
 
 \f
 ;; Handle links from together.app
-
-(org-add-link-type "x-together-item" 'org-mac-together-item-open)
+(org-link-set-parameters "x-together-item" :follow #'org-mac-together-item-open)
 
 (defun org-mac-together-item-open (uid)
   "Open UID, which is a reference to an item in Together."
@@ -498,8 +497,7 @@ The links are of the form <link>::split::<name>."
 
 \f
 ;; Handle links from AddressBook.app
-
-(org-add-link-type "addressbook" 'org-mac-addressbook-item-open)
+(org-link-set-parameters "addressbook" :follow #'org-mac-addressbook-item-open)
 
 (defun org-mac-addressbook-item-open (uid)
   "Open UID, which is a reference to an item in the addressbook."
@@ -532,7 +530,7 @@ The links are of the form <link>::split::<name>."
 ;;
 ;; Original code & idea by Christopher Suckling (org-mac-protocol)
 
-(org-add-link-type "skim" 'org-mac-skim-open)
+(org-link-set-parameters "skim" :follow #'org-mac-skim-open)
 
 (defun org-mac-skim-open (uri)
   "Visit page of pdf in Skim"
@@ -589,7 +587,7 @@ The links are of the form <link>::split::<name>."
 ;;
 ;; The URI format is path_to_pdf_file::page_number
 
-(org-add-link-type "acrobat" 'org-mac-acrobat-open)
+(org-link-set-parameters "acrobat" :follow #'org-mac-acrobat-open)
 
 (defun org-mac-acrobat-open (uri)
   "Visit page of pdf in Acrobat"
@@ -637,7 +635,7 @@ The links are of the form <link>::split::<name>."
 \f
 ;; Handle links from Microsoft Outlook.app
 
-(org-add-link-type "mac-outlook" 'org-mac-outlook-message-open)
+(org-link-set-parameters "mac-outlook" :follow #'org-mac-outlook-message-open)
 
 (defun org-mac-outlook-message-open (msgid)
   "Open a message in Outlook"
@@ -746,7 +744,7 @@ after heading."
 \f
 ;; Handle links from Evernote.app
 
-(org-add-link-type "mac-evernote" 'org-mac-evernote-note-open)
+(org-link-set-parameters "mac-evernote" :follow #'org-mac-evernote-note-open)
 
 (defun org-mac-evernote-note-open (noteid)
   "Open a note in Evernote"
@@ -796,7 +794,7 @@ note(s) in Evernote.app and make a link out of it/them."
 \f
 ;; Handle links from DEVONthink Pro Office.app
 
-(org-add-link-type "x-devonthink-item" 'org-devonthink-item-open)
+(org-link-set-parameters "x-devonthink-item" :follow #'org-devonthink-item-open)
 
 (defun org-devonthink-item-open (uid)
   "Open UID, which is a reference to an item in DEVONthink Pro Office."
@@ -843,7 +841,7 @@ selected items in DEVONthink Pro Office and make link(s) out of it/them."
 \f
 ;; Handle links from Mail.app
 
-(org-add-link-type "message" 'org-mac-message-open)
+(org-link-set-parameters "message" :follow #'org-mac-message-open)
 
 (defun org-mac-message-open (message-id)
   "Visit the message with MESSAGE-ID.
-- 
2.9.2


[-- Attachment #9: 0008-Update-mairix-link-definition.patch --]
[-- Type: text/x-patch, Size: 923 bytes --]

From 3245b6acbde612b65c99369838293fe7c598b5dc Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 08/14] Update mairix link definition

* contrib/lisp/org-mairix.el ("mairix"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-mairix.el | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/contrib/lisp/org-mairix.el b/contrib/lisp/org-mairix.el
index a19719e..84a9582 100644
--- a/contrib/lisp/org-mairix.el
+++ b/contrib/lisp/org-mairix.el
@@ -82,8 +82,9 @@ correctly, you should not need to change this.
 
 ;;; The hooks to integrate mairix into org
 
-(org-add-link-type "mairix" 'org-mairix-open)
-(add-hook 'org-store-link-functions 'org-mairix-store-gnus-link)
+(org-link-set-parameters "mairix"
+			 :follow #'org-mairix-open
+			 :store #'org-mairix-store-gnus-link)
 
 ;;; Generic org-mairix functions
 
-- 
2.9.2


[-- Attachment #10: 0009-Update-man-link-definition.patch --]
[-- Type: text/x-patch, Size: 898 bytes --]

From 97a3fe593203a2357d092793c7222082807d1f4f Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 09/14] Update man link definition

* contrib/lisp/org-man.el ("man"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-man.el | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/contrib/lisp/org-man.el b/contrib/lisp/org-man.el
index a9db83d..1ccd942 100644
--- a/contrib/lisp/org-man.el
+++ b/contrib/lisp/org-man.el
@@ -25,8 +25,10 @@
 
 (require 'org)
 
-(org-add-link-type "man" 'org-man-open 'org-man-export)
-(add-hook 'org-store-link-functions 'org-man-store-link)
+(org-link-set-parameters "man"
+			 :follow #'org-man-open
+			 :export #'org-man-export
+			 :store #'org-man-store-link)
 
 (defcustom org-man-command 'man
   "The Emacs command to be used to display a man page."
-- 
2.9.2


[-- Attachment #11: 0010-Update-mew-link-definition.patch --]
[-- Type: text/x-patch, Size: 868 bytes --]

From d263e3e0915ef120b4fa8e77947d1955692a586b Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 10/14] Update mew link definition

* contrib/lisp/org-mew.el ("mew"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-mew.el | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/contrib/lisp/org-mew.el b/contrib/lisp/org-mew.el
index 4f2559b..f4c845c 100644
--- a/contrib/lisp/org-mew.el
+++ b/contrib/lisp/org-mew.el
@@ -148,8 +148,7 @@ with \"t\" key."
 (defvar mew-summary-goto-line-then-display)
 
 ;; Install the link type
-(org-add-link-type "mew" 'org-mew-open)
-(add-hook 'org-store-link-functions 'org-mew-store-link)
+(org-link-set-parameters "mew" :follow #'org-mew-open :store #'org-mew-store-link)
 
 ;; Implementation
 (defun org-mew-store-link ()
-- 
2.9.2


[-- Attachment #12: 0011-Update-notmuch-and-notmuch-search-link-definitions.patch --]
[-- Type: text/x-patch, Size: 1450 bytes --]

From d93acc39c724f5e55b39804e2751c904297c26da Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 11/14] Update notmuch and notmuch-search link definitions

* contrib/lisp/org-notmuch.el ("notmuch"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-notmuch.el | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/contrib/lisp/org-notmuch.el b/contrib/lisp/org-notmuch.el
index 265742e..b77df03 100644
--- a/contrib/lisp/org-notmuch.el
+++ b/contrib/lisp/org-notmuch.el
@@ -65,8 +65,9 @@ Should accept a notmuch search string as the sole argument."
 \f
 
 ;; Install the link type
-(org-add-link-type "notmuch" 'org-notmuch-open)
-(add-hook 'org-store-link-functions 'org-notmuch-store-link)
+(org-link-set-parameters "notmuch"
+			 :follow #'org-notmuch-open
+			 :store #'org-notmuch-store-link)
 
 (defun org-notmuch-store-link ()
   "Store a link to a notmuch search or message."
@@ -98,8 +99,9 @@ Can link to more than one message, if so all matching messages are shown."
 
 \f
 
-(org-add-link-type "notmuch-search" 'org-notmuch-search-open)
-(add-hook 'org-store-link-functions 'org-notmuch-search-store-link)
+(org-link-set-parameters "notmuch-search"
+			 :follow #'org-notmuch-search-open
+			 :store #'org-notmuch-search-store-link)
 
 (defun org-notmuch-search-store-link ()
   "Store a link to a notmuch search or message."
-- 
2.9.2


[-- Attachment #13: 0012-Update-vm-link-definition.patch --]
[-- Type: text/x-patch, Size: 935 bytes --]

From 66dbfd7a3781e3c026e0f605df464b0a3ff8c041 Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 12/14] Update vm link definition

* contrib/lisp/org-vm.el ("vm"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-vm.el | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/contrib/lisp/org-vm.el b/contrib/lisp/org-vm.el
index ce20314..f55d7f8 100644
--- a/contrib/lisp/org-vm.el
+++ b/contrib/lisp/org-vm.el
@@ -55,9 +55,8 @@
 (defvar vm-folder-directory)
 
 ;; Install the link type
-(org-add-link-type "vm" 'org-vm-open)
-(org-add-link-type "vm-imap" 'org-vm-imap-open)
-(add-hook 'org-store-link-functions 'org-vm-store-link)
+(org-link-set-parameters "vm" :follow #'org-vm-open :store #'org-vm-store-link)
+(org-link-set-parameters "vm-imap" :follow #'org-vm-imap-open)
 
 ;; Implementation
 (defun org-vm-store-link ()
-- 
2.9.2


[-- Attachment #14: 0013-Update-wl-link-definition.patch --]
[-- Type: text/x-patch, Size: 857 bytes --]

From 6b5bd1f02b996ae9612e77ab88a9686f05077bf3 Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:23 +0200
Subject: [PATCH 13/14] Update wl link definition

* contrib/lisp/org-wl.el ("wl"):

Update to use org-link-set-parameters.
---
 contrib/lisp/org-wl.el | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/contrib/lisp/org-wl.el b/contrib/lisp/org-wl.el
index befbc16..e4d7306 100644
--- a/contrib/lisp/org-wl.el
+++ b/contrib/lisp/org-wl.el
@@ -109,8 +109,7 @@ googlegroups otherwise."
   "List of folder indicators.  See Wanderlust manual, section 3.")
 
 ;; Install the link type
-(org-add-link-type "wl" 'org-wl-open)
-(add-hook 'org-store-link-functions 'org-wl-store-link)
+(org-link-set-parameters "wl" :follow #'org-wl-open :store #'org-wl-store-link)
 
 ;; Implementation
 
-- 
2.9.2


[-- Attachment #15: 0014-Update-replacement-for-org-add-link-type.patch --]
[-- Type: text/x-patch, Size: 953 bytes --]

From 39741405189fba92eff4ff5b0c6e834167d47db4 Mon Sep 17 00:00:00 2001
From: Robert Klein <roklein@roklein.de>
Date: Mon, 8 Aug 2016 03:24:24 +0200
Subject: [PATCH 14/14] Update replacement for org-add-link-type

* lisp/org-compat.el ("org-add-link-type"):

replacement for org-add-link-type is org-link-set-parameters,
notorg-linkk-add, now.
---
 lisp/org-compat.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index d5b4515..3120e80 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -223,7 +223,7 @@ See `org-link-parameters' for documentation on the other parameters."
   (org-link-set-parameters type :follow follow :export export)
   (message "Created %s link." type))
 
-(make-obsolete 'org-add-link-type "use `org-link-add' instead." "Org 9.0")
+(make-obsolete 'org-add-link-type "use `org-link-set-parameters' instead." "Org 9.0")
 
 ;;;; Obsolete link types
 
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH] Re: links-9.0 v3
  2016-08-06  1:14                         ` [PATCH] " Matt Lundin
  2016-08-08  0:12                           ` John Kitchin
@ 2016-08-08  9:08                           ` Nicolas Goaziou
  1 sibling, 0 replies; 26+ messages in thread
From: Nicolas Goaziou @ 2016-08-08  9:08 UTC (permalink / raw)
  To: Matt Lundin; +Cc: emacs-orgmode@gnu.org, John Kitchin

Hello,

Matt Lundin <mdl@imapmail.org> writes:

> Thanks, John, for improving link functionality in org-mode!
>
> I just discovered that this change breaks the contrib files that use
> org-store-link-functions and org-add-link-type.
>
> I'm not familiar enough with the details of org-link-set-parameters to
> fix all of the contrib files, but I am including a simple patch to
> update a contrib file that I use regularly: org-eww.el.

Applied. Thank you.

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH] Re: links-9.0 v3
  2016-08-08  5:30                             ` Robert Klein
@ 2016-08-08  9:21                               ` Nicolas Goaziou
  0 siblings, 0 replies; 26+ messages in thread
From: Nicolas Goaziou @ 2016-08-08  9:21 UTC (permalink / raw)
  To: Robert Klein; +Cc: Matt Lundin, emacs-orgmode@gnu.org, John Kitchin

Hello,

Robert Klein <roklein@roklein.de> writes:

> attached are Patches for contrib except ox-bibtex.el and
> org-velocity.el.
>
> Some files are spitting out errors during compile, some of those
> probably vanish if you require the stuff they depend on.
>
> I modified Matt's patch to also open eww links with eww (but this could
> also be something with `browse-url').
>
> The last patch also updates the replacement for org-add-link-type in
> org-compat.el.

Applied. Thank you.

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2016-08-08  9:21 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-06 14:41 links-9.0 v3 John Kitchin
2016-07-06 22:10 ` Nicolas Goaziou
2016-07-06 23:06   ` John Kitchin
2016-07-07  1:55   ` John Kitchin
2016-07-07  8:20     ` Nicolas Goaziou
2016-07-07 13:27       ` John Kitchin
2016-07-07 14:56         ` Nicolas Goaziou
2016-07-07 19:17           ` John Kitchin
2016-07-08 21:32             ` Nicolas Goaziou
2016-07-07 19:21           ` John Kitchin
2016-07-08 21:48             ` Nicolas Goaziou
2016-07-08 22:04               ` John Kitchin
2016-07-09 13:27               ` John Kitchin
2016-07-18 12:02                 ` Nicolas Goaziou
2016-07-15  1:12               ` John Kitchin
2016-07-18 11:48                 ` Nicolas Goaziou
2016-07-18 15:20                   ` John Kitchin
2016-07-18 16:05                     ` Nicolas Goaziou
2016-07-18 16:55                       ` John Kitchin
2016-07-18 21:59                         ` Nicolas Goaziou
2016-07-18 23:37                           ` John Kitchin
2016-08-06  1:14                         ` [PATCH] " Matt Lundin
2016-08-08  0:12                           ` John Kitchin
2016-08-08  5:30                             ` Robert Klein
2016-08-08  9:21                               ` Nicolas Goaziou
2016-08-08  9:08                           ` Nicolas Goaziou

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).