1 ;;; browse-url.el --- pass a URL to a WWW browser
3 ;; Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001, 2002, 2003, 2005
4 ;; Free Software Foundation, Inc.
6 ;; Author: Denis Howe <dbh@doc.ic.ac.uk>
7 ;; Maintainer: XEmacs Development Team
8 ;; Created: 03 Apr 1995
9 ;; Keywords: hypertext, hypermedia, mouse
11 ;; This file is part of XEmacs.
13 ;; XEmacs is free software; you can redistribute it and/or modify
14 ;; it under the terms of the GNU General Public License as published by
15 ;; the Free Software Foundation; either version 2, or (at your option)
18 ;; XEmacs is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;; GNU General Public License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with XEmacs; see the file COPYING. If not, write to the
25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 ;; Boston, MA 02111-1307, USA.
28 ;;; Synched up with: Version 1.32 in CVS
32 ;; This package provides functions which read a URL (Uniform Resource
33 ;; Locator) from the minibuffer, defaulting to the URL around point,
34 ;; and ask a World-Wide Web browser to load it. It can also load the
35 ;; URL associated with the current buffer. Different browsers use
36 ;; different methods of remote control so there is one function for
37 ;; each supported browser. If the chosen browser is not running, it
38 ;; is started. Currently there is support for the following browsers,
39 ;; some of them probably now obsolete:
41 ;; Function Browser Earliest version
42 ;; browse-url-seamonkey SeaMonkey 1st tried with 1.0.4
43 ;; browse-url-mozilla Mozilla Don't know
44 ;; browse-url-firefox Firefox Don't know (1st tried with 1.0.1)
45 ;; browse-url-galeon Galeon Don't know
46 ;; browse-url-epiphany Epiphany Don't know
47 ;; browse-url-netscape Netscape 1.1b1
48 ;; browse-url-mosaic XMosaic/mMosaic <= 2.4
49 ;; browse-url-cci XMosaic 2.5
51 ;; browse-url-w3-gnudoit w3 remotely
52 ;; browse-url-w3m w3m 0.2.1, probably
53 ;; browse-url-w3m-gnudoit w3m remotely 0.2.1, probably
54 ;; browse-url-iximosaic IXI Mosaic ?
55 ;; browse-url-lynx-* Lynx 0
56 ;; browse-url-grail Grail 0.3b1
57 ;; browse-url-mmm MMM ?
58 ;; browse-url-generic arbitrary
59 ;; browse-url-default-windows-browser MS-Windows browser
60 ;; browse-url-default-macosx-browser Mac OS X browser
61 ;; browse-url-default-xdg-browser freedesktop.org browser
62 ;; browse-url-gnome-moz GNOME interface to Mozilla
63 ;; browse-url-kde KDE konqueror (kfm)
64 ;; browse-url-opera Opera
66 ;; [A version of the Netscape browser is now free software
67 ;; <URL:http://www.mozilla.org/>, albeit not GPLed, so it is
68 ;; reasonable to have that as the default.]
70 ;; Note that versions of Netscape before 1.1b1 did not have remote
71 ;; control. <URL:http://www.netscape.com/newsref/std/x-remote.html>.
73 ;; Browsers can cache Web pages so it may be necessary to tell them to
74 ;; reload the current page if it has changed (e.g. if you have edited
75 ;; it). There is currently no perfect automatic solution to this.
77 ;; Netscape allows you to specify the id of the window you want to
78 ;; control but which window DO you want to control and how do you
81 ;; If using XMosaic before version 2.5, check the definition of
82 ;; browse-url-usr1-signal below.
83 ;; <URL:http://www.ncsa.uiuc.edu/SDG/Software/XMosaic/remote-control.html>
85 ;; XMosaic version 2.5 introduced Common Client Interface allowing you
86 ;; to control mosaic through Unix sockets.
87 ;; <URL:http://www.ncsa.uiuc.edu/SDG/Software/XMosaic/CCI/cci-spec.html>
89 ;; William M. Perry's excellent "w3" WWW browser for
90 ;; Emacs <URL:ftp://cs.indiana.edu/pub/elisp/w3/>
91 ;; has a function w3-follow-url-at-point, but that
92 ;; doesn't let you edit the URL like browse-url.
93 ;; The `gnuserv' package that can be used to control it in another
94 ;; Emacs process is available from
95 ;; <URL:ftp://ftp.splode.com/pub/users/friedman/packages/>.
97 ;; Grail is the freely available WWW browser implemented in Python, a
98 ;; cool object-oriented freely available interpreted language. Grail
99 ;; 0.3b1 was the first version to have remote control as distributed.
100 ;; For more information on Grail see
101 ;; <URL:http://grail.cnri.reston.va.us/> and for more information on
102 ;; Python see <url:http://www.python.org/>. Grail support in
103 ;; browse-url.el written by Barry Warsaw <bwarsaw@python.org>.
105 ;; MMM is a semi-free WWW browser implemented in Objective Caml, an
106 ;; interesting impure functional programming language. See
107 ;; <URL:http://pauillac.inria.fr/%7Erouaix/mmm/>.
109 ;; Lynx is now distributed by the FSF. See also
110 ;; <URL:http://lynx.browser.org/>.
112 ;; Free graphical browsers that could be used by `browse-url-generic'
113 ;; include Chimera <URL:ftp://ftp.cs.unlv.edu/pub/chimera> and
114 ;; <URL:http://www.unlv.edu/chimera/>, Arena
115 ;; <URL:ftp://ftp.yggdrasil.com/pub/dist/web/arena> and Amaya
116 ;; <URL:ftp://ftp.w3.org/pub/amaya>. mMosaic
117 ;; <URL:ftp://ftp.enst.fr/pub/mbone/mMosaic/>,
118 ;; <URL:http://www.enst.fr/~dauphin/mMosaic/> (with development
119 ;; support for Java applets and multicast) can be used like Mosaic by
120 ;; setting `browse-url-mosaic-program' appropriately.
122 ;; I [Denis Howe, not Dave Love] recommend Nelson Minar
123 ;; <nelson@santafe.edu>'s excellent html-helper-mode.el for editing
124 ;; HTML and thank Nelson for his many useful comments on this code.
125 ;; <URL:http://www.santafe.edu/%7Enelson/hhm-beta/>
127 ;; See also hm--html-menus <URL:http://www.tnt.uni-hannover.de/%7Emuenkel/
128 ;; software/own/hm--html-menus/>. For composing correct HTML see also
129 ;; PSGML the general SGML structure editor package
130 ;; <URL:ftp://ftp.lysator.liu.se/pub/sgml>; hm--html-menus can be used
133 ;; This package generalises function html-previewer-process in Marc
134 ;; Andreessen's html-mode (LCD modes/html-mode.el.Z). See also the
135 ;; ffap.el package. The huge hyperbole package also contains similar
138 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
141 ;; Can you write and test some code for the Macintrash and Windoze
142 ;; Netscape remote control APIs? (See the URL above).
144 ;; Do any other browsers have remote control?
146 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
149 ;; To display the URL at or before point:
150 ;; M-x browse-url-at-point RET
151 ;; or, similarly but with the opportunity to edit the URL extracted from
155 ;; To display a URL by shift-clicking on it, put this in your ~/.emacs
157 ;; (global-set-key [S-mouse-2] 'browse-url-at-mouse)
158 ;; (Note that using Shift-mouse-1 is not desirable because
159 ;; that event has a standard meaning in Emacs.)
161 ;; To display the current buffer in a web browser:
162 ;; M-x browse-url-of-buffer RET
164 ;; To display the current region in a web browser:
165 ;; M-x browse-url-of-region RET
167 ;; In Dired, to display the file named on the current line:
168 ;; M-x browse-url-of-dired-file RET
170 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
171 ;; Customisation (~/.emacs)
173 ;; To see what variables are available for customization, type
174 ;; `M-x set-variable browse-url TAB'. Better, use
175 ;; `M-x customize-group browse-url'.
177 ;; Bind the browse-url commands to keys with the `C-c C-z' prefix
178 ;; (as used by html-helper-mode):
179 ;; (global-set-key "\C-c\C-z." 'browse-url-at-point)
180 ;; (global-set-key "\C-c\C-zb" 'browse-url-of-buffer)
181 ;; (global-set-key "\C-c\C-zr" 'browse-url-of-region)
182 ;; (global-set-key "\C-c\C-zu" 'browse-url)
183 ;; (global-set-key "\C-c\C-zv" 'browse-url-of-file)
184 ;; (add-hook 'dired-mode-hook
186 ;; (local-set-key "\C-c\C-zf" 'browse-url-of-dired-file)))
188 ;; Browse URLs in mail messages under RMAIL by clicking mouse-2:
189 ;; (add-hook 'rmail-mode-hook (lambda () ; rmail-mode startup
190 ;; (define-key rmail-mode-map [mouse-2] 'browse-url-at-mouse)))
191 ;; Alternatively, add `goto-address' to `rmail-show-message-hook'.
193 ;; Gnus provides a standard feature to activate URLs in article
194 ;; buffers for invocation of browse-url.
196 ;; Use the Emacs w3 browser when not running under X11:
197 ;; (or (eq window-system 'x)
198 ;; (setq browse-url-browser-function 'browse-url-w3))
200 ;; To always save modified buffers before displaying the file in a browser:
201 ;; (setq browse-url-save-file t)
203 ;; To get round the Netscape caching problem, you could EITHER have
204 ;; write-file in html-helper-mode make Netscape reload the document:
206 ;; (autoload 'browse-url-netscape-reload "browse-url"
207 ;; "Ask a WWW browser to redisplay the current file." t)
208 ;; (add-hook 'html-helper-mode-hook
210 ;; (add-hook 'local-write-file-hooks
212 ;; (let ((local-write-file-hooks))
214 ;; (browse-url-netscape-reload)
215 ;; t) ; => file written by hook
216 ;; t))) ; append to l-w-f-hooks
218 ;; OR have browse-url-of-file ask Netscape to load and then reload the
221 ;; (add-hook 'browse-url-of-file-hook 'browse-url-netscape-reload)
223 ;; You may also want to customise browse-url-netscape-arguments, e.g.
224 ;; (setq browse-url-netscape-arguments '("-install"))
226 ;; or similarly for the other browsers.
228 ;; To invoke different browsers for different URLs:
229 ;; (setq browse-url-browser-function '(("^mailto:" . browse-url-mail)
230 ;; ("." . browse-url-netscape)))
232 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
235 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
238 (eval-when-compile (require 'thingatpt)
240 (require 'executable))
242 (defgroup browse-url nil
243 "Use a web browser to look at a URL."
244 :prefix "browse-url-"
245 :link '(emacs-commentary-link "browse-url")
249 (defcustom browse-url-browser-function
251 ((memq system-type '(windows-nt ms-dos cygwin32)) ;; XEmacs change
252 'browse-url-default-windows-browser)
253 ((memq system-type '(darwin)) 'browse-url-default-macosx-browser)
254 ;; XEmacs TODO: add 'browse-url-default-xdg-browser here, but how to detect
255 ;; a freedesktop.org desktop? executable-find xdg-open is not the way.
256 (t 'browse-url-default-browser))
257 "*Function to display the current buffer in a WWW browser.
258 This is used by the `browse-url-at-point', `browse-url-at-mouse', and
259 `browse-url-of-file' commands.
261 If the value is not a function it should be a list of pairs
262 \(REGEXP . FUNCTION). In this case the function called will be the one
263 associated with the first REGEXP which matches the current URL. The
264 function is passed the URL and any other args of `browse-url'. The last
265 regexp should probably be \".\" to specify a default browser."
267 (function-item :tag "Emacs W3" :value browse-url-w3)
268 (function-item :tag "W3 in another Emacs via `gnudoit'"
269 :value browse-url-w3-gnudoit)
270 (function-item :tag "Emacs W3M" :value browse-url-w3)
271 (function-item :tag "W3M in another Emacs via `gnudoit'"
272 :value browse-url-w3-gnudoit)
273 (function-item :tag "SeaMonkey" :value browse-url-seamonkey)
274 (function-item :tag "Mozilla" :value browse-url-mozilla)
275 (function-item :tag "Firefox" :value browse-url-firefox)
276 (function-item :tag "Galeon" :value browse-url-galeon)
277 (function-item :tag "Epiphany" :value browse-url-epiphany)
278 (function-item :tag "Netscape" :value browse-url-netscape)
279 (function-item :tag "Mosaic" :value browse-url-mosaic)
280 (function-item :tag "Mosaic using CCI" :value browse-url-cci)
281 (function-item :tag "IXI Mosaic" :value browse-url-iximosaic)
282 (function-item :tag "Lynx in an xterm window"
283 :value browse-url-lynx-xterm)
284 (function-item :tag "Lynx in an Emacs window"
285 :value browse-url-lynx-emacs)
286 (function-item :tag "Grail" :value browse-url-grail)
287 (function-item :tag "MMM" :value browse-url-mmm)
288 (function-item :tag "KDE" :value browse-url-kde)
289 (function-item :tag "Opera" :value browse-url-opera) ;; XEmacs
290 (function-item :tag "Specified by `Browse Url Generic Program'"
291 :value browse-url-generic)
292 (function-item :tag "Default Windows browser"
293 :value browse-url-default-windows-browser)
294 (function-item :tag "Default Mac OS X browser"
295 :value browse-url-default-macosx-browser)
297 (function-item :tag "Default freedesktop.org browser"
298 :value browse-url-default-xdg-browser)
299 (function-item :tag "GNOME invoking Mozilla"
300 :value browse-url-gnome-moz)
301 (function-item :tag "Default browser"
302 :value browse-url-default-browser)
303 (function :tag "Your own function")
304 ;; XEmacs: Emacs has an `alist' custom type here, but custom
305 ;; in XEmacs is buggy and cannot handle it, so we don't
306 ;; include the following:
307 ;; (alist :tag "Regexp/function association list"
308 ;; :key-type regexp :value-type function))
312 (defcustom browse-url-netscape-program "netscape"
313 ;; Info about netscape-remote from Karl Berry.
314 "*The name by which to invoke Netscape.
316 The free program `netscape-remote' from
317 <URL:http://home.netscape.com/newsref/std/remote.c> is said to start
318 up very much quicker than `netscape'. Reported to compile on a GNU
319 system, given vroot.h from the same directory, with cc flags
320 -DSTANDALONE -L/usr/X11R6/lib -lXmu -lX11."
324 (defcustom browse-url-netscape-arguments nil
325 "*A list of strings to pass to Netscape as arguments."
326 :type '(repeat (string :tag "Argument"))
329 (defcustom browse-url-netscape-startup-arguments browse-url-netscape-arguments
330 "*A list of strings to pass to Netscape when it starts up.
331 Defaults to the value of `browse-url-netscape-arguments' at the time
332 `browse-url' is loaded."
333 :type '(repeat (string :tag "Argument"))
337 (defcustom browse-url-browser-display nil
338 "*The X display for running the browser, if not same as Emacs'."
339 :type '(choice string (const :tag "Default" nil))
343 (defcustom browse-url-seamonkey-program "seamonkey"
344 "*The name by which to invoke SeaMonkey."
348 (defcustom browse-url-seamonkey-arguments nil
349 "*A list of strings to pass to SeaMonkey as arguments."
350 :type '(repeat (string :tag "Argument"))
353 (defcustom browse-url-seamonkey-startup-arguments browse-url-seamonkey-arguments
354 "*A list of strings to pass to SeaMonkey when it starts up.
355 Defaults to the value of `browse-url-seamonkey-arguments' at the time
356 `browse-url' is loaded."
357 :type '(repeat (string :tag "Argument"))
361 (defcustom browse-url-mozilla-program "mozilla"
362 "*The name by which to invoke Mozilla."
366 (defcustom browse-url-mozilla-arguments nil
367 "*A list of strings to pass to Mozilla as arguments."
368 :type '(repeat (string :tag "Argument"))
371 (defcustom browse-url-mozilla-startup-arguments browse-url-mozilla-arguments
372 "*A list of strings to pass to Mozilla when it starts up.
373 Defaults to the value of `browse-url-mozilla-arguments' at the time
374 `browse-url' is loaded."
375 :type '(repeat (string :tag "Argument"))
379 (defcustom browse-url-firefox-program "firefox"
380 "*The name by which to invoke Firefox."
384 (defcustom browse-url-firefox-arguments nil
385 "*A list of strings to pass to Firefox as arguments."
386 :type '(repeat (string :tag "Argument"))
389 (defcustom browse-url-firefox-startup-arguments browse-url-firefox-arguments
390 "*A list of strings to pass to Firefox when it starts up.
391 Defaults to the value of `browse-url-firefox-arguments' at the time
392 `browse-url' is loaded."
393 :type '(repeat (string :tag "Argument"))
397 (defcustom browse-url-galeon-program "galeon"
398 "*The name by which to invoke Galeon."
402 (defcustom browse-url-galeon-arguments nil
403 "*A list of strings to pass to Galeon as arguments."
404 :type '(repeat (string :tag "Argument"))
407 (defcustom browse-url-galeon-startup-arguments browse-url-galeon-arguments
408 "*A list of strings to pass to Galeon when it starts up.
409 Defaults to the value of `browse-url-galeon-arguments' at the time
410 `browse-url' is loaded."
411 :type '(repeat (string :tag "Argument"))
414 (defcustom browse-url-epiphany-program "epiphany"
415 "*The name by which to invoke Epiphany."
419 (defcustom browse-url-epiphany-arguments nil
420 "*A list of strings to pass to Epiphany as arguments."
421 :type '(repeat (string :tag "Argument"))
424 (defcustom browse-url-epiphany-startup-arguments browse-url-epiphany-arguments
425 "*A list of strings to pass to Epiphany when it starts up.
426 Defaults to the value of `browse-url-epiphany-arguments' at the time
427 `browse-url' is loaded."
428 :type '(repeat (string :tag "Argument"))
431 (defcustom browse-url-seamonkey-new-window-is-tab nil
432 "*Whether to open up new windows in a tab or a new window.
433 If non-nil, then open the URL in a new tab rather than a new window if
434 `browse-url-seamonkey' is asked to open it in a new window."
438 (defcustom browse-url-mozilla-new-window-is-tab nil
439 "*Whether to open up new windows in a tab or a new window.
440 If non-nil, then open the URL in a new tab rather than a new window if
441 `browse-url-mozilla' is asked to open it in a new window."
445 (defcustom browse-url-firefox-new-window-is-tab nil
446 "*Whether to open up new windows in a tab or a new window.
447 If non-nil, then open the URL in a new tab rather than a new window if
448 `browse-url-firefox' is asked to open it in a new window."
452 (defcustom browse-url-galeon-new-window-is-tab nil
453 "*Whether to open up new windows in a tab or a new window.
454 If non-nil, then open the URL in a new tab rather than a new window if
455 `browse-url-galeon' is asked to open it in a new window."
459 (defcustom browse-url-epiphany-new-window-is-tab nil
460 "*Whether to open up new windows in a tab or a new window.
461 If non-nil, then open the URL in a new tab rather than a new window if
462 `browse-url-epiphany' is asked to open it in a new window."
466 (defcustom browse-url-netscape-new-window-is-tab nil
467 "*Whether to open up new windows in a tab or a new window.
468 If non-nil, then open the URL in a new tab rather than a new window if
469 `browse-url-netscape' is asked to open it in a new window."
474 (defcustom browse-url-new-window-flag nil
475 "*If non-nil, always open a new browser window with appropriate browsers.
476 Passing an interactive argument to \\[browse-url], or specific browser
477 commands reverses the effect of this variable. Requires Netscape version
478 1.1N or later or XMosaic version 2.5 or later if using those browsers."
482 ;; XEmacs backwards compatibility
484 (defvaralias 'browse-url-new-window-p 'browse-url-new-window-flag)
486 (defcustom browse-url-mosaic-program "xmosaic"
487 "*The name by which to invoke Mosaic (or mMosaic)."
491 (defcustom browse-url-mosaic-arguments nil
492 "*A list of strings to pass to Mosaic as arguments."
493 :type '(repeat (string :tag "Argument"))
496 (defcustom browse-url-mosaic-pidfile "~/.mosaicpid"
497 "*The name of the pidfile created by Mosaic."
501 (defcustom browse-url-filename-alist
502 (\` ; Backquote syntax won't work.
503 (("^/\\(ftp@\\|anonymous@\\)?\\([^:]+\\):/*" . "ftp://\\2/")
504 ;; The above loses the username to avoid the browser prompting for
505 ;; it in anonymous cases. If it's not anonymous the next regexp
507 ("^/\\([^:@]+@\\)?\\([^:]+\\):/*" . "ftp://\\1\\2/")
508 (,@ (if (memq system-type '(windows-nt ms-dos cygwin32)) ;; XEmacs change
509 '(("^\\([a-zA-Z]:\\)[\\/]" . "file:\\1/")
510 ("^[\\/][\\/]+" . "file://"))))
512 "An alist of (REGEXP . STRING) pairs used by `browse-url-of-file'.
513 Any substring of a filename matching one of the REGEXPs is replaced by
514 the corresponding STRING using `replace-match', not treating STRING
515 literally. All pairs are applied in the order given. The default
516 value converts ange-ftp/EFS-style file names into ftp URLs and prepends
517 `file:' to any file name beginning with `/'.
519 For example, adding to the default a specific translation of an ange-ftp
520 address to an HTTP URL:
522 (setq browse-url-filename-alist
523 '((\"/webmaster@webserver:/home/www/html/\" .
524 \"http://www.acme.co.uk/\")
525 (\"^/\\(ftp@\\|anonymous@\\)?\\([^:]+\\):/*\" . \"ftp://\\2/\")
526 (\"^/\\([^:@]+@\\)?\\([^:]+\\):/*\" . \"ftp://\\1\\2/\")
527 (\"^/+\" . \"file:/\")))
529 :type '(repeat (cons :format "%v"
530 (regexp :tag "Regexp")
531 (string :tag "Replacement")))
535 (defcustom browse-url-save-file nil
536 "*If non-nil, save the buffer before displaying its file.
537 Used by the `browse-url-of-file' command."
541 (defcustom browse-url-of-file-hook nil
542 "*Run after `browse-url-of-file' has asked a browser to load a file.
544 Set this to `browse-url-netscape-reload' to force Netscape to load the
545 file rather than displaying a cached copy."
547 :options '(browse-url-netscape-reload)
550 (defcustom browse-url-CCI-port 3003
551 "*Port to access XMosaic via CCI.
552 This can be any number between 1024 and 65535 but must correspond to
553 the value set in the browser."
557 (defcustom browse-url-CCI-host "localhost"
558 "*Host to access XMosaic via CCI.
559 This should be the host name of the machine running XMosaic with CCI
560 enabled. The port number should be set in `browse-url-CCI-port'."
564 (defvar browse-url-temp-file-name nil)
565 (make-variable-buffer-local 'browse-url-temp-file-name)
567 (defcustom browse-url-xterm-program "xterm"
568 "*The name of the terminal emulator used by `browse-url-lynx-xterm'.
569 This might, for instance, be a separate colour version of xterm."
573 (defcustom browse-url-xterm-args nil
574 "*A list of strings defining options for `browse-url-xterm-program'.
575 These might set its size, for instance."
576 :type '(repeat (string :tag "Argument"))
579 (defcustom browse-url-lynx-emacs-args (and (not window-system)
581 "*A list of strings defining options for Lynx in an Emacs buffer.
583 The default is none in a window system, otherwise `-show_cursor' to
584 indicate the position of the current link in the absence of
585 highlighting, assuming the normal default for showing the cursor."
586 :type '(repeat (string :tag "Argument"))
589 (defcustom browse-url-gnudoit-program "gnuclient" ;; XEmacs
590 "*The name of the `gnudoit' program.
591 Used by `browse-url-w3-gnudoit' and `browse-url-w3m-gnudoit'."
595 (defcustom browse-url-gnudoit-args '("-batch" "-eval") ;; XEmacs
596 "*A list of strings defining options for `browse-url-gnudoit-program'.
597 These might set the port, for instance."
598 :type '(repeat (string :tag "Argument"))
602 (defcustom browse-url-generic-program nil
603 "*The name of the browser program used by `browse-url-generic'."
604 :type '(choice string (const :tag "None" nil))
607 (defcustom browse-url-generic-args nil
608 "*A list of strings defining options for `browse-url-generic-program'."
609 :type '(repeat (string :tag "Argument"))
612 (defcustom browse-url-temp-dir (temp-directory) ;; XEmacs change
613 "*The name of a directory for browse-url's temporary files.
614 Such files are generated by functions like `browse-url-of-region'.
615 You might want to set this to somewhere with restricted read permissions
620 (defcustom browse-url-netscape-version
622 "*The version of Netscape you are using.
623 This affects how URL reloading is done; the mechanism changed
624 incompatibly at version 4."
628 (defcustom browse-url-lynx-input-field 'avoid
629 "*Action on selecting an existing Lynx buffer at an input field.
630 What to do when sending a new URL to an existing Lynx buffer in Emacs
631 if the Lynx cursor is on an input field (in which case the `g' command
632 would be entered as data). Such fields are recognized by the
633 underlines ____. Allowed values: nil: disregard it, 'warn: warn the
634 user and don't emit the URL, 'avoid: try to avoid the field by moving
635 down (this *won't* always work)."
636 :type '(choice (const :tag "Move to try to avoid field" :value avoid)
637 (const :tag "Disregard" :value nil)
638 (const :tag "Warn, don't emit URL" :value warn))
641 (defcustom browse-url-lynx-input-attempts 10
642 "*How many times to try to move down from a series of lynx input fields."
646 (defcustom browse-url-lynx-input-delay 0.2
647 "*How many seconds to wait for lynx between moves down from an input field."
651 (defcustom browse-url-kde-program "kfmclient"
652 "*The name by which to invoke the KDE web browser."
656 (defcustom browse-url-kde-args '("openURL")
657 "*A list of strings defining options for `browse-url-kde-program'."
658 :type '(repeat (string :tag "Argument"))
661 (defcustom browse-url-opera-program "opera"
662 "*The name by which to invoke Opera."
666 (defcustom browse-url-opera-arguments '()
667 "*A list of strings to pass to Opera as arguments."
668 :type '(repeat (string :tag "Argument"))
671 (defcustom browse-url-opera-startup-arguments browse-url-opera-arguments
672 "*A list of strings to pass to Opera when it starts up.
673 Defaults to the value of `browse-url-opera-arguments' at the time
674 `browse-url' is loaded."
675 :type '(repeat (string :tag "Argument"))
678 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
681 (defun browse-url-url-at-point ()
682 (let ((url (thing-at-point 'url)))
683 (unless (zerop (length url)) ;; XEmacs bug workaround,
684 ;; `set-text-properties' in XEmacs <=
685 ;; 21.4.6 doesn't handle 0-0.
686 (set-text-properties 0 (length url) nil url))
689 ;; Having this as a separate function called by the browser-specific
690 ;; functions allows them to be stand-alone commands, making it easier
691 ;; to switch between browsers.
693 (defun browse-url-interactive-arg (prompt)
694 "Read a URL from the minibuffer, prompting with PROMPT.
695 Default to the URL at or before point. If invoked with a mouse button,
696 set point to the position clicked first. Return a list for use in
697 `interactive' containing the URL and `browse-url-new-window-flag' or its
698 negation if a prefix argument was given."
699 (let ((event (elt (this-command-keys) 0)))
700 (and (listp event) (mouse-set-point event)))
701 (list (read-string prompt (browse-url-url-at-point))
702 (not (eq (null browse-url-new-window-flag)
703 (null current-prefix-arg)))))
705 ;; interactive-p needs to be called at a function's top-level, hence
707 (defmacro browse-url-maybe-new-window (arg)
708 `(if (not (interactive-p))
710 browse-url-new-window-flag))
712 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
713 ;; Browse current buffer
716 (defun browse-url-of-file (&optional file)
717 "Ask a WWW browser to display FILE.
718 Display the current buffer's file if FILE is nil or if called
719 interactively. Turn the filename into a URL with function
720 `browse-url-file-url'. Pass the URL to a browser using the
721 `browse-url' function then run `browse-url-of-file-hook'."
724 (setq file (buffer-file-name))
725 (error "Current buffer has no file"))
726 (let ((buf (get-file-buffer file)))
730 (cond ((not (buffer-modified-p)))
731 (browse-url-save-file (save-buffer))
732 (t (message "%s modified since last save" file))))))
733 (browse-url (browse-url-file-url file))
734 (run-hooks 'browse-url-of-file-hook))
736 (defun browse-url-file-url (file)
737 "Return the URL corresponding to FILE.
738 Use variable `browse-url-filename-alist' to map filenames to URLs."
739 ;; URL-encode special chars, do % first
741 (while (setq s (string-match "%" file s))
742 (setq file (replace-match "%25" t t file)
744 (while (string-match "[*\"()',=;? ]" file)
745 (let ((enc (format "%%%x" (aref file (match-beginning 0)))))
746 (setq file (replace-match enc t t file))))
747 (dolist (map browse-url-filename-alist)
748 (when (and map (string-match (car map) file))
749 (setq file (replace-match (cdr map) t nil file))))
753 (defun browse-url-of-buffer (&optional buffer)
754 "Ask a WWW browser to display BUFFER.
755 Display the current buffer if BUFFER is nil. Display only the
756 currently visible part of BUFFER (from a temporary file) if buffer is
760 (and buffer (set-buffer buffer))
762 ;; Ignore real name if restricted
763 (and (= (- (point-max) (point-min)) (buffer-size))
765 (and (boundp 'dired-directory) dired-directory)))))
768 (or browse-url-temp-file-name
769 (setq browse-url-temp-file-name
770 (convert-standard-filename
771 (make-temp-name ;; XEmacs doesn't have make-temp-file
772 (expand-file-name "burl" browse-url-temp-dir)))))
773 (setq file-name browse-url-temp-file-name)
774 (write-region (point-min) (point-max) file-name nil 'no-message)))
775 (browse-url-of-file file-name))))
777 (defun browse-url-delete-temp-file (&optional temp-file-name)
778 "Delete `browse-url-temp-file-name' from the file system.
779 If the optional argument TEMP-FILE-NAME is non-nil, delete it instead."
780 (let ((file-name (or temp-file-name browse-url-temp-file-name)))
781 (if (and file-name (file-exists-p file-name))
782 (delete-file file-name))))
784 (add-hook 'kill-buffer-hook 'browse-url-delete-temp-file)
787 (defun browse-url-of-dired-file ()
788 "In Dired, ask a WWW browser to display the file named on this line."
790 (browse-url-of-file (dired-get-filename)))
793 (defun browse-url-of-region (min max)
794 "Ask a WWW browser to display the current region."
798 (narrow-to-region min max)
799 (browse-url-of-buffer))))
801 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
802 ;; Browser-independent commands
804 ;; A generic command to call the current browse-url-browser-function
807 (defun browse-url (url &rest args)
808 "Ask a WWW browser to load URL.
809 Prompts for a URL, defaulting to the URL at or before point. Variable
810 `browse-url-browser-function' says which browser to use."
811 (interactive (browse-url-interactive-arg "URL: "))
812 (unless (interactive-p)
813 (setq args (or args (list browse-url-new-window-flag))))
814 (if (functionp browse-url-browser-function)
815 (apply browse-url-browser-function url args)
816 ;; The `function' can be an alist; look down it for first match
817 ;; and apply the function (which might be a lambda).
819 (dolist (bf browse-url-browser-function)
820 (when (string-match (car bf) url)
821 (apply (cdr bf) url args)
823 (error "No browse-url-browser-function matching URL %s"
827 (defun browse-url-at-point (&optional arg)
828 "Ask a WWW browser to load the URL at or before point.
829 Doesn't let you edit the URL like `browse-url'. Variable
830 `browse-url-browser-function' says which browser to use."
832 (let ((url (browse-url-url-at-point)))
834 (browse-url url (if arg
835 (not browse-url-new-window-flag)
836 browse-url-new-window-flag))
837 (error "No URL found"))))
840 (defun browse-url-at-mouse (event)
841 "Ask a WWW browser to load a URL clicked with the mouse.
842 The URL is the one around or before the position of the mouse click
843 but point is not changed. Doesn't let you edit the URL like
844 `browse-url'. Variable `browse-url-browser-function' says which browser
848 (mouse-set-point event)
849 ;; This handles browse-url-new-window-flag properly
850 ;; when it gets no arg.
851 (browse-url-at-point)))
853 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
854 ;; Browser-specific commands
856 ;; --- Default MS-Windows browser ---
858 (defun browse-url-default-windows-browser (url &optional new-window)
859 (interactive (browse-url-interactive-arg "URL: "))
860 (if (featurep 'xemacs) ;; XEmacs change
861 (mswindows-shell-execute "open" url)
862 (w32-shell-execute "open" url)))
864 (defun browse-url-default-macosx-browser (url &optional new-window)
865 (interactive (browse-url-interactive-arg "URL: "))
866 (start-process (concat "open " url) nil "open" url))
870 (defcustom browse-url-xdg-open-program "xdg-open"
871 "*The name by which to invoke xdg-open."
877 (defun browse-url-default-xdg-browser (url &optional new-window)
878 (interactive (browse-url-interactive-arg "URL: "))
879 (let ((process-environment (browse-url-process-environment))
880 (process-connection-type nil))
881 (start-process (concat browse-url-xdg-open-program " " url) nil
882 browse-url-xdg-open-program url)))
886 (defun browse-url-process-environment ()
887 "Set DISPLAY in the environment to the X display the browser will use.
888 This is either the value of variable `browse-url-browser-display' if
889 non-nil, or the same display as Emacs if different from the current
890 environment, otherwise just use the current environment."
891 (let ((display (or browse-url-browser-display (browse-url-emacs-display))))
893 (cons (concat "DISPLAY=" display) process-environment)
894 process-environment)))
896 (defun browse-url-emacs-display ()
897 "Return the X display Emacs is running on.
898 This is nil if the display is the same as the DISPLAY environment variable.
900 Actually Emacs could be using several displays; this just returns the
901 one showing the selected frame."
902 (let ((display (cdr-safe (assq 'display (frame-parameters)))))
903 (and (not (equal display (getenv "DISPLAY")))
907 (defun browse-url-default-browser (url &rest args)
908 "Find a suitable browser and ask it to load URL.
909 Default to the URL around or before point.
911 When called interactively, if variable `browse-url-new-window-flag' is
912 non-nil, load the document in a new window, if possible, otherwise use
913 a random existing one. A non-nil interactive prefix argument reverses
914 the effect of `browse-url-new-window-flag'.
916 When called non-interactively, optional second argument NEW-WINDOW is
917 used instead of `browse-url-new-window-flag'.
919 The order attempted is freedesktop.org default, gnome-moz-remote, Mozilla,
920 Firefox, SeaMonkey, Galeon, Konqueror, Netscape, Opera, Mosaic, IXI Mosaic,
921 emacs-w3m, Lynx in an xterm, MMM, and then W3."
925 ((executable-find browse-url-xdg-open-program)
926 'browse-url-default-xdg-browser)
927 ((executable-find browse-url-gnome-moz-program) 'browse-url-gnome-moz)
928 ((executable-find browse-url-mozilla-program) 'browse-url-mozilla)
929 ((executable-find browse-url-firefox-program) 'browse-url-firefox)
930 ((executable-find browse-url-seamonkey-program) 'browse-url-seamonkey)
931 ((executable-find browse-url-galeon-program) 'browse-url-galeon)
932 ((executable-find browse-url-kde-program) 'browse-url-kde)
933 ((executable-find browse-url-netscape-program) 'browse-url-netscape)
934 ((executable-find browse-url-opera-program) 'browse-url-opera)
935 ((executable-find browse-url-mosaic-program) 'browse-url-mosaic)
936 ((executable-find "tellw3b") 'browse-url-iximosaic)
937 ((fboundp 'w3m-goto-url-new-session) 'browse-url-w3m)
938 ((executable-find browse-url-xterm-program) 'browse-url-lynx-xterm)
939 ((executable-find "mmm") 'browse-url-mmm)
944 (defun browse-url-netscape (url &optional new-window)
945 "Ask the Netscape WWW browser to load URL.
946 Default to the URL around or before point. The strings in variable
947 `browse-url-netscape-arguments' are also passed to Netscape.
949 When called interactively, if variable `browse-url-new-window-flag' is
950 non-nil, load the document in a new Netscape window, otherwise use a
951 random existing one. A non-nil interactive prefix argument reverses
952 the effect of `browse-url-new-window-flag'.
954 If `browse-url-netscape-new-window-is-tab' is non-nil, then
955 whenever a document would otherwise be loaded in a new window, it
956 is loaded in a new tab in an existing window instead.
958 When called non-interactively, optional second argument NEW-WINDOW is
959 used instead of `browse-url-new-window-flag'."
960 (interactive (browse-url-interactive-arg "URL: "))
961 ;; URL encode any `confusing' characters in the URL. This needs to
962 ;; include at least commas; presumably also close parens.
963 (while (string-match "[,)]" url)
964 (setq url (replace-match
965 (format "%%%x" (string-to-char (match-string 0 url))) t t url)))
966 (let* ((process-environment (browse-url-process-environment))
968 (apply 'start-process
969 (concat "netscape " url) nil
970 browse-url-netscape-program
972 browse-url-netscape-arguments
973 (if (eq (console-type) 'mswindows) ;; XEmacs change
976 (if new-window '("-noraise"))
978 (concat "openURL(" url
979 (if (browse-url-maybe-new-window
981 (if browse-url-netscape-new-window-is-tab
985 (set-process-sentinel process
986 `(lambda (process change)
987 (browse-url-netscape-sentinel process ,url)))))
989 (defun browse-url-netscape-sentinel (process url)
990 "Handle a change to the process communicating with Netscape."
991 (or (eq (process-exit-status process) 0)
992 (let* ((process-environment (browse-url-process-environment)))
993 ;; Netscape not running - start it
994 (message "Starting Netscape...")
995 (apply 'start-process (concat "netscape" url) nil
996 browse-url-netscape-program
997 (append browse-url-netscape-startup-arguments (list url))))))
999 (defun browse-url-netscape-reload ()
1000 "Ask Netscape to reload its current document.
1001 How depends on `browse-url-netscape-version'."
1003 ;; Backwards incompatibility reported by
1004 ;; <peter.kruse@psychologie.uni-regensburg.de>.
1005 (browse-url-netscape-send (if (>= browse-url-netscape-version 4)
1006 "xfeDoCommand(reload)"
1009 (defun browse-url-netscape-send (command)
1010 "Send a remote control command to Netscape."
1011 (let* ((process-environment (browse-url-process-environment)))
1012 (apply 'start-process "netscape" nil
1013 browse-url-netscape-program
1014 (append browse-url-netscape-arguments
1015 (list "-remote" command)))))
1018 (defun browse-url-seamonkey (url &optional new-window)
1019 "Ask the SeaMonkey WWW browser to load URL.
1020 Default to the URL around or before point. The strings in variable
1021 `browse-url-seamonkey-arguments' are also passed to SeaMonkey.
1023 When called interactively, if variable `browse-url-new-window-flag' is
1024 non-nil, load the document in a new SeaMonkey window, otherwise use a
1025 random existing one. A non-nil interactive prefix argument reverses
1026 the effect of `browse-url-new-window-flag'.
1028 If `browse-url-seamonkey-new-window-is-tab' is non-nil, then whenever a
1029 document would otherwise be loaded in a new window, it is loaded in a
1030 new tab in an existing window instead.
1032 When called non-interactively, optional second argument NEW-WINDOW is
1033 used instead of `browse-url-new-window-flag'.
1035 On MS-Windows systems the optional `new-window' parameter is ignored.
1036 SeaMonkey for Windows does not support the \"-remote\" command line
1037 parameter. Therefore the `browse-url-new-window-flag',
1038 `browse-url-new-window-flag' and `browse-url-seamonkey-new-window-is-tab'
1039 are ignored as well. SeaMonkey on Windows will always open the
1040 requested URL in a new window."
1041 (interactive (browse-url-interactive-arg "URL: "))
1042 ;; URL encode any `confusing' characters in the URL. This needs to
1043 ;; include at least commas; presumably also close parens.
1044 (while (string-match "[,)]" url)
1045 (setq url (replace-match
1046 (format "%%%x" (string-to-char (match-string 0 url))) t t url)))
1047 (let* ((process-environment (browse-url-process-environment))
1049 (apply 'start-process
1050 (concat "seamonkey " url) nil
1051 browse-url-seamonkey-program
1053 browse-url-seamonkey-arguments
1054 (if (or (featurep 'dos-w32)
1055 (string-match "win32" system-configuration))
1060 (if (browse-url-maybe-new-window
1062 (if browse-url-seamonkey-new-window-is-tab
1066 (set-process-sentinel process
1067 `(lambda (process change)
1068 (browse-url-seamonkey-sentinel process ,url)))))
1070 (defun browse-url-seamonkey-sentinel (process url)
1071 "Handle a change to the process communicating with SeaMonkey."
1072 (or (eq (process-exit-status process) 0)
1073 (let* ((process-environment (browse-url-process-environment)))
1074 ;; SeaMonkey is not running - start it
1075 (message "Starting SeaMonkey...")
1076 (apply 'start-process (concat "seamonkey " url) nil
1077 browse-url-seamonkey-program
1078 (append browse-url-seamonkey-startup-arguments (list url))))))
1081 (defun browse-url-mozilla (url &optional new-window)
1082 "Ask the Mozilla WWW browser to load URL.
1083 Default to the URL around or before point. The strings in variable
1084 `browse-url-mozilla-arguments' are also passed to Mozilla.
1086 When called interactively, if variable `browse-url-new-window-flag' is
1087 non-nil, load the document in a new Mozilla window, otherwise use a
1088 random existing one. A non-nil interactive prefix argument reverses
1089 the effect of `browse-url-new-window-flag'.
1091 If `browse-url-mozilla-new-window-is-tab' is non-nil, then whenever a
1092 document would otherwise be loaded in a new window, it is loaded in a
1093 new tab in an existing window instead.
1095 When called non-interactively, optional second argument NEW-WINDOW is
1096 used instead of `browse-url-new-window-flag'.
1098 On MS-Windows systems the optional `new-window' parameter is ignored.
1099 Mozilla for Windows does not support the \"-remote\" command line
1100 parameter. Therefore the `browse-url-new-window-flag',
1101 `browse-url-new-window-flag' and `browse-url-mozilla-new-window-is-tab'
1102 are ignored as well. Mozilla on Windows will always open the
1103 requested URL in a new window."
1104 (interactive (browse-url-interactive-arg "URL: "))
1105 ;; URL encode any `confusing' characters in the URL. This needs to
1106 ;; include at least commas; presumably also close parens.
1107 (while (string-match "[,)]" url)
1108 (setq url (replace-match
1109 (format "%%%x" (string-to-char (match-string 0 url))) t t url)))
1110 (let* ((process-environment (browse-url-process-environment))
1112 (apply 'start-process
1113 (concat "mozilla " url) nil
1114 browse-url-mozilla-program
1116 browse-url-mozilla-arguments
1117 (if (or (featurep 'dos-w32)
1118 (string-match "win32" system-configuration))
1123 (if (browse-url-maybe-new-window
1125 (if browse-url-mozilla-new-window-is-tab
1129 (set-process-sentinel process
1130 `(lambda (process change)
1131 (browse-url-mozilla-sentinel process ,url)))))
1133 (defun browse-url-mozilla-sentinel (process url)
1134 "Handle a change to the process communicating with Mozilla."
1135 (or (eq (process-exit-status process) 0)
1136 (let* ((process-environment (browse-url-process-environment)))
1137 ;; Mozilla is not running - start it
1138 (message "Starting Mozilla...")
1139 (apply 'start-process (concat "mozilla " url) nil
1140 browse-url-mozilla-program
1141 (append browse-url-mozilla-startup-arguments (list url))))))
1144 (defun browse-url-firefox (url &optional new-window)
1145 "Ask the Firefox WWW browser to load URL.
1146 Default to the URL around or before point. The strings in variable
1147 `browse-url-firefox-arguments' are also passed to Firefox.
1149 When called interactively, if variable `browse-url-new-window-flag' is
1150 non-nil, load the document in a new Firefox window, otherwise use a
1151 random existing one. A non-nil interactive prefix argument reverses
1152 the effect of `browse-url-new-window-flag'.
1154 If `browse-url-firefox-new-window-is-tab' is non-nil, then whenever a
1155 document would otherwise be loaded in a new window, it is loaded in a
1156 new tab in an existing window instead.
1158 When called non-interactively, optional second argument NEW-WINDOW is
1159 used instead of `browse-url-new-window-flag'.
1161 On MS-Windows systems the optional `new-window' parameter is ignored.
1162 Firefox for Windows does not support the \"-remote\" command line
1163 parameter. Therefore the `browse-url-new-window-flag',
1164 `browse-url-new-window-flag' and `browse-url-firefox-new-window-is-tab'
1165 are ignored as well. Firefox on Windows will always open the
1166 requested URL in a new window."
1167 (interactive (browse-url-interactive-arg "URL: "))
1168 ;; URL encode any `confusing' characters in the URL. This needs to
1169 ;; include at least commas; presumably also close parens.
1170 (while (string-match "[,)]" url)
1171 (setq url (replace-match
1172 (format "%%%x" (string-to-char (match-string 0 url))) t t url)))
1173 (let* ((process-environment (browse-url-process-environment))
1175 (apply 'start-process
1176 (concat "firefox " url) nil
1177 browse-url-firefox-program
1179 browse-url-firefox-arguments
1180 (if (or (featurep 'dos-w32)
1181 (string-match "win32" system-configuration))
1186 (if (browse-url-maybe-new-window
1188 (if browse-url-firefox-new-window-is-tab
1192 (set-process-sentinel process
1193 `(lambda (process change)
1194 (browse-url-firefox-sentinel process ,url)))))
1196 (defun browse-url-firefox-sentinel (process url)
1197 "Handle a change to the process communicating with Firefox."
1198 (or (eq (process-exit-status process) 0)
1199 (let* ((process-environment (browse-url-process-environment)))
1200 ;; Firefox is not running - start it
1201 (message "Starting Firefox...")
1202 (apply 'start-process (concat "firefox " url) nil
1203 browse-url-firefox-program
1204 (append browse-url-firefox-startup-arguments (list url))))))
1207 (defun browse-url-galeon (url &optional new-window)
1208 "Ask the Galeon WWW browser to load URL.
1209 Default to the URL around or before point. The strings in variable
1210 `browse-url-galeon-arguments' are also passed to Galeon.
1212 When called interactively, if variable `browse-url-new-window-flag' is
1213 non-nil, load the document in a new Galeon window, otherwise use a
1214 random existing one. A non-nil interactive prefix argument reverses
1215 the effect of `browse-url-new-window-flag'.
1217 If `browse-url-galeon-new-window-is-tab' is non-nil, then whenever a
1218 document would otherwise be loaded in a new window, it is loaded in a
1219 new tab in an existing window instead.
1221 When called non-interactively, optional second argument NEW-WINDOW is
1222 used instead of `browse-url-new-window-flag'."
1223 (interactive (browse-url-interactive-arg "URL: "))
1224 ;; URL encode any `confusing' characters in the URL. This needs to
1225 ;; include at least commas; presumably also close parens.
1226 (while (string-match "[,)]" url)
1227 (setq url (replace-match
1228 (format "%%%x" (string-to-char (match-string 0 url))) t t url)))
1229 (let* ((process-environment (browse-url-process-environment))
1230 (process (apply 'start-process
1231 (concat "galeon " url)
1233 browse-url-galeon-program
1235 browse-url-galeon-arguments
1236 (if (browse-url-maybe-new-window new-window)
1237 (if browse-url-galeon-new-window-is-tab
1239 '("--new-window" "--noraise"))
1242 (set-process-sentinel process
1243 `(lambda (process change)
1244 (browse-url-galeon-sentinel process ,url)))))
1246 (defun browse-url-galeon-sentinel (process url)
1247 "Handle a change to the process communicating with Galeon."
1248 (or (eq (process-exit-status process) 0)
1249 (let* ((process-environment (browse-url-process-environment)))
1250 ;; Galeon is not running - start it
1251 (message "Starting Galeon...")
1252 (apply 'start-process (concat "galeon " url) nil
1253 browse-url-galeon-program
1254 (append browse-url-galeon-startup-arguments (list url))))))
1256 (defun browse-url-epiphany (url &optional new-window)
1257 "Ask the Epiphany WWW browser to load URL.
1258 Default to the URL around or before point. The strings in variable
1259 `browse-url-galeon-arguments' are also passed to Epiphany.
1261 When called interactively, if variable `browse-url-new-window-flag' is
1262 non-nil, load the document in a new Epiphany window, otherwise use a
1263 random existing one. A non-nil interactive prefix argument reverses
1264 the effect of `browse-url-new-window-flag'.
1266 If `browse-url-epiphany-new-window-is-tab' is non-nil, then whenever a
1267 document would otherwise be loaded in a new window, it is loaded in a
1268 new tab in an existing window instead.
1270 When called non-interactively, optional second argument NEW-WINDOW is
1271 used instead of `browse-url-new-window-flag'."
1272 (interactive (browse-url-interactive-arg "URL: "))
1273 ;; URL encode any `confusing' characters in the URL. This needs to
1274 ;; include at least commas; presumably also close parens.
1275 (while (string-match "[,)]" url)
1276 (setq url (replace-match
1277 (format "%%%x" (string-to-char (match-string 0 url))) t t url)))
1278 (let* ((process-environment (browse-url-process-environment))
1279 (process (apply 'start-process
1280 (concat "epiphany " url)
1282 browse-url-epiphany-program
1284 browse-url-epiphany-arguments
1285 (if (browse-url-maybe-new-window new-window)
1286 (if browse-url-epiphany-new-window-is-tab
1288 '("--new-window" "--noraise"))
1291 (set-process-sentinel process
1292 `(lambda (process change)
1293 (browse-url-epiphany-sentinel process ,url)))))
1295 (defun browse-url-epiphany-sentinel (process url)
1296 "Handle a change to the process communicating with Epiphany."
1297 (or (eq (process-exit-status process) 0)
1298 (let* ((process-environment (browse-url-process-environment)))
1299 ;; Epiphany is not running - start it
1300 (message "Starting Epiphany...")
1301 (apply 'start-process (concat "epiphany " url) nil
1302 browse-url-epiphany-program
1303 (append browse-url-epiphany-startup-arguments (list url))))))
1305 ;; GNOME means of invoking either Mozilla or Netscape.
1306 (defvar browse-url-gnome-moz-program "gnome-moz-remote")
1307 (defcustom browse-url-gnome-moz-arguments '()
1308 "*A list of strings passed to the GNOME mozilla viewer as arguments."
1309 :type '(repeat (string :tag "Argument"))
1313 (defun browse-url-gnome-moz (url &optional new-window)
1314 "Ask Mozilla/Netscape to load URL via the GNOME program `gnome-moz-remote'.
1315 Default to the URL around or before point. The strings in variable
1316 `browse-url-gnome-moz-arguments' are also passed.
1318 When called interactively, if variable `browse-url-new-window-flag' is
1319 non-nil, load the document in a new browser window, otherwise use an
1320 existing one. A non-nil interactive prefix argument reverses the
1321 effect of `browse-url-new-window-flag'.
1323 When called non-interactively, optional second argument NEW-WINDOW is
1324 used instead of `browse-url-new-window-flag'."
1325 (interactive (browse-url-interactive-arg "URL: "))
1326 (apply 'start-process (concat "gnome-moz-remote " url)
1328 browse-url-gnome-moz-program
1330 browse-url-gnome-moz-arguments
1331 (if (browse-url-maybe-new-window new-window)
1333 (list "--raise" url))))
1338 (defun browse-url-mosaic (url &optional new-window)
1339 "Ask the XMosaic WWW browser to load URL.
1341 Default to the URL around or before point. The strings in variable
1342 `browse-url-mosaic-arguments' are also passed to Mosaic and the
1343 program is invoked according to the variable
1344 `browse-url-mosaic-program'.
1346 When called interactively, if variable `browse-url-new-window-flag' is
1347 non-nil, load the document in a new Mosaic window, otherwise use a
1348 random existing one. A non-nil interactive prefix argument reverses
1349 the effect of `browse-url-new-window-flag'.
1351 When called non-interactively, optional second argument NEW-WINDOW is
1352 used instead of `browse-url-new-window-flag'."
1353 (interactive (browse-url-interactive-arg "Mosaic URL: "))
1354 (let ((pidfile (expand-file-name browse-url-mosaic-pidfile))
1356 (if (file-readable-p pidfile)
1358 (insert-file-contents pidfile)
1359 (setq pid (read (current-buffer)))))
1360 (if (and (integerp pid) (zerop (signal-process pid 0))) ; Mosaic running
1363 (insert (if (browse-url-maybe-new-window new-window)
1367 (if (file-exists-p (setq pidfile (format "/tmp/Mosaic.%d" pid)))
1368 (delete-file pidfile))
1369 ;; http://debbugs.gnu.org/17428. Use O_EXCL.
1370 (write-region nil nil pidfile nil 'silent nil 'excl))
1371 ;; Send signal SIGUSR to Mosaic
1372 (message "Signalling Mosaic...")
1373 (signal-process pid 'SIGUSR1)
1374 ;; Or you could try:
1375 ;; (call-process "kill" nil 0 nil "-USR1" (int-to-string pid))
1376 (message "Signalling Mosaic...done"))
1377 ;; Mosaic not running - start it
1378 (message "Starting Mosaic...")
1379 (apply 'start-process "xmosaic" nil browse-url-mosaic-program
1380 (append browse-url-mosaic-arguments (list url)))
1381 (message "Starting Mosaic...done"))))
1386 (defvar browse-url-grail
1387 (concat (or (getenv "GRAILDIR") "~/.grail") "/user/rcgrail.py")
1388 "Location of Grail remote control client script `rcgrail.py'.
1389 Typically found in $GRAILDIR/rcgrail.py, or ~/.grail/user/rcgrail.py.")
1392 (defun browse-url-grail (url &optional new-window)
1393 "Ask the Grail WWW browser to load URL.
1394 Default to the URL around or before point. Runs the program in the
1395 variable `browse-url-grail'."
1396 (interactive (browse-url-interactive-arg "Grail URL: "))
1397 (message "Sending URL to Grail...")
1399 (set-buffer (get-buffer-create " *Shell Command Output*"))
1401 ;; don't worry about this failing.
1402 (if (browse-url-maybe-new-window new-window)
1403 (call-process browse-url-grail nil 0 nil "-b" url)
1404 (call-process browse-url-grail nil 0 nil url))
1405 (message "Sending URL to Grail... done")))
1407 ;; --- Mosaic using CCI ---
1410 (defun browse-url-cci (url &optional new-window)
1411 "Ask the XMosaic WWW browser to load URL.
1412 Default to the URL around or before point.
1414 This function only works for XMosaic version 2.5 or later. You must
1415 select `CCI' from XMosaic's File menu, set the CCI Port Address to the
1416 value of variable `browse-url-CCI-port', and enable `Accept requests'.
1418 When called interactively, if variable `browse-url-new-window-flag' is
1419 non-nil, load the document in a new browser window, otherwise use a
1420 random existing one. A non-nil interactive prefix argument reverses
1421 the effect of `browse-url-new-window-flag'.
1423 When called non-interactively, optional second argument NEW-WINDOW is
1424 used instead of `browse-url-new-window-flag'."
1425 (interactive (browse-url-interactive-arg "Mosaic URL: "))
1426 (open-network-stream "browse-url" " *browse-url*"
1427 browse-url-CCI-host browse-url-CCI-port)
1428 ;; Todo: start browser if fails
1429 (process-send-string "browse-url"
1430 (concat "get url (" url ") output "
1431 (if (browse-url-maybe-new-window new-window)
1435 (process-send-string "browse-url" "disconnect\r\n")
1436 (delete-process "browse-url"))
1438 ;; --- IXI Mosaic ---
1441 (defun browse-url-iximosaic (url &optional new-window)
1442 ;; new-window ignored
1443 "Ask the IXIMosaic WWW browser to load URL.
1444 Default to the URL around or before point."
1445 (interactive (browse-url-interactive-arg "IXI Mosaic URL: "))
1446 (start-process "tellw3b" nil "tellw3b"
1447 "-service WWW_BROWSER ixi_showurl " url))
1452 (defun browse-url-w3 (url &optional new-window)
1453 "Ask the w3 WWW browser to load URL.
1454 Default to the URL around or before point.
1456 When called interactively, if variable `browse-url-new-window-flag' is
1457 non-nil, load the document in a new window. A non-nil interactive
1458 prefix argument reverses the effect of `browse-url-new-window-flag'.
1460 When called non-interactively, optional second argument NEW-WINDOW is
1461 used instead of `browse-url-new-window-flag'."
1462 (interactive (browse-url-interactive-arg "W3 URL: "))
1463 (require 'w3) ; w3-fetch-other-window not autoloaded
1464 (if (browse-url-maybe-new-window new-window)
1465 (w3-fetch-other-window url)
1469 (defun browse-url-w3-gnudoit (url &optional new-window)
1470 ;; new-window ignored
1471 "Ask another Emacs running gnuserv to load the URL using the W3 browser.
1472 The `browse-url-gnudoit-program' program is used with options given by
1473 `browse-url-gnudoit-args'. Default to the URL around or before point."
1474 (interactive (browse-url-interactive-arg "W3 URL: "))
1475 (apply 'start-process (concat "gnudoit:" url) nil
1476 browse-url-gnudoit-program
1477 (append browse-url-gnudoit-args
1478 (list (concat "(w3-fetch \"" url "\")")
1481 ;; --- emacs-w3m ---
1484 (defun browse-url-w3m (url &optional new-window)
1485 "Ask the emacs-w3m WWW browser to load URL.
1486 Default to the URL around or before point.
1488 When called interactively, if variable `browse-url-new-window-flag' is
1489 non-nil, load the document in a new window. A non-nil interactive
1490 prefix argument reverses the effect of `browse-url-new-window-flag'.
1492 When called non-interactively, optional second argument NEW-WINDOW is
1493 used instead of `browse-url-new-window-flag'."
1494 (interactive (browse-url-interactive-arg "W3M URL: "))
1495 (if (browse-url-maybe-new-window new-window)
1497 (split-window) (other-window 1)))
1498 (w3m-goto-url-new-session url))
1501 (defun browse-url-w3m-gnudoit (url &optional new-window)
1502 ;; new-window ignored
1503 "Ask the Emacs running gnuserv to load the URL using the emacs-w3m browser.
1504 The `browse-url-gnudoit-program' program is used with options given by
1505 `browse-url-gnudoit-args'. Default to the URL around or before point."
1506 (interactive (browse-url-interactive-arg "W3M URL: "))
1507 (apply 'start-process (concat "gnudoit:" url) nil
1508 browse-url-gnudoit-program
1509 (append browse-url-gnudoit-args
1510 (list (concat "(w3m-goto-url-new-session \"" url "\")")
1513 ;; --- Lynx in an xterm ---
1516 (defun browse-url-lynx-xterm (url &optional new-window)
1517 ;; new-window ignored
1518 "Ask the Lynx WWW browser to load URL.
1519 Default to the URL around or before point. A new Lynx process is run
1520 in an Xterm window using the Xterm program named by `browse-url-xterm-program'
1521 with possible additional arguments `browse-url-xterm-args'."
1522 (interactive (browse-url-interactive-arg "Lynx URL: "))
1523 (apply #'start-process `(,(concat "lynx" url) nil ,browse-url-xterm-program
1524 ,@browse-url-xterm-args "-e" "lynx"
1527 ;; --- Lynx in an Emacs "term" window ---
1530 (defun browse-url-lynx-emacs (url &optional new-buffer)
1531 "Ask the Lynx WWW browser to load URL.
1532 Default to the URL around or before point. With a prefix argument, run
1533 a new Lynx process in a new buffer.
1535 When called interactively, if variable `browse-url-new-window-flag' is
1536 non-nil, load the document in a new lynx in a new term window,
1537 otherwise use any existing one. A non-nil interactive prefix argument
1538 reverses the effect of `browse-url-new-window-flag'.
1540 When called non-interactively, optional second argument NEW-WINDOW is
1541 used instead of `browse-url-new-window-flag'."
1542 (interactive (browse-url-interactive-arg "Lynx URL: "))
1543 (let* ((system-uses-terminfo t) ; Lynx uses terminfo
1544 ;; (term-term-name "vt100") ; ??
1545 (buf (get-buffer "*lynx*"))
1546 (proc (and buf (get-buffer-process buf)))
1547 (n browse-url-lynx-input-attempts))
1548 (if (and (browse-url-maybe-new-window new-buffer) buf)
1549 ;; Rename away the OLD buffer. This isn't very polite, but
1550 ;; term insists on working in a buffer named *lynx* and would
1551 ;; choke on *lynx*<1>
1552 (progn (set-buffer buf)
1554 (if (or (browse-url-maybe-new-window new-buffer)
1557 (not (memq (process-status proc) '(run stop))))
1562 `("lynx" "lynx" nil ,@browse-url-lynx-emacs-args
1564 (switch-to-buffer buf)
1566 (set-process-sentinel
1567 (get-buffer-process buf)
1568 ;; Don't leave around a dead one (especially because of its
1570 (lambda (process event)
1571 (if (not (memq (process-status process) '(run stop)))
1572 (let ((buf (process-buffer process)))
1573 (if buf (kill-buffer buf)))))))
1574 ;; send the url to lynx in the old buffer
1575 (let ((win (get-buffer-window buf t)))
1578 (switch-to-buffer buf)))
1579 (if (eq (following-char) ?_)
1580 (cond ((eq browse-url-lynx-input-field 'warn)
1581 (error "Please move out of the input field first"))
1582 ((eq browse-url-lynx-input-field 'avoid)
1583 (while (and (eq (following-char) ?_) (> n 0))
1584 (term-send-down) ; down arrow
1585 (sit-for browse-url-lynx-input-delay))
1586 (if (eq (following-char) ?_)
1587 (error "Cannot move out of the input field, sorry")))))
1588 (term-send-string proc (concat "g" ; goto
1589 "\C-u" ; kill default url
1596 (defun browse-url-mmm (url &optional new-window)
1597 "Ask the MMM WWW browser to load URL.
1598 Default to the URL around or before point."
1599 (interactive (browse-url-interactive-arg "MMM URL: "))
1600 (message "Sending URL to MMM...")
1602 (set-buffer (get-buffer-create " *Shell Command Output*"))
1604 ;; mmm_remote just SEGVs if the file isn't there...
1605 (if (or (file-exists-p (expand-file-name "~/.mmm_remote"))
1606 ;; location in v 0.4:
1607 (file-exists-p (expand-file-name "~/.mmm/remote")))
1608 (call-process "mmm_remote" nil 0 nil url)
1609 (call-process "mmm" nil 0 nil "-external" url))
1610 (message "Sending URL to MMM... done")))
1615 (defun browse-url-mail (url &optional new-window)
1616 "Open a new mail message buffer within Emacs.
1617 Default to using the mailto: URL around or before point as the
1618 recipient's address. Supplying a non-nil interactive prefix argument
1619 will cause the mail to be composed in another window rather than the
1622 When called interactively, if variable `browse-url-new-window-flag' is
1623 non-nil use `compose-mail-other-window', otherwise `compose-mail'. A
1624 non-nil interactive prefix argument reverses the effect of
1625 `browse-url-new-window-flag'.
1627 When called non-interactively, optional second argument NEW-WINDOW is
1628 used instead of `browse-url-new-window-flag'."
1629 (interactive (browse-url-interactive-arg "Mailto URL: "))
1631 (let ((to (if (string-match "^mailto:" url)
1634 (if (browse-url-maybe-new-window new-window)
1635 (compose-mail-other-window to nil nil nil
1636 (list 'insert-buffer (current-buffer)))
1637 (compose-mail to nil nil nil nil
1638 (list 'insert-buffer (current-buffer)))))))
1640 ;; --- Random browser ---
1643 (defun browse-url-generic (url &optional new-window)
1644 ;; new-window ignored
1645 "Ask the WWW browser defined by `browse-url-generic-program' to load URL.
1646 Default to the URL around or before point. A fresh copy of the
1647 browser is started up in a new process with possible additional arguments
1648 `browse-url-generic-args'. This is appropriate for browsers which
1649 don't offer a form of remote control."
1650 (interactive (browse-url-interactive-arg "URL: "))
1651 (if (not browse-url-generic-program)
1652 (error "No browser defined (`browse-url-generic-program')"))
1653 (apply 'start-process (concat browse-url-generic-program url) nil
1654 browse-url-generic-program
1655 (append browse-url-generic-args (list url))))
1660 (defun browse-url-kde (url &optional new-window)
1661 "Ask the KDE WWW browser to load URL.
1662 Default to the URL around or before point."
1663 (interactive (browse-url-interactive-arg "KDE URL: "))
1664 (message "Sending URL to KDE...")
1665 (apply #'start-process `(,(concat "KDE" url) nil ,browse-url-kde-program
1666 ,@browse-url-kde-args ,url)))
1668 (defalias 'browse-url-kfm 'browse-url-kde) ;; XEmacs backwards compatibility
1673 (defun browse-url-opera (url &optional new-window)
1674 "Ask the Opera WWW browser to load URL.
1675 Default to the URL around or before point. The strings in variable
1676 `browse-url-opera-arguments' are also passed to Opera.
1678 When called interactively, if variable `browse-url-new-window-flag' is
1679 non-nil, load the document in a new Opera window, otherwise use an
1680 existing one. A non-nil interactive prefix argument reverses the
1681 effect of `browse-url-new-window-flag'.
1683 When called non-interactively, optional second argument NEW-WINDOW is
1684 used instead of `browse-url-new-window-flag'."
1685 (interactive (browse-url-interactive-arg "URL: "))
1686 ;; URL encode any `confusing' characters in the URL. This needs to
1687 ;; include at least commas; presumably also close parens.
1688 (while (string-match "[,)]" url)
1689 (setq url (replace-match
1690 (format "%%%x" (string-to-char (match-string 0 url))) t t url)))
1691 (let* ((process-environment (browse-url-process-environment))
1692 (process (apply 'start-process
1693 (concat "opera " url) nil
1694 browse-url-opera-program
1696 browse-url-opera-arguments
1700 (if new-window ",new-window")
1702 (set-process-sentinel process
1703 `(lambda (process change)
1704 (browse-url-opera-sentinel process ,url)))))
1706 (defun browse-url-opera-sentinel (process url)
1707 "Handle a change to the process communicating with Opera."
1708 (or (eq (process-exit-status process) 0)
1709 (let* ((process-environment (browse-url-process-environment)))
1710 ;; Opera is not running - start it
1711 (message "Starting Opera...")
1712 (apply 'start-process (concat "opera " url) nil
1713 browse-url-opera-program
1714 (append browse-url-opera-startup-arguments (list url))))))
1716 (provide 'browse-url)
1718 ;;; browse-url.el ends here