-;;; browse-url.el --- Pass a URL to a WWW browser
+;;; browse-url.el --- pass a URL to a WWW browser
;; Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001
;; Free Software Foundation, Inc.
;; Author: Denis Howe <dbh@doc.ic.ac.uk>
-;; Maintainer: Dave Love <fx@gnu.org>
+;; Maintainer: FSF
;; Created: 03 Apr 1995
;; Keywords: hypertext, hypermedia, mouse
;; some of them probably now obsolete:
;; Function Browser Earliest version
+;; browse-url-mozilla Mozilla Don't know
+;; browse-url-galeon Galeon Don't know
;; browse-url-netscape Netscape 1.1b1
;; browse-url-mosaic XMosaic/mMosaic <= 2.4
;; browse-url-cci XMosaic 2.5
;; browse-url-generic arbitrary
;; browse-url-default-windows-browser MS-Windows browser
;; browse-url-gnome-moz GNOME interface to Mozilla
+;; browse-url-kde KDE konqueror (kfm)
;; [A version of the Netscape browser is now free software
;; <URL:http://www.mozilla.org/>, albeit not GPLed, so it is
;; control but which window DO you want to control and how do you
;; discover its id?
-;; If using XMosaic before version 2.5, check the definition of
-;; browse-url-usr1-signal below.
-;; <URL:http://www.ncsa.uiuc.edu/SDG/Software/XMosaic/remote-control.html>
-
-;; XMosaic version 2.5 introduced Common Client Interface allowing you
-;; to control mosaic through Unix sockets.
-;; <URL:http://www.ncsa.uiuc.edu/SDG/Software/XMosaic/CCI/cci-spec.html>
-
;; William M. Perry's excellent "w3" WWW browser for
;; Emacs <URL:ftp://cs.indiana.edu/pub/elisp/w3/>
;; has a function w3-follow-url-at-point, but that
;; Python see <url:http://www.python.org/>. Grail support in
;; browse-url.el written by Barry Warsaw <bwarsaw@python.org>.
-;; MMM is a semi-free WWW browser implemented in Objective Caml, an
-;; interesting impure functional programming language. See
-;; <URL:http://pauillac.inria.fr/%7Erouaix/mmm/>.
-
;; Lynx is now distributed by the FSF. See also
;; <URL:http://lynx.browser.org/>.
(eval-when-compile (require 'thingatpt)
(require 'term)
(require 'dired)
+ (require 'executable)
(require 'w3-auto nil t))
(defgroup browse-url nil
;;;###autoload
(defcustom browse-url-browser-function
- (if (eq system-type 'windows-nt)
+ (if (memq system-type '(windows-nt ms-dos))
'browse-url-default-windows-browser
- 'browse-url-netscape)
+ 'browse-url-default-browser)
"*Function to display the current buffer in a WWW browser.
This is used by the `browse-url-at-point', `browse-url-at-mouse', and
`browse-url-of-file' commands.
(function-item :tag "Emacs W3" :value browse-url-w3)
(function-item :tag "W3 in another Emacs via `gnudoit'"
:value browse-url-w3-gnudoit)
+ (function-item :tag "Mozilla" :value browse-url-mozilla)
+ (function-item :tag "Galeon" :value browse-url-galeon)
(function-item :tag "Netscape" :value browse-url-netscape)
(function-item :tag "Mosaic" :value browse-url-mosaic)
(function-item :tag "Mosaic using CCI" :value browse-url-cci)
:value browse-url-lynx-emacs)
(function-item :tag "Grail" :value browse-url-grail)
(function-item :tag "MMM" :value browse-url-mmm)
+ (function-item :tag "KDE" :value browse-url-kde)
(function-item :tag "Specified by `Browse Url Generic Program'"
:value browse-url-generic)
(function-item :tag "Default Windows browser"
:value browse-url-default-windows-browser)
(function-item :tag "GNOME invoking Mozilla"
:value browse-url-gnome-moz)
+ (function-item :tag "Default browser"
+ :value browse-url-default-browser)
(function :tag "Your own function")
(alist :tag "Regexp/function association list"
:key-type regexp :value-type function))
(defcustom browse-url-netscape-program "netscape"
;; Info about netscape-remote from Karl Berry.
- "The name by which to invoke Netscape.
+ "*The name by which to invoke Netscape.
The free program `netscape-remote' from
<URL:http://home.netscape.com/newsref/std/remote.c> is said to start
:group 'browse-url)
(defcustom browse-url-netscape-arguments nil
- "A list of strings to pass to Netscape as arguments."
+ "*A list of strings to pass to Netscape as arguments."
:type '(repeat (string :tag "Argument"))
:group 'browse-url)
(defcustom browse-url-netscape-startup-arguments browse-url-netscape-arguments
- "A list of strings to pass to Netscape when it starts up.
+ "*A list of strings to pass to Netscape when it starts up.
Defaults to the value of `browse-url-netscape-arguments' at the time
`browse-url' is loaded."
:type '(repeat (string :tag "Argument"))
:group 'browse-url)
+;;;###autoload
+(defcustom browse-url-browser-display nil
+ "*The X display for running the browser, if not same as Emacs'."
+ :type '(choice string (const :tag "Default" nil))
+ :group 'browse-url)
+
+(defcustom browse-url-mozilla-program "mozilla"
+ "*The name by which to invoke Mozilla."
+ :type 'string
+ :group 'browse-url)
+
+(defcustom browse-url-mozilla-arguments nil
+ "*A list of strings to pass to Mozilla as arguments."
+ :type '(repeat (string :tag "Argument"))
+ :group 'browse-url)
+
+(defcustom browse-url-mozilla-startup-arguments browse-url-mozilla-arguments
+ "*A list of strings to pass to Mozilla when it starts up.
+Defaults to the value of `browse-url-mozilla-arguments' at the time
+`browse-url' is loaded."
+ :type '(repeat (string :tag "Argument"))
+ :group 'browse-url)
+
+;;;###autoload
+(defcustom browse-url-galeon-program "galeon"
+ "*The name by which to invoke Galeon."
+ :type 'string
+ :group 'browse-url)
+
+(defcustom browse-url-galeon-arguments nil
+ "*A list of strings to pass to Galeon as arguments."
+ :type '(repeat (string :tag "Argument"))
+ :group 'browse-url)
+
+(defcustom browse-url-galeon-startup-arguments browse-url-galeon-arguments
+ "*A list of strings to pass to Galeon when it starts up.
+Defaults to the value of `browse-url-galeon-arguments' at the time
+`browse-url' is loaded."
+ :type '(repeat (string :tag "Argument"))
+ :group 'browse-url)
+
+(defcustom browse-url-galeon-new-window-is-tab nil
+ "*Whether to open up new windows in a tab or a new window.
+If non-nil, then open the URL in a new tab rather than a new window if
+`browse-url-galeon' is asked to open it in a new window."
+ :type 'boolean
+ :group 'browse-url)
+
;;;###autoload
(defcustom browse-url-new-window-flag nil
"*If non-nil, always open a new browser window with appropriate browsers.
:type 'boolean
:group 'browse-url)
-;;;###autoload
-(defcustom browse-url-netscape-display nil
- "*The X display for running Netscape, if not same as Emacs'."
- :type '(choice string (const :tag "Default" nil))
- :group 'browse-url)
-
(defcustom browse-url-mosaic-program "xmosaic"
- "The name by which to invoke Mosaic (or mMosaic)."
+ "*The name by which to invoke Mosaic (or mMosaic)."
:type 'string
:version "20.3"
:group 'browse-url)
(defcustom browse-url-mosaic-arguments nil
- "A list of strings to pass to Mosaic as arguments."
+ "*A list of strings to pass to Mosaic as arguments."
:type '(repeat (string :tag "Argument"))
:group 'browse-url)
+(defcustom browse-url-mosaic-pidfile "~/.mosaicpid"
+ "*The name of the pidfile created by Mosaic."
+ :type 'string
+ :group 'browse-url)
+
(defcustom browse-url-filename-alist
(\` ; Backquote syntax won't work.
(("^/\\(ftp@\\|anonymous@\\)?\\([^:]+\\):/*" . "ftp://\\2/")
'(("^\\([a-zA-Z]:\\)[\\/]" . "file:\\1/")
("^[\\/][\\/]+" . "file://"))))
("^/+" . "file:/")))
- "An alist of (REGEXP . STRING) pairs used by `browse-url-of-file'.
+ "*An alist of (REGEXP . STRING) pairs used by `browse-url-of-file'.
Any substring of a filename matching one of the REGEXPs is replaced by
the corresponding STRING using `replace-match', not treating STRING
literally. All pairs are applied in the order given. The default
:group 'browse-url)
(defcustom browse-url-of-file-hook nil
- "Run after `browse-url-of-file' has asked a browser to load a file.
+ "*Run after `browse-url-of-file' has asked a browser to load a file.
Set this to `browse-url-netscape-reload' to force Netscape to load the
file rather than displaying a cached copy."
which is 30 on SunOS and 16 on HP-UX and Solaris.")
(defcustom browse-url-CCI-port 3003
- "Port to access XMosaic via CCI.
+ "*Port to access XMosaic via CCI.
This can be any number between 1024 and 65535 but must correspond to
the value set in the browser."
:type 'integer
(make-variable-buffer-local 'browse-url-temp-file-name)
(defcustom browse-url-xterm-program "xterm"
- "The name of the terminal emulator used by `browse-url-lynx-xterm'.
+ "*The name of the terminal emulator used by `browse-url-lynx-xterm'.
This might, for instance, be a separate colour version of xterm."
:type 'string
:group 'browse-url)
(defcustom browse-url-lynx-emacs-args (and (not window-system)
'("-show_cursor"))
- "A list of strings defining options for Lynx in an Emacs buffer.
+ "*A list of strings defining options for Lynx in an Emacs buffer.
The default is none in a window system, otherwise `-show_cursor' to
indicate the position of the current link in the absence of
:group 'browse-url)
(defcustom browse-url-gnudoit-program "gnudoit"
- "The name of the `gnudoit' program used by `browse-url-w3-gnudoit'."
+ "*The name of the `gnudoit' program used by `browse-url-w3-gnudoit'."
:type 'string
:group 'browse-url)
:group 'browse-url)
(defcustom browse-url-temp-dir temporary-file-directory
- "The name of a directory for browse-url's temporary files.
+ "*The name of a directory for browse-url's temporary files.
Such files are generated by functions like `browse-url-of-region'.
You might want to set this to somewhere with restricted read permissions
for privacy's sake."
(defcustom browse-url-netscape-version
3
- "The version of Netscape you are using.
+ "*The version of Netscape you are using.
This affects how URL reloading is done; the mechanism changed
incompatibly at version 4."
:type 'number
:version "20.3"
:group 'browse-url)
-(defvar browse-url-lynx-input-attempts 10
- "*How many times to try to move down from a series of lynx input fields.")
+(defcustom browse-url-lynx-input-attempts 10
+ "*How many times to try to move down from a series of lynx input fields."
+ :type 'integer
+ :group 'browse-url)
(defcustom browse-url-lynx-input-delay 0.2
- "How many seconds to wait for lynx between moves down from an input field.")
+ "*How many seconds to wait for lynx between moves down from an input field."
+ :type 'number
+ :group 'browse-url)
+
+(defcustom browse-url-kde-program "kfmclient"
+ "*The name by which to invoke the KDE web browser."
+ :type 'string
+ :version "21.1"
+ :group 'browse-url)
+
+(defcustom browse-url-kde-args '("openURL")
+ "*A list of strings defining options for `browse-url-kde-program'."
+ :type '(repeat (string :tag "Argument"))
+ :group 'browse-url)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; URL input
;; interactive-p needs to be called at a function's top-level, hence
;; the macro.
(defmacro browse-url-maybe-new-window (arg)
- `(if (interactive-p)
+ `(if (not (interactive-p))
,arg
browse-url-new-window-flag))
(interactive "e")
(save-excursion
(mouse-set-point event)
- (browse-url-at-point browse-url-new-window-flag)))
+ ;; This handles browse-url-new-window-flag properly
+ ;; when it gets no arg.
+ (browse-url-at-point)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Browser-specific commands
(defun browse-url-default-windows-browser (url &optional new-window)
(interactive (browse-url-interactive-arg "URL: "))
- (w32-shell-execute "open" url))
+ (if (eq system-type 'ms-dos)
+ (if dos-windows-version
+ (shell-command (concat "start " (shell-quote-argument url)))
+ (error "Browsing URLs is not supported on this system"))
+ (w32-shell-execute "open" url)))
;; --- Netscape ---
(defun browse-url-process-environment ()
- "Set DISPLAY in the environment to the X display Netscape is running on.
-This is either the value of variable `browse-url-netscape-display' if
+ "Set DISPLAY in the environment to the X display the browser will use.
+This is either the value of variable `browse-url-browser-display' if
non-nil, or the same display as Emacs if different from the current
environment, otherwise just use the current environment."
- (let ((display (or browse-url-netscape-display (browse-url-emacs-display))))
+ (let ((display (or browse-url-browser-display (browse-url-emacs-display))))
(if display
(cons (concat "DISPLAY=" display) process-environment)
process-environment)))
(and (not (equal display (getenv "DISPLAY")))
display)))
+;;;###autoload
+(defun browse-url-default-browser (url &rest args)
+ "Find a suitable browser and ask it to load URL.
+Default to the URL around or before point.
+
+When called interactively, if variable `browse-url-new-window-flag' is
+non-nil, load the document in a new window, if possible, otherwise use
+a random existing one. A non-nil interactive prefix argument reverses
+the effect of `browse-url-new-window-flag'.
+
+When called non-interactively, optional second argument NEW-WINDOW is
+used instead of `browse-url-new-window-flag'.
+
+The order attempted is gnome-moz-remote, Mozilla, Galeon, Netscape,
+Mosaic, IXI Mosaic, Lynx in an xterm, MMM, Konqueror, and then W3."
+ (apply
+ (cond
+ ((executable-find "gnome-moz-remote") 'browse-url-gnome-moz)
+ ((executable-find browse-url-mozilla-program) 'browse-url-mozilla)
+ ((executable-find browse-url-galeon-program) 'browse-url-galeon)
+ ((executable-find browse-url-kde-program) 'browse-url-kde)
+ ((executable-find browse-url-netscape-program) 'browse-url-netscape)
+ ((executable-find browse-url-mosaic-program) 'browse-url-mosaic)
+ ((executable-find "tellw3b") 'browse-url-iximosaic)
+ ((executable-find browse-url-xterm-program) 'browse-url-lynx-xterm)
+ ((executable-find "mmm") 'browse-url-mmm)
+ (t 'browse-url-w3))
+ url args))
+
;;;###autoload
(defun browse-url-netscape (url &optional new-window)
"Ask the Netscape WWW browser to load URL.
(append browse-url-netscape-arguments
(list "-remote" command)))))
+;;;###autoload
+(defun browse-url-mozilla (url &optional new-window)
+ "Ask the Mozilla WWW browser to load URL.
+Default to the URL around or before point. The strings in variable
+`browse-url-mozilla-arguments' are also passed to Mozilla.
+
+When called interactively, if variable `browse-url-new-window-flag' is
+non-nil, load the document in a new Mozilla window, otherwise use a
+random existing one. A non-nil interactive prefix argument reverses
+the effect of `browse-url-new-window-flag'.
+
+When called non-interactively, optional second argument NEW-WINDOW is
+used instead of `browse-url-new-window-flag'."
+ (interactive (browse-url-interactive-arg "URL: "))
+ ;; URL encode any `confusing' characters in the URL. This needs to
+ ;; include at least commas; presumably also close parens.
+ (while (string-match "[,)]" url)
+ (setq url (replace-match
+ (format "%%%x" (string-to-char (match-string 0 url))) t t url)))
+ (let* ((process-environment (browse-url-process-environment))
+ (process (apply 'start-process
+ (concat "mozilla " url) nil
+ browse-url-mozilla-program
+ (append
+ browse-url-mozilla-arguments
+ (list "-remote"
+ (concat "openURL("
+ url
+ (if new-window ",new-window")
+ ")"))))))
+ (set-process-sentinel process
+ `(lambda (process change)
+ (browse-url-mozilla-sentinel process ,url)))))
+
+(defun browse-url-mozilla-sentinel (process url)
+ "Handle a change to the process communicating with Mozilla."
+ (or (eq (process-exit-status process) 0)
+ (let* ((process-environment (browse-url-process-environment)))
+ ;; Mozilla is not running - start it
+ (message "Starting Mozilla...")
+ (apply 'start-process (concat "mozilla " url) nil
+ browse-url-mozilla-program
+ (append browse-url-mozilla-startup-arguments (list url))))))
+
+;;;###autoload
+(defun browse-url-galeon (url &optional new-window)
+ "Ask the Galeon WWW browser to load URL.
+Default to the URL around or before point. The strings in variable
+`browse-url-galeon-arguments' are also passed to Galeon.
+
+When called interactively, if variable `browse-url-new-window-flag' is
+non-nil, load the document in a new Galeon window, otherwise use a
+random existing one. A non-nil interactive prefix argument reverses
+the effect of `browse-url-new-window-flag'.
+
+If `browse-url-galeon-new-window-is-tab' is non-nil, then whenever a
+document would otherwise be loaded in a new window, it is loaded in a
+new tab in an existing window instead.
+
+When called non-interactively, optional second argument NEW-WINDOW is
+used instead of `browse-url-new-window-flag'."
+ (interactive (browse-url-interactive-arg "URL: "))
+ ;; URL encode any `confusing' characters in the URL. This needs to
+ ;; include at least commas; presumably also close parens.
+ (while (string-match "[,)]" url)
+ (setq url (replace-match
+ (format "%%%x" (string-to-char (match-string 0 url))) t t url)))
+ (let* ((process-environment (browse-url-process-environment))
+ (process (apply 'start-process
+ (concat "galeon " url) nil
+ browse-url-galeon-program
+ (append
+ browse-url-galeon-arguments
+ (if (browse-url-maybe-new-window new-window)
+ (if browse-url-galeon-new-window-is-tab
+ '("--new-tab")
+ '("--new-window" "--noraise"))
+ '("--existing"))
+ (list url)))))
+ (set-process-sentinel process
+ `(lambda (process change)
+ (browse-url-galeon-sentinel process ,url)))))
+
+(defun browse-url-galeon-sentinel (process url)
+ "Handle a change to the process communicating with Galeon."
+ (or (eq (process-exit-status process) 0)
+ (let* ((process-environment (browse-url-process-environment)))
+ ;; Galeon is not running - start it
+ (message "Starting Galeon...")
+ (apply 'start-process (concat "galeon " url) nil
+ browse-url-galeon-program
+ (append browse-url-galeon-startup-arguments (list url))))))
+
;; GNOME means of invoking either Mozilla or Netrape.
(defcustom browse-url-gnome-moz-arguments '()
- "A list of strings passed to the GNOME mozilla viewer as arguments."
+ "*A list of strings passed to the GNOME mozilla viewer as arguments."
:version "21.1"
:type '(repeat (string :tag "Argument"))
:group 'browse-url)
When called non-interactively, optional second argument NEW-WINDOW is
used instead of `browse-url-new-window-flag'."
(interactive (browse-url-interactive-arg "Mosaic URL: "))
- (let ((pidfile (expand-file-name "~/.mosaicpid"))
+ (let ((pidfile (expand-file-name browse-url-mosaic-pidfile))
pid)
(if (file-readable-p pidfile)
(save-excursion
(set-buffer (get-buffer-create " *Shell Command Output*"))
(erase-buffer)
;; don't worry about this failing.
- (if new-window
+ (if (browse-url-maybe-new-window new-window)
(call-process browse-url-grail nil 0 nil "-b" url)
(call-process browse-url-grail nil 0 nil url))
(message "Sending URL to Grail... done")))
(switch-to-buffer buf)))
(if (eq (following-char) ?_)
(cond ((eq browse-url-lynx-input-field 'warn)
- (error "Please move out of the input field first."))
+ (error "Please move out of the input field first"))
((eq browse-url-lynx-input-field 'avoid)
(while (and (eq (following-char) ?_) (> n 0))
(term-send-down) ; down arrow
(sit-for browse-url-lynx-input-delay))
(if (eq (following-char) ?_)
- (error "Cannot move out of the input field, sorry.")))))
+ (error "Cannot move out of the input field, sorry")))))
(term-send-string proc (concat "g" ; goto
"\C-u" ; kill default url
url
browse-url-generic-program
(append browse-url-generic-args (list url))))
+;;;###autoload
+(defun browse-url-kde (url &optional new-window)
+ "Ask the KDE WWW browser to load URL.
+Default to the URL around or before point."
+ (interactive (browse-url-interactive-arg "KDE URL: "))
+ (message "Sending URL to KDE...")
+ (apply #'start-process `(,(concat "KDE" url) nil ,browse-url-kde-program
+ ,@browse-url-kde-args ,url)))
+
(provide 'browse-url)
;;; browse-url.el ends here