From b0f9cbb3da6124c540b0a577e0928e85b362b277 Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Thu, 7 May 2020 13:02:13 +0200 Subject: [PATCH] Categorize browse-url functions into internal and external ones. * lisp/net/browse-url.el: Write package documentation explaining browse-url-browser-kind symbol property. Categorize existing browse-url functions into internal and external ones. (browse-url--browser-kind, browse-url--browser-kind-mailto) (browse-url--browser-kind-man, browse-url--browser-kind-browser): New functions. (browse-url-select-handler): Add KIND argument to restrict selection. * lisp/dnd.el (dnd-handle-one-url): Only select browse-url handler of kind `internal'. * lisp/net/eww.el (eww): Add `browse-url-browser-kind' symbol property with value `internal'. --- lisp/dnd.el | 2 +- lisp/net/browse-url.el | 110 +++++++++++++++++++++++++++++++++++++++-- lisp/net/eww.el | 2 + 3 files changed, 109 insertions(+), 5 deletions(-) diff --git a/lisp/dnd.el b/lisp/dnd.el index 102bc752b07..298241bf174 100644 --- a/lisp/dnd.el +++ b/lisp/dnd.el @@ -103,7 +103,7 @@ is what has been dropped. Returns ACTION." (catch 'done ;; Autoloaded but the byte-compiler still complains. (declare-function browse-url-select-handler "browse-url" (url)) - (let ((browser (browse-url-select-handler url))) + (let ((browser (browse-url-select-handler url 'internal))) (when browser (setq ret 'private) (funcall browser url action) diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 9d7eca72286..6dc9f8961a8 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -119,6 +119,17 @@ ;; could be done by setting `browse-url-browser-function' to an alist ;; but this usage is deprecated now. +;; All browser functions provided by here have a +;; `browse-url-browser-kind' symbol property set to either `internal' +;; or `external' which determines if they browse the given URL inside +;; Emacs or spawn an external application with it. Some parts of +;; Emacs make use of that, e.g., when an URL is dragged into Emacs, it +;; is not sensible to invoke an external browser with it, so here only +;; internal browsers are considered. Therefore, it is advised to put +;; that property also on custom browser functions. +;; (put 'my-browse-url-in-emacs 'browse-url-browser-kind 'internal) +;; (put 'my-browse-url-externally 'browse-url-browser-kind 'external) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Code: @@ -593,18 +604,45 @@ down (this *won't* always work)." "Wrapper command prepended to the Elinks command-line." :type '(repeat (string :tag "Wrapper"))) +(defun browse-url--browser-kind (function url) + "Return the browser kind of a browser FUNCTION for URL. +The browser kind is either `internal' (the browser runs inside +Emacs), `external' (the browser is spawned in an external +process), or nil (we don't know)." + (let ((kind (if (symbolp function) + (get function 'browse-url-browser-kind)))) + (if (functionp kind) + (funcall kind url) + kind))) + (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--browser-kind-mailto (url) + (browse-url--browser-kind browse-url-mailto-function url)) +(put 'browse-url--mailto 'browse-url-browser-kind + #'browse-url--browser-kind-mailto) + (defun browse-url--man (url &rest args) "Calls `browse-url-man-function' with URL and ARGS." (funcall browse-url-man-function url args)) +(defun browse-url--browser-kind-man (url) + (browse-url--browser-kind browse-url-man-function url)) +(put 'browse-url--man 'browse-url-browser-kind + #'browse-url--browser-kind-man) + (defun browse-url--browser (url &rest args) "Calls `browse-url-browser-function' with URL and ARGS." (funcall browse-url-browser-function url args)) +(defun browse-url--browser-kind-browser (url) + (browse-url--browser-kind browse-url-browser-function url)) +(put 'browse-url--browser 'browse-url-browser-kind + #'browse-url--browser-kind-browser) + + ;;;###autoload (defvar browse-url-default-handlers '(("\\`mailto:" . browse-url--mailto) @@ -636,12 +674,16 @@ match, the URL is opened using the value of :version "28.1") ;;;###autoload -(defun browse-url-select-handler (url) - "Return a handler suitable for browsing URL. +(defun browse-url-select-handler (url &optional kind) + "Return a handler of suitable for browsing URL. This searches `browse-url-handlers', and `browse-url-default-handlers' for a matching handler. Return nil if no handler is found. +If KIND is given, the search is restricted to handlers whose +function symbol has the symbol-property `browse-url-browser-kind' +set to KIND. + 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." @@ -659,7 +701,10 @@ alist is deprecated. Use `browse-url-handlers' instead.") browse-url-browser-function) browse-url-handlers browse-url-default-handlers)) - (when (string-match-p (car regex-handler) url) + (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)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -930,12 +975,18 @@ The optional NEW-WINDOW argument is not used." (url-unhex-string url) url))))) +(put 'browse-url-default-windows-browser 'browse-url-browser-kind + 'external) + (defun browse-url-default-macosx-browser (url &optional _new-window) "Invoke the macOS system's default Web browser. The optional NEW-WINDOW argument is not used." (interactive (browse-url-interactive-arg "URL: ")) (start-process (concat "open " url) nil "open" url)) +(put 'browse-url-default-macosx-browser 'browse-url-browser-kind + 'external) + ;; --- Netscape --- (defun browse-url-process-environment () @@ -992,6 +1043,10 @@ instead of `browse-url-new-window-flag'." (lambda (&rest _ignore) (error "No usable browser found")))) url args)) +(put 'browse-url-default-browser 'browse-url-browser-kind + ;; Well, most probably external if we ignore w3. + 'external) + (defun browse-url-can-use-xdg-open () "Return non-nil if the \"xdg-open\" program can be used. xdg-open is a desktop utility that calls your preferred web browser." @@ -1011,6 +1066,8 @@ The optional argument IGNORED is not used." (interactive (browse-url-interactive-arg "URL: ")) (call-process "xdg-open" nil 0 nil url)) +(put 'browse-url-xdg-open 'browse-url-browser-kind 'external) + ;;;###autoload (defun browse-url-netscape (url &optional new-window) "Ask the Netscape WWW browser to load URL. @@ -1054,6 +1111,8 @@ used instead of `browse-url-new-window-flag'." `(lambda (process change) (browse-url-netscape-sentinel process ,url))))) +(put 'browse-url-netscape 'browse-url-browser-kind 'external) + (defun browse-url-netscape-sentinel (process url) "Handle a change to the process communicating with Netscape." (declare (obsolete nil "25.1")) @@ -1124,6 +1183,8 @@ used instead of `browse-url-new-window-flag'." `(lambda (process change) (browse-url-mozilla-sentinel process ,url))))) +(put 'browse-url-mozilla 'browse-url-browser-kind 'external) + (defun browse-url-mozilla-sentinel (process url) "Handle a change to the process communicating with Mozilla." (or (eq (process-exit-status process) 0) @@ -1164,6 +1225,8 @@ instead of `browse-url-new-window-flag'." '("-new-window"))) (list url))))) +(put 'browse-url-firefox 'browse-url-browser-kind 'external) + ;;;###autoload (defun browse-url-chromium (url &optional _new-window) "Ask the Chromium WWW browser to load URL. @@ -1181,6 +1244,8 @@ The optional argument NEW-WINDOW is not used." browse-url-chromium-arguments (list url))))) +(put 'browse-url-chromium 'browse-url-browser-kind 'external) + (defun browse-url-chrome (url &optional _new-window) "Ask the Google Chrome WWW browser to load URL. Default to the URL around or before point. The strings in @@ -1197,6 +1262,8 @@ The optional argument NEW-WINDOW is not used." browse-url-chrome-arguments (list url))))) +(put 'browse-url-chrome 'browse-url-browser-kind 'external) + ;;;###autoload (defun browse-url-galeon (url &optional new-window) "Ask the Galeon WWW browser to load URL. @@ -1234,6 +1301,8 @@ used instead of `browse-url-new-window-flag'." `(lambda (process change) (browse-url-galeon-sentinel process ,url))))) +(put 'browse-url-galeon 'browse-url-browser-kind 'external) + (defun browse-url-galeon-sentinel (process url) "Handle a change to the process communicating with Galeon." (declare (obsolete nil "25.1")) @@ -1280,6 +1349,8 @@ used instead of `browse-url-new-window-flag'." `(lambda (process change) (browse-url-epiphany-sentinel process ,url))))) +(put 'browse-url-epiphany 'browse-url-browser-kind 'external) + (defun browse-url-epiphany-sentinel (process url) "Handle a change to the process communicating with Epiphany." (or (eq (process-exit-status process) 0) @@ -1304,6 +1375,8 @@ currently selected window instead." file-name-handler-alist))) (if same-window (find-file url) (find-file-other-window url)))) +(put 'browse-url-emacs 'browse-url-browser-kind 'internal) + ;;;###autoload (defun browse-url-gnome-moz (url &optional new-window) "Ask Mozilla/Netscape to load URL via the GNOME program `gnome-moz-remote'. @@ -1328,6 +1401,8 @@ used instead of `browse-url-new-window-flag'." '("--newwin")) (list "--raise" url)))) +(put 'browse-url-gnome-moz 'browse-url-browser-kind 'external) + ;; --- Mosaic --- ;;;###autoload @@ -1379,6 +1454,8 @@ used instead of `browse-url-new-window-flag'." (append browse-url-mosaic-arguments (list url))) (message "Starting %s...done" browse-url-mosaic-program)))) +(put 'browse-url-mosaic 'browse-url-browser-kind 'external) + ;; --- Mosaic using CCI --- ;;;###autoload @@ -1411,6 +1488,8 @@ used instead of `browse-url-new-window-flag'." (process-send-string "browse-url" "disconnect\r\n") (delete-process "browse-url")) +(put 'browse-url-cci 'browse-url-browser-kind 'external) + ;; --- Conkeror --- ;;;###autoload (defun browse-url-conkeror (url &optional new-window) @@ -1447,6 +1526,9 @@ NEW-WINDOW instead of `browse-url-new-window-flag'." "window") "buffer") url)))))) + +(put 'browse-url-conkeror 'browse-url-browser-kind 'external) + ;; --- W3 --- ;; External. @@ -1470,6 +1552,8 @@ used instead of `browse-url-new-window-flag'." (w3-fetch-other-window url) (w3-fetch url))) +(put 'browse-url-w3 'browse-url-browser-kind 'internal) + ;;;###autoload (defun browse-url-w3-gnudoit (url &optional _new-window) ;; new-window ignored @@ -1484,6 +1568,8 @@ The `browse-url-gnudoit-program' program is used with options given by (list (concat "(w3-fetch \"" url "\")") "(raise-frame)")))) +(put 'browse-url-w3-gnudoit 'browse-url-browser-kind 'internal) + ;; --- Lynx in an xterm --- ;;;###autoload @@ -1501,6 +1587,8 @@ The optional argument NEW-WINDOW is not used." ,@browse-url-xterm-args "-e" ,browse-url-text-browser ,url))) +(put 'browse-url-text-xterm 'browse-url-browser-kind 'external) + ;; --- Lynx in an Emacs "term" window --- (declare-function term-char-mode "term" ()) @@ -1575,6 +1663,8 @@ used instead of `browse-url-new-window-flag'." url "\r"))))) +(put 'browse-url-text-emacs 'browse-url-browser-kind 'internal) + ;; --- mailto --- (autoload 'rfc2368-parse-mailto-url "rfc2368") @@ -1622,6 +1712,8 @@ used instead of `browse-url-new-window-flag'." (unless (bolp) (insert "\n")))))))) +(put 'browse-url-mail 'browse-url-browser-kind 'internal) + ;; --- man --- (defvar manual-program) @@ -1633,7 +1725,9 @@ used instead of `browse-url-new-window-flag'." (setq url (replace-regexp-in-string "\\`man:" "" url)) (cond ((executable-find manual-program) (man url)) - (t (woman (replace-regexp-in-string "([[:alnum:]]+)" "" url))))) + (t (woman (replace-regexp-in-string "([[:alnum:]]+)" "" url))))) + +(put 'browse-url-man 'browse-url-browser-kind 'internal) ;; --- Random browser --- @@ -1652,6 +1746,8 @@ don't offer a form of remote control." 0 nil (append browse-url-generic-args (list url)))) +(put 'browse-url-generic 'browse-url-browser-kind 'external) + ;;;###autoload (defun browse-url-kde (url &optional _new-window) "Ask the KDE WWW browser to load URL. @@ -1662,6 +1758,8 @@ The optional argument NEW-WINDOW is not used." (apply #'start-process (concat "KDE " url) nil browse-url-kde-program (append browse-url-kde-args (list url)))) +(put 'browse-url-kde 'browse-url-browser-kind 'external) + (defun browse-url-elinks-new-window (url) "Ask the Elinks WWW browser to load URL in a new window." (let ((process-environment (browse-url-process-environment))) @@ -1671,6 +1769,8 @@ The optional argument NEW-WINDOW is not used." browse-url-elinks-wrapper (list "elinks" url))))) +(put 'browse-url-elinks-new-window 'browse-url-browser-kind 'external) + ;;;###autoload (defun browse-url-elinks (url &optional new-window) "Ask the Elinks WWW browser to load URL. @@ -1692,6 +1792,8 @@ from `browse-url-elinks-wrapper'." `(lambda (process change) (browse-url-elinks-sentinel process ,url)))))) +(put 'browse-url-elinks 'browse-url-browser-kind 'external) + (defun browse-url-elinks-sentinel (process url) "Determines if Elinks is running or a new one has to be started." ;; Try to determine if an instance is running or if we have to diff --git a/lisp/net/eww.el b/lisp/net/eww.el index 9cf9ecea0bf..a6c1abdbb19 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -310,6 +310,8 @@ the default EWW buffer." (url-retrieve url 'eww-render (list url nil (current-buffer))))) +(put 'eww 'browse-url-browser-kind 'internal) + (defun eww--dwim-expand-url (url) (setq url (string-trim url)) (cond ((string-match-p "\\`file:/" url)) -- 2.39.5