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