From 909591a4b25901392686f1cf68870260d3016afe Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Fri, 8 May 2020 20:57:19 +0200 Subject: [PATCH] Allow predicates for matching in browse-url-handlers. * lisp/net/browse-url.el (browse-url-handlers): Allow predicates for matching in browse-url-handlers. Adapt docs and customize type. (browse-url-select-handler): Support predicates in addition to regexes. (browse-url--non-html-file-url-p): New defun. (browse-url-default-handlers): Use above predicate entry instead of two entries. --- doc/emacs/misc.texi | 3 ++- etc/NEWS | 20 +++++++++++++++----- lisp/net/browse-url.el | 41 ++++++++++++++++++++++++----------------- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index d1854f31ff3..1336da12b07 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -2926,7 +2926,8 @@ 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. +expressions or predicates paired with functions to browse matching +URLs. For more information, view the package commentary by typing @kbd{C-h P browse-url @key{RET}}. diff --git a/etc/NEWS b/etc/NEWS index ac93a76ff95..9c71752b621 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -310,16 +310,26 @@ or use it in a custom ‘c-style’. *** 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). +'browse-url-handlers' being alists with (REGEXP-OR-PREDICATE +. 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. +*** Categorization of browsing functions in internal vs. external + +All standard browsing functions such as 'browse-url-firefox', +'browse-url-mail', or 'eww' have been categorized into internal (URL +is browsed in Emacs) or external (an external application is spawned +with the URL). This is done by adding a 'browse-url-browser-kind' +symbol property to the browsing functions. With a new command +'browse-url-with-browser-kind', an URL can explicitly be browsed with +either an internal or external browser. + * New Modes and Packages in Emacs 28.1 diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index d7b8521563a..9073f896831 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -642,15 +642,16 @@ process), or nil (we don't know)." (put 'browse-url--browser 'browse-url-browser-kind #'browse-url--browser-kind-browser) +(defun browse-url--non-html-file-url-p (url) + "Return non-nil if URL is a file:// URL of a non-HTML file." + (and (string-match-p "\\`file://" url) + (not (string-match-p "\\`file://.*\\.html?\\b" url)))) ;;;###autoload (defvar browse-url-default-handlers '(("\\`mailto:" . browse-url--mailto) ("\\`man:" . browse-url--man) - ;; Render file:// URLs if they are HTML pages, otherwise just find - ;; the file. - ("\\`file://.*\\.html?\\b" . browse-url--browser) - ("\\`file://" . browse-url-emacs)) + (browse-url--non-html-file-url-p . browse-url-emacs)) "Like `browse-url-handlers' but populated by Emacs and packages. Emacs and external packages capable of browsing certain URLs @@ -658,18 +659,20 @@ 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. + "An alist with elements of the form (REGEXP-OR-PREDICATE . HANDLER). +Each REGEXP-OR-PREDICATE 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 +If no REGEXP-OR-PREDICATE 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") + :type '(alist :key-type (choice + (regexp :tag "Regexp") + (function :tag "Predicate")) :value-type (function :tag "Handler")) :version "28.1") @@ -688,7 +691,7 @@ Currently, it also consults `browse-url-browser-function' first if it is set to an alist, although this usage is deprecated since Emacs 28.1 and will be removed in a future release." (catch 'custom-url-handler - (dolist (regex-handler + (dolist (rxpred-handler (append ;; The alist choice of browse-url-browser-function ;; is deprecated since 28.1, so the (unless ...) @@ -701,11 +704,15 @@ alist is deprecated. Use `browse-url-handlers' instead.") browse-url-browser-function) browse-url-handlers browse-url-default-handlers)) - (when (and (or (null kind) - (eq kind (browse-url--browser-kind - (cdr regex-handler) url))) - (string-match-p (car regex-handler) url)) - (throw 'custom-url-handler (cdr regex-handler)))))) + (let ((rx-or-pred (car rxpred-handler)) + (handler (cdr rxpred-handler))) + (when (and (or (null kind) + (eq kind (browse-url--browser-kind + handler url))) + (if (functionp rx-or-pred) + (funcall rx-or-pred url) + (string-match-p rx-or-pred url))) + (throw 'custom-url-handler handler)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; URL encoding -- 2.39.2