shr.el (shr-insert): Don't insert double spaces.
[bpt/emacs.git] / lisp / net / browse-url.el
CommitLineData
e8af40ee 1;;; browse-url.el --- pass a URL to a WWW browser
8749abea 2
1fc7dabf
GM
3;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4;; 2004, 2005, 2006, 2007, 2008, 2009, 2010
5;; Free Software Foundation, Inc.
8749abea
GM
6
7;; Author: Denis Howe <dbh@doc.ic.ac.uk>
7f61a9ee 8;; Maintainer: FSF
8749abea
GM
9;; Created: 03 Apr 1995
10;; Keywords: hypertext, hypermedia, mouse
11
12;; This file is part of GNU Emacs.
13
874a927a 14;; GNU Emacs is free software: you can redistribute it and/or modify
8749abea 15;; it under the terms of the GNU General Public License as published by
874a927a
GM
16;; the Free Software Foundation, either version 3 of the License, or
17;; (at your option) any later version.
8749abea
GM
18
19;; GNU Emacs is distributed in the hope that it will be useful,
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;; GNU General Public License for more details.
23
24;; You should have received a copy of the GNU General Public License
874a927a 25;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
8749abea
GM
26
27;;; Commentary:
28
29;; This package provides functions which read a URL (Uniform Resource
30;; Locator) from the minibuffer, defaulting to the URL around point,
31;; and ask a World-Wide Web browser to load it. It can also load the
32;; URL associated with the current buffer. Different browsers use
33;; different methods of remote control so there is one function for
34;; each supported browser. If the chosen browser is not running, it
3abc9fa1
DL
35;; is started. Currently there is support for the following browsers,
36;; some of them probably now obsolete:
37
38;; Function Browser Earliest version
7f61a9ee 39;; browse-url-mozilla Mozilla Don't know
49866ff8 40;; browse-url-firefox Firefox Don't know (tried with 1.0.1)
7f61a9ee 41;; browse-url-galeon Galeon Don't know
654805e3 42;; browse-url-epiphany Epiphany Don't know
3abc9fa1
DL
43;; browse-url-netscape Netscape 1.1b1
44;; browse-url-mosaic XMosaic/mMosaic <= 2.4
45;; browse-url-cci XMosaic 2.5
46;; browse-url-w3 w3 0
47;; browse-url-w3-gnudoit w3 remotely
d9774611 48;; browse-url-text-* Any text browser 0
3abc9fa1
DL
49;; browse-url-generic arbitrary
50;; browse-url-default-windows-browser MS-Windows browser
662871dd 51;; browse-url-default-macosx-browser Mac OS X browser
b12e6de3 52;; browse-url-gnome-moz GNOME interface to Mozilla
af06f459 53;; browse-url-kde KDE konqueror (kfm)
8c22c51a 54;; browse-url-elinks Elinks Don't know (tried with 0.12.GIT)
8749abea
GM
55
56;; [A version of the Netscape browser is now free software
57;; <URL:http://www.mozilla.org/>, albeit not GPLed, so it is
58;; reasonable to have that as the default.]
59
60;; Note that versions of Netscape before 1.1b1 did not have remote
61;; control. <URL:http://www.netscape.com/newsref/std/x-remote.html>.
62
63;; Browsers can cache Web pages so it may be necessary to tell them to
64;; reload the current page if it has changed (e.g. if you have edited
65;; it). There is currently no perfect automatic solution to this.
66
67;; Netscape allows you to specify the id of the window you want to
68;; control but which window DO you want to control and how do you
69;; discover its id?
70
6eddc3bb 71;; William M. Perry's excellent "w3" WWW browser for
8749abea
GM
72;; Emacs <URL:ftp://cs.indiana.edu/pub/elisp/w3/>
73;; has a function w3-follow-url-at-point, but that
74;; doesn't let you edit the URL like browse-url.
75;; The `gnuserv' package that can be used to control it in another
76;; Emacs process is available from
77;; <URL:ftp://ftp.splode.com/pub/users/friedman/packages/>.
78
8749abea
GM
79;; Lynx is now distributed by the FSF. See also
80;; <URL:http://lynx.browser.org/>.
81
82;; Free graphical browsers that could be used by `browse-url-generic'
83;; include Chimera <URL:ftp://ftp.cs.unlv.edu/pub/chimera> and
84;; <URL:http://www.unlv.edu/chimera/>, Arena
85;; <URL:ftp://ftp.yggdrasil.com/pub/dist/web/arena> and Amaya
86;; <URL:ftp://ftp.w3.org/pub/amaya>. mMosaic
85d30d29
PJ
87;; <URL:ftp://ftp.enst.fr/pub/mbone/mMosaic/>,
88;; <URL:http://www.enst.fr/~dauphin/mMosaic/> (with development
8749abea
GM
89;; support for Java applets and multicast) can be used like Mosaic by
90;; setting `browse-url-mosaic-program' appropriately.
91
92;; I [Denis Howe, not Dave Love] recommend Nelson Minar
93;; <nelson@santafe.edu>'s excellent html-helper-mode.el for editing
94;; HTML and thank Nelson for his many useful comments on this code.
95;; <URL:http://www.santafe.edu/%7Enelson/hhm-beta/>
96
97;; See also hm--html-menus <URL:http://www.tnt.uni-hannover.de/%7Emuenkel/
98;; software/own/hm--html-menus/>. For composing correct HTML see also
99;; PSGML the general SGML structure editor package
100;; <URL:ftp://ftp.lysator.liu.se/pub/sgml>; hm--html-menus can be used
101;; with this.
102
103;; This package generalises function html-previewer-process in Marc
104;; Andreessen's html-mode (LCD modes/html-mode.el.Z). See also the
105;; ffap.el package. The huge hyperbole package also contains similar
106;; functions.
107
108;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
109;; Help!
110
111;; Can you write and test some code for the Macintrash and Windoze
112;; Netscape remote control APIs? (See the URL above).
113
114;; Do any other browsers have remote control?
115
116;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
117;; Usage
118
119;; To display the URL at or before point:
120;; M-x browse-url-at-point RET
121;; or, similarly but with the opportunity to edit the URL extracted from
122;; the buffer, use:
123;; M-x browse-url
124
125;; To display a URL by shift-clicking on it, put this in your ~/.emacs
126;; file:
127;; (global-set-key [S-mouse-2] 'browse-url-at-mouse)
128;; (Note that using Shift-mouse-1 is not desirable because
129;; that event has a standard meaning in Emacs.)
130
131;; To display the current buffer in a web browser:
132;; M-x browse-url-of-buffer RET
133
134;; To display the current region in a web browser:
135;; M-x browse-url-of-region RET
136
137;; In Dired, to display the file named on the current line:
138;; M-x browse-url-of-dired-file RET
139
140;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
141;; Customisation (~/.emacs)
142
143;; To see what variables are available for customization, type
144;; `M-x set-variable browse-url TAB'. Better, use
145;; `M-x customize-group browse-url'.
146
147;; Bind the browse-url commands to keys with the `C-c C-z' prefix
148;; (as used by html-helper-mode):
149;; (global-set-key "\C-c\C-z." 'browse-url-at-point)
150;; (global-set-key "\C-c\C-zb" 'browse-url-of-buffer)
151;; (global-set-key "\C-c\C-zr" 'browse-url-of-region)
152;; (global-set-key "\C-c\C-zu" 'browse-url)
153;; (global-set-key "\C-c\C-zv" 'browse-url-of-file)
154;; (add-hook 'dired-mode-hook
155;; (lambda ()
156;; (local-set-key "\C-c\C-zf" 'browse-url-of-dired-file)))
157
3abc9fa1 158;; Browse URLs in mail messages under RMAIL by clicking mouse-2:
8749abea
GM
159;; (add-hook 'rmail-mode-hook (lambda () ; rmail-mode startup
160;; (define-key rmail-mode-map [mouse-2] 'browse-url-at-mouse)))
3abc9fa1 161;; Alternatively, add `goto-address' to `rmail-show-message-hook'.
8749abea 162
3abc9fa1
DL
163;; Gnus provides a standard feature to activate URLs in article
164;; buffers for invocation of browse-url.
8749abea
GM
165
166;; Use the Emacs w3 browser when not running under X11:
167;; (or (eq window-system 'x)
168;; (setq browse-url-browser-function 'browse-url-w3))
169
170;; To always save modified buffers before displaying the file in a browser:
171;; (setq browse-url-save-file t)
172
173;; To get round the Netscape caching problem, you could EITHER have
174;; write-file in html-helper-mode make Netscape reload the document:
175;;
176;; (autoload 'browse-url-netscape-reload "browse-url"
177;; "Ask a WWW browser to redisplay the current file." t)
178;; (add-hook 'html-helper-mode-hook
179;; (lambda ()
180;; (add-hook 'local-write-file-hooks
181;; (lambda ()
182;; (let ((local-write-file-hooks))
183;; (save-buffer))
184;; (browse-url-netscape-reload)
185;; t) ; => file written by hook
186;; t))) ; append to l-w-f-hooks
187;;
188;; OR have browse-url-of-file ask Netscape to load and then reload the
189;; file:
190;;
191;; (add-hook 'browse-url-of-file-hook 'browse-url-netscape-reload)
192
193;; You may also want to customise browse-url-netscape-arguments, e.g.
194;; (setq browse-url-netscape-arguments '("-install"))
195;;
196;; or similarly for the other browsers.
197
198;; To invoke different browsers for different URLs:
199;; (setq browse-url-browser-function '(("^mailto:" . browse-url-mail)
200;; ("." . browse-url-netscape)))
201
202;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
203;;; Code:
204
205;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
206;; Variables
207
5edcabcb
EZ
208(eval-when-compile (require 'cl)
209 (require 'thingatpt)
8749abea
GM
210 (require 'term)
211 (require 'dired)
7f61a9ee 212 (require 'executable)
8749abea
GM
213 (require 'w3-auto nil t))
214
215(defgroup browse-url nil
216 "Use a web browser to look at a URL."
217 :prefix "browse-url-"
082527fe 218 :link '(emacs-commentary-link "browse-url")
eba5b4dd 219 :group 'external
26f4b8ab 220 :group 'comm)
8749abea
GM
221
222;;;###autoload
223(defcustom browse-url-browser-function
662871dd
SM
224 (cond
225 ((memq system-type '(windows-nt ms-dos cygwin))
226 'browse-url-default-windows-browser)
227 ((memq system-type '(darwin)) 'browse-url-default-macosx-browser)
228 (t 'browse-url-default-browser))
5e835c9f 229 "Function to display the current buffer in a WWW browser.
8749abea
GM
230This is used by the `browse-url-at-point', `browse-url-at-mouse', and
231`browse-url-of-file' commands.
232
233If the value is not a function it should be a list of pairs
082527fe 234\(REGEXP . FUNCTION). In this case the function called will be the one
8749abea
GM
235associated with the first REGEXP which matches the current URL. The
236function is passed the URL and any other args of `browse-url'. The last
237regexp should probably be \".\" to specify a default browser."
238 :type '(choice
082527fe
DL
239 (function-item :tag "Emacs W3" :value browse-url-w3)
240 (function-item :tag "W3 in another Emacs via `gnudoit'"
241 :value browse-url-w3-gnudoit)
7f61a9ee 242 (function-item :tag "Mozilla" :value browse-url-mozilla)
49866ff8 243 (function-item :tag "Firefox" :value browse-url-firefox)
7f61a9ee 244 (function-item :tag "Galeon" :value browse-url-galeon)
654805e3 245 (function-item :tag "Epiphany" :value browse-url-epiphany)
082527fe
DL
246 (function-item :tag "Netscape" :value browse-url-netscape)
247 (function-item :tag "Mosaic" :value browse-url-mosaic)
248 (function-item :tag "Mosaic using CCI" :value browse-url-cci)
d9774611
RS
249 (function-item :tag "Text browser in an xterm window"
250 :value browse-url-text-xterm)
251 (function-item :tag "Text browser in an Emacs window"
252 :value browse-url-text-emacs)
af06f459 253 (function-item :tag "KDE" :value browse-url-kde)
8c22c51a 254 (function-item :tag "Elinks" :value browse-url-elinks)
082527fe
DL
255 (function-item :tag "Specified by `Browse Url Generic Program'"
256 :value browse-url-generic)
257 (function-item :tag "Default Windows browser"
b12e6de3 258 :value browse-url-default-windows-browser)
662871dd
SM
259 (function-item :tag "Default Mac OS X browser"
260 :value browse-url-default-macosx-browser)
b12e6de3
DL
261 (function-item :tag "GNOME invoking Mozilla"
262 :value browse-url-gnome-moz)
7f61a9ee
RS
263 (function-item :tag "Default browser"
264 :value browse-url-default-browser)
082527fe
DL
265 (function :tag "Your own function")
266 (alist :tag "Regexp/function association list"
267 :key-type regexp :value-type function))
f86f6d1e 268 :version "21.1"
8749abea
GM
269 :group 'browse-url)
270
271(defcustom browse-url-netscape-program "netscape"
272 ;; Info about netscape-remote from Karl Berry.
5e835c9f 273 "The name by which to invoke Netscape.
8749abea
GM
274
275The free program `netscape-remote' from
276<URL:http://home.netscape.com/newsref/std/remote.c> is said to start
277up very much quicker than `netscape'. Reported to compile on a GNU
278system, given vroot.h from the same directory, with cc flags
279 -DSTANDALONE -L/usr/X11R6/lib -lXmu -lX11."
280 :type 'string
281 :group 'browse-url)
282
283(defcustom browse-url-netscape-arguments nil
5e835c9f 284 "A list of strings to pass to Netscape as arguments."
8749abea
GM
285 :type '(repeat (string :tag "Argument"))
286 :group 'browse-url)
287
288(defcustom browse-url-netscape-startup-arguments browse-url-netscape-arguments
5e835c9f 289 "A list of strings to pass to Netscape when it starts up.
8749abea
GM
290Defaults to the value of `browse-url-netscape-arguments' at the time
291`browse-url' is loaded."
292 :type '(repeat (string :tag "Argument"))
293 :group 'browse-url)
294
7f61a9ee 295(defcustom browse-url-browser-display nil
5e835c9f 296 "The X display for running the browser, if not same as Emacs'."
7f61a9ee
RS
297 :type '(choice string (const :tag "Default" nil))
298 :group 'browse-url)
299
300(defcustom browse-url-mozilla-program "mozilla"
5e835c9f 301 "The name by which to invoke Mozilla."
7f61a9ee
RS
302 :type 'string
303 :group 'browse-url)
304
305(defcustom browse-url-mozilla-arguments nil
5e835c9f 306 "A list of strings to pass to Mozilla as arguments."
7f61a9ee
RS
307 :type '(repeat (string :tag "Argument"))
308 :group 'browse-url)
309
310(defcustom browse-url-mozilla-startup-arguments browse-url-mozilla-arguments
5e835c9f 311 "A list of strings to pass to Mozilla when it starts up.
7f61a9ee
RS
312Defaults to the value of `browse-url-mozilla-arguments' at the time
313`browse-url' is loaded."
314 :type '(repeat (string :tag "Argument"))
315 :group 'browse-url)
316
7d353d11
SM
317(defcustom browse-url-firefox-program
318 (let ((candidates '("firefox" "iceweasel")))
319 (while (and candidates (not (executable-find (car candidates))))
320 (setq candidates (cdr candidates)))
321 (or (car candidates) "firefox"))
5e835c9f 322 "The name by which to invoke Firefox."
49866ff8
EZ
323 :type 'string
324 :group 'browse-url)
325
326(defcustom browse-url-firefox-arguments nil
5e835c9f 327 "A list of strings to pass to Firefox as arguments."
49866ff8
EZ
328 :type '(repeat (string :tag "Argument"))
329 :group 'browse-url)
330
331(defcustom browse-url-firefox-startup-arguments browse-url-firefox-arguments
5e835c9f 332 "A list of strings to pass to Firefox when it starts up.
49866ff8
EZ
333Defaults to the value of `browse-url-firefox-arguments' at the time
334`browse-url' is loaded."
335 :type '(repeat (string :tag "Argument"))
336 :group 'browse-url)
337
7d353d11 338(defcustom browse-url-galeon-program "galeon"
5e835c9f 339 "The name by which to invoke Galeon."
7f61a9ee
RS
340 :type 'string
341 :group 'browse-url)
342
343(defcustom browse-url-galeon-arguments nil
5e835c9f 344 "A list of strings to pass to Galeon as arguments."
7f61a9ee
RS
345 :type '(repeat (string :tag "Argument"))
346 :group 'browse-url)
347
348(defcustom browse-url-galeon-startup-arguments browse-url-galeon-arguments
5e835c9f 349 "A list of strings to pass to Galeon when it starts up.
7f61a9ee
RS
350Defaults to the value of `browse-url-galeon-arguments' at the time
351`browse-url' is loaded."
352 :type '(repeat (string :tag "Argument"))
353 :group 'browse-url)
354
654805e3 355(defcustom browse-url-epiphany-program "epiphany"
5e835c9f 356 "The name by which to invoke Epiphany."
654805e3
RS
357 :type 'string
358 :group 'browse-url)
359
360(defcustom browse-url-epiphany-arguments nil
5e835c9f 361 "A list of strings to pass to Epiphany as arguments."
654805e3
RS
362 :type '(repeat (string :tag "Argument"))
363 :group 'browse-url)
364
365(defcustom browse-url-epiphany-startup-arguments browse-url-epiphany-arguments
5e835c9f 366 "A list of strings to pass to Epiphany when it starts up.
654805e3
RS
367Defaults to the value of `browse-url-epiphany-arguments' at the time
368`browse-url' is loaded."
369 :type '(repeat (string :tag "Argument"))
370 :group 'browse-url)
371
db324706
RS
372;; GNOME means of invoking either Mozilla or Netrape.
373(defvar browse-url-gnome-moz-program "gnome-moz-remote")
374
375(defcustom browse-url-gnome-moz-arguments '()
5e835c9f 376 "A list of strings passed to the GNOME mozilla viewer as arguments."
db324706
RS
377 :version "21.1"
378 :type '(repeat (string :tag "Argument"))
379 :group 'browse-url)
380
d6da15ec 381(defcustom browse-url-mozilla-new-window-is-tab nil
5e835c9f 382 "Whether to open up new windows in a tab or a new window.
d6da15ec
SJ
383If non-nil, then open the URL in a new tab rather than a new window if
384`browse-url-mozilla' is asked to open it in a new window."
385 :type 'boolean
386 :group 'browse-url)
387
49866ff8 388(defcustom browse-url-firefox-new-window-is-tab nil
5e835c9f 389 "Whether to open up new windows in a tab or a new window.
49866ff8
EZ
390If non-nil, then open the URL in a new tab rather than a new window if
391`browse-url-firefox' is asked to open it in a new window.
392
393This option is currently ignored on MS-Windows, since the necessary
394functionality is not available there."
395 :type 'boolean
396 :group 'browse-url)
397
1d5d4123 398(defcustom browse-url-galeon-new-window-is-tab nil
5e835c9f 399 "Whether to open up new windows in a tab or a new window.
1d5d4123
RS
400If non-nil, then open the URL in a new tab rather than a new window if
401`browse-url-galeon' is asked to open it in a new window."
402 :type 'boolean
403 :group 'browse-url)
404
654805e3 405(defcustom browse-url-epiphany-new-window-is-tab nil
5e835c9f 406 "Whether to open up new windows in a tab or a new window.
654805e3
RS
407If non-nil, then open the URL in a new tab rather than a new window if
408`browse-url-epiphany' is asked to open it in a new window."
409 :type 'boolean
410 :group 'browse-url)
411
fe77c061 412(defcustom browse-url-netscape-new-window-is-tab nil
5e835c9f 413 "Whether to open up new windows in a tab or a new window.
fe77c061
SJ
414If non-nil, then open the URL in a new tab rather than a new
415window if `browse-url-netscape' is asked to open it in a new
416window."
417 :type 'boolean
418 :group 'browse-url)
419
408d5219 420(defcustom browse-url-new-window-flag nil
6eddc3bb 421 "Non-nil means always open a new browser window with appropriate browsers.
8749abea
GM
422Passing an interactive argument to \\[browse-url], or specific browser
423commands reverses the effect of this variable. Requires Netscape version
4241.1N or later or XMosaic version 2.5 or later if using those browsers."
425 :type 'boolean
426 :group 'browse-url)
427
8749abea 428(defcustom browse-url-mosaic-program "xmosaic"
5e835c9f 429 "The name by which to invoke Mosaic (or mMosaic)."
8749abea
GM
430 :type 'string
431 :version "20.3"
432 :group 'browse-url)
433
434(defcustom browse-url-mosaic-arguments nil
5e835c9f 435 "A list of strings to pass to Mosaic as arguments."
8749abea
GM
436 :type '(repeat (string :tag "Argument"))
437 :group 'browse-url)
438
1665be47 439(defcustom browse-url-mosaic-pidfile "~/.mosaicpid"
5e835c9f 440 "The name of the pidfile created by Mosaic."
1665be47
RS
441 :type 'string
442 :group 'browse-url)
443
8749abea 444(defcustom browse-url-filename-alist
5e835c9f 445 `(("^/\\(ftp@\\|anonymous@\\)?\\([^:]+\\):/*" . "ftp://\\2/")
8749abea
GM
446 ;; The above loses the username to avoid the browser prompting for
447 ;; it in anonymous cases. If it's not anonymous the next regexp
448 ;; applies.
449 ("^/\\([^:@]+@\\)?\\([^:]+\\):/*" . "ftp://\\1\\2/")
5e835c9f 450 ,@(if (memq system-type '(windows-nt ms-dos cygwin))
5241b291 451 '(("^\\([a-zA-Z]:\\)[\\/]" . "file:///\\1/")
5e835c9f 452 ("^[\\/][\\/]+" . "file://")))
dee8ac10 453 ("^/+" . "file:///"))
5e835c9f 454 "An alist of (REGEXP . STRING) pairs used by `browse-url-of-file'.
8749abea
GM
455Any substring of a filename matching one of the REGEXPs is replaced by
456the corresponding STRING using `replace-match', not treating STRING
457literally. All pairs are applied in the order given. The default
4dd14ef0
KS
458value converts ange-ftp/EFS-style file names into ftp URLs and prepends
459`file:' to any file name beginning with `/'.
8749abea
GM
460
461For example, adding to the default a specific translation of an ange-ftp
462address to an HTTP URL:
463
464 (setq browse-url-filename-alist
465 '((\"/webmaster@webserver:/home/www/html/\" .
466 \"http://www.acme.co.uk/\")
467 (\"^/\\(ftp@\\|anonymous@\\)?\\([^:]+\\):/*\" . \"ftp://\\2/\")
468 (\"^/\\([^:@]+@\\)?\\([^:]+\\):/*\" . \"ftp://\\1\\2/\")
5e835c9f 469 (\"^/+\" . \"file:/\")))"
8749abea
GM
470 :type '(repeat (cons :format "%v"
471 (regexp :tag "Regexp")
472 (string :tag "Replacement")))
3257a734 473 :version "23.1"
8749abea
GM
474 :group 'browse-url)
475
8749abea 476(defcustom browse-url-save-file nil
5e835c9f 477 "If non-nil, save the buffer before displaying its file.
8749abea
GM
478Used by the `browse-url-of-file' command."
479 :type 'boolean
480 :group 'browse-url)
481
482(defcustom browse-url-of-file-hook nil
5e835c9f 483 "Run after `browse-url-of-file' has asked a browser to load a file.
8749abea
GM
484
485Set this to `browse-url-netscape-reload' to force Netscape to load the
486file rather than displaying a cached copy."
487 :type 'hook
488 :options '(browse-url-netscape-reload)
489 :group 'browse-url)
490
8749abea 491(defcustom browse-url-CCI-port 3003
5e835c9f 492 "Port to access XMosaic via CCI.
8749abea
GM
493This can be any number between 1024 and 65535 but must correspond to
494the value set in the browser."
495 :type 'integer
496 :group 'browse-url)
497
498(defcustom browse-url-CCI-host "localhost"
5e835c9f 499 "Host to access XMosaic via CCI.
8749abea
GM
500This should be the host name of the machine running XMosaic with CCI
501enabled. The port number should be set in `browse-url-CCI-port'."
502 :type 'string
503 :group 'browse-url)
504
505(defvar browse-url-temp-file-name nil)
506(make-variable-buffer-local 'browse-url-temp-file-name)
db6003fb 507
8749abea 508(defcustom browse-url-xterm-program "xterm"
d9774611 509 "The name of the terminal emulator used by `browse-url-text-xterm'.
028f45d2 510This might, for instance, be a separate color version of xterm."
8749abea
GM
511 :type 'string
512 :group 'browse-url)
513
514(defcustom browse-url-xterm-args nil
5e835c9f 515 "A list of strings defining options for `browse-url-xterm-program'.
8749abea
GM
516These might set its size, for instance."
517 :type '(repeat (string :tag "Argument"))
518 :group 'browse-url)
519
8749abea 520(defcustom browse-url-gnudoit-program "gnudoit"
5e835c9f 521 "The name of the `gnudoit' program used by `browse-url-w3-gnudoit'."
8749abea
GM
522 :type 'string
523 :group 'browse-url)
524
525(defcustom browse-url-gnudoit-args '("-q")
5e835c9f 526 "A list of strings defining options for `browse-url-gnudoit-program'.
8749abea
GM
527These might set the port, for instance."
528 :type '(repeat (string :tag "Argument"))
529 :group 'browse-url)
530
8749abea 531(defcustom browse-url-generic-program nil
5e835c9f 532 "The name of the browser program used by `browse-url-generic'."
8749abea
GM
533 :type '(choice string (const :tag "None" nil))
534 :group 'browse-url)
535
536(defcustom browse-url-generic-args nil
5e835c9f 537 "A list of strings defining options for `browse-url-generic-program'."
8749abea
GM
538 :type '(repeat (string :tag "Argument"))
539 :group 'browse-url)
540
541(defcustom browse-url-temp-dir temporary-file-directory
5e835c9f 542 "The name of a directory for browse-url's temporary files.
8749abea
GM
543Such files are generated by functions like `browse-url-of-region'.
544You might want to set this to somewhere with restricted read permissions
545for privacy's sake."
546 :type 'string
547 :group 'browse-url)
548
5e835c9f
SM
549(defcustom browse-url-netscape-version 3
550 "The version of Netscape you are using.
8749abea
GM
551This affects how URL reloading is done; the mechanism changed
552incompatibly at version 4."
553 :type 'number
554 :group 'browse-url)
555
d9774611
RS
556(defcustom browse-url-text-browser "lynx"
557 "The name of the text browser to invoke."
558 :type 'string
559 :group 'browse-url
560 :version "23.1")
561
562(defcustom browse-url-text-emacs-args (and (not window-system)
563 '("-show_cursor"))
564 "A list of strings defining options for a text browser in an Emacs buffer.
565
566The default is none in a window system, otherwise `-show_cursor' to
567indicate the position of the current link in the absence of
568highlighting, assuming the normal default for showing the cursor."
569 :type '(repeat (string :tag "Argument"))
570 :version "23.1"
571 :group 'browse-url)
572
573(defcustom browse-url-text-input-field 'avoid
574 "Action on selecting an existing text browser buffer at an input field.
575What to do when sending a new URL to an existing text browser buffer in Emacs
576if the browser cursor is on an input field (in which case the `g' command
8749abea 577would be entered as data). Such fields are recognized by the
d9774611
RS
578underlines ____. Allowed values: nil: disregard it, `warn': warn the
579user and don't emit the URL, `avoid': try to avoid the field by moving
8749abea
GM
580down (this *won't* always work)."
581 :type '(choice (const :tag "Move to try to avoid field" :value avoid)
582 (const :tag "Disregard" :value nil)
583 (const :tag "Warn, don't emit URL" :value warn))
d9774611 584 :version "23.1"
8749abea
GM
585 :group 'browse-url)
586
d9774611
RS
587(defcustom browse-url-text-input-attempts 10
588 "How many times to try to move down from a series of text browser input fields."
64f6f486 589 :type 'integer
d9774611 590 :version "23.1"
64f6f486 591 :group 'browse-url)
8749abea 592
d9774611
RS
593(defcustom browse-url-text-input-delay 0.2
594 "Seconds to wait for a text browser between moves down from an input field."
64f6f486 595 :type 'number
d9774611 596 :version "23.1"
64f6f486 597 :group 'browse-url)
8749abea 598
af06f459 599(defcustom browse-url-kde-program "kfmclient"
5e835c9f 600 "The name by which to invoke the KDE web browser."
af06f459
GM
601 :type 'string
602 :version "21.1"
603 :group 'browse-url)
604
605(defcustom browse-url-kde-args '("openURL")
5e835c9f 606 "A list of strings defining options for `browse-url-kde-program'."
af06f459
GM
607 :type '(repeat (string :tag "Argument"))
608 :group 'browse-url)
609
8c22c51a 610(defcustom browse-url-elinks-wrapper '("xterm" "-e")
1fc7dabf 611 "Wrapper command prepended to the Elinks command-line."
8c22c51a
GM
612 :type '(repeat (string :tag "Wrapper"))
613 :group 'browse-url)
614
615;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
616;; URL encoding
617
6eddc3bb
MC
618(defun browse-url-url-encode-chars (text chars)
619 "URL-encode the chars in TEXT that match CHARS.
da76998b 620CHARS is a regexp-like character alternative (e.g., \"[)$]\")."
59c4e1da 621 (let ((encoded-text (copy-sequence text))
ad56e18b 622 (s 0))
59c4e1da
MC
623 (while (setq s (string-match chars encoded-text s))
624 (setq encoded-text
8c22c51a 625 (replace-match (format "%%%x"
59c4e1da
MC
626 (string-to-char (match-string 0 encoded-text)))
627 t t encoded-text)
ad56e18b 628 s (1+ s)))
59c4e1da 629 encoded-text))
8c22c51a 630
6eddc3bb
MC
631(defun browse-url-encode-url (url)
632 "Escape annoying characters in URL.
da76998b
CY
633The annoying characters are those that can mislead a web browser
634regarding its parameter treatment."
635 ;; FIXME: Is there an actual example of a web browser getting
636 ;; confused? (This used to encode commas, but at least Firefox
637 ;; handles commas correctly and doesn't accept encoded commas.)
638 (browse-url-url-encode-chars url "[)$]"))
6eddc3bb 639
8749abea
GM
640;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
641;; URL input
642
6be44fbf 643;;;###autoload
8749abea
GM
644(defun browse-url-url-at-point ()
645 (let ((url (thing-at-point 'url)))
646 (set-text-properties 0 (length url) nil url)
647 url))
648
649;; Having this as a separate function called by the browser-specific
650;; functions allows them to be stand-alone commands, making it easier
651;; to switch between browsers.
652
653(defun browse-url-interactive-arg (prompt)
654 "Read a URL from the minibuffer, prompting with PROMPT.
4c493999 655If `transient-mark-mode' is non-nil and the mark is active,
657962fc
RS
656it defaults to the current region, else to the URL at or before
657point. If invoked with a mouse button, it moves point to the
658position clicked before acting.
659
660This function returns a list (URL NEW-WINDOW-FLAG)
661for use in `interactive'."
8749abea
GM
662 (let ((event (elt (this-command-keys) 0)))
663 (and (listp event) (mouse-set-point event)))
4c493999
JB
664 (list (read-string prompt (or (and transient-mark-mode mark-active
665 ;; rfc2396 Appendix E.
666 (replace-regexp-in-string
667 "[\t\r\f\n ]+" ""
668 (buffer-substring-no-properties
669 (region-beginning) (region-end))))
670 (browse-url-url-at-point)))
408d5219 671 (not (eq (null browse-url-new-window-flag)
8749abea
GM
672 (null current-prefix-arg)))))
673
2de9d0c3
RS
674;; called-interactive-p needs to be called at a function's top-level, hence
675;; this macro. We use that rather than interactive-p because
676;; use in a keyboard macro should not change this behavior.
01f97560 677(defmacro browse-url-maybe-new-window (arg)
12a3c28c 678 `(if (or noninteractive (not (called-interactively-p 'any)))
01f97560 679 ,arg
408d5219 680 browse-url-new-window-flag))
01f97560 681
8749abea
GM
682;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
683;; Browse current buffer
684
685;;;###autoload
686(defun browse-url-of-file (&optional file)
687 "Ask a WWW browser to display FILE.
688Display the current buffer's file if FILE is nil or if called
689interactively. Turn the filename into a URL with function
690`browse-url-file-url'. Pass the URL to a browser using the
691`browse-url' function then run `browse-url-of-file-hook'."
692 (interactive)
693 (or file
694 (setq file (buffer-file-name))
695 (error "Current buffer has no file"))
696 (let ((buf (get-file-buffer file)))
697 (if buf
378f9937 698 (with-current-buffer buf
8749abea
GM
699 (cond ((not (buffer-modified-p)))
700 (browse-url-save-file (save-buffer))
701 (t (message "%s modified since last save" file))))))
702 (browse-url (browse-url-file-url file))
703 (run-hooks 'browse-url-of-file-hook))
704
705(defun browse-url-file-url (file)
706 "Return the URL corresponding to FILE.
707Use variable `browse-url-filename-alist' to map filenames to URLs."
5241b291
CY
708 ;; De-munge Cygwin filenames before passing them to Windows browser.
709 (if (eq system-type 'cygwin)
710 (let ((winfile (with-output-to-string
711 (call-process "cygpath" nil standard-output
712 nil "-m" file))))
713 (setq file (substring winfile 0 -1))))
95e55d20 714 (let ((coding (and (default-value 'enable-multibyte-characters)
59b71501
YM
715 (or file-name-coding-system
716 default-file-name-coding-system))))
717 (if coding (setq file (encode-coding-string file coding))))
6eddc3bb 718 (setq file (browse-url-url-encode-chars file "[*\"()',=;?% ]"))
63900fcf
SS
719 (dolist (map browse-url-filename-alist)
720 (when (and map (string-match (car map) file))
721 (setq file (replace-match (cdr map) t nil file))))
8749abea
GM
722 file)
723
724;;;###autoload
725(defun browse-url-of-buffer (&optional buffer)
726 "Ask a WWW browser to display BUFFER.
727Display the current buffer if BUFFER is nil. Display only the
728currently visible part of BUFFER (from a temporary file) if buffer is
729narrowed."
730 (interactive)
731 (save-excursion
732 (and buffer (set-buffer buffer))
733 (let ((file-name
734 ;; Ignore real name if restricted
735 (and (= (- (point-max) (point-min)) (buffer-size))
736 (or buffer-file-name
737 (and (boundp 'dired-directory) dired-directory)))))
738 (or file-name
739 (progn
740 (or browse-url-temp-file-name
741 (setq browse-url-temp-file-name
742 (convert-standard-filename
743 (make-temp-file
2e167dc4
RS
744 (expand-file-name "burl" browse-url-temp-dir)
745 nil ".html"))))
8749abea
GM
746 (setq file-name browse-url-temp-file-name)
747 (write-region (point-min) (point-max) file-name nil 'no-message)))
748 (browse-url-of-file file-name))))
749
750(defun browse-url-delete-temp-file (&optional temp-file-name)
751 ;; Delete browse-url-temp-file-name from the file system
752 ;; If optional arg TEMP-FILE-NAME is non-nil, delete it instead
753 (let ((file-name (or temp-file-name browse-url-temp-file-name)))
754 (if (and file-name (file-exists-p file-name))
755 (delete-file file-name))))
756
757(add-hook 'kill-buffer-hook 'browse-url-delete-temp-file)
758
759;;;###autoload
760(defun browse-url-of-dired-file ()
761 "In Dired, ask a WWW browser to display the file named on this line."
762 (interactive)
763 (browse-url-of-file (dired-get-filename)))
764
765;;;###autoload
766(defun browse-url-of-region (min max)
767 "Ask a WWW browser to display the current region."
768 (interactive "r")
769 (save-excursion
770 (save-restriction
771 (narrow-to-region min max)
772 (browse-url-of-buffer))))
773
774;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
775;; Browser-independent commands
776
777;; A generic command to call the current browse-url-browser-function
778
779;;;###autoload
780(defun browse-url (url &rest args)
781 "Ask a WWW browser to load URL.
782Prompts for a URL, defaulting to the URL at or before point. Variable
783`browse-url-browser-function' says which browser to use."
784 (interactive (browse-url-interactive-arg "URL: "))
32226619 785 (unless (called-interactively-p 'interactive)
408d5219 786 (setq args (or args (list browse-url-new-window-flag))))
addc252e
SM
787 (let ((process-environment (copy-sequence process-environment)))
788 ;; When connected to various displays, be careful to use the display of
789 ;; the currently selected frame, rather than the original start display,
790 ;; which may not even exist any more.
791 (if (stringp (frame-parameter (selected-frame) 'display))
792 (setenv "DISPLAY" (frame-parameter (selected-frame) 'display)))
9c16fc95
KR
793 (if (and (consp browse-url-browser-function)
794 (not (functionp browse-url-browser-function)))
795 ;; The `function' can be an alist; look down it for first match
796 ;; and apply the function (which might be a lambda).
797 (catch 'done
798 (dolist (bf browse-url-browser-function)
799 (when (string-match (car bf) url)
800 (apply (cdr bf) url args)
801 (throw 'done t)))
802 (error "No browse-url-browser-function matching URL %s"
803 url))
804 ;; Unbound symbols go down this leg, since void-function from
805 ;; apply is clearer than wrong-type-argument from dolist.
806 (apply browse-url-browser-function url args))))
8749abea
GM
807
808;;;###autoload
01f97560 809(defun browse-url-at-point (&optional arg)
8749abea
GM
810 "Ask a WWW browser to load the URL at or before point.
811Doesn't let you edit the URL like `browse-url'. Variable
812`browse-url-browser-function' says which browser to use."
01f97560 813 (interactive "P")
3abc9fa1
DL
814 (let ((url (browse-url-url-at-point)))
815 (if url
816 (browse-url url (if arg
408d5219
GM
817 (not browse-url-new-window-flag)
818 browse-url-new-window-flag))
3abc9fa1 819 (error "No URL found"))))
8749abea
GM
820
821;;;###autoload
822(defun browse-url-at-mouse (event)
823 "Ask a WWW browser to load a URL clicked with the mouse.
824The URL is the one around or before the position of the mouse click
825but point is not changed. Doesn't let you edit the URL like
826`browse-url'. Variable `browse-url-browser-function' says which browser
827to use."
828 (interactive "e")
829 (save-excursion
3abc9fa1 830 (mouse-set-point event)
857356cb
RS
831 ;; This handles browse-url-new-window-flag properly
832 ;; when it gets no arg.
833 (browse-url-at-point)))
8749abea
GM
834
835;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
836;; Browser-specific commands
837
838;; --- Default MS-Windows browser ---
839
14a06a2d 840(defvar dos-windows-version)
73e6adaa 841(declare-function w32-shell-execute "w32fns.c") ;; Defined in C.
14a06a2d 842
8749abea
GM
843(defun browse-url-default-windows-browser (url &optional new-window)
844 (interactive (browse-url-interactive-arg "URL: "))
e572025f
CY
845 (cond ((eq system-type 'ms-dos)
846 (if dos-windows-version
847 (shell-command (concat "start " (shell-quote-argument url)))
848 (error "Browsing URLs is not supported on this system")))
849 ((eq system-type 'cygwin)
5241b291 850 (call-process "cygstart" nil nil nil url))
e572025f 851 (t (w32-shell-execute "open" url))))
8749abea 852
662871dd
SM
853(defun browse-url-default-macosx-browser (url &optional new-window)
854 (interactive (browse-url-interactive-arg "URL: "))
855 (start-process (concat "open " url) nil "open" url))
856
8749abea
GM
857;; --- Netscape ---
858
859(defun browse-url-process-environment ()
7f61a9ee
RS
860 "Set DISPLAY in the environment to the X display the browser will use.
861This is either the value of variable `browse-url-browser-display' if
8749abea
GM
862non-nil, or the same display as Emacs if different from the current
863environment, otherwise just use the current environment."
7f61a9ee 864 (let ((display (or browse-url-browser-display (browse-url-emacs-display))))
8749abea
GM
865 (if display
866 (cons (concat "DISPLAY=" display) process-environment)
867 process-environment)))
868
869(defun browse-url-emacs-display ()
870 "Return the X display Emacs is running on.
871This is nil if the display is the same as the DISPLAY environment variable.
872
873Actually Emacs could be using several displays; this just returns the
874one showing the selected frame."
875 (let ((display (cdr-safe (assq 'display (frame-parameters)))))
876 (and (not (equal display (getenv "DISPLAY")))
877 display)))
878
7f61a9ee
RS
879;;;###autoload
880(defun browse-url-default-browser (url &rest args)
881 "Find a suitable browser and ask it to load URL.
882Default to the URL around or before point.
883
884When called interactively, if variable `browse-url-new-window-flag' is
885non-nil, load the document in a new window, if possible, otherwise use
886a random existing one. A non-nil interactive prefix argument reverses
887the effect of `browse-url-new-window-flag'.
888
889When called non-interactively, optional second argument NEW-WINDOW is
890used instead of `browse-url-new-window-flag'.
891
49866ff8 892The order attempted is gnome-moz-remote, Mozilla, Firefox,
66dc1ca2 893Galeon, Konqueror, Netscape, Mosaic, Lynx in an xterm, and then W3."
7f61a9ee 894 (apply
6eddc3bb 895 (cond
2269b349 896 ((browse-url-can-use-xdg-open) 'browse-url-xdg-open)
6eddc3bb
MC
897 ((executable-find browse-url-gnome-moz-program) 'browse-url-gnome-moz)
898 ((executable-find browse-url-mozilla-program) 'browse-url-mozilla)
899 ((executable-find browse-url-firefox-program) 'browse-url-firefox)
900 ((executable-find browse-url-galeon-program) 'browse-url-galeon)
901 ((executable-find browse-url-kde-program) 'browse-url-kde)
902 ((executable-find browse-url-netscape-program) 'browse-url-netscape)
903 ((executable-find browse-url-mosaic-program) 'browse-url-mosaic)
d9774611 904 ((executable-find browse-url-xterm-program) 'browse-url-text-xterm)
6eddc3bb
MC
905 ((locate-library "w3") 'browse-url-w3)
906 (t
db6003fb 907 (lambda (&rest ignore) (error "No usable browser found"))))
6eddc3bb 908 url args))
7f61a9ee 909
2269b349
JD
910(defun browse-url-can-use-xdg-open ()
911 "Check if xdg-open can be used, i.e. we are on Gnome, KDE or xfce4."
912 (and (getenv "DISPLAY")
913 (executable-find "xdg-open")
914 ;; xdg-open may call gnome-open and that does not wait for its child
915 ;; to finish. This child may then be killed when the parent dies.
916 ;; Use nohup to work around.
917 (executable-find "nohup")
918 (or (getenv "GNOME_DESKTOP_SESSION_ID")
919 ;; GNOME_DESKTOP_SESSION_ID is deprecated, check on Dbus also.
920 (condition-case nil
921 (eq 0 (call-process
922 "dbus-send" nil nil nil
923 "--dest=org.gnome.SessionManager"
924 "--print-reply"
925 "/org/gnome/SessionManager"
926 "org.gnome.SessionManager.CanShutdown"))
927 (error nil))
928 (equal (getenv "KDE_FULL_SESSION") "true")
929 (condition-case nil
930 (eq 0 (call-process
931 "/bin/sh" nil nil nil
932 "-c"
933 "xprop -root _DT_SAVE_MODE|grep xfce4"))
934 (error nil)))))
935
936
937;;;###autoload
938(defun browse-url-xdg-open (url &optional new-window)
939 (interactive (browse-url-interactive-arg "URL: "))
2187e5bb 940 (call-process "nohup" nil nil nil "xdg-open" url))
2269b349 941
8749abea
GM
942;;;###autoload
943(defun browse-url-netscape (url &optional new-window)
944 "Ask the Netscape WWW browser to load URL.
8749abea
GM
945Default to the URL around or before point. The strings in variable
946`browse-url-netscape-arguments' are also passed to Netscape.
947
408d5219 948When called interactively, if variable `browse-url-new-window-flag' is
8749abea
GM
949non-nil, load the document in a new Netscape window, otherwise use a
950random existing one. A non-nil interactive prefix argument reverses
408d5219 951the effect of `browse-url-new-window-flag'.
8749abea 952
fe77c061
SJ
953If `browse-url-netscape-new-window-is-tab' is non-nil, then
954whenever a document would otherwise be loaded in a new window, it
955is loaded in a new tab in an existing window instead.
956
8749abea 957When called non-interactively, optional second argument NEW-WINDOW is
408d5219 958used instead of `browse-url-new-window-flag'."
de5552d5 959 (interactive (browse-url-interactive-arg "URL: "))
8c22c51a 960 (setq url (browse-url-encode-url url))
8749abea 961 (let* ((process-environment (browse-url-process-environment))
fe77c061
SJ
962 (process
963 (apply 'start-process
964 (concat "netscape " url) nil
965 browse-url-netscape-program
966 (append
967 browse-url-netscape-arguments
968 (if (eq window-system 'w32)
969 (list url)
970 (append
971 (if new-window '("-noraise"))
972 (list "-remote"
973 (concat "openURL(" url
974 (if (browse-url-maybe-new-window
975 new-window)
976 (if browse-url-netscape-new-window-is-tab
977 ",new-tab"
978 ",new-window"))
979 ")"))))))))
8749abea 980 (set-process-sentinel process
3abc9fa1
DL
981 `(lambda (process change)
982 (browse-url-netscape-sentinel process ,url)))))
8749abea
GM
983
984(defun browse-url-netscape-sentinel (process url)
985 "Handle a change to the process communicating with Netscape."
986 (or (eq (process-exit-status process) 0)
987 (let* ((process-environment (browse-url-process-environment)))
988 ;; Netscape not running - start it
7844257c 989 (message "Starting %s..." browse-url-netscape-program)
8749abea
GM
990 (apply 'start-process (concat "netscape" url) nil
991 browse-url-netscape-program
992 (append browse-url-netscape-startup-arguments (list url))))))
993
994(defun browse-url-netscape-reload ()
995 "Ask Netscape to reload its current document.
996How depends on `browse-url-netscape-version'."
997 (interactive)
998 ;; Backwards incompatibility reported by
999 ;; <peter.kruse@psychologie.uni-regensburg.de>.
1000 (browse-url-netscape-send (if (>= browse-url-netscape-version 4)
1001 "xfeDoCommand(reload)"
6eddc3bb 1002 "reload")))
8749abea
GM
1003
1004(defun browse-url-netscape-send (command)
1005 "Send a remote control command to Netscape."
1006 (let* ((process-environment (browse-url-process-environment)))
1007 (apply 'start-process "netscape" nil
1008 browse-url-netscape-program
1009 (append browse-url-netscape-arguments
1010 (list "-remote" command)))))
1011
7f61a9ee
RS
1012;;;###autoload
1013(defun browse-url-mozilla (url &optional new-window)
1014 "Ask the Mozilla WWW browser to load URL.
1015Default to the URL around or before point. The strings in variable
1016`browse-url-mozilla-arguments' are also passed to Mozilla.
1017
1018When called interactively, if variable `browse-url-new-window-flag' is
1019non-nil, load the document in a new Mozilla window, otherwise use a
1020random existing one. A non-nil interactive prefix argument reverses
1021the effect of `browse-url-new-window-flag'.
1022
d6da15ec
SJ
1023If `browse-url-mozilla-new-window-is-tab' is non-nil, then whenever a
1024document would otherwise be loaded in a new window, it is loaded in a
1025new tab in an existing window instead.
1026
7f61a9ee
RS
1027When called non-interactively, optional second argument NEW-WINDOW is
1028used instead of `browse-url-new-window-flag'."
1029 (interactive (browse-url-interactive-arg "URL: "))
8c22c51a 1030 (setq url (browse-url-encode-url url))
7f61a9ee 1031 (let* ((process-environment (browse-url-process-environment))
d6da15ec
SJ
1032 (process
1033 (apply 'start-process
1034 (concat "mozilla " url) nil
1035 browse-url-mozilla-program
1036 (append
1037 browse-url-mozilla-arguments
1038 (list "-remote"
1039 (concat "openURL("
1040 url
1041 (if (browse-url-maybe-new-window
1042 new-window)
1043 (if browse-url-mozilla-new-window-is-tab
c29cf9a4
RS
1044 ",new-tab"
1045 ",new-window"))
d6da15ec 1046 ")"))))))
7f61a9ee
RS
1047 (set-process-sentinel process
1048 `(lambda (process change)
1049 (browse-url-mozilla-sentinel process ,url)))))
1050
1051(defun browse-url-mozilla-sentinel (process url)
1052 "Handle a change to the process communicating with Mozilla."
1053 (or (eq (process-exit-status process) 0)
1054 (let* ((process-environment (browse-url-process-environment)))
1055 ;; Mozilla is not running - start it
7844257c 1056 (message "Starting %s..." browse-url-mozilla-program)
7f61a9ee
RS
1057 (apply 'start-process (concat "mozilla " url) nil
1058 browse-url-mozilla-program
1059 (append browse-url-mozilla-startup-arguments (list url))))))
49866ff8
EZ
1060
1061;;;###autoload
1062(defun browse-url-firefox (url &optional new-window)
1063 "Ask the Firefox WWW browser to load URL.
1064Default to the URL around or before point. The strings in
1065variable `browse-url-firefox-arguments' are also passed to
1066Firefox.
1067
1068When called interactively, if variable
1069`browse-url-new-window-flag' is non-nil, load the document in a
1070new Firefox window, otherwise use a random existing one. A
1071non-nil interactive prefix argument reverses the effect of
1072`browse-url-new-window-flag'.
1073
1074If `browse-url-firefox-new-window-is-tab' is non-nil, then
1075whenever a document would otherwise be loaded in a new window, it
1076is loaded in a new tab in an existing window instead.
1077
1078When called non-interactively, optional second argument
1079NEW-WINDOW is used instead of `browse-url-new-window-flag'.
1080
1081On MS-Windows systems the optional `new-window' parameter is
1082ignored. Firefox for Windows does not support the \"-remote\"
1083command line parameter. Therefore, the
1084`browse-url-new-window-flag' and `browse-url-firefox-new-window-is-tab'
1085are ignored as well. Firefox on Windows will always open the requested
1086URL in a new window."
1087 (interactive (browse-url-interactive-arg "URL: "))
8c22c51a 1088 (setq url (browse-url-encode-url url))
49866ff8
EZ
1089 (let* ((process-environment (browse-url-process-environment))
1090 (process
1091 (apply 'start-process
1092 (concat "firefox " url) nil
1093 browse-url-firefox-program
1094 (append
1095 browse-url-firefox-arguments
1096 (if (or (featurep 'dos-w32)
1097 (string-match "win32" system-configuration))
1098 (list url)
1099 (list "-remote"
1100 (concat "openURL("
1101 url
1102 (if (browse-url-maybe-new-window
1103 new-window)
1104 (if browse-url-firefox-new-window-is-tab
1105 ",new-tab"
1106 ",new-window"))
1107 ")")))))))
1108 (set-process-sentinel process
1109 `(lambda (process change)
1110 (browse-url-firefox-sentinel process ,url)))))
1111
1112(defun browse-url-firefox-sentinel (process url)
1113 "Handle a change to the process communicating with Firefox."
1114 (or (eq (process-exit-status process) 0)
1115 (let* ((process-environment (browse-url-process-environment)))
1116 ;; Firefox is not running - start it
1117 (message "Starting Firefox...")
1118 (apply 'start-process (concat "firefox " url) nil
1119 browse-url-firefox-program
1120 (append browse-url-firefox-startup-arguments (list url))))))
7f61a9ee
RS
1121
1122;;;###autoload
1123(defun browse-url-galeon (url &optional new-window)
1124 "Ask the Galeon WWW browser to load URL.
1125Default to the URL around or before point. The strings in variable
1126`browse-url-galeon-arguments' are also passed to Galeon.
1127
1128When called interactively, if variable `browse-url-new-window-flag' is
1129non-nil, load the document in a new Galeon window, otherwise use a
1130random existing one. A non-nil interactive prefix argument reverses
1131the effect of `browse-url-new-window-flag'.
1132
b77784f7
RS
1133If `browse-url-galeon-new-window-is-tab' is non-nil, then whenever a
1134document would otherwise be loaded in a new window, it is loaded in a
1135new tab in an existing window instead.
1136
7f61a9ee
RS
1137When called non-interactively, optional second argument NEW-WINDOW is
1138used instead of `browse-url-new-window-flag'."
1139 (interactive (browse-url-interactive-arg "URL: "))
5edcabcb 1140 (setq url (browse-url-encode-url url))
7f61a9ee
RS
1141 (let* ((process-environment (browse-url-process-environment))
1142 (process (apply 'start-process
654805e3
RS
1143 (concat "galeon " url)
1144 nil
7f61a9ee
RS
1145 browse-url-galeon-program
1146 (append
1147 browse-url-galeon-arguments
1d5d4123
RS
1148 (if (browse-url-maybe-new-window new-window)
1149 (if browse-url-galeon-new-window-is-tab
1150 '("--new-tab")
b77784f7
RS
1151 '("--new-window" "--noraise"))
1152 '("--existing"))
1153 (list url)))))
7f61a9ee
RS
1154 (set-process-sentinel process
1155 `(lambda (process change)
1156 (browse-url-galeon-sentinel process ,url)))))
1157
1158(defun browse-url-galeon-sentinel (process url)
1159 "Handle a change to the process communicating with Galeon."
1160 (or (eq (process-exit-status process) 0)
1161 (let* ((process-environment (browse-url-process-environment)))
1162 ;; Galeon is not running - start it
7844257c 1163 (message "Starting %s..." browse-url-galeon-program)
7f61a9ee
RS
1164 (apply 'start-process (concat "galeon " url) nil
1165 browse-url-galeon-program
1166 (append browse-url-galeon-startup-arguments (list url))))))
1167
654805e3
RS
1168(defun browse-url-epiphany (url &optional new-window)
1169 "Ask the Epiphany WWW browser to load URL.
1170Default to the URL around or before point. The strings in variable
1171`browse-url-galeon-arguments' are also passed to Epiphany.
1172
1173When called interactively, if variable `browse-url-new-window-flag' is
1174non-nil, load the document in a new Epiphany window, otherwise use a
1175random existing one. A non-nil interactive prefix argument reverses
1176the effect of `browse-url-new-window-flag'.
1177
674dd916 1178If `browse-url-epiphany-new-window-is-tab' is non-nil, then whenever a
654805e3
RS
1179document would otherwise be loaded in a new window, it is loaded in a
1180new tab in an existing window instead.
1181
1182When called non-interactively, optional second argument NEW-WINDOW is
1183used instead of `browse-url-new-window-flag'."
1184 (interactive (browse-url-interactive-arg "URL: "))
8c22c51a 1185 (setq url (browse-url-encode-url url))
654805e3
RS
1186 (let* ((process-environment (browse-url-process-environment))
1187 (process (apply 'start-process
1188 (concat "epiphany " url)
1189 nil
1190 browse-url-epiphany-program
1191 (append
1192 browse-url-epiphany-arguments
1193 (if (browse-url-maybe-new-window new-window)
1194 (if browse-url-epiphany-new-window-is-tab
1195 '("--new-tab")
1196 '("--new-window" "--noraise"))
1197 '("--existing"))
1198 (list url)))))
1199 (set-process-sentinel process
1200 `(lambda (process change)
1201 (browse-url-epiphany-sentinel process ,url)))))
1202
1203(defun browse-url-epiphany-sentinel (process url)
1204 "Handle a change to the process communicating with Epiphany."
1205 (or (eq (process-exit-status process) 0)
1206 (let* ((process-environment (browse-url-process-environment)))
1207 ;; Epiphany is not running - start it
7844257c 1208 (message "Starting %s..." browse-url-epiphany-program)
654805e3
RS
1209 (apply 'start-process (concat "epiphany " url) nil
1210 browse-url-epiphany-program
1211 (append browse-url-epiphany-startup-arguments (list url))))))
1212
3fe5c37a
DN
1213(defvar url-handler-regexp)
1214
378f9937
SM
1215;;;###autoload
1216(defun browse-url-emacs (url &optional new-window)
1217 "Ask Emacs to load URL into a buffer and show it in another window."
1218 (interactive (browse-url-interactive-arg "URL: "))
1219 (require 'url-handlers)
1220 (let ((file-name-handler-alist
1221 (cons (cons url-handler-regexp 'url-file-handler)
1222 file-name-handler-alist)))
1223 ;; Ignore `new-window': with all other browsers the URL is always shown
1224 ;; in another window than the current Emacs one since it's shown in
1225 ;; another application's window.
1226 ;; (if new-window (find-file-other-window url) (find-file url))
1227 (find-file-other-window url)))
1228
b12e6de3 1229;;;###autoload
de5552d5
DL
1230(defun browse-url-gnome-moz (url &optional new-window)
1231 "Ask Mozilla/Netscape to load URL via the GNOME program `gnome-moz-remote'.
1232Default to the URL around or before point. The strings in variable
1233`browse-url-gnome-moz-arguments' are also passed.
1234
408d5219 1235When called interactively, if variable `browse-url-new-window-flag' is
de5552d5
DL
1236non-nil, load the document in a new browser window, otherwise use an
1237existing one. A non-nil interactive prefix argument reverses the
408d5219 1238effect of `browse-url-new-window-flag'.
de5552d5
DL
1239
1240When called non-interactively, optional second argument NEW-WINDOW is
408d5219 1241used instead of `browse-url-new-window-flag'."
c60ee5e7 1242 (interactive (browse-url-interactive-arg "URL: "))
de5552d5
DL
1243 (apply 'start-process (concat "gnome-moz-remote " url)
1244 nil
662871dd 1245 browse-url-gnome-moz-program
de5552d5
DL
1246 (append
1247 browse-url-gnome-moz-arguments
1248 (if (browse-url-maybe-new-window new-window)
6eddc3bb 1249 '("--newwin"))
de5552d5
DL
1250 (list "--raise" url))))
1251
8749abea
GM
1252;; --- Mosaic ---
1253
1254;;;###autoload
1255(defun browse-url-mosaic (url &optional new-window)
1256 "Ask the XMosaic WWW browser to load URL.
1257
1258Default to the URL around or before point. The strings in variable
1259`browse-url-mosaic-arguments' are also passed to Mosaic and the
1260program is invoked according to the variable
1261`browse-url-mosaic-program'.
1262
408d5219 1263When called interactively, if variable `browse-url-new-window-flag' is
8749abea
GM
1264non-nil, load the document in a new Mosaic window, otherwise use a
1265random existing one. A non-nil interactive prefix argument reverses
408d5219 1266the effect of `browse-url-new-window-flag'.
8749abea
GM
1267
1268When called non-interactively, optional second argument NEW-WINDOW is
408d5219 1269used instead of `browse-url-new-window-flag'."
8749abea 1270 (interactive (browse-url-interactive-arg "Mosaic URL: "))
1665be47 1271 (let ((pidfile (expand-file-name browse-url-mosaic-pidfile))
8749abea
GM
1272 pid)
1273 (if (file-readable-p pidfile)
1274 (save-excursion
1275 (find-file pidfile)
1276 (goto-char (point-min))
1277 (setq pid (read (current-buffer)))
1278 (kill-buffer nil)))
1279 (if (and pid (zerop (signal-process pid 0))) ; Mosaic running
1280 (save-excursion
1281 (find-file (format "/tmp/Mosaic.%d" pid))
1282 (erase-buffer)
01f97560 1283 (insert (if (browse-url-maybe-new-window new-window)
8749abea
GM
1284 "newwin\n"
1285 "goto\n")
1286 url "\n")
1287 (save-buffer)
1288 (kill-buffer nil)
1289 ;; Send signal SIGUSR to Mosaic
84c2714c 1290 (message "Signaling Mosaic...")
662871dd 1291 (signal-process pid 'SIGUSR1)
8749abea
GM
1292 ;; Or you could try:
1293 ;; (call-process "kill" nil 0 nil "-USR1" (int-to-string pid))
84c2714c 1294 (message "Signaling Mosaic...done")
8749abea
GM
1295 )
1296 ;; Mosaic not running - start it
7844257c 1297 (message "Starting %s..." browse-url-mosaic-program)
8749abea
GM
1298 (apply 'start-process "xmosaic" nil browse-url-mosaic-program
1299 (append browse-url-mosaic-arguments (list url)))
7844257c 1300 (message "Starting %s...done" browse-url-mosaic-program))))
8749abea 1301
8749abea
GM
1302;; --- Mosaic using CCI ---
1303
1304;;;###autoload
1305(defun browse-url-cci (url &optional new-window)
1306 "Ask the XMosaic WWW browser to load URL.
1307Default to the URL around or before point.
1308
1309This function only works for XMosaic version 2.5 or later. You must
1310select `CCI' from XMosaic's File menu, set the CCI Port Address to the
1311value of variable `browse-url-CCI-port', and enable `Accept requests'.
1312
408d5219 1313When called interactively, if variable `browse-url-new-window-flag' is
8749abea
GM
1314non-nil, load the document in a new browser window, otherwise use a
1315random existing one. A non-nil interactive prefix argument reverses
408d5219 1316the effect of `browse-url-new-window-flag'.
8749abea
GM
1317
1318When called non-interactively, optional second argument NEW-WINDOW is
408d5219 1319used instead of `browse-url-new-window-flag'."
8749abea
GM
1320 (interactive (browse-url-interactive-arg "Mosaic URL: "))
1321 (open-network-stream "browse-url" " *browse-url*"
1322 browse-url-CCI-host browse-url-CCI-port)
1323 ;; Todo: start browser if fails
1324 (process-send-string "browse-url"
1325 (concat "get url (" url ") output "
01f97560 1326 (if (browse-url-maybe-new-window new-window)
8749abea
GM
1327 "new"
1328 "current")
1329 "\r\n"))
1330 (process-send-string "browse-url" "disconnect\r\n")
1331 (delete-process "browse-url"))
1332
8749abea
GM
1333;; --- W3 ---
1334
352d2dea
GM
1335;; External.
1336(declare-function w3-fetch-other-window "ext:w3m" (&optional url))
1337(declare-function w3-fetch "ext:w3m" (&optional url target))
1338
8749abea
GM
1339;;;###autoload
1340(defun browse-url-w3 (url &optional new-window)
1341 "Ask the w3 WWW browser to load URL.
1342Default to the URL around or before point.
1343
408d5219 1344When called interactively, if variable `browse-url-new-window-flag' is
8749abea 1345non-nil, load the document in a new window. A non-nil interactive
408d5219 1346prefix argument reverses the effect of `browse-url-new-window-flag'.
8749abea
GM
1347
1348When called non-interactively, optional second argument NEW-WINDOW is
408d5219 1349used instead of `browse-url-new-window-flag'."
8749abea 1350 (interactive (browse-url-interactive-arg "W3 URL: "))
6eddc3bb 1351 (require 'w3) ; w3-fetch-other-window not autoloaded
01f97560 1352 (if (browse-url-maybe-new-window new-window)
8749abea
GM
1353 (w3-fetch-other-window url)
1354 (w3-fetch url)))
1355
1356;;;###autoload
1357(defun browse-url-w3-gnudoit (url &optional new-window)
1358 ;; new-window ignored
1359 "Ask another Emacs running gnuserv to load the URL using the W3 browser.
1360The `browse-url-gnudoit-program' program is used with options given by
1361`browse-url-gnudoit-args'. Default to the URL around or before point."
1362 (interactive (browse-url-interactive-arg "W3 URL: "))
6eddc3bb
MC
1363 (apply 'start-process (concat "gnudoit:" url) nil
1364 browse-url-gnudoit-program
1365 (append browse-url-gnudoit-args
1366 (list (concat "(w3-fetch \"" url "\")")
1367 "(raise-frame)"))))
8749abea
GM
1368
1369;; --- Lynx in an xterm ---
1370
1371;;;###autoload
d9774611 1372(defun browse-url-text-xterm (url &optional new-window)
8749abea 1373 ;; new-window ignored
d9774611 1374 "Ask a text browser to load URL.
db6003fb 1375URL defaults to the URL around or before point.
d9774611 1376This runs the text browser specified by `browse-url-text-browser'.
8749abea
GM
1377in an Xterm window using the Xterm program named by `browse-url-xterm-program'
1378with possible additional arguments `browse-url-xterm-args'."
d9774611
RS
1379 (interactive (browse-url-interactive-arg "Text browser URL: "))
1380 (apply #'start-process `(,(concat browse-url-text-browser url)
1381 nil ,browse-url-xterm-program
03e49c06 1382 ,@browse-url-xterm-args "-e" ,browse-url-text-browser
6eddc3bb 1383 ,url)))
8749abea
GM
1384
1385;; --- Lynx in an Emacs "term" window ---
1386
1387;;;###autoload
d9774611
RS
1388(defun browse-url-text-emacs (url &optional new-buffer)
1389 "Ask a text browser to load URL.
db6003fb 1390URL defaults to the URL around or before point.
d9774611
RS
1391This runs the text browser specified by `browse-url-text-browser'.
1392With a prefix argument, it runs a new browser process in a new buffer.
8749abea 1393
408d5219 1394When called interactively, if variable `browse-url-new-window-flag' is
d9774611 1395non-nil, load the document in a new browser process in a new term window,
8749abea 1396otherwise use any existing one. A non-nil interactive prefix argument
408d5219 1397reverses the effect of `browse-url-new-window-flag'.
8749abea
GM
1398
1399When called non-interactively, optional second argument NEW-WINDOW is
408d5219 1400used instead of `browse-url-new-window-flag'."
d9774611 1401 (interactive (browse-url-interactive-arg "Text browser URL: "))
6eddc3bb 1402 (let* ((system-uses-terminfo t) ; Lynx uses terminfo
8749abea 1403 ;; (term-term-name "vt100") ; ??
d9774611 1404 (buf (get-buffer "*text browser*"))
8749abea 1405 (proc (and buf (get-buffer-process buf)))
d9774611 1406 (n browse-url-text-input-attempts))
01f97560 1407 (if (and (browse-url-maybe-new-window new-buffer) buf)
8749abea
GM
1408 ;; Rename away the OLD buffer. This isn't very polite, but
1409 ;; term insists on working in a buffer named *lynx* and would
1410 ;; choke on *lynx*<1>
1411 (progn (set-buffer buf)
1412 (rename-uniquely)))
01f97560 1413 (if (or (browse-url-maybe-new-window new-buffer)
8749abea
GM
1414 (not buf)
1415 (not proc)
1416 (not (memq (process-status proc) '(run stop))))
d9774611 1417 ;; start a new text browser
8749abea
GM
1418 (progn
1419 (setq buf
1420 (apply #'make-term
d9774611
RS
1421 `(,browse-url-text-browser
1422 ,browse-url-text-browser
1423 nil ,@browse-url-text-emacs-args
01f97560 1424 ,url)))
8749abea
GM
1425 (switch-to-buffer buf)
1426 (term-char-mode)
1427 (set-process-sentinel
1428 (get-buffer-process buf)
1429 ;; Don't leave around a dead one (especially because of its
1430 ;; munged keymap.)
1431 (lambda (process event)
1432 (if (not (memq (process-status process) '(run stop)))
1433 (let ((buf (process-buffer process)))
1434 (if buf (kill-buffer buf)))))))
d9774611 1435 ;; Send the url to the text browser in the old buffer
8749abea
GM
1436 (let ((win (get-buffer-window buf t)))
1437 (if win
1438 (select-window win)
1439 (switch-to-buffer buf)))
1440 (if (eq (following-char) ?_)
d9774611 1441 (cond ((eq browse-url-text-input-field 'warn)
e8af40ee 1442 (error "Please move out of the input field first"))
d9774611 1443 ((eq browse-url-text-input-field 'avoid)
8749abea 1444 (while (and (eq (following-char) ?_) (> n 0))
6eddc3bb 1445 (term-send-down) ; down arrow
d9774611 1446 (sit-for browse-url-text-input-delay))
8749abea 1447 (if (eq (following-char) ?_)
e8af40ee 1448 (error "Cannot move out of the input field, sorry")))))
6eddc3bb 1449 (term-send-string proc (concat "g" ; goto
8749abea
GM
1450 "\C-u" ; kill default url
1451 url
1452 "\r")))))
1453
8749abea
GM
1454;; --- mailto ---
1455
1abcd088
EZ
1456(autoload 'rfc2368-parse-mailto-url "rfc2368")
1457
8749abea
GM
1458;;;###autoload
1459(defun browse-url-mail (url &optional new-window)
1abcd088 1460 "Open a new mail message buffer within Emacs for the RFC 2368 URL.
8749abea
GM
1461Default to using the mailto: URL around or before point as the
1462recipient's address. Supplying a non-nil interactive prefix argument
1463will cause the mail to be composed in another window rather than the
1464current one.
1465
408d5219 1466When called interactively, if variable `browse-url-new-window-flag' is
8749abea
GM
1467non-nil use `compose-mail-other-window', otherwise `compose-mail'. A
1468non-nil interactive prefix argument reverses the effect of
408d5219 1469`browse-url-new-window-flag'.
8749abea
GM
1470
1471When called non-interactively, optional second argument NEW-WINDOW is
408d5219 1472used instead of `browse-url-new-window-flag'."
8749abea
GM
1473 (interactive (browse-url-interactive-arg "Mailto URL: "))
1474 (save-excursion
1abcd088
EZ
1475 (let* ((alist (rfc2368-parse-mailto-url url))
1476 (to (assoc "To" alist))
1477 (subject (assoc "Subject" alist))
1478 (body (assoc "Body" alist))
1479 (rest (delete to (delete subject (delete body alist))))
1480 (to (cdr to))
1481 (subject (cdr subject))
1482 (body (cdr body))
1483 (mail-citation-hook (unless body mail-citation-hook)))
01f97560 1484 (if (browse-url-maybe-new-window new-window)
1abcd088
EZ
1485 (compose-mail-other-window to subject rest nil
1486 (if body
1487 (list 'insert body)
1488 (list 'insert-buffer (current-buffer))))
1489 (compose-mail to subject rest nil nil
1490 (if body
1491 (list 'insert body)
1492 (list 'insert-buffer (current-buffer))))))))
8749abea
GM
1493
1494;; --- Random browser ---
1495
1496;;;###autoload
1497(defun browse-url-generic (url &optional new-window)
1498 ;; new-window ignored
1499 "Ask the WWW browser defined by `browse-url-generic-program' to load URL.
1500Default to the URL around or before point. A fresh copy of the
1501browser is started up in a new process with possible additional arguments
1502`browse-url-generic-args'. This is appropriate for browsers which
1503don't offer a form of remote control."
1504 (interactive (browse-url-interactive-arg "URL: "))
1505 (if (not browse-url-generic-program)
6eddc3bb 1506 (error "No browser defined (`browse-url-generic-program')"))
78cfc6ad
DK
1507 (apply 'call-process browse-url-generic-program nil
1508 0 nil
8749abea
GM
1509 (append browse-url-generic-args (list url))))
1510
af06f459
GM
1511;;;###autoload
1512(defun browse-url-kde (url &optional new-window)
1513 "Ask the KDE WWW browser to load URL.
1514Default to the URL around or before point."
1515 (interactive (browse-url-interactive-arg "KDE URL: "))
1516 (message "Sending URL to KDE...")
662871dd 1517 (apply #'start-process (concat "KDE " url) nil browse-url-kde-program
6eddc3bb 1518 (append browse-url-kde-args (list url))))
af06f459 1519
a38de16e
MC
1520(defun browse-url-elinks-new-window (url)
1521 "Ask the Elinks WWW browser to load URL in a new window."
db6003fb 1522 (let ((process-environment (browse-url-process-environment)))
a38de16e
MC
1523 (apply #'start-process
1524 (append (list (concat "elinks:" url)
1525 nil)
1526 browse-url-elinks-wrapper
1527 (list "elinks" url)))))
1528
8c22c51a 1529;;;###autoload
a38de16e 1530(defun browse-url-elinks (url &optional new-window)
8c22c51a
GM
1531 "Ask the Elinks WWW browser to load URL.
1532Default to the URL around the point.
1533
1534The document is loaded in a new tab of a running Elinks or, if
1535none yet running, a newly started instance.
1536
1537The Elinks command will be prepended by the program+arguments
a38de16e 1538from `browse-url-elinks-wrapper'."
8c22c51a
GM
1539 (interactive (browse-url-interactive-arg "URL: "))
1540 (setq url (browse-url-encode-url url))
a38de16e
MC
1541 (if new-window
1542 (browse-url-elinks-new-window url)
1543 (let ((process-environment (browse-url-process-environment))
1544 (elinks-ping-process (start-process "elinks-ping" nil
1545 "elinks" "-remote" "ping()")))
1546 (set-process-sentinel elinks-ping-process
1547 `(lambda (process change)
1548 (browse-url-elinks-sentinel process ,url))))))
8c22c51a
GM
1549
1550(defun browse-url-elinks-sentinel (process url)
1551 "Determines if Elinks is running or a new one has to be started."
a38de16e 1552 (let ((exit-status (process-exit-status process)))
8c22c51a
GM
1553 ;; Try to determine if an instance is running or if we have to
1554 ;; create a new one.
1555 (case exit-status
6eddc3bb
MC
1556 (5
1557 ;; No instance, start a new one.
a38de16e 1558 (browse-url-elinks-new-window url))
6eddc3bb
MC
1559 (0
1560 ;; Found an instance, open URL in new tab.
a38de16e
MC
1561 (let ((process-environment (browse-url-process-environment)))
1562 (start-process (concat "elinks:" url) nil
1563 "elinks" "-remote"
1564 (concat "openURL(\"" url "\",new-tab)"))))
6eddc3bb 1565 (otherwise
a38de16e
MC
1566 (error "Unrecognized exit-code %d of process `elinks'"
1567 exit-status)))))
8c22c51a 1568
8749abea
GM
1569(provide 'browse-url)
1570
1571;;; browse-url.el ends here