;; 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:
"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)
: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."
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))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(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 ()
(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."
(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.
`(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"))
`(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)
'("-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.
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
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.
`(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"))
`(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)
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'.
'("--newwin"))
(list "--raise" url))))
+(put 'browse-url-gnome-moz 'browse-url-browser-kind 'external)
+
;; --- Mosaic ---
;;;###autoload
(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
(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)
"window")
"buffer")
url))))))
+
+(put 'browse-url-conkeror 'browse-url-browser-kind 'external)
+
;; --- W3 ---
;; External.
(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
(list (concat "(w3-fetch \"" url "\")")
"(raise-frame)"))))
+(put 'browse-url-w3-gnudoit 'browse-url-browser-kind 'internal)
+
;; --- Lynx in an xterm ---
;;;###autoload
,@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" ())
url
"\r")))))
+(put 'browse-url-text-emacs 'browse-url-browser-kind 'internal)
+
;; --- mailto ---
(autoload 'rfc2368-parse-mailto-url "rfc2368")
(unless (bolp)
(insert "\n"))))))))
+(put 'browse-url-mail 'browse-url-browser-kind 'internal)
+
;; --- man ---
(defvar manual-program)
(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 ---
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.
(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)))
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.
`(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