emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master c4adfba: Allow for custom URL handlers in browse-url.


From: Tassilo Horn
Subject: master c4adfba: Allow for custom URL handlers in browse-url.
Date: Wed, 6 May 2020 04:32:33 -0400 (EDT)

branch: master
commit c4adfbae24d920f0ce62cb88b988219348d1ec73
Author: Tassilo Horn <address@hidden>
Commit: Tassilo Horn <address@hidden>

    Allow for custom URL handlers in browse-url.
    
    * lisp/net/browse-url.el (browse-url-handlers): New defcustom.
    (browse-url-default-handlers): New defvar.
    (browse-url): Use them.  Adapt docstring.  Issue a warning pointing to
    browse-url-handlers when browse-url-browser-function is an alist.
    (browse-url--mailto, browse-url--man): New functions.
    (browse-url--browser-defcustom-type): Add :doc that the alist usage is
    deprecated.
    (browse-url-browser-function): Remove documentation referring to the
    alist usage and mention browse-url-handlers.
    * doc/emacs/misc.texi: Document browse-url-handlers in Browse-URL
    node.
    * etc/NEWS: Mention browse-url-default-handlers and
    browse-url-handlers.
---
 doc/emacs/misc.texi    |  13 ++++--
 etc/NEWS               |  16 +++++++
 lisp/net/browse-url.el | 114 +++++++++++++++++++++++++++++++++----------------
 3 files changed, 104 insertions(+), 39 deletions(-)

diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index 47f195d..d1854f3 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -2920,9 +2920,16 @@ you might like to bind to keys, such as 
@code{browse-url-at-point} and
   You can customize Browse-URL's behavior via various options in the
 @code{browse-url} Customize group.  In particular, the option
 @code{browse-url-mailto-function} lets you define how to follow
-@samp{mailto:} URLs, while @code{browse-url-browser-function} lets you
-define how to follow other types of URLs.  For more information, view
-the package commentary by typing @kbd{C-h P browse-url @key{RET}}.
+@samp{mailto:} URLs, while @code{browse-url-browser-function}
+specifies your default browser.
+
+@vindex browse-url-handlers
+  You can define that certain URLs are browsed with other functions by
+customizing @code{browse-url-handlers}, an alist of regular
+expressions paired with functions to browse matching URLs.
+
+For more information, view the package commentary by typing @kbd{C-h P
+browse-url @key{RET}}.
 
 @node Goto Address mode
 @subsection Activating URLs
diff --git a/etc/NEWS b/etc/NEWS
index 0f4b624..ac93a76 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -304,6 +304,22 @@ use ‘doxygen’ by default one might evaluate:
                     (c++-mode  . doxygen)))
 
 or use it in a custom ‘c-style’.
+
+** browse-url
+
+*** Added support for custom URL handlers
+
+There is a new defvar 'browse-url-default-handlers' and a defcustom
+'browse-url-handlers' being alists with (REGEXP . FUNCTION) entries
+allowing to define different browsing FUNCTIONs depending on the URL
+to be browsed.  The defvar is for default handlers provided by Emacs
+itself or external packages, the defcustom is for the user (and allows
+for overriding the default handlers).
+
+Formerly, one could do the same by setting
+'browse-url-browser-function' to such an alist.  This usage is still
+supported but deprecated.
+
 
 * New Modes and Packages in Emacs 28.1
 
diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el
index 7aad44b..1275c15 100644
--- a/lisp/net/browse-url.el
+++ b/lisp/net/browse-url.el
@@ -114,9 +114,10 @@
 ;; To always save modified buffers before displaying the file in a browser:
 ;;     (setq browse-url-save-file t)
 
