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