(make-frame): Call `custom-initialize-frame'.
[emacs.git] / lisp / browse-url.el
blobd4e6988a38780ebb033efc6dbb241964cf10da2b
1 ;;; browse-url.el --- ask a WWW browser to load a URL
3 ;; Copyright 1995, 1996 Free Software Foundation, Inc.
5 ;; Author: Denis Howe <dbh@doc.ic.ac.uk>
6 ;; Maintainer: Denis Howe <dbh@doc.ic.ac.uk>
7 ;; Created: 03 Apr 1995
8 ;; Keywords: hypertext
9 ;; X-Home page: http://wombat.doc.ic.ac.uk/
11 ;; This file is part of GNU Emacs.
13 ;; GNU Emacs is free software; you can redistribute it and/or modify
14 ;; it under the terms of the GNU General Public License as published by
15 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; any later version.
18 ;; GNU Emacs is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;; GNU General Public License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with GNU Emacs; see the file COPYING. If not, write to the
25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 ;; Boston, MA 02111-1307, USA.
28 ;;; Commentary:
30 ;; The latest version of this package should be available from
31 ;; <URL:http://wombat.doc.ic.ac.uk/emacs/browse-url.el>.
33 ;; This package provides functions which read a URL (Uniform Resource
34 ;; Locator) from the minibuffer, defaulting to the URL around point,
35 ;; and ask a World-Wide Web browser to load it. It can also load the
36 ;; URL associated with the current buffer. Different browsers use
37 ;; different methods of remote control so there is one function for
38 ;; each supported browser. If the chosen browser is not running, it
39 ;; is started. Currently there is support for:
41 ;; Function Browser Earliest version
42 ;; browse-url-netscape Netscape 1.1b1
43 ;; browse-url-mosaic XMosaic <= 2.4
44 ;; browse-url-cci XMosaic 2.5
45 ;; browse-url-w3 w3 0
46 ;; browse-url-iximosaic IXI Mosaic ?
47 ;; browse-url-lynx-* Lynx 0
48 ;; browse-url-grail Grail 0.3b1
50 ;; Note that versions of Netscape before 1.1b1 did not have remote
51 ;; control. <URL:http://www.netscape.com/newsref/std/x-remote.html>
52 ;; and <URL:http://www.netscape.com/info/APIs/>.
54 ;; Netscape can cache Web pages so it may be necessary to tell it to
55 ;; reload the current page if it has changed (e.g. if you have edited
56 ;; it). There is currently no perfect automatic solution to this.
58 ;; Netscape allows you to specify the id of the window you want to
59 ;; control but which window DO you want to control and how do you
60 ;; discover its id?
62 ;; If using XMosaic before version 2.5, check the definition of
63 ;; browse-url-usr1-signal below.
64 ;; <URL:http://www.ncsa.uiuc.edu/SDG/Software/XMosaic/remote-control.html>
66 ;; XMosaic version 2.5 introduced Common Client Interface allowing you
67 ;; to control mosaic through Unix sockets.
68 ;; <URL:http://www.ncsa.uiuc.edu/SDG/Software/XMosaic/CCI/cci-spec.html>
70 ;; William M. Perry's excellent "w3" WWW browser for
71 ;; Emacs <URL:ftp://cs.indiana.edu/pub/elisp/w3/>
72 ;; has a function w3-follow-url-at-point, but that
73 ;; doesn't let you edit the URL like browse-url.
75 ;; I recommend Nelson Minar <nelson@santafe.edu>'s excellent
76 ;; html-helper-mode.el for editing HTML and thank Nelson for
77 ;; his many useful comments on this code.
78 ;; <URL:http://www.santafe.edu/~nelson/hhm-beta/>
80 ;; This package generalises function html-previewer-process in Marc
81 ;; Andreessen <marca@ncsa.uiuc.edu>'s html-mode (LCD
82 ;; modes/html-mode.el.Z) and provides better versions of the URL
83 ;; functions in Michelangelo Grigni <mic@cs.ucsd.edu>'s ffap.el
84 ;; (find-file-at-point) <URL:ftp://cs.ucsd.edu:/pub/mic/>. The huge
85 ;; hyperbole package also contains similar functions.
87 ;; Grail is the freely available WWW browser implemented in Python, a
88 ;; cool object-oriented freely available interpreted language. Grail
89 ;; 0.3b1 was the first version to have remote control as distributed.
90 ;; For more information on Grail see
91 ;; <URL:http://monty.cnri.reston.va.us/> and for more information on
92 ;; Python see <url:http://www.python.org/>. Grail support in
93 ;; browse-url.el written by Barry Warsaw <bwarsaw@python.org>.
95 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
96 ;; Help!
98 ;; Can you write and test some code for the Macintrash and Windoze
99 ;; Netscape remote control APIs? (See the URL above).
101 ;; Do any other browsers have remote control?
103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
104 ;; Usage
106 ;; To display the URL at or before point:
107 ;; M-x browse-url-at-point RET
109 ;; To display a URL by shift-clicking on it, put this in your ~/.emacs
110 ;; file:
111 ;; (global-set-key [S-mouse-2] 'browse-url-at-mouse)
112 ;; (Note that using Shift-mouse-1 is not desirable because
113 ;; that event has a standard meaning in Emacs.)
115 ;; To display the current buffer in a web browser:
116 ;; M-x browse-url-of-buffer RET
118 ;; In Dired, to display the file named on the current line:
119 ;; M-x browse-url-of-dired-file RET
121 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
122 ;; Customisation (~/.emacs)
124 ;; To see what variables are available for customization, type
125 ;; `M-x set-variable browse-url TAB'.
127 ;; Bind the browse-url commands to keys with the `C-c C-z' prefix
128 ;; (as used by html-helper-mode):
129 ;; (global-set-key "\C-c\C-z." 'browse-url-at-point)
130 ;; (global-set-key "\C-c\C-zb" 'browse-url-of-buffer)
131 ;; (global-set-key "\C-c\C-zu" 'browse-url)
132 ;; (global-set-key "\C-c\C-zv" 'browse-url-of-file)
133 ;; (add-hook 'dired-mode-hook
134 ;; (function (lambda ()
135 ;; (local-set-key "\C-c\C-zf" 'browse-url-of-dired-file))))
137 ;; Browse URLs in mail messages by clicking mouse-2:
138 ;; (add-hook 'rmail-mode-hook (function (lambda () ; rmail-mode startup
139 ;; (define-key rmail-mode-map [mouse-2] 'browse-url-at-mouse))))
141 ;; Browse URLs in Usenet messages by clicking mouse-2:
142 ;; (eval-after-load "gnus"
143 ;; '(define-key gnus-article-mode-map [mouse-2] 'browse-url-at-mouse))
145 ;; Use the Emacs w3 browser when not running under X11:
146 ;; (or (eq window-system 'x)
147 ;; (setq browse-url-browser-function 'browse-url-w3))
149 ;; To always save modified buffers before displaying the file in a browser:
150 ;; (setq browse-url-save-file t)
152 ;; To get round the Netscape caching problem, you could EITHER have
153 ;; write-file in html-helper-mode make Netscape reload the document:
155 ;; (autoload 'browse-url-netscape-reload "browse-url"
156 ;; "Ask a WWW browser to redisplay the current file." t)
157 ;; (add-hook 'html-helper-mode-hook
158 ;; (function (lambda ()
159 ;; (add-hook 'local-write-file-hooks
160 ;; (function (lambda ()
161 ;; (let ((local-write-file-hooks))
162 ;; (save-buffer))
163 ;; (browse-url-netscape-reload)
164 ;; t)) ; => file written by hook
165 ;; t)))) ; append to l-w-f-hooks
167 ;; OR have browse-url-of-file ask Netscape to load and then reload the
168 ;; file:
170 ;; (add-hook 'browse-url-of-file-hook 'browse-url-netscape-reload)
172 ;; You may also want to customise browse-url-netscape-arguments, e.g.
173 ;; (setq browse-url-netscape-arguments '("-install"))
175 ;; or similarly for the other browsers.
177 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
178 ;;; Change Log:
180 ;; 0.00 03 Apr 1995 Denis Howe <dbh@doc.ic.ac.uk>
181 ;; Created.
183 ;; 0.01 04 Apr 1995
184 ;; All names start with "browse-url-". Added provide.
186 ;; 0.02 05 Apr 1995
187 ;; Save file at start of browse-url-of-file.
188 ;; Use start-process instead of start-process-shell-command.
190 ;; 0.03 06 Apr 1995
191 ;; Add browse-url-netscape-reload, browse-url-netscape-send.
192 ;; browse-url-of-file save file option.
194 ;; 0.04 08 Apr 1995
195 ;; b-u-file-url separate function. Change b-u-filename-alist
196 ;; default.
198 ;; 0.05 09 Apr 1995
199 ;; Added b-u-of-file-hook.
201 ;; 0.06 11 Apr 1995
202 ;; Improved .emacs suggestions and documentation.
204 ;; 0.07 13 Apr 1995
205 ;; Added browse-url-interactive-arg optional prompt.
207 ;; 0.08 18 Apr 1995
208 ;; Exclude final "." from browse-url-regexp.
210 ;; 0.09 21 Apr 1995
211 ;; Added mouse-set-point to browse-url-interactive-arg.
213 ;; 0.10 24 Apr 1995
214 ;; Added Mosaic signal sending variations.
215 ;; Thanks Brian K Servis <servis@ecn.purdue.edu>.
216 ;; Don't use xprop for Netscape.
218 ;; 0.11 25 Apr 1995
219 ;; Fix reading of ~/.mosaicpid. Thanks Dag.H.Wanvik@kvatro.no.
221 ;; 0.12 27 Apr 1995
222 ;; Interactive prefix arg => URL *after* point.
223 ;; Thanks Michelangelo Grigni <mic@cs.ucsd.edu>.
224 ;; Added IXI Mosaic support.
225 ;; Thanks David Karr <dkarr@nmo.gtegsc.com>.
227 ;; 0.13 28 Apr 1995
228 ;; Exclude final [,;] from browse-url-regexp.
230 ;; 0.14 02 May 1995
231 ;; Provide browser argument variables.
233 ;; 0.15 07 May 1995
234 ;; More Netscape options. Thanks Peter Arius
235 ;; <arius@immd2.informatik.uni-erlangen.de>.
237 ;; 0.16 17 May 1995
238 ;; Added browse-url-at-mouse.
239 ;; Thanks Wayne Mesard <wmesard@sgi.com>
241 ;; 0.17 27 Jun 1995
242 ;; Renamed browse-url-at-point to browse-url-url-at-point.
243 ;; Added browse-url-at-point.
244 ;; Thanks Jonathan Cano <cano@patch.tandem.com>.
246 ;; 0.18 16 Aug 1995
247 ;; Fixed call to browse-url-url-at-point in browse-url-at-point.
248 ;; Thanks Eric Ding <ericding@San-Jose.ate.slb.com>.
250 ;; 0.19 24 Aug 1995
251 ;; Improved documentation.
252 ;; Thanks Kevin Rodgers <kevin.rodgers@ihs.com>.
254 ;; 0.20 31 Aug 1995
255 ;; browse-url-of-buffer to handle file-less buffers.
256 ;; browse-url-of-dired-file browses current file in dired.
257 ;; Thanks Kevin Rodgers <kevin.rodgers@ihs.com>.
259 ;; 0.21 09 Sep 1995
260 ;; XMosaic CCI functions.
261 ;; Thanks Marc Furrer <Marc.Furrer@di.epfl.ch>.
263 ;; 0.22 13 Sep 1995
264 ;; Fixed new-window documentation and added to browse-url-cci.
265 ;; Thanks Dilip Sequeira <djs@dcs.ed.ac.uk>.
267 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
268 ;;; Code:
270 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
271 ;; Variables
273 (eval-when-compile (require 'dired))
275 (defvar browse-url-path-regexp
276 "[^]\t\n \"'()<>[^`{}]*[^]\t\n \"'()<>[^`{}.,;]+"
277 "A regular expression probably matching the host, path or e-mail
278 part of a URL.")
280 (defvar browse-url-short-regexp
281 (concat "[-A-Za-z0-9.]+" browse-url-path-regexp)
282 "A regular expression probably matching a URL without an access scheme.
283 Hostname matching is stricter in this case than for
284 ``browse-url-regexp''.")
286 (defvar browse-url-regexp
287 (concat
288 "\\(https?://\\|ftp://\\|gopher://\\|telnet://\\|wais://\\|file:/\\|s?news:\\|mailto:\\)"
289 browse-url-path-regexp)
290 "A regular expression probably matching a complete URL.")
293 ;;;###autoload
294 (defvar browse-url-browser-function
295 'browse-url-netscape
296 "*Function to display the current buffer in a WWW browser.
297 Used by the `browse-url-at-point', `browse-url-at-mouse', and
298 `browse-url-of-file' commands.")
300 (defvar browse-url-netscape-command "netscape"
301 "*The name by which to invoke Netscape.")
303 (defvar browse-url-netscape-arguments nil
304 "*A list of strings to pass to Netscape as arguments.")
306 (defvar browse-url-netscape-startup-arguments browse-url-netscape-arguments
307 "*A list of strings to pass to Netscape when it starts up.
308 Defaults to the value of browse-url-netscape-arguments at the time
309 browse-url is loaded.")
311 (defvar browse-url-new-window-p nil
312 "*If non-nil, always open a new browser window.
313 Passing an interactive argument to \\[browse-url-netscape] or
314 \\[browse-url-cci] reverses the effect of this variable. Requires
315 Netscape version 1.1N or later or XMosaic version 2.5 or later.")
317 (defvar browse-url-mosaic-arguments nil
318 "*A list of strings to pass to Mosaic as arguments.")
320 (defvar browse-url-filename-alist
321 '(("^/+" . "file:/"))
322 "An alist of (REGEXP . STRING) pairs.
323 Any substring of a filename matching one of the REGEXPs is replaced by
324 the corresponding STRING. All pairs are applied in the order given.
325 The default value prepends `file:' to any path beginning with `/'.
326 Used by the `browse-url-of-file' command.")
328 (defvar browse-url-save-file nil
329 "If non-nil, save the buffer before displaying its file.
330 Used by the `browse-url-of-file' command.")
332 (defvar browse-url-of-file-hook nil
333 "A hook to be run with run-hook after `browse-url-of-file' has asked
334 a browser to load a file.
336 Set this to `browse-url-netscape-reload' to force Netscape to load the
337 file rather than displaying a cached copy.")
339 (defvar browse-url-usr1-signal
340 (if (and (boundp 'emacs-major-version)
341 (or (> emacs-major-version 19) (>= emacs-minor-version 29)))
342 'SIGUSR1 ; Why did I think this was in lower case before?
343 30) ; Check /usr/include/signal.h.
344 "The argument to `signal-process' for sending SIGUSR1 to XMosaic.
345 Emacs 19.29 accepts 'SIGUSR1, earlier versions require an integer
346 which is 30 on SunOS and 16 on HP-UX and Solaris.")
348 (defvar browse-url-CCI-port 3003
349 "Port to access XMosaic via CCI.
350 This can be any number between 1024 and 65535 but must correspond to
351 the value set in the browser.")
353 (defvar browse-url-CCI-host "localhost"
354 "*Host to access XMosaic via CCI.
355 This should be the host name of the machine running XMosaic with CCI
356 enabled. The port number should be set in `browse-url-CCI-port'.")
358 (defvar browse-url-temp-file-name nil)
359 (make-variable-buffer-local 'browse-url-temp-file-name)
361 (defvar browse-url-temp-file-list '())
363 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
364 ;; URL input
366 ;; thingatpt.el doesn't work for complex regexps
368 (defun browse-url-url-at-point ()
369 "Return the URL around or before point.
370 Search backwards for the start of a URL ending at or after
371 point. If no URL found, return the empty string.
372 A file name is also acceptable, and `http://' will be prepended to it."
373 (or (thing-at-point 'url)
374 (let ((file (thing-at-point 'filename)))
375 (if file (concat "http://" file)))
376 ""))
378 ;; Having this as a separate function called by the browser-specific
379 ;; functions allows them to be stand-alone commands, making it easier
380 ;; to switch between browsers.
382 (defun browse-url-interactive-arg (prompt)
383 "Read a URL from the minibuffer, prompting with PROMPT.
384 Default to the URL at or before point. If invoke with a mouse button,
385 set point to the position clicked first. Return a list for use in
386 `interactive' containing the URL and browse-url-new-window-p or its
387 negation if a prefix argument was given."
388 (let ((event (elt (this-command-keys) 0)))
389 (and (listp event) (mouse-set-point event)))
390 (list (read-string prompt (browse-url-url-at-point))
391 (not (eq (null browse-url-new-window-p)
392 (null current-prefix-arg)))))
394 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
395 ;; Browse current buffer
397 ;;;###autoload
398 (defun browse-url-of-file (&optional file)
399 "Ask a WWW browser to display FILE.
400 Display the current buffer's file if FILE is nil or if called
401 interactively. Turn the filename into a URL with function
402 browse-url-file-url. Pass the URL to a browser using variable
403 `browse-url-browser-function' then run `browse-url-of-file-hook'."
404 (interactive)
405 (or file
406 (setq file (buffer-file-name))
407 (error "Current buffer has no file"))
408 (let ((buf (get-file-buffer file)))
409 (if buf
410 (save-excursion
411 (set-buffer buf)
412 (cond ((not (buffer-modified-p)))
413 (browse-url-save-file (save-buffer))
414 (t (message "%s modified since last save" file))))))
415 (funcall browse-url-browser-function (browse-url-file-url file))
416 (run-hooks 'browse-url-of-file-hook))
418 (defun browse-url-file-url (file)
419 "Return the URL corresponding to FILE.
420 Use variable `browse-url-filename-alist' to map filenames to URLs.
421 Convert EFS file names of the form /USER@HOST:PATH to ftp://HOST/PATH."
422 ;; URL-encode special chars, do % first
423 (let ((s 0))
424 (while (setq s (string-match "%" file s))
425 (setq file (replace-match "%25" t t file)
426 s (1+ s))))
427 (while (string-match "[*\"()',=;? ]" file)
428 (let ((enc (format "%%%x" (aref file (match-beginning 0)))))
429 (setq file (replace-match enc t t file))))
430 (let ((maps browse-url-filename-alist))
431 (while maps
432 (let* ((map (car maps))
433 (from-re (car map))
434 (to-string (cdr map)))
435 (setq maps (cdr maps))
436 (and (string-match from-re file)
437 (setq file (replace-match to-string t t file))))))
438 ;; Check for EFS path
439 (and (string-match "^/\\([^:@]+@\\)?\\([^:]+\\):/*" file)
440 (setq file (concat "ftp://"
441 (substring file (match-beginning 2) (match-end 2))
442 "/" (substring file (match-end 0)))))
443 file)
445 ;;;###autoload
446 (defun browse-url-of-buffer (&optional buffer)
447 "Ask a WWW browser to display BUFFER.
448 Display the current buffer if BUFFER is nil."
449 (interactive)
450 (save-excursion
451 (and buffer (set-buffer buffer))
452 (let ((file-name
453 (or buffer-file-name
454 (and (boundp 'dired-directory) dired-directory))))
455 (or file-name
456 (progn
457 (or browse-url-temp-file-name
458 (setq browse-url-temp-file-name
459 (make-temp-name
460 (expand-file-name (buffer-name)
461 (or (getenv "TMPDIR") "/tmp")))
462 browse-url-temp-file-list
463 (cons browse-url-temp-file-name
464 browse-url-temp-file-list)))
465 (setq file-name browse-url-temp-file-name)
466 (write-region (point-min) (point-max) file-name nil 'no-message)))
467 (browse-url-of-file file-name))))
469 (defun browse-url-delete-temp-file (&optional temp-file-name)
470 ;; Delete browse-url-temp-file-name from the file system and from
471 ;; browse-url-temp-file-list. If optional arg TEMP-FILE-NAME is
472 ;; non-nil, delete it instead, but only from the file system --
473 ;; browse-url-temp-file-list is not affected.
474 (let ((file-name (or temp-file-name browse-url-temp-file-name)))
475 (if (and file-name (file-exists-p file-name))
476 (progn
477 (delete-file file-name)
478 (if (null temp-file-name)
479 (setq browse-url-temp-file-list
480 (delete browse-url-temp-file-name
481 browse-url-temp-file-list)))))))
483 (defun browse-url-delete-temp-file-list ()
484 ;; Delete all elements of browse-url-temp-file-list.
485 (while browse-url-temp-file-list
486 (browse-url-delete-temp-file (car browse-url-temp-file-list))
487 (setq browse-url-temp-file-list
488 (cdr browse-url-temp-file-list))))
490 (add-hook 'kill-buffer-hook 'browse-url-delete-temp-file)
491 (add-hook 'kill-emacs-hook 'browse-url-delete-temp-file-list)
493 ;;;###autoload
494 (defun browse-url-of-dired-file ()
495 "In Dired, ask a WWW browser to display the file named on this line."
496 (interactive)
497 (browse-url-of-file (dired-get-filename)))
499 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
500 ;; Browser-independant commands
502 ;; A generic command to call the current b-u-browser-function
504 (defun browse-url (&rest args)
505 "Ask a WWW browser to load URL.
506 Prompts for a URL, defaulting to the URL at or before point. Variable
507 `browse-url-browser-function' says which browser to use."
508 (interactive (browse-url-interactive-arg "URL: "))
509 (apply browse-url-browser-function args))
511 ;;;###autoload
512 (defun browse-url-at-point ()
513 "Ask a WWW browser to load the URL at or before point.
514 Doesn't let you edit the URL like browse-url. Variable
515 `browse-url-browser-function' says which browser to use."
516 (interactive)
517 (funcall browse-url-browser-function (browse-url-url-at-point)))
519 ;; Define these if not already defined (XEmacs compatibility)
521 (eval-and-compile
522 (or (fboundp 'event-buffer)
523 (defun event-buffer (event)
524 (window-buffer (posn-window (event-start event))))))
526 (eval-and-compile
527 (or (fboundp 'event-point)
528 (defun event-point (event)
529 (posn-point (event-start event)))))
531 ;;;###autoload
532 (defun browse-url-at-mouse (event)
533 "Ask a WWW browser to load a URL clicked with the mouse.
534 The URL is the one around or before the position of the mouse click
535 but point is not changed. Doesn't let you edit the URL like
536 browse-url. Variable `browse-url-browser-function' says which browser
537 to use."
538 (interactive "e")
539 (save-excursion
540 (set-buffer (event-buffer event))
541 (goto-char (event-point event))
542 (let ((url (browse-url-url-at-point)))
543 (if (string-equal url "")
544 (error "No URL found"))
545 (funcall browse-url-browser-function url))))
547 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
548 ;; Browser-specific commands
550 ;; --- Netscape ---
552 ;; Put the correct DISPLAY value in the environment for Netscape
553 ;; launched from multi-display Emacs.
555 (defun browse-url-process-environment ()
556 (let* ((device (and (fboundp 'selected-device)
557 (fboundp 'device-connection)
558 (selected-device)))
559 (display (and device (fboundp 'device-type)
560 (eq (device-type device) 'x)
561 (not (equal (device-connection device)
562 (getenv "DISPLAY"))))))
563 (if display
564 ;; Attempt to run on the correct display
565 (cons (concat "DISPLAY=" (device-connection device))
566 process-environment)
567 process-environment)))
570 ;;;###autoload
571 (defun browse-url-netscape (url &optional new-window)
572 "Ask the Netscape WWW browser to load URL.
574 Default to the URL around or before point. The strings in variable
575 `browse-url-netscape-arguments' are also passed to Netscape.
577 When called interactively, if variable `browse-url-new-window-p' is
578 non-nil, load the document in a new Netscape window, otherwise use a
579 random existing one. A non-nil interactive prefix argument reverses
580 the effect of browse-url-new-window-p.
582 When called non-interactively, optional second argument NEW-WINDOW is
583 used instead of browse-url-new-window-p."
584 (interactive (browse-url-interactive-arg "Netscape URL: "))
585 ;; URL encode any commas in the URL
586 (while (string-match "," url)
587 (setq url (replace-match "%2C" t t url)))
588 (let* ((process-environment (browse-url-process-environment))
589 (process (apply 'start-process
590 (concat "netscape " url) nil
591 browse-url-netscape-command
592 (append browse-url-netscape-arguments
593 (if new-window '("-noraise"))
594 (list "-remote"
595 (concat "openURL(" url
596 (if new-window ",new-window")
597 ")"))))))
598 (set-process-sentinel process
599 (list 'lambda '(process change)
600 (list 'browse-url-netscape-sentinel 'process url)))))
602 (defun browse-url-netscape-sentinel (process url)
603 "Handle a change to the process communicating with Netscape."
604 (or (eq (process-exit-status process) 0)
605 (let* ((process-environment (browse-url-process-environment)))
606 ;; Netscape not running - start it
607 (message "Starting Netscape...")
608 (apply 'start-process (concat "netscape" url) nil
609 browse-url-netscape-command
610 (append browse-url-netscape-startup-arguments (list url))))))
612 (defun browse-url-netscape-reload ()
613 "Ask Netscape to reload its current document."
614 (interactive)
615 (browse-url-netscape-send "reload"))
617 (defun browse-url-netscape-send (command)
618 "Send a remote control command to Netscape."
619 (let* ((process-environment (browse-url-process-environment)))
620 (apply 'start-process "netscape" nil
621 browse-url-netscape-command
622 (append browse-url-netscape-arguments
623 (list "-remote" command)))))
625 ;; --- Mosaic ---
627 ;;;###autoload
628 (defun browse-url-mosaic (url &optional new-window)
629 ;; new-window ignored
630 "Ask the XMosaic WWW browser to load URL.
631 Default to the URL around or before point."
632 (interactive (browse-url-interactive-arg "Mosaic URL: "))
633 (let ((pidfile (expand-file-name "~/.mosaicpid"))
634 pid pidbuf)
635 (if (file-readable-p pidfile)
636 (save-excursion
637 (find-file pidfile)
638 (goto-char (point-min))
639 (setq pid (read (current-buffer)))
640 (kill-buffer nil)))
641 (if (and pid (zerop (signal-process pid 0))) ; Mosaic running
642 (save-excursion
643 (find-file (format "/tmp/Mosaic.%d" pid))
644 (erase-buffer)
645 (insert "goto\n" url "\n")
646 (save-buffer)
647 (kill-buffer nil)
648 ;; Send signal SIGUSR to Mosaic
649 (message "Signalling Mosaic...")
650 (signal-process pid browse-url-usr1-signal)
651 ;; Or you could try:
652 ;; (call-process "kill" nil 0 nil "-USR1" (int-to-string pid))
653 (message "Signalling Mosaic...done")
655 ;; Mosaic not running - start it
656 (message "Starting Mosaic...")
657 (apply 'start-process "xmosaic" nil "xmosaic"
658 (append browse-url-mosaic-arguments (list url)))
659 (message "Starting Mosaic...done"))))
661 ;; --- Grail ---
663 ;;;###autoload
664 (defvar browse-url-grail
665 (concat (or (getenv "GRAILDIR") "~/.grail") "/user/rcgrail.py")
666 "*Location of Grail remote control client script `rcgrail.py'.
667 Typically found in $GRAILDIR/rcgrail.py, or ~/.grail/user/rcgrail.py.")
669 ;;;###autoload
670 (defun browse-url-grail (url)
671 "Ask the Grail WWW browser to load URL.
672 Default to the URL around or before point. Runs the program in the
673 variable `browse-url-grail'."
674 (interactive (browse-url-interactive-arg "Grail URL: "))
675 (message "Sending URL to Grail...")
676 (save-excursion
677 (set-buffer (get-buffer-create " *Shell Command Output*"))
678 (erase-buffer)
679 ;; don't worry about this failing.
680 (call-process browse-url-grail nil 0 nil url)
681 (message "Sending URL to Grail... done")))
683 ;; --- Mosaic using CCI ---
685 (defun browse-url-cci (url &optional new-window)
686 "Ask the XMosaic WWW browser to load URL.
687 Default to the URL around or before point.
689 This function only works for XMosaic version 2.5 or later. You must
690 select `CCI' from XMosaic's File menu, set the CCI Port Address to the
691 value of variable `browse-url-CCI-port', and enable `Accept requests'.
693 When called interactively, if variable `browse-url-new-window-p' is
694 non-nil, load the document in a new browser window, otherwise use a
695 random existing one. A non-nil interactive prefix argument reverses
696 the effect of browse-url-new-window-p.
698 When called non-interactively, optional second argument NEW-WINDOW is
699 used instead of browse-url-new-window-p."
700 (interactive (browse-url-interactive-arg "Mosaic URL: "))
701 (open-network-stream "browse-url" " *browse-url*"
702 browse-url-CCI-host browse-url-CCI-port)
703 ;; Todo: start browser if fails
704 (process-send-string "browse-url"
705 (concat "get url (" url ") output "
706 (if new-window "new" "current") "\r\n"))
707 (process-send-string "browse-url" "disconnect\r\n")
708 (delete-process "browse-url"))
710 ;; --- IXI Mosaic ---
712 ;;;###autoload
713 (defun browse-url-iximosaic (url &optional new-window)
714 ;; new-window ignored
715 "Ask the IXIMosaic WWW browser to load URL.
716 Default to the URL around or before point."
717 (interactive (browse-url-interactive-arg "IXI Mosaic URL: "))
718 (start-process "tellw3b" nil "tellw3b"
719 "-service WWW_BROWSER ixi_showurl " url))
721 ;; --- W3 ---
723 ;;;###autoload
724 (defun browse-url-w3 (url &optional new-window)
725 ;; new-window ignored
726 "Ask the w3 WWW browser to load URL.
727 Default to the URL around or before point."
728 (interactive (browse-url-interactive-arg "W3 URL: "))
729 (w3-fetch url))
731 ;; --- Lynx in an xterm ---
733 ;;;###autoload
734 (defun browse-url-lynx-xterm (url &optional new-window)
735 ;; new-window ignored
736 "Ask the Lynx WWW browser to load URL.
737 Default to the URL around or before point. A new Lynx process is run
738 in an Xterm window."
739 (interactive (browse-url-interactive-arg "Lynx URL: "))
740 (start-process (concat "lynx" url) nil "xterm" "-e" "lynx" url))
742 (eval-when-compile (require 'term))
744 ;; --- Lynx in an Emacs "term" window ---
746 ;;;###autoload
747 (defun browse-url-lynx-emacs (url &optional new-window)
748 ;; new-window ignored
749 "Ask the Lynx WWW browser to load URL.
750 Default to the URL around or before point. Run a new Lynx process in
751 an Emacs buffer."
752 (interactive (browse-url-interactive-arg "Lynx URL: "))
753 (let ((system-uses-terminfo t)) ; Lynx uses terminfo
754 (if (fboundp 'make-term)
755 (let ((term-term-name "vt100"))
756 (set-buffer (make-term "browse-url" "lynx" nil url))
757 (term-mode)
758 (term-char-mode)
759 (switch-to-buffer "*browse-url*"))
760 (terminal-emulator "*browse-url*" "lynx" (list url)))))
762 (provide 'browse-url)
764 ;;; browse-url.el ends here