-;; To invoke different browsers for different URLs:
-;;      (setq browse-url-browser-function '(("^mailto:"; . browse-url-mail)
-;;                                         ("." . browse-url-firefox)))
+;; To invoke different browsers/tools for different URLs, customize
+;; `browse-url-handlers'.  In earlier versions of Emacs, the same
+;; could be done by setting `browse-url-browser-function' to an alist
+;; but this usage is deprecated now.
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Code:
@@ -157,7 +158,9 @@
                   :value browse-url-default-browser)
     (function :tag "Your own function")
     (alist :tag "Regexp/function association list"
-          :key-type regexp :value-type function)))
+          :key-type regexp :value-type function
+           :format "%{%t%}\n%d%v\n"
+           :doc "Deprecated.  Use `browse-url-handlers' instead.")))
 
 ;;;###autoload
 (defcustom browse-url-browser-function 'browse-url-default-browser
@@ -165,13 +168,8 @@
 This is used by the `browse-url-at-point', `browse-url-at-mouse', and
 `browse-url-of-file' commands.
 
-If the value is not a function it should be a list of pairs
-\(REGEXP . FUNCTION).  In this case the function called will be the one
-associated with the first REGEXP which matches the current URL.  The
-function is passed the URL and any other args of `browse-url'.  The last
-regexp should probably be \".\" to specify a default browser.
-
-Also see `browse-url-secondary-browser-function'."
+Also see `browse-url-secondary-browser-function' and
+`browse-url-handlers'."
   :type browse-url--browser-defcustom-type
   :version "24.1")
 
@@ -595,6 +593,41 @@ down (this *won't* always work)."
   "Wrapper command prepended to the Elinks command-line."
   :type '(repeat (string :tag "Wrapper")))
 
+(defun browse-url--mailto (url &rest args)
+  "Calls `browse-url-mailto-function' with URL and ARGS."
+  (funcall browse-url-mailto-function url args))
+
+(defun browse-url--man (url &rest args)
+  "Calls `browse-url-man-function' with URL and ARGS."
+  (funcall browse-url-man-function url args))
+
+;;;###autoload
+(defvar browse-url-default-handlers
+  '(("\\`mailto:"; . browse-url--mailto)
+    ("\\`man:" . browse-url--man)
+    ("\\`file://" . browse-url-emacs))
+  "Like `browse-url-handlers' but populated by Emacs and packages.
+
+Emacs and external packages capable of browsing certain URLs
+should place their entries in this alist rather than
+`browse-url-handlers' which is reserved for the user.")
+
+(defcustom browse-url-handlers nil
+  "An alist with elements of the form (REGEXP HANDLER).
+Each REGEXP is matched against the URL to be opened in turn and
+the first match's HANDLER is invoked with the URL.
+
+A HANDLER must be a function with the same arguments as
+`browse-url'.
+
+If no REGEXP matches, the same procedure is performed with the
+value of `browse-url-default-handlers'.  If there is also no
+match, the URL is opened using the value of
+`browse-url-browser-function'."
+  :type '(alist :key-type (regexp :tag "Regexp")
+                :value-type (function :tag "Handler"))
+  :version "28.1")
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; URL encoding
 
@@ -768,16 +801,18 @@ narrowed."
   "Ask a WWW browser to load URL.
 Prompt for a URL, defaulting to the URL at or before point.
 Invokes a suitable browser function which does the actual job.
-The variable `browse-url-browser-function' says which browser function to
-use.  If the URL is a mailto: URL, consult `browse-url-mailto-function'
-first, if that exists.
-
-The additional ARGS are passed to the browser function.  See the doc
-strings of the actual functions, starting with `browse-url-browser-function',
-for information about the significance of ARGS (most of the functions
-ignore it).
-If ARGS are omitted, the default is to pass `browse-url-new-window-flag'
-as ARGS."
+
+The variables `browse-url-browser-function',
+`browse-url-handlers', and `browse-url-default-handlers'
+determine which browser function to use.
+
+The additional ARGS are passed to the browser function.  See the
+doc strings of the actual functions, starting with
+`browse-url-browser-function', for information about the
+significance of ARGS (most of the functions ignore it).
+
+If ARGS are omitted, the default is to pass
+`browse-url-new-window-flag' as ARGS."
   (interactive (browse-url-interactive-arg "URL: "))
   (unless (called-interactively-p 'interactive)
     (setq args (or args (list browse-url-new-window-flag))))
@@ -786,12 +821,15 @@ as ARGS."
              (not (string-match "\\`[a-z]+:" url)))
     (setq url (expand-file-name url)))
   (let ((process-environment (copy-sequence process-environment))
-       (function (or (and (string-match "\\`mailto:"; url)
-                          browse-url-mailto-function)
-                      (and (string-match "\\`man:" url)
-                           browse-url-man-function)
-                     browse-url-browser-function))
-       ;; Ensure that `default-directory' exists and is readable (b#6077).
+       (function
+         (catch 'custom-url-handler
+           (dolist (regex-handler (append browse-url-handlers
+                                          browse-url-default-handlers))
+             (when (string-match-p (car regex-handler) url)
+               (throw 'custom-url-handler (cdr regex-handler))))
+           ;; No special handler found.
+           browse-url-browser-function))
+       ;; Ensure that `default-directory' exists and is readable (bug#6077).
        (default-directory (or (unhandled-file-name-directory default-directory)
                               (expand-file-name "~/"))))
     ;; When connected to various displays, be careful to use the display of
@@ -801,15 +839,19 @@ as ARGS."
         (setenv "DISPLAY" (frame-parameter nil 'display)))
     (if (and (consp function)
             (not (functionp function)))
-       ;; The `function' can be an alist; look down it for first match
-       ;; and apply the function (which might be a lambda).
-       (catch 'done
-         (dolist (bf function)
-           (when (string-match (car bf) url)
-             (apply (cdr bf) url args)
-             (throw 'done t)))
-         (error "No browse-url-browser-function matching URL %s"
-                url))
+       ;; The `function' can be an alist; look down it for first
+       ;; match and apply the function (which might be a lambda).
+       ;; However, this usage is deprecated as of Emacs 28.1.
+        (progn
+          (warn "Having `browse-url-browser-function' set to an
+alist is deprecated.  Use `browse-url-handlers' instead.")
+          (catch 'done
+           (dolist (bf function)
+             (when (string-match (car bf) url)
+               (apply (cdr bf) url args)
+               (throw 'done t)))
+           (error "No browse-url-browser-function matching URL %s"
+                  url)))
       ;; Unbound symbols go down this leg, since void-function from
       ;; apply is clearer than wrong-type-argument from dolist.
       (apply function url args))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]