aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTassilo Horn2020-05-04 11:24:08 +0200
committerTassilo Horn2020-05-06 10:14:58 +0200
commitc4adfbae24d920f0ce62cb88b988219348d1ec73 (patch)
treeb60ac0e763bc09d50c56795e833fe1a44070f28a
parent58c234aa8cb6e76d377f07cbf0b59f2552eb296b (diff)
downloademacs-c4adfbae24d920f0ce62cb88b988219348d1ec73.tar.gz
emacs-c4adfbae24d920f0ce62cb88b988219348d1ec73.zip
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.
-rw-r--r--doc/emacs/misc.texi13
-rw-r--r--etc/NEWS16
-rw-r--r--lisp/net/browse-url.el114
3 files changed, 104 insertions, 39 deletions
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index 47f195d0b20..d1854f31ff3 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
2920 You can customize Browse-URL's behavior via various options in the 2920 You can customize Browse-URL's behavior via various options in the
2921@code{browse-url} Customize group. In particular, the option 2921@code{browse-url} Customize group. In particular, the option
2922@code{browse-url-mailto-function} lets you define how to follow 2922@code{browse-url-mailto-function} lets you define how to follow
2923@samp{mailto:} URLs, while @code{browse-url-browser-function} lets you 2923@samp{mailto:} URLs, while @code{browse-url-browser-function}
2924define how to follow other types of URLs. For more information, view 2924specifies your default browser.
2925the package commentary by typing @kbd{C-h P browse-url @key{RET}}. 2925
2926@vindex browse-url-handlers
2927 You can define that certain URLs are browsed with other functions by
2928customizing @code{browse-url-handlers}, an alist of regular
2929expressions paired with functions to browse matching URLs.
2930
2931For more information, view the package commentary by typing @kbd{C-h P
2932browse-url @key{RET}}.
2926 2933
2927@node Goto Address mode 2934@node Goto Address mode
2928@subsection Activating URLs 2935@subsection Activating URLs
diff --git a/etc/NEWS b/etc/NEWS
index 0f4b6244c62..ac93a76ff95 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -304,6 +304,22 @@ use ‘doxygen’ by default one might evaluate:
304 (c++-mode . doxygen))) 304 (c++-mode . doxygen)))
305 305
306or use it in a custom ‘c-style’. 306or use it in a custom ‘c-style’.
307
308** browse-url
309
310*** Added support for custom URL handlers
311
312There is a new defvar 'browse-url-default-handlers' and a defcustom
313'browse-url-handlers' being alists with (REGEXP . FUNCTION) entries
314allowing to define different browsing FUNCTIONs depending on the URL
315to be browsed. The defvar is for default handlers provided by Emacs
316itself or external packages, the defcustom is for the user (and allows
317for overriding the default handlers).
318
319Formerly, one could do the same by setting
320'browse-url-browser-function' to such an alist. This usage is still
321supported but deprecated.
322
307 323
308* New Modes and Packages in Emacs 28.1 324* New Modes and Packages in Emacs 28.1
309 325
diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el
index 7aad44b2876..1275c15578f 100644
--- a/lisp/net/browse-url.el
+++ b/lisp/net/browse-url.el
@@ -114,9 +114,10 @@
114;; To always save modified buffers before displaying the file in a browser: 114;; To always save modified buffers before displaying the file in a browser:
115;; (setq browse-url-save-file t) 115;; (setq browse-url-save-file t)
116 116
117;; To invoke different browsers for different URLs: 117;; To invoke different browsers/tools for different URLs, customize
118;; (setq browse-url-browser-function '(("^mailto:" . browse-url-mail) 118;; `browse-url-handlers'. In earlier versions of Emacs, the same
119;; ("." . browse-url-firefox))) 119;; could be done by setting `browse-url-browser-function' to an alist
120;; but this usage is deprecated now.
120 121
121;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 122;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
122;;; Code: 123;;; Code:
@@ -157,7 +158,9 @@
157 :value browse-url-default-browser) 158 :value browse-url-default-browser)
158 (function :tag "Your own function") 159 (function :tag "Your own function")
159 (alist :tag "Regexp/function association list" 160 (alist :tag "Regexp/function association list"
160 :key-type regexp :value-type function))) 161 :key-type regexp :value-type function
162 :format "%{%t%}\n%d%v\n"
163 :doc "Deprecated. Use `browse-url-handlers' instead.")))
161 164
162;;;###autoload 165;;;###autoload
163(defcustom browse-url-browser-function 'browse-url-default-browser 166(defcustom browse-url-browser-function 'browse-url-default-browser
@@ -165,13 +168,8 @@
165This is used by the `browse-url-at-point', `browse-url-at-mouse', and 168This is used by the `browse-url-at-point', `browse-url-at-mouse', and
166`browse-url-of-file' commands. 169`browse-url-of-file' commands.
167 170
168If the value is not a function it should be a list of pairs 171Also see `browse-url-secondary-browser-function' and
169\(REGEXP . FUNCTION). In this case the function called will be the one 172`browse-url-handlers'."
170associated with the first REGEXP which matches the current URL. The
171function is passed the URL and any other args of `browse-url'. The last
172regexp should probably be \".\" to specify a default browser.
173
174Also see `browse-url-secondary-browser-function'."
175 :type browse-url--browser-defcustom-type 173 :type browse-url--browser-defcustom-type
176 :version "24.1") 174 :version "24.1")
177 175
@@ -595,6 +593,41 @@ down (this *won't* always work)."
595 "Wrapper command prepended to the Elinks command-line." 593 "Wrapper command prepended to the Elinks command-line."
596 :type '(repeat (string :tag "Wrapper"))) 594 :type '(repeat (string :tag "Wrapper")))
597 595
596(defun browse-url--mailto (url &rest args)
597 "Calls `browse-url-mailto-function' with URL and ARGS."
598 (funcall browse-url-mailto-function url args))
599
600(defun browse-url--man (url &rest args)
601 "Calls `browse-url-man-function' with URL and ARGS."
602 (funcall browse-url-man-function url args))
603
604;;;###autoload
605(defvar browse-url-default-handlers
606 '(("\\`mailto:" . browse-url--mailto)
607 ("\\`man:" . browse-url--man)
608 ("\\`file://" . browse-url-emacs))
609 "Like `browse-url-handlers' but populated by Emacs and packages.
610
611Emacs and external packages capable of browsing certain URLs
612should place their entries in this alist rather than
613`browse-url-handlers' which is reserved for the user.")
614
615(defcustom browse-url-handlers nil
616 "An alist with elements of the form (REGEXP HANDLER).
617Each REGEXP is matched against the URL to be opened in turn and
618the first match's HANDLER is invoked with the URL.
619
620A HANDLER must be a function with the same arguments as
621`browse-url'.
622
623If no REGEXP matches, the same procedure is performed with the
624value of `browse-url-default-handlers'. If there is also no
625match, the URL is opened using the value of
626`browse-url-browser-function'."
627 :type '(alist :key-type (regexp :tag "Regexp")
628 :value-type (function :tag "Handler"))
629 :version "28.1")
630
598;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
599;; URL encoding 632;; URL encoding
600 633
@@ -768,16 +801,18 @@ narrowed."
768 "Ask a WWW browser to load URL. 801 "Ask a WWW browser to load URL.
769Prompt for a URL, defaulting to the URL at or before point. 802Prompt for a URL, defaulting to the URL at or before point.
770Invokes a suitable browser function which does the actual job. 803Invokes a suitable browser function which does the actual job.
771The variable `browse-url-browser-function' says which browser function to 804
772use. If the URL is a mailto: URL, consult `browse-url-mailto-function' 805The variables `browse-url-browser-function',
773first, if that exists. 806`browse-url-handlers', and `browse-url-default-handlers'
774 807determine which browser function to use.
775The additional ARGS are passed to the browser function. See the doc 808
776strings of the actual functions, starting with `browse-url-browser-function', 809The additional ARGS are passed to the browser function. See the
777for information about the significance of ARGS (most of the functions 810doc strings of the actual functions, starting with
778ignore it). 811`browse-url-browser-function', for information about the
779If ARGS are omitted, the default is to pass `browse-url-new-window-flag' 812significance of ARGS (most of the functions ignore it).
780as ARGS." 813
814If ARGS are omitted, the default is to pass
815`browse-url-new-window-flag' as ARGS."
781 (interactive (browse-url-interactive-arg "URL: ")) 816 (interactive (browse-url-interactive-arg "URL: "))
782 (unless (called-interactively-p 'interactive) 817 (unless (called-interactively-p 'interactive)
783 (setq args (or args (list browse-url-new-window-flag)))) 818 (setq args (or args (list browse-url-new-window-flag))))
@@ -786,12 +821,15 @@ as ARGS."
786 (not (string-match "\\`[a-z]+:" url))) 821 (not (string-match "\\`[a-z]+:" url)))
787 (setq url (expand-file-name url))) 822 (setq url (expand-file-name url)))
788 (let ((process-environment (copy-sequence process-environment)) 823 (let ((process-environment (copy-sequence process-environment))
789 (function (or (and (string-match "\\`mailto:" url) 824 (function
790 browse-url-mailto-function) 825 (catch 'custom-url-handler
791 (and (string-match "\\`man:" url) 826 (dolist (regex-handler (append browse-url-handlers
792 browse-url-man-function) 827 browse-url-default-handlers))
793 browse-url-browser-function)) 828 (when (string-match-p (car regex-handler) url)
794 ;; Ensure that `default-directory' exists and is readable (b#6077). 829 (throw 'custom-url-handler (cdr regex-handler))))
830 ;; No special handler found.
831 browse-url-browser-function))
832 ;; Ensure that `default-directory' exists and is readable (bug#6077).
795 (default-directory (or (unhandled-file-name-directory default-directory) 833 (default-directory (or (unhandled-file-name-directory default-directory)
796 (expand-file-name "~/")))) 834 (expand-file-name "~/"))))
797 ;; When connected to various displays, be careful to use the display of 835 ;; When connected to various displays, be careful to use the display of
@@ -801,15 +839,19 @@ as ARGS."
801 (setenv "DISPLAY" (frame-parameter nil 'display))) 839 (setenv "DISPLAY" (frame-parameter nil 'display)))
802 (if (and (consp function) 840 (if (and (consp function)
803 (not (functionp function))) 841 (not (functionp function)))
804 ;; The `function' can be an alist; look down it for first match 842 ;; The `function' can be an alist; look down it for first
805 ;; and apply the function (which might be a lambda). 843 ;; match and apply the function (which might be a lambda).
806 (catch 'done 844 ;; However, this usage is deprecated as of Emacs 28.1.
807 (dolist (bf function) 845 (progn
808 (when (string-match (car bf) url) 846 (warn "Having `browse-url-browser-function' set to an
809 (apply (cdr bf) url args) 847alist is deprecated. Use `browse-url-handlers' instead.")
810 (throw 'done t))) 848 (catch 'done
811 (error "No browse-url-browser-function matching URL %s" 849 (dolist (bf function)
812 url)) 850 (when (string-match (car bf) url)
851 (apply (cdr bf) url args)
852 (throw 'done t)))
853 (error "No browse-url-browser-function matching URL %s"
854 url)))
813 ;; Unbound symbols go down this leg, since void-function from 855 ;; Unbound symbols go down this leg, since void-function from
814 ;; apply is clearer than wrong-type-argument from dolist. 856 ;; apply is clearer than wrong-type-argument from dolist.
815 (apply function url args)))) 857 (apply function url args))))