Moved here from lisp.
[bpt/emacs.git] / lisp / browse-url.el
CommitLineData
5db57514 1;;; browse-url.el --- Pass a URL to a WWW browser
b578f267 2
ef7deaa9 3;; Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
a69315a1
RS
4
5;; Author: Denis Howe <dbh@doc.ic.ac.uk>
a43d1a2a 6;; Maintainer: Dave Love <fx@gnu.org>
a69315a1 7;; Created: 03 Apr 1995
5db57514 8;; Keywords: hypertext, hypermedia, mouse
a69315a1
RS
9
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
b578f267
EN
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation; either version 2, or (at your option)
15;; any later version.
a69315a1 16
b578f267
EN
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.
a69315a1
RS
21
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to the
b578f267
EN
24;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25;; Boston, MA 02111-1307, USA.
a69315a1 26
a69315a1
RS
27;;; Commentary:
28
a69315a1
RS
29;; This package provides functions which read a URL (Uniform Resource
30;; Locator) from the minibuffer, defaulting to the URL around point,
31;; and ask a World-Wide Web browser to load it. It can also load the
32;; URL associated with the current buffer. Different browsers use
33;; different methods of remote control so there is one function for
34;; each supported browser. If the chosen browser is not running, it
35;; is started. Currently there is support for:
36
37;; Function Browser Earliest version
a43d1a2a 38;; browse-url-netscape Netscape 1.1b1
837984b1 39;; browse-url-mosaic XMosaic/mMosaic <= 2.4
a69315a1
RS
40;; browse-url-cci XMosaic 2.5
41;; browse-url-w3 w3 0
5db57514 42;; browse-url-w3-gnudoit w3 remotely
a69315a1 43;; browse-url-iximosaic IXI Mosaic ?
96adeb99
RS
44;; browse-url-lynx-* Lynx 0
45;; browse-url-grail Grail 0.3b1
5db57514
RS
46;; browse-url-mmm MMM ?
47;; browse-url-generic arbitrary
a69315a1 48
db814a74 49;; [A version of the Netscape browser is now free software
9d843bef 50;; <URL:http://www.mozilla.org/>, albeit not GPLed, so it is
db814a74 51;; reasonable to have that as the default.]
9d843bef 52
a69315a1 53;; Note that versions of Netscape before 1.1b1 did not have remote
5db57514 54;; control. <URL:http://www.netscape.com/newsref/std/x-remote.html>.
a69315a1 55
9d843bef 56;; Browsers can cache Web pages so it may be necessary to tell them to
96adeb99 57;; reload the current page if it has changed (e.g. if you have edited
a69315a1
RS
58;; it). There is currently no perfect automatic solution to this.
59
60;; Netscape allows you to specify the id of the window you want to
61;; control but which window DO you want to control and how do you
62;; discover its id?
63
64;; If using XMosaic before version 2.5, check the definition of
65;; browse-url-usr1-signal below.
66;; <URL:http://www.ncsa.uiuc.edu/SDG/Software/XMosaic/remote-control.html>
67
68;; XMosaic version 2.5 introduced Common Client Interface allowing you
69;; to control mosaic through Unix sockets.
70;; <URL:http://www.ncsa.uiuc.edu/SDG/Software/XMosaic/CCI/cci-spec.html>
71
72;; William M. Perry's excellent "w3" WWW browser for
73;; Emacs <URL:ftp://cs.indiana.edu/pub/elisp/w3/>
74;; has a function w3-follow-url-at-point, but that
75;; doesn't let you edit the URL like browse-url.
5db57514
RS
76;; The `gnuserv' package that can be used to control it in another
77;; Emacs process is available from
a43d1a2a 78;; <URL:ftp://ftp.splode.com/pub/users/friedman/packages/>.
5db57514
RS
79
80;; Grail is the freely available WWW browser implemented in Python, a
81;; cool object-oriented freely available interpreted language. Grail
82;; 0.3b1 was the first version to have remote control as distributed.
83;; For more information on Grail see
84;; <URL:http://grail.cnri.reston.va.us/> and for more information on
85;; Python see <url:http://www.python.org/>. Grail support in
86;; browse-url.el written by Barry Warsaw <bwarsaw@python.org>.
87
c7f836c7
DL
88;; MMM is a semi-free WWW browser implemented in Objective Caml, an
89;; interesting impure functional programming language. See
5db57514
RS
90;; <URL:http://pauillac.inria.fr/%7Erouaix/mmm/>.
91
92;; Lynx is now distributed by the FSF. See also
93;; <URL:http://lynx.browser.org/>.
94
95;; Free graphical browsers that could be used by `browse-url-generic'
bc6d0d71
RS
96;; include Chimera <URL:ftp://ftp.cs.unlv.edu/pub/chimera> and
97;; <URL:http://www.unlv.edu/chimera/>, Arena
837984b1
DL
98;; <URL:ftp://ftp.yggdrasil.com/pub/dist/web/arena> and Amaya
99;; <URL:ftp://ftp.w3.org/pub/amaya>. mMosaic
c7f836c7
DL
100;; <URL:ftp://sig.enst.fr/pub/multicast/mMosaic/>,
101;; <URL:http://sig.enst.fr/~dauphin/mMosaic/> (with development
837984b1
DL
102;; support for Java applets and multicast) can be used like Mosaic by
103;; setting `browse-url-mosaic-program' appropriately.
a69315a1 104
9d843bef
DL
105;; I [Denis Howe, not Dave Love] recommend Nelson Minar
106;; <nelson@santafe.edu>'s excellent html-helper-mode.el for editing
107;; HTML and thank Nelson for his many useful comments on this code.
5db57514 108;; <URL:http://www.santafe.edu/%7Enelson/hhm-beta/>
a69315a1 109
59966fb6
RS
110;; See also hm--html-menus <URL:http://www.tnt.uni-hannover.de/%7Emuenkel/
111;; software/own/hm--html-menus/>. For composing correct HTML see also
112;; PSGML the general SGML structure editor package
113;; <URL:ftp://ftp.lysator.liu.se/pub/sgml>; hm--html-menus can be used
114;; with this.
115
a69315a1 116;; This package generalises function html-previewer-process in Marc
a43d1a2a
DL
117;; Andreessen's html-mode (LCD modes/html-mode.el.Z). See also the
118;; ffap.el package. The huge hyperbole package also contains similar
119;; functions.
a69315a1
RS
120
121;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
122;; Help!
123
124;; Can you write and test some code for the Macintrash and Windoze
125;; Netscape remote control APIs? (See the URL above).
126
127;; Do any other browsers have remote control?
128
a69315a1
RS
129;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
130;; Usage
131
132;; To display the URL at or before point:
133;; M-x browse-url-at-point RET
5db57514
RS
134;; or, similarly but with the opportunity to edit the URL extracted from
135;; the buffer, use:
136;; M-x browse-url
a69315a1
RS
137
138;; To display a URL by shift-clicking on it, put this in your ~/.emacs
139;; file:
a5f6b207
RS
140;; (global-set-key [S-mouse-2] 'browse-url-at-mouse)
141;; (Note that using Shift-mouse-1 is not desirable because
142;; that event has a standard meaning in Emacs.)
a69315a1
RS
143
144;; To display the current buffer in a web browser:
145;; M-x browse-url-of-buffer RET
146
5db57514
RS
147;; To display the current region in a web browser:
148;; M-x browse-url-of-region RET
149
a69315a1
RS
150;; In Dired, to display the file named on the current line:
151;; M-x browse-url-of-dired-file RET
152
153;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
154;; Customisation (~/.emacs)
155
96adeb99 156;; To see what variables are available for customization, type
09d8b0bc
DL
157;; `M-x set-variable browse-url TAB'. Better, use
158;; `M-x customize-group browse-url'.
a69315a1 159
96adeb99
RS
160;; Bind the browse-url commands to keys with the `C-c C-z' prefix
161;; (as used by html-helper-mode):
162;; (global-set-key "\C-c\C-z." 'browse-url-at-point)
163;; (global-set-key "\C-c\C-zb" 'browse-url-of-buffer)
5db57514 164;; (global-set-key "\C-c\C-zr" 'browse-url-of-region)
96adeb99
RS
165;; (global-set-key "\C-c\C-zu" 'browse-url)
166;; (global-set-key "\C-c\C-zv" 'browse-url-of-file)
5db57514 167;; (add-hook 'dired-mode-hook
e49172c8
DL
168;; (lambda ()
169;; (local-set-key "\C-c\C-zf" 'browse-url-of-dired-file)))
96adeb99
RS
170
171;; Browse URLs in mail messages by clicking mouse-2:
e49172c8
DL
172;; (add-hook 'rmail-mode-hook (lambda () ; rmail-mode startup
173;; (define-key rmail-mode-map [mouse-2] 'browse-url-at-mouse)))
96adeb99
RS
174
175;; Browse URLs in Usenet messages by clicking mouse-2:
176;; (eval-after-load "gnus"
177;; '(define-key gnus-article-mode-map [mouse-2] 'browse-url-at-mouse))
59966fb6
RS
178;; [The current version of Gnus provides a standard feature to
179;; activate URLs in article buffers for invocation of browse-url with
180;; mouse-2.]
96adeb99
RS
181
182;; Use the Emacs w3 browser when not running under X11:
183;; (or (eq window-system 'x)
5db57514 184;; (setq browse-url-browser-function 'browse-url-w3))
a69315a1
RS
185
186;; To always save modified buffers before displaying the file in a browser:
5db57514 187;; (setq browse-url-save-file t)
a69315a1 188
96adeb99
RS
189;; To get round the Netscape caching problem, you could EITHER have
190;; write-file in html-helper-mode make Netscape reload the document:
a69315a1 191;;
5db57514
RS
192;; (autoload 'browse-url-netscape-reload "browse-url"
193;; "Ask a WWW browser to redisplay the current file." t)
194;; (add-hook 'html-helper-mode-hook
e49172c8 195;; (lambda ()
5db57514 196;; (add-hook 'local-write-file-hooks
e49172c8 197;; (lambda ()
5db57514
RS
198;; (let ((local-write-file-hooks))
199;; (save-buffer))
200;; (browse-url-netscape-reload)
e49172c8
DL
201;; t) ; => file written by hook
202;; t))) ; append to l-w-f-hooks
a69315a1 203;;
96adeb99 204;; OR have browse-url-of-file ask Netscape to load and then reload the
a69315a1
RS
205;; file:
206;;
5db57514 207;; (add-hook 'browse-url-of-file-hook 'browse-url-netscape-reload)
a69315a1 208
96adeb99 209;; You may also want to customise browse-url-netscape-arguments, e.g.
5db57514 210;; (setq browse-url-netscape-arguments '("-install"))
a69315a1 211;;
5db57514 212;; or similarly for the other browsers.
a69315a1 213
5db57514
RS
214;; To invoke different browsers for different URLs:
215;; (setq browse-url-browser-function '(("^mailto:" . browse-url-mail)
216;; ("." . browse-url-netscape)))
a69315a1
RS
217
218;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
219;;; Code:
220
5db57514
RS
221;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
222;; Variables
a69315a1 223
380a0a12 224(eval-when-compile (require 'thingatpt)
e61d8515 225 (require 'term)
c7f836c7 226 (require 'dired)
e61d8515 227 (require 'w3-auto nil t))
a43d1a2a 228
0a3fc8a2
RS
229(defgroup browse-url nil
230 "Use a web browser to look at a URL."
09d8b0bc 231 :prefix "browse-url-"
f6680f0b 232 :group 'hypermedia)
96adeb99
RS
233
234;;;###autoload
0a3fc8a2 235(defcustom browse-url-browser-function
ef233c01
AI
236 (if (eq system-type 'windows-nt)
237 'browse-url-default-windows-browser
238 'browse-url-netscape)
a69315a1 239 "*Function to display the current buffer in a WWW browser.
0a3fc8a2 240This is used by the `browse-url-at-point', `browse-url-at-mouse', and
1341d237 241`browse-url-of-file' commands.
5db57514
RS
242
243If the value is not a function it should be a list of pairs
a43d1a2a 244(REGEXP . FUNCTION). In this case the function called will be the one
5db57514
RS
245associated with the first REGEXP which matches the current URL. The
246function is passed the URL and any other args of `browse-url'. The last
247regexp should probably be \".\" to specify a default browser."
e49172c8
DL
248 :type '(choice
249 (function-item :tag "Emacs W3" :value browse-url-w3)
250 (function-item :tag "W3 in another Emacs via `gnudoit'"
251 :value browse-url-w3-gnudoit)
252 (function-item :tag "Netscape" :value browse-url-netscape)
253 (function-item :tag "Mosaic" :value browse-url-mosaic)
254 (function-item :tag "Mosaic using CCI" :value browse-url-cci)
255 (function-item :tag "IXI Mosaic" :value browse-url-iximosaic)
256 (function-item :tag "Lynx in an xterm window"
257 :value browse-url-lynx-xterm)
258 (function-item :tag "Lynx in an Emacs window"
259 :value browse-url-lynx-emacs)
260 (function-item :tag "Grail" :value browse-url-grail)
261 (function-item :tag "MMM" :value browse-url-mmm)
262 (function-item :tag "Specified by `Browse Url Generic Program'"
263 :value browse-url-generic)
ef233c01
AI
264 (function-item :tag "Default Windows browser"
265 :value browse-url-default-windows-browser)
e49172c8 266 (function :tag "Your own function"))
27401ec7 267 :version "20.4"
0a3fc8a2
RS
268 :group 'browse-url)
269
270(defcustom browse-url-netscape-program "netscape"
0a383cc7 271 ;; Info about netscape-remote from Karl Berry.
a43d1a2a 272 "The name by which to invoke Netscape.
ac999fb9 273
0a383cc7
DL
274The free program `netscape-remote' from
275<URL:http://home.netscape.com/newsref/std/remote.c> is said to start
276up very much quicker than `netscape'. Reported to compile on a GNU
277system, given vroot.h from the same directory, with cc flags
278 -DSTANDALONE -L/usr/X11R6/lib -lXmu -lX11."
0a3fc8a2
RS
279 :type 'string
280 :group 'browse-url)
281
282(defcustom browse-url-netscape-arguments nil
a43d1a2a 283 "A list of strings to pass to Netscape as arguments."
0a3fc8a2
RS
284 :type '(repeat (string :tag "Argument"))
285 :group 'browse-url)
286
287(defcustom browse-url-netscape-startup-arguments browse-url-netscape-arguments
a43d1a2a 288 "A list of strings to pass to Netscape when it starts up.
0a3fc8a2 289Defaults to the value of `browse-url-netscape-arguments' at the time
5db57514 290`browse-url' is loaded."
0a3fc8a2
RS
291 :type '(repeat (string :tag "Argument"))
292 :group 'browse-url)
96adeb99 293
a43d1a2a 294;;;###autoload
0a3fc8a2 295(defcustom browse-url-new-window-p nil
e49172c8
DL
296 "*If non-nil, always open a new browser window with appropriate browsers.
297Passing an interactive argument to \\[browse-url], or specific browser
298commands reverses the effect of this variable. Requires Netscape version
2991.1N or later or XMosaic version 2.5 or later if using those browsers."
0a3fc8a2
RS
300 :type 'boolean
301 :group 'browse-url)
302
a43d1a2a 303;;;###autoload
5db57514 304(defcustom browse-url-netscape-display nil
837984b1 305 "*The X display for running Netscape, if not same as Emacs'."
e49172c8 306 :type '(choice string (const :tag "Default" nil))
5db57514
RS
307 :group 'browse-url)
308
837984b1 309(defcustom browse-url-mosaic-program "xmosaic"
a43d1a2a 310 "The name by which to invoke Mosaic (or mMosaic)."
837984b1 311 :type 'string
a43d1a2a 312 :version "20.3"
837984b1
DL
313 :group 'browse-url)
314
0a3fc8a2 315(defcustom browse-url-mosaic-arguments nil
a43d1a2a 316 "A list of strings to pass to Mosaic as arguments."
0a3fc8a2
RS
317 :type '(repeat (string :tag "Argument"))
318 :group 'browse-url)
a69315a1 319
09d8b0bc 320(defcustom browse-url-filename-alist
ac999fb9
DL
321 '(("^/\\(ftp@\\|anonymous@\\)?\\([^:]+\\):/*" . "ftp://\\2/")
322 ;; The above loses the username to avoid the browser prompting for
323 ;; it in anonymous cases. If it's not anonymous the next regexp
324 ;; applies.
325 ("^/\\([^:@]+@\\)?\\([^:]+\\):/*" . "ftp://\\1\\2/")
326 ("^/+" . "file:/"))
a43d1a2a 327 "An alist of (REGEXP . STRING) pairs used by `browse-url-of-file'.
a69315a1 328Any substring of a filename matching one of the REGEXPs is replaced by
ac999fb9
DL
329the corresponding STRING using `replace-match', not treating STRING
330literally. All pairs are applied in the order given. The default
331value converts ange-ftp/EFS-style paths into ftp URLs and prepends
332`file:' to any path beginning with `/'.
5db57514 333
ac999fb9
DL
334For example, adding to the default a specific translation of an ange-ftp
335address to an HTTP URL:
5db57514
RS
336
337 (setq browse-url-filename-alist
338 '((\"/webmaster@webserver:/home/www/html/\" .
339 \"http://www.acme.co.uk/\")
ac999fb9
DL
340 (\"^/\\(ftp@\\|anonymous@\\)?\\([^:]+\\):/*\" . \"ftp://\\2/\")
341 (\"^/\\([^:@]+@\\)?\\([^:]+\\):/*\" . \"ftp://\\1\\2/\")
5db57514 342 (\"^/+\" . \"file:/\")))
09d8b0bc
DL
343"
344 :type '(repeat (cons :format "%v"
e49172c8 345 (regexp :tag "Regexp")
09d8b0bc 346 (string :tag "Replacement")))
ac999fb9 347 :version "20.3"
09d8b0bc 348 :group 'browse-url)
a69315a1 349
a43d1a2a 350;;;###autoload
09d8b0bc
DL
351(defcustom browse-url-save-file nil
352 "*If non-nil, save the buffer before displaying its file.
353Used by the `browse-url-of-file' command."
354 :type 'boolean
355 :group 'browse-url)
a69315a1 356
09d8b0bc 357(defcustom browse-url-of-file-hook nil
a43d1a2a 358 "Run after `browse-url-of-file' has asked a browser to load a file.
a69315a1
RS
359
360Set this to `browse-url-netscape-reload' to force Netscape to load the
09d8b0bc
DL
361file rather than displaying a cached copy."
362 :type 'hook
a43d1a2a 363 :options '(browse-url-netscape-reload)
09d8b0bc 364 :group 'browse-url)
a69315a1
RS
365
366(defvar browse-url-usr1-signal
367 (if (and (boundp 'emacs-major-version)
5db57514 368 (or (> emacs-major-version 19) (>= emacs-minor-version 29)))
96adeb99 369 'SIGUSR1 ; Why did I think this was in lower case before?
5db57514 370 30) ; Check /usr/include/signal.h.
a69315a1 371 "The argument to `signal-process' for sending SIGUSR1 to XMosaic.
00232ce3 372Emacs 19.29 accepts 'SIGUSR1, earlier versions require an integer
a69315a1
RS
373which is 30 on SunOS and 16 on HP-UX and Solaris.")
374
09d8b0bc 375(defcustom browse-url-CCI-port 3003
a43d1a2a 376 "Port to access XMosaic via CCI.
a69315a1 377This can be any number between 1024 and 65535 but must correspond to
09d8b0bc
DL
378the value set in the browser."
379 :type 'integer
380 :group 'browse-url)
a69315a1 381
09d8b0bc 382(defcustom browse-url-CCI-host "localhost"
96adeb99
RS
383 "*Host to access XMosaic via CCI.
384This should be the host name of the machine running XMosaic with CCI
09d8b0bc
DL
385enabled. The port number should be set in `browse-url-CCI-port'."
386 :type 'string
387 :group 'browse-url)
96adeb99
RS
388
389(defvar browse-url-temp-file-name nil)
390(make-variable-buffer-local 'browse-url-temp-file-name)
391
5db57514 392(defcustom browse-url-xterm-program "xterm"
a43d1a2a 393 "The name of the terminal emulator used by `browse-url-lynx-xterm'.
5db57514
RS
394This might, for instance, be a separate colour version of xterm."
395 :type 'string
396 :group 'browse-url)
397
398(defcustom browse-url-xterm-args nil
399 "*A list of strings defining options for `browse-url-xterm-program'.
400These might set its size, for instance."
401 :type '(repeat (string :tag "Argument"))
402 :group 'browse-url)
403
a43d1a2a
DL
404(defcustom browse-url-lynx-emacs-args (and (not window-system)
405 '("-show_cursor"))
406 "A list of strings defining options for Lynx in an Emacs buffer.
407
408The default is none in a window system, otherwise `-show_cursor' to
409indicate the position of the current link in the absence of
410highlighting, assuming the normal default for showing the cursor."
411 :type '(repeat (string :tag "Argument"))
412 :version "20.3"
413 :group 'browse-url)
414
5db57514 415(defcustom browse-url-gnudoit-program "gnudoit"
a43d1a2a 416 "The name of the `gnudoit' program used by `browse-url-w3-gnudoit'."
5db57514
RS
417 :type 'string
418 :group 'browse-url)
419
420(defcustom browse-url-gnudoit-args '("-q")
421 "*A list of strings defining options for `browse-url-gnudoit-program'.
422These might set the port, for instance."
423 :type '(repeat (string :tag "Argument"))
424 :group 'browse-url)
425
a43d1a2a 426;;;###autoload
5db57514
RS
427(defcustom browse-url-generic-program nil
428 "*The name of the browser program used by `browse-url-generic'."
e49172c8 429 :type '(choice string (const :tag "None" nil))
5db57514
RS
430 :group 'browse-url)
431
432(defcustom browse-url-generic-args nil
433 "*A list of strings defining options for `browse-url-generic-program'."
434 :type '(repeat (string :tag "Argument"))
435 :group 'browse-url)
436
406757ff 437(defcustom browse-url-temp-dir temporary-file-directory
a43d1a2a 438 "The name of a directory for browse-url's temporary files.
837984b1
DL
439Such files are generated by functions like `browse-url-of-region'.
440You might want to set this to somewhere with restricted read permissions
441for privacy's sake."
bc6d0d71
RS
442 :type 'string
443 :group 'browse-url)
444
f6680f0b
RS
445(defcustom browse-url-netscape-version
446 3
a43d1a2a 447 "The version of Netscape you are using.
f6680f0b
RS
448This affects how URL reloading is done; the mechanism changed
449incompatibly at version 4."
450 :type 'number
451 :group 'browse-url)
452
09d8b0bc 453(defcustom browse-url-lynx-input-field 'avoid
837984b1
DL
454 "*Action on selecting an existing Lynx buffer at an input field.
455What to do when sending a new URL to an existing Lynx buffer in Emacs
456if the Lynx cursor is on an input field (in which case the `g' command
457would be entered as data). Such fields are recognized by the
458underlines ____. Allowed values: nil: disregard it, 'warn: warn the
459user and don't emit the URL, 'avoid: try to avoid the field by moving
09d8b0bc
DL
460down (this *won't* always work)."
461 :type '(choice (const :tag "Move to try to avoid field" :value avoid)
462 (const :tag "Disregard" :value nil)
463 (const :tag "Warn, don't emit URL" :value warn))
a43d1a2a 464 :version "20.3"
09d8b0bc 465 :group 'browse-url)
837984b1 466
380a0a12
DL
467(defvar browse-url-lynx-input-attempts 10
468 "*How many times to try to move down from a series of lynx input fields.")
837984b1 469
09d8b0bc 470(defcustom browse-url-lynx-input-delay 0.2
380a0a12 471 "How many seconds to wait for lynx between moves down from an input field.")
837984b1 472
a69315a1
RS
473;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
474;; URL input
475
a69315a1 476(defun browse-url-url-at-point ()
6debdec5
RS
477 (let ((url (thing-at-point 'url)))
478 (set-text-properties 0 (length url) nil url)
5db57514
RS
479 url))
480
96adeb99
RS
481;; Having this as a separate function called by the browser-specific
482;; functions allows them to be stand-alone commands, making it easier
483;; to switch between browsers.
484
485(defun browse-url-interactive-arg (prompt)
486 "Read a URL from the minibuffer, prompting with PROMPT.
bc6d0d71 487Default to the URL at or before point. If invoked with a mouse button,
96adeb99 488set point to the position clicked first. Return a list for use in
5db57514 489`interactive' containing the URL and `browse-url-new-window-p' or its
96adeb99 490negation if a prefix argument was given."
a69315a1
RS
491 (let ((event (elt (this-command-keys) 0)))
492 (and (listp event) (mouse-set-point event)))
96adeb99
RS
493 (list (read-string prompt (browse-url-url-at-point))
494 (not (eq (null browse-url-new-window-p)
495 (null current-prefix-arg)))))
a69315a1
RS
496
497;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
498;; Browse current buffer
499
8941c0cf 500;;;###autoload
a69315a1
RS
501(defun browse-url-of-file (&optional file)
502 "Ask a WWW browser to display FILE.
503Display the current buffer's file if FILE is nil or if called
96adeb99 504interactively. Turn the filename into a URL with function
5db57514
RS
505`browse-url-file-url'. Pass the URL to a browser using the
506`browse-url' function then run `browse-url-of-file-hook'."
a69315a1 507 (interactive)
5db57514 508 (or file
96adeb99
RS
509 (setq file (buffer-file-name))
510 (error "Current buffer has no file"))
a69315a1
RS
511 (let ((buf (get-file-buffer file)))
512 (if buf
5db57514
RS
513 (save-excursion
514 (set-buffer buf)
515 (cond ((not (buffer-modified-p)))
516 (browse-url-save-file (save-buffer))
517 (t (message "%s modified since last save" file))))))
518 (browse-url (browse-url-file-url file))
a69315a1
RS
519 (run-hooks 'browse-url-of-file-hook))
520
521(defun browse-url-file-url (file)
522 "Return the URL corresponding to FILE.
ac999fb9 523Use variable `browse-url-filename-alist' to map filenames to URLs."
96adeb99
RS
524 ;; URL-encode special chars, do % first
525 (let ((s 0))
526 (while (setq s (string-match "%" file s))
527 (setq file (replace-match "%25" t t file)
528 s (1+ s))))
529 (while (string-match "[*\"()',=;? ]" file)
530 (let ((enc (format "%%%x" (aref file (match-beginning 0)))))
531 (setq file (replace-match enc t t file))))
a69315a1
RS
532 (let ((maps browse-url-filename-alist))
533 (while maps
534 (let* ((map (car maps))
5db57514
RS
535 (from-re (car map))
536 (to-string (cdr map)))
537 (setq maps (cdr maps))
96adeb99 538 (and (string-match from-re file)
ac999fb9 539 (setq file (replace-match to-string t nil file))))))
a69315a1
RS
540 file)
541
8941c0cf 542;;;###autoload
a69315a1
RS
543(defun browse-url-of-buffer (&optional buffer)
544 "Ask a WWW browser to display BUFFER.
5db57514
RS
545Display the current buffer if BUFFER is nil. Display only the
546currently visible part of BUFFER (from a temporary file) if buffer is
547narrowed."
a69315a1
RS
548 (interactive)
549 (save-excursion
96adeb99 550 (and buffer (set-buffer buffer))
a69315a1 551 (let ((file-name
5db57514
RS
552 ;; Ignore real name if restricted
553 (and (= (- (point-max) (point-min)) (buffer-size))
554 (or buffer-file-name
555 (and (boundp 'dired-directory) dired-directory)))))
96adeb99 556 (or file-name
5db57514 557 (progn
96adeb99 558 (or browse-url-temp-file-name
5db57514 559 (setq browse-url-temp-file-name
bc6d0d71 560 (convert-standard-filename
767d12f2 561 (make-temp-file
bc6d0d71 562 (expand-file-name "burl" browse-url-temp-dir)))))
96adeb99
RS
563 (setq file-name browse-url-temp-file-name)
564 (write-region (point-min) (point-max) file-name nil 'no-message)))
565 (browse-url-of-file file-name))))
a69315a1
RS
566
567(defun browse-url-delete-temp-file (&optional temp-file-name)
767d12f2
SM
568 ;; Delete browse-url-temp-file-name from the file system
569 ;; If optional arg TEMP-FILE-NAME is non-nil, delete it instead
a69315a1
RS
570 (let ((file-name (or temp-file-name browse-url-temp-file-name)))
571 (if (and file-name (file-exists-p file-name))
767d12f2 572 (delete-file file-name))))
a69315a1
RS
573
574(add-hook 'kill-buffer-hook 'browse-url-delete-temp-file)
a69315a1 575
8941c0cf 576;;;###autoload
a69315a1
RS
577(defun browse-url-of-dired-file ()
578 "In Dired, ask a WWW browser to display the file named on this line."
579 (interactive)
580 (browse-url-of-file (dired-get-filename)))
581
5db57514
RS
582;;;###autoload
583(defun browse-url-of-region (min max)
584 "Ask a WWW browser to display the current region."
585 (interactive "r")
586 (save-excursion
587 (save-restriction
f64905b5 588 (narrow-to-region min max)
5db57514
RS
589 (browse-url-of-buffer))))
590
a69315a1 591;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5db57514 592;; Browser-independent commands
96adeb99 593
5db57514 594;; A generic command to call the current browse-url-browser-function
96adeb99 595
5db57514 596;;;###autoload
a43d1a2a 597(defun browse-url (url &rest args)
96adeb99
RS
598 "Ask a WWW browser to load URL.
599Prompts for a URL, defaulting to the URL at or before point. Variable
600`browse-url-browser-function' says which browser to use."
601 (interactive (browse-url-interactive-arg "URL: "))
c7f836c7
DL
602 (if (functionp browse-url-browser-function)
603 (apply browse-url-browser-function url args)
604 ;; The `function' can be an alist; look down it for first match
605 ;; and apply the function (which might be a lambda).
606 (catch 'done
607 (mapcar
608 (lambda (bf)
609 (when (string-match (car bf) url)
610 (apply (cdr bf) url args)
611 (throw 'done t)))
612 browse-url-browser-function)
613 (error "No browser in browse-url-browser-function matching URL %s"
614 url))))
96adeb99 615
8941c0cf 616;;;###autoload
96adeb99
RS
617(defun browse-url-at-point ()
618 "Ask a WWW browser to load the URL at or before point.
837984b1 619Doesn't let you edit the URL like `browse-url'. Variable
96adeb99
RS
620`browse-url-browser-function' says which browser to use."
621 (interactive)
5db57514 622 (browse-url (browse-url-url-at-point)))
96adeb99 623
78c11a9c
RS
624(defun browse-url-event-buffer (event)
625 (window-buffer (posn-window (event-start event))))
96adeb99 626
78c11a9c
RS
627(defun browse-url-event-point (event)
628 (posn-point (event-start event)))
96adeb99 629
8941c0cf 630;;;###autoload
96adeb99
RS
631(defun browse-url-at-mouse (event)
632 "Ask a WWW browser to load a URL clicked with the mouse.
633The URL is the one around or before the position of the mouse click
634but point is not changed. Doesn't let you edit the URL like
837984b1 635`browse-url'. Variable `browse-url-browser-function' says which browser
96adeb99
RS
636to use."
637 (interactive "e")
638 (save-excursion
78c11a9c
RS
639 (set-buffer (browse-url-event-buffer event))
640 (goto-char (browse-url-event-point event))
96adeb99
RS
641 (let ((url (browse-url-url-at-point)))
642 (if (string-equal url "")
643 (error "No URL found"))
837984b1 644 (browse-url url browse-url-new-window-p))))
96adeb99
RS
645
646;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
647;; Browser-specific commands
648
ef233c01
AI
649;; --- Default MS-Windows browser ---
650
651(defun browse-url-default-windows-browser (url &optional new-window)
652 (interactive (browse-url-interactive-arg "URL: "))
653 (w32-shell-execute "open" url))
654
96adeb99
RS
655;; --- Netscape ---
656
96adeb99 657(defun browse-url-process-environment ()
5db57514
RS
658 "Set DISPLAY in the environment to the X display Netscape is running on.
659This is either the value of variable `browse-url-netscape-display' if
660non-nil, or the same display as Emacs if different from the current
661environment, otherwise just use the current environment."
662 (let ((display (or browse-url-netscape-display (browse-url-emacs-display))))
96adeb99 663 (if display
5db57514 664 (cons (concat "DISPLAY=" display) process-environment)
96adeb99
RS
665 process-environment)))
666
5db57514
RS
667(defun browse-url-emacs-display ()
668 "Return the X display Emacs is running on.
837984b1 669This is nil if the display is the same as the DISPLAY environment variable.
5db57514 670
a43d1a2a
DL
671Actually Emacs could be using several displays; this just returns the
672one showing the selected frame."
673 (let ((display (cdr-safe (assq 'display (frame-parameters)))))
674 (and (not (equal display (getenv "DISPLAY")))
675 display)))
a69315a1 676
96adeb99 677;;;###autoload
a69315a1
RS
678(defun browse-url-netscape (url &optional new-window)
679 "Ask the Netscape WWW browser to load URL.
680
681Default to the URL around or before point. The strings in variable
682`browse-url-netscape-arguments' are also passed to Netscape.
683
684When called interactively, if variable `browse-url-new-window-p' is
685non-nil, load the document in a new Netscape window, otherwise use a
686random existing one. A non-nil interactive prefix argument reverses
5db57514 687the effect of `browse-url-new-window-p'.
a69315a1
RS
688
689When called non-interactively, optional second argument NEW-WINDOW is
5db57514 690used instead of `browse-url-new-window-p'."
96adeb99 691 (interactive (browse-url-interactive-arg "Netscape URL: "))
9d843bef
DL
692 ;; URL encode any `confusing' characters in the URL. This needs to
693 ;; include at least commas; presumably also close parens.
694 (while (string-match "[,)]" url)
695 (setq url (replace-match
ddff3d80 696 (format "%%%x" (string-to-char (match-string 0 url))) t t url)))
96adeb99
RS
697 (let* ((process-environment (browse-url-process-environment))
698 (process (apply 'start-process
a0f036f8
DL
699 (concat "netscape " url) nil
700 browse-url-netscape-program
701 (append
702 browse-url-netscape-arguments
703 (if (eq window-system 'w32)
704 (list url)
705 (append
706 (if new-window '("-noraise"))
707 (list "-remote"
708 (concat "openURL(" url
15eff622 709 (if new-window ",new-window")
a0f036f8 710 ")"))))))))
96adeb99 711 (set-process-sentinel process
5db57514
RS
712 (list 'lambda '(process change)
713 (list 'browse-url-netscape-sentinel 'process url)))))
96adeb99
RS
714
715(defun browse-url-netscape-sentinel (process url)
716 "Handle a change to the process communicating with Netscape."
717 (or (eq (process-exit-status process) 0)
718 (let* ((process-environment (browse-url-process-environment)))
719 ;; Netscape not running - start it
5db57514 720 (message "Starting Netscape...")
96adeb99 721 (apply 'start-process (concat "netscape" url) nil
6be23be6 722 browse-url-netscape-program
96adeb99 723 (append browse-url-netscape-startup-arguments (list url))))))
a69315a1
RS
724
725(defun browse-url-netscape-reload ()
837984b1
DL
726 "Ask Netscape to reload its current document.
727How depends on `browse-url-netscape-version'."
a69315a1 728 (interactive)
f6680f0b
RS
729 ;; Backwards incompatibility reported by
730 ;; <peter.kruse@psychologie.uni-regensburg.de>.
731 (browse-url-netscape-send (if (>= browse-url-netscape-version 4)
732 "xfeDoCommand(reload)"
733 "reload")))
a69315a1 734
96adeb99 735(defun browse-url-netscape-send (command)
a69315a1 736 "Send a remote control command to Netscape."
96adeb99
RS
737 (let* ((process-environment (browse-url-process-environment)))
738 (apply 'start-process "netscape" nil
6be23be6 739 browse-url-netscape-program
5db57514 740 (append browse-url-netscape-arguments
96adeb99
RS
741 (list "-remote" command)))))
742
743;; --- Mosaic ---
a69315a1 744
96adeb99
RS
745;;;###autoload
746(defun browse-url-mosaic (url &optional new-window)
a69315a1 747 "Ask the XMosaic WWW browser to load URL.
837984b1
DL
748
749Default to the URL around or before point. The strings in variable
750`browse-url-mosaic-arguments' are also passed to Mosaic and the
751program is invoked according to the variable
752`browse-url-mosaic-program'.
753
754When called interactively, if variable `browse-url-new-window-p' is
755non-nil, load the document in a new Mosaic window, otherwise use a
756random existing one. A non-nil interactive prefix argument reverses
757the effect of `browse-url-new-window-p'.
758
759When called non-interactively, optional second argument NEW-WINDOW is
760used instead of `browse-url-new-window-p'."
a69315a1
RS
761 (interactive (browse-url-interactive-arg "Mosaic URL: "))
762 (let ((pidfile (expand-file-name "~/.mosaicpid"))
380a0a12 763 pid)
a69315a1 764 (if (file-readable-p pidfile)
5db57514
RS
765 (save-excursion
766 (find-file pidfile)
767 (goto-char (point-min))
768 (setq pid (read (current-buffer)))
769 (kill-buffer nil)))
a69315a1 770 (if (and pid (zerop (signal-process pid 0))) ; Mosaic running
5db57514
RS
771 (save-excursion
772 (find-file (format "/tmp/Mosaic.%d" pid))
773 (erase-buffer)
15eff622 774 (insert (if new-window
837984b1 775 "newwin\n"
15eff622 776 "goto\n")
837984b1 777 url "\n")
5db57514
RS
778 (save-buffer)
779 (kill-buffer nil)
780 ;; Send signal SIGUSR to Mosaic
96adeb99 781 (message "Signalling Mosaic...")
5db57514
RS
782 (signal-process pid browse-url-usr1-signal)
783 ;; Or you could try:
784 ;; (call-process "kill" nil 0 nil "-USR1" (int-to-string pid))
96adeb99 785 (message "Signalling Mosaic...done")
5db57514 786 )
a69315a1
RS
787 ;; Mosaic not running - start it
788 (message "Starting Mosaic...")
837984b1 789 (apply 'start-process "xmosaic" nil browse-url-mosaic-program
5db57514 790 (append browse-url-mosaic-arguments (list url)))
a5f6b207 791 (message "Starting Mosaic...done"))))
a69315a1 792
96adeb99
RS
793;; --- Grail ---
794
795;;;###autoload
796(defvar browse-url-grail
797 (concat (or (getenv "GRAILDIR") "~/.grail") "/user/rcgrail.py")
a43d1a2a 798 "Location of Grail remote control client script `rcgrail.py'.
96adeb99
RS
799Typically found in $GRAILDIR/rcgrail.py, or ~/.grail/user/rcgrail.py.")
800
801;;;###autoload
5db57514 802(defun browse-url-grail (url &optional new-window)
96adeb99
RS
803 "Ask the Grail WWW browser to load URL.
804Default to the URL around or before point. Runs the program in the
805variable `browse-url-grail'."
806 (interactive (browse-url-interactive-arg "Grail URL: "))
807 (message "Sending URL to Grail...")
808 (save-excursion
809 (set-buffer (get-buffer-create " *Shell Command Output*"))
810 (erase-buffer)
811 ;; don't worry about this failing.
380a0a12
DL
812 (if new-window
813 (call-process browse-url-grail nil 0 nil "-b" url)
814 (call-process browse-url-grail nil 0 nil url))
96adeb99
RS
815 (message "Sending URL to Grail... done")))
816
817;; --- Mosaic using CCI ---
818
380a0a12 819;;;###autoload
a69315a1
RS
820(defun browse-url-cci (url &optional new-window)
821 "Ask the XMosaic WWW browser to load URL.
822Default to the URL around or before point.
823
824This function only works for XMosaic version 2.5 or later. You must
825select `CCI' from XMosaic's File menu, set the CCI Port Address to the
826value of variable `browse-url-CCI-port', and enable `Accept requests'.
827
828When called interactively, if variable `browse-url-new-window-p' is
829non-nil, load the document in a new browser window, otherwise use a
830random existing one. A non-nil interactive prefix argument reverses
5db57514 831the effect of `browse-url-new-window-p'.
a69315a1
RS
832
833When called non-interactively, optional second argument NEW-WINDOW is
5db57514 834used instead of `browse-url-new-window-p'."
96adeb99 835 (interactive (browse-url-interactive-arg "Mosaic URL: "))
a69315a1 836 (open-network-stream "browse-url" " *browse-url*"
96adeb99 837 browse-url-CCI-host browse-url-CCI-port)
a69315a1
RS
838 ;; Todo: start browser if fails
839 (process-send-string "browse-url"
5db57514 840 (concat "get url (" url ") output "
15eff622 841 (if new-window
837984b1
DL
842 "new"
843 "current")
844 "\r\n"))
a69315a1
RS
845 (process-send-string "browse-url" "disconnect\r\n")
846 (delete-process "browse-url"))
847
96adeb99
RS
848;; --- IXI Mosaic ---
849
850;;;###autoload
851(defun browse-url-iximosaic (url &optional new-window)
852 ;; new-window ignored
a69315a1
RS
853 "Ask the IXIMosaic WWW browser to load URL.
854Default to the URL around or before point."
855 (interactive (browse-url-interactive-arg "IXI Mosaic URL: "))
856 (start-process "tellw3b" nil "tellw3b"
5db57514 857 "-service WWW_BROWSER ixi_showurl " url))
a69315a1 858
96adeb99
RS
859;; --- W3 ---
860
861;;;###autoload
862(defun browse-url-w3 (url &optional new-window)
a69315a1 863 "Ask the w3 WWW browser to load URL.
e49172c8
DL
864Default to the URL around or before point.
865
866When called interactively, if variable `browse-url-new-window-p' is
867non-nil, load the document in a new window. A non-nil interactive
868prefix argument reverses the effect of `browse-url-new-window-p'.
869
870When called non-interactively, optional second argument NEW-WINDOW is
871used instead of `browse-url-new-window-p'."
a69315a1 872 (interactive (browse-url-interactive-arg "W3 URL: "))
e61d8515 873 (require 'w3) ; w3-fetch-other-window not autoloaded
15eff622 874 (if new-window
e61d8515 875 (w3-fetch-other-window url)
837984b1 876 (w3-fetch url)))
a69315a1 877
5db57514
RS
878;;;###autoload
879(defun browse-url-w3-gnudoit (url &optional new-window)
880 ;; new-window ignored
881 "Ask another Emacs running gnuserv to load the URL using the W3 browser.
882The `browse-url-gnudoit-program' program is used with options given by
883`browse-url-gnudoit-args'. Default to the URL around or before point."
884 (interactive (browse-url-interactive-arg "W3 URL: "))
885 (apply 'start-process (concat "gnudoit:" url) nil
886 browse-url-gnudoit-program
887 (append browse-url-gnudoit-args (list (concat "(w3-fetch \"" url "\")") "(raise-frame)"))))
888
96adeb99
RS
889;; --- Lynx in an xterm ---
890
891;;;###autoload
892(defun browse-url-lynx-xterm (url &optional new-window)
893 ;; new-window ignored
894 "Ask the Lynx WWW browser to load URL.
895Default to the URL around or before point. A new Lynx process is run
5db57514
RS
896in an Xterm window using the Xterm program named by `browse-url-xterm-program'
897with possible additional arguments `browse-url-xterm-args'."
96adeb99 898 (interactive (browse-url-interactive-arg "Lynx URL: "))
a43d1a2a
DL
899 (apply #'start-process `(,(concat "lynx" url) nil ,browse-url-xterm-program
900 ,@browse-url-xterm-args "-e" "lynx" ,url)))
96adeb99 901
96adeb99
RS
902;; --- Lynx in an Emacs "term" window ---
903
904;;;###autoload
837984b1 905(defun browse-url-lynx-emacs (url &optional new-buffer)
96adeb99 906 "Ask the Lynx WWW browser to load URL.
837984b1 907Default to the URL around or before point. With a prefix argument, run
e49172c8
DL
908a new Lynx process in a new buffer.
909
910When called interactively, if variable `browse-url-new-window-p' is
911non-nil, load the document in a new lynx in a new term window,
912otherwise use any existing one. A non-nil interactive prefix argument
913reverses the effect of `browse-url-new-window-p'.
914
915When called non-interactively, optional second argument NEW-WINDOW is
916used instead of `browse-url-new-window-p'."
96adeb99 917 (interactive (browse-url-interactive-arg "Lynx URL: "))
837984b1
DL
918 (let* ((system-uses-terminfo t) ; Lynx uses terminfo
919 ;; (term-term-name "vt100") ; ??
920 (buf (get-buffer "*lynx*"))
921 (proc (and buf (get-buffer-process buf)))
922 (n browse-url-lynx-input-attempts))
15eff622 923 (if (and new-buffer buf)
837984b1
DL
924 ;; Rename away the OLD buffer. This isn't very polite, but
925 ;; term insists on working in a buffer named *lynx* and would
926 ;; choke on *lynx*<1>
927 (progn (set-buffer buf)
928 (rename-uniquely)))
15eff622 929 (if (or new-buffer
837984b1
DL
930 (not buf)
931 (not proc)
932 (not (memq (process-status proc) '(run stop))))
933 ;; start a new lynx
a43d1a2a
DL
934 (progn
935 (setq buf
936 (apply #'make-term
937 `("lynx" "lynx" nil ,@browse-url-lynx-emacs-args ,url)))
938 (switch-to-buffer buf)
939 (term-char-mode)
940 (set-process-sentinel
941 (get-buffer-process buf)
942 ;; Don't leave around a dead one (especially because of its
943 ;; munged keymap.)
944 (lambda (process event)
945 (if (not (memq (process-status process) '(run stop)))
946 (let ((buf (process-buffer process)))
947 (if buf (kill-buffer buf)))))))
837984b1
DL
948 ;; send the url to lynx in the old buffer
949 (let ((win (get-buffer-window buf t)))
950 (if win
951 (select-window win)
952 (switch-to-buffer buf)))
953 (if (eq (following-char) ?_)
954 (cond ((eq browse-url-lynx-input-field 'warn)
955 (error "Please move out of the input field first."))
956 ((eq browse-url-lynx-input-field 'avoid)
957 (while (and (eq (following-char) ?_) (> n 0))
958 (term-send-down) ; down arrow
959 (sit-for browse-url-lynx-input-delay))
960 (if (eq (following-char) ?_)
961 (error "Cannot move out of the input field, sorry.")))))
962 (term-send-string proc (concat "g" ; goto
963 "\C-u" ; kill default url
964 url
965 "\r")))))
8bc9b4f1 966
5db57514
RS
967;; --- MMM ---
968
969;;;###autoload
970(defun browse-url-mmm (url &optional new-window)
971 "Ask the MMM WWW browser to load URL.
972Default to the URL around or before point."
973 (interactive (browse-url-interactive-arg "MMM URL: "))
974 (message "Sending URL to MMM...")
975 (save-excursion
976 (set-buffer (get-buffer-create " *Shell Command Output*"))
977 (erase-buffer)
978 ;; mmm_remote just SEGVs if the file isn't there...
979 (if (or (file-exists-p (expand-file-name "~/.mmm_remote"))
980 ;; location in v 0.4:
981 (file-exists-p (expand-file-name "~/.mmm/remote")))
982 (call-process "mmm_remote" nil 0 nil url)
983 (call-process "mmm" nil 0 nil "-external" url))
984 (message "Sending URL to MMM... done")))
985
986;; --- mailto ---
987
988;;;###autoload
59966fb6 989(defun browse-url-mail (url &optional new-window)
5db57514 990 "Open a new mail message buffer within Emacs.
59966fb6
RS
991Default to using the mailto: URL around or before point as the
992recipient's address. Supplying a non-nil interactive prefix argument
993will cause the mail to be composed in another window rather than the
e49172c8
DL
994current one.
995
996When called interactively, if variable `browse-url-new-window-p' is
997non-nil use `compose-mail-other-window', otherwise `compose-mail'. A
998non-nil interactive prefix argument reverses the effect of
999`browse-url-new-window-p'.
1000
1001When called non-interactively, optional second argument NEW-WINDOW is
1002used instead of `browse-url-new-window-p'."
5db57514
RS
1003 (interactive (browse-url-interactive-arg "Mailto URL: "))
1004 (save-excursion
685a6f2e 1005 (let ((to (if (string-match "^mailto:" url)
5db57514 1006 (substring url 7)
59966fb6 1007 url)))
15eff622 1008 (if new-window
e58883dd
RS
1009 (compose-mail-other-window to nil nil nil
1010 (list 'insert-buffer (current-buffer)))
1011 (compose-mail to nil nil nil nil
1012 (list 'insert-buffer (current-buffer)))))))
5db57514
RS
1013
1014;; --- Random browser ---
1015
1016;;;###autoload
1017(defun browse-url-generic (url &optional new-window)
1018 ;; new-window ignored
1019 "Ask the WWW browser defined by `browse-url-generic-program' to load URL.
1020Default to the URL around or before point. A fresh copy of the
1021browser is started up in a new process with possible additional arguments
1022`browse-url-generic-args'. This is appropriate for browsers which
1023don't offer a form of remote control."
1024 (interactive (browse-url-interactive-arg "URL: "))
1025 (if (not browse-url-generic-program)
1026 (error "No browser defined (`browse-url-generic-program')"))
1027 (apply 'start-process (concat browse-url-generic-program url) nil
1028 browse-url-generic-program
1029 (append browse-url-generic-args (list url))))
1030
a69315a1
RS
1031(provide 'browse-url)
1032
1033;;; browse-url.el ends here