aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1996-10-11 02:32:17 +0000
committerRichard M. Stallman1996-10-11 02:32:17 +0000
commit96adeb99c9ef03a7365a259254473aac117da8be (patch)
tree8e9a130511474e50b9285634e8886c1b429738b4
parentbfc6cac943420b0f643075cbeeb5d60c0bd4e027 (diff)
downloademacs-96adeb99c9ef03a7365a259254473aac117da8be.tar.gz
emacs-96adeb99c9ef03a7365a259254473aac117da8be.zip
(browse-url): New function.
(browse-url-CCI-host): New variable. (browse-url-at-mouse): Added event-buffer and event-point functions for XEmacs compatibility. (browse-url-file-url): Check for EFS after alist, URL-encode special chars. (browse-url-grail): New function. (browse-url-interactive-arg): Add new-window logic. (browse-url-looking-at): Fixed. (browse-url-lynx-xterm): New function. (browse-url-lynx-emacs): Use term.el instead of terminal.el. (browse-url-netscape): Contact/start Netscape in the background. Multi-display support. Renamed browse-url-netscape-send. URL-encode comma. (browse-url-netscape-command): New variable. (browse-url-netscape-startup-arguments): New variable. (browse-url-url-at-point): Improved matching to supply missing "http://". Other fixes for byte-compilation.
-rw-r--r--lisp/browse-url.el492
1 files changed, 341 insertions, 151 deletions
diff --git a/lisp/browse-url.el b/lisp/browse-url.el
index 6d7ef6fe6a0..cc51a9a6bfa 100644
--- a/lisp/browse-url.el
+++ b/lisp/browse-url.el
@@ -44,13 +44,15 @@
44;; browse-url-cci XMosaic 2.5 44;; browse-url-cci XMosaic 2.5
45;; browse-url-w3 w3 0 45;; browse-url-w3 w3 0
46;; browse-url-iximosaic IXI Mosaic ? 46;; browse-url-iximosaic IXI Mosaic ?
47;; browse-url-lynx-* Lynx 0
48;; browse-url-grail Grail 0.3b1
47 49
48;; Note that versions of Netscape before 1.1b1 did not have remote 50;; Note that versions of Netscape before 1.1b1 did not have remote
49;; control. <URL:http://home.netscape.com/newsref/std/x-remote.html> 51;; control. <URL:http://www.netscape.com/newsref/std/x-remote.html>
50;; and <URL:http://home.netscape.com/info/APIs/>. 52;; and <URL:http://www.netscape.com/info/APIs/>.
51 53
52;; Netscape can cache Web pages so it may be necessary to tell it to 54;; Netscape can cache Web pages so it may be necessary to tell it to
53;; reload the current page if it has changed (eg. if you have edited 55;; reload the current page if it has changed (e.g. if you have edited
54;; it). There is currently no perfect automatic solution to this. 56;; it). There is currently no perfect automatic solution to this.
55 57
56;; Netscape allows you to specify the id of the window you want to 58;; Netscape allows you to specify the id of the window you want to
@@ -82,6 +84,14 @@
82;; (find-file-at-point) <URL:ftp://cs.ucsd.edu:/pub/mic/>. The huge 84;; (find-file-at-point) <URL:ftp://cs.ucsd.edu:/pub/mic/>. The huge
83;; hyperbole package also contains similar functions. 85;; hyperbole package also contains similar functions.
84 86
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>.
94
85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 95;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
86;; Help! 96;; Help!
87 97
@@ -91,6 +101,22 @@
91;; Do any other browsers have remote control? 101;; Do any other browsers have remote control?
92 102
93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
104;; Installation
105
106;; Put the following in your ~/.emacs file:
107;;
108;; (autoload 'browse-url-at-point "browse-url"
109;; "Ask a WWW browser to load the URL at or before point." t)
110;; (autoload 'browse-url-at-mouse "browse-url"
111;; "Ask a WWW browser to load a URL clicked with the mouse." t)
112;; (autoload 'browse-url-of-buffer "browse-url"
113;; "Ask a WWW browser to display BUFFER." t)
114;; (autoload 'browse-url-of-file "browse-url"
115;; "Ask a WWW browser to display FILE." t)
116;; (autoload 'browse-url-of-dired-file "browse-url"
117;; "In Dired, ask a WWW browser to display the file named on this line." t)
118
119;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
94;; Usage 120;; Usage
95 121
96;; To display the URL at or before point: 122;; To display the URL at or before point:
@@ -111,32 +137,36 @@
111;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 137;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
112;; Customisation (~/.emacs) 138;; Customisation (~/.emacs)
113 139
114;; To see what variables are available for customization, type `M-x 140;; To see what variables are available for customization, type
115;; set-variable browse-url TAB'. 141;; `M-x set-variable browse-url TAB'.
116 142
117;; To bind the browse-url commands to keys with the `C-c u' prefix: 143;; Bind the browse-url commands to keys with the `C-c C-z' prefix
118;; (global-set-key "\C-cu." 'browse-url-at-point) 144;; (as used by html-helper-mode):
119;; (global-set-key "\C-cub" 'browse-url-of-buffer) 145;; (global-set-key "\C-c\C-z." 'browse-url-at-point)
120;; (global-set-key "\C-cuf" 'browse-url-of-file) 146;; (global-set-key "\C-c\C-zb" 'browse-url-of-buffer)
147;; (global-set-key "\C-c\C-zu" 'browse-url)
148;; (global-set-key "\C-c\C-zv" 'browse-url-of-file)
121;; (add-hook 'dired-mode-hook 149;; (add-hook 'dired-mode-hook
122;; (lambda () 150;; (function (lambda ()
123;; (local-set-key "\C-cuf" 'browse-url-of-dired-file)))) 151;; (local-set-key "\C-c\C-zf" 'browse-url-of-dired-file))))
124;; (if (boundp 'browse-url-browser-function) 152
125;; (global-set-key "\C-cuu" browse-url-browser-function) 153;; Browse URLs in mail messages by clicking mouse-2:
126;; (eval-after-load 154;; (add-hook 'rmail-mode-hook (function (lambda () ; rmail-mode startup
127;; "browse-url" 155;; (define-key rmail-mode-map [mouse-2] 'browse-url-at-mouse))))
128;; '(global-set-key "\C-cuu" browse-url-browser-function))) 156
129 157;; Browse URLs in Usenet messages by clicking mouse-2:
130;; To use the Emacs w3 browser when not running under X11: 158;; (eval-after-load "gnus"
131;; (if (not (eq window-system 'x)) 159;; '(define-key gnus-article-mode-map [mouse-2] 'browse-url-at-mouse))
160
161;; Use the Emacs w3 browser when not running under X11:
162;; (or (eq window-system 'x)
132;; (setq browse-url-browser-function 'browse-url-w3)) 163;; (setq browse-url-browser-function 'browse-url-w3))
133 164
134;; To always save modified buffers before displaying the file in a browser: 165;; To always save modified buffers before displaying the file in a browser:
135;; (setq browse-url-save-file t) 166;; (setq browse-url-save-file t)
136 167
137;; To get round the Netscape caching problem, you could try either of 168;; To get round the Netscape caching problem, you could EITHER have
138;; the following (but not both). EITHER write-file in 169;; write-file in html-helper-mode make Netscape reload the document:
139;; html-helper-mode makes Netscape reload document:
140;; 170;;
141;; (autoload 'browse-url-netscape-reload "browse-url" 171;; (autoload 'browse-url-netscape-reload "browse-url"
142;; "Ask a WWW browser to redisplay the current file." t) 172;; "Ask a WWW browser to redisplay the current file." t)
@@ -150,15 +180,12 @@
150;; t)) ; => file written by hook 180;; t)) ; => file written by hook
151;; t)))) ; append to l-w-f-hooks 181;; t)))) ; append to l-w-f-hooks
152;; 182;;
153;; [Does this work for html-mode too?] 183;; OR have browse-url-of-file ask Netscape to load and then reload the
154;;
155;; OR browse-url-of-file ask Netscape to load and then reload the
156;; file: 184;; file:
157;; 185;;
158;; (add-hook 'browse-url-of-file-hook 'browse-url-netscape-reload) 186;; (add-hook 'browse-url-of-file-hook 'browse-url-netscape-reload)
159 187
160;; You may also want to customise browse-url-netscape-arguments, eg. 188;; You may also want to customise browse-url-netscape-arguments, e.g.
161;;
162;; (setq browse-url-netscape-arguments '("-install")) 189;; (setq browse-url-netscape-arguments '("-install"))
163;; 190;;
164;; or similarly for the other browsers. 191;; or similarly for the other browsers.
@@ -177,7 +204,7 @@
177;; Use start-process instead of start-process-shell-command. 204;; Use start-process instead of start-process-shell-command.
178 205
179;; 0.03 06 Apr 1995 206;; 0.03 06 Apr 1995
180;; Add browse-url-netscape-reload, browse-url-netscape-command. 207;; Add browse-url-netscape-reload, browse-url-netscape-send.
181;; browse-url-of-file save file option. 208;; browse-url-of-file save file option.
182 209
183;; 0.04 08 Apr 1995 210;; 0.04 08 Apr 1995
@@ -256,32 +283,53 @@
256;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 283;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
257;;; Code: 284;;; Code:
258 285
286;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
287;; Variables
288
289(eval-when-compile (require 'dired))
290
291(defvar browse-url-path-regexp
292 "[^]\t\n \"'()<>[^`{}]*[^]\t\n \"'()<>[^`{}.,;]+"
293 "A regular expression probably matching the host, path or e-mail
294part of a URL.")
295
296(defvar browse-url-short-regexp
297 (concat "[-A-Za-z0-9.]+" browse-url-path-regexp)
298 "A regular expression probably matching a URL without an access scheme.
299Hostname matching is stricter in this case than for
300``browse-url-regexp''.")
301
259(defvar browse-url-regexp 302(defvar browse-url-regexp
260 "\\(https?://\\|ftp://\\|gopher://\\|telnet://\\|wais://\\|file:/\\|s?news:\\|mailto:\\)[^]\t\n \"'()<>[^`{}]*[^]\t\n \"'()<>[^`{}.,;]+" 303 (concat
261 "A regular expression probably matching a URL.") 304 "\\(https?://\\|ftp://\\|gopher://\\|telnet://\\|wais://\\|file:/\\|s?news:\\|mailto:\\)"
305 browse-url-path-regexp)
306 "A regular expression probably matching a complete URL.")
262 307
308
309;;;###autoload
263(defvar browse-url-browser-function 310(defvar browse-url-browser-function
264 'browse-url-choose-browser 311 'browse-url-netscape
265 "*Function to display the current buffer in a WWW browser. 312 "*Function to display the current buffer in a WWW browser.
266This is used by the `browse-url-at-point', `browse-url-at-mouse', and 313Used by the `browse-url-at-point', `browse-url-at-mouse', and
267`browse-url-of-file' commands. 314`browse-url-of-file' commands.")
268The function should take one argument, an URL.")
269 315
270(defvar browse-url-netscape-program "netscape" 316(defvar browse-url-netscape-command "netscape"
271 "*The name for invoking Netscape.") 317 "*The name by which to invoke Netscape.")
272 318
273(defvar browse-url-netscape-arguments nil 319(defvar browse-url-netscape-arguments nil
274 "*A list of strings to pass to Netscape as arguments.") 320 "*A list of strings to pass to Netscape as arguments.")
275 321
322(defvar browse-url-netscape-startup-arguments browse-url-netscape-arguments
323 "*A list of strings to pass to Netscape when it starts up.
324Defaults to the value of browse-url-netscape-arguments at the time
325browse-url is loaded.")
326
276(defvar browse-url-new-window-p nil 327(defvar browse-url-new-window-p nil
277 "*If non-nil, always open a new browser window. 328 "*If non-nil, always open a new browser window.
278Passing an interactive argument to \\[browse-url-netscape] or 329Passing an interactive argument to \\[browse-url-netscape] or
279\\[browse-url-cci] reverses the effect of this variable. Requires 330\\[browse-url-cci] reverses the effect of this variable. Requires
280Netscape version 1.1N or later or XMosaic version 2.5 or later.") 331Netscape version 1.1N or later or XMosaic version 2.5 or later.")
281 332
282(defvar browse-url-mosaic-program "xmosaic"
283 "*The name for invoking Mosaic.")
284
285(defvar browse-url-mosaic-arguments nil 333(defvar browse-url-mosaic-arguments nil
286 "*A list of strings to pass to Mosaic as arguments.") 334 "*A list of strings to pass to Mosaic as arguments.")
287 335
@@ -290,6 +338,7 @@ Netscape version 1.1N or later or XMosaic version 2.5 or later.")
290 "An alist of (REGEXP . STRING) pairs. 338 "An alist of (REGEXP . STRING) pairs.
291Any substring of a filename matching one of the REGEXPs is replaced by 339Any substring of a filename matching one of the REGEXPs is replaced by
292the corresponding STRING. All pairs are applied in the order given. 340the corresponding STRING. All pairs are applied in the order given.
341The default value prepends `file:' to any path beginning with `/'.
293Used by the `browse-url-of-file' command.") 342Used by the `browse-url-of-file' command.")
294 343
295(defvar browse-url-save-file nil 344(defvar browse-url-save-file nil
@@ -306,7 +355,7 @@ file rather than displaying a cached copy.")
306(defvar browse-url-usr1-signal 355(defvar browse-url-usr1-signal
307 (if (and (boundp 'emacs-major-version) 356 (if (and (boundp 'emacs-major-version)
308 (or (> emacs-major-version 19) (>= emacs-minor-version 29))) 357 (or (> emacs-major-version 19) (>= emacs-minor-version 29)))
309 'SIGUSR1 358 'SIGUSR1 ; Why did I think this was in lower case before?
310 30) ; Check /usr/include/signal.h. 359 30) ; Check /usr/include/signal.h.
311 "The argument to `signal-process' for sending SIGUSR1 to XMosaic. 360 "The argument to `signal-process' for sending SIGUSR1 to XMosaic.
312Emacs 19.29 accepts 'SIGUSR1, earlier versions require an integer 361Emacs 19.29 accepts 'SIGUSR1, earlier versions require an integer
@@ -317,77 +366,80 @@ which is 30 on SunOS and 16 on HP-UX and Solaris.")
317This can be any number between 1024 and 65535 but must correspond to 366This can be any number between 1024 and 65535 but must correspond to
318the value set in the browser.") 367the value set in the browser.")
319 368
369(defvar browse-url-CCI-host "localhost"
370 "*Host to access XMosaic via CCI.
371This should be the host name of the machine running XMosaic with CCI
372enabled. The port number should be set in `browse-url-CCI-port'.")
373
374(defvar browse-url-temp-file-name nil)
375(make-variable-buffer-local 'browse-url-temp-file-name)
376
377(defvar browse-url-temp-file-list '())
378
320;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 379;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
321;; URL input 380;; URL input
322 381
323;; thingatpt.el doesn't work for complex regexps. 382;; thingatpt.el doesn't work for complex regexps
324 383
325(defun browse-url-url-at-point () 384(defun browse-url-url-at-point ()
326 "Return the URL around or before point. 385 "Return the URL around or before point.
327Then search backwards for the start of a URL. If no URL found, return 386Search backwards for the start of a URL ending at or after
328the empty string." 387point. If no URL found, return the empty string. The
329 (if (or (looking-at browse-url-regexp) ; Already at start 388access scheme, `http://' will be prepended if absent."
330 (let ((eol (save-excursion (end-of-line) (point)))) 389 (cond ((browse-url-looking-at browse-url-regexp)
331 ;; Search forwards for the next URL or end of line in case 390 (buffer-substring (match-beginning 0) (match-end 0)))
332 ;; we're in the middle of one. 391 ;; Access scheme omitted?
333 (and (re-search-forward browse-url-regexp eol 'lim) 392 ((browse-url-looking-at browse-url-short-regexp)
334 (goto-char (match-beginning 0))) 393 (concat "http://"
335 ;; Now back to where we started or earlier. 394 (buffer-substring (match-beginning 0) (match-end 0))))
336 (re-search-backward browse-url-regexp nil t))) 395 (t ""))) ; No match
337 (buffer-substring (match-beginning 0) (match-end 0)) 396
338 "")) ; No match 397(defun browse-url-looking-at (regexp)
339 398 "Return non-nil if point is in or just after a match for REGEXP.
340;; Todo: restrict to around or immediately before point. Expand bare 399Set the match data from the earliest such match in the current line
341;; hostname to URL. 400ending at or after point."
342 401 (save-excursion
343(defun browse-url-interactive-arg (&optional prompt) 402 (let ((old-point (point))
344 "Read a URL from the minibuffer, optionally prompting with PROMPT. 403 (eol (progn (end-of-line) (point)))
345Default to the URL at or before point. If bound to a mouse button, 404 (hit nil))
346set point to the position clicked. Return the result as a list for 405 (beginning-of-line)
347use in `interactive'." 406 (or (and (looking-at regexp)
407 (>= (match-end 0) old-point))
408 (progn
409 (while (and (re-search-forward regexp eol t)
410 (<= (match-beginning 0) old-point)
411 (not (setq hit (>= (match-end 0) old-point)))))
412 hit)))))
413
414;; Having this as a separate function called by the browser-specific
415;; functions allows them to be stand-alone commands, making it easier
416;; to switch between browsers.
417
418(defun browse-url-interactive-arg (prompt)
419 "Read a URL from the minibuffer, prompting with PROMPT.
420Default to the URL at or before point. If invoke with a mouse button,
421set point to the position clicked first. Return a list for use in
422`interactive' containing the URL and browse-url-new-window-p or its
423negation if a prefix argument was given."
348 (let ((event (elt (this-command-keys) 0))) 424 (let ((event (elt (this-command-keys) 0)))
349 (and (listp event) (mouse-set-point event))) 425 (and (listp event) (mouse-set-point event)))
350 (list (read-string (or prompt "URL: ") (browse-url-url-at-point)))) 426 (list (read-string prompt (browse-url-url-at-point))
351 427 (not (eq (null browse-url-new-window-p)
352;;;###autoload 428 (null current-prefix-arg)))))
353(defun browse-url-at-point ()
354 "Ask a WWW browser to load the URL at or before point.
355The URL is loaded according to the value of `browse-url-browser-function'."
356 (interactive)
357 (funcall browse-url-browser-function (browse-url-url-at-point)))
358
359;;;###autoload
360(defun browse-url-at-mouse (event)
361 "Ask a WWW browser to load a URL clicked with the mouse.
362The URL is the one around or before the position of the mouse click
363but point is not changed. The URL is loaded according to the value of
364`browse-url-browser-function'."
365 (interactive "e")
366 (save-excursion
367 (let ((posn (event-start event)))
368 (set-buffer (window-buffer (posn-window posn)))
369 (goto-char (posn-point posn))
370 (let ((url (browse-url-url-at-point)))
371 (if (string-equal url "")
372 (error "No URL found"))
373 (funcall browse-url-browser-function url)))))
374 429
375;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 430;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
376;; Browse current buffer 431;; Browse current buffer
377 432
378;;;###autoload
379(defun browse-url-of-file (&optional file) 433(defun browse-url-of-file (&optional file)
380 "Ask a WWW browser to display FILE. 434 "Ask a WWW browser to display FILE.
381Display the current buffer's file if FILE is nil or if called 435Display the current buffer's file if FILE is nil or if called
382interactively. Turn the filename into a URL by performing 436interactively. Turn the filename into a URL with function
383replacements given in variable `browse-url-filename-alist'. Pass the 437browse-url-file-url. Pass the URL to a browser using variable
384URL to a browser using variable `browse-url-browser-function' then run 438`browse-url-browser-function' then run `browse-url-of-file-hook'."
385`browse-url-of-file-hook'."
386 (interactive) 439 (interactive)
387 (setq file
388 (or file 440 (or file
389 (buffer-file-name) 441 (setq file (buffer-file-name))
390 (error "Current buffer has no file"))) 442 (error "Current buffer has no file"))
391 (let ((buf (get-file-buffer file))) 443 (let ((buf (get-file-buffer file)))
392 (if buf 444 (if buf
393 (save-excursion 445 (save-excursion
@@ -400,48 +452,53 @@ URL to a browser using variable `browse-url-browser-function' then run
400 452
401(defun browse-url-file-url (file) 453(defun browse-url-file-url (file)
402 "Return the URL corresponding to FILE. 454 "Return the URL corresponding to FILE.
403Uses variable `browse-url-filename-alist' to map filenames to URLs." 455Use variable `browse-url-filename-alist' to map filenames to URLs.
456Convert EFS file names of the form /USER@HOST:PATH to ftp://HOST/PATH."
457 ;; URL-encode special chars, do % first
458 (let ((s 0))
459 (while (setq s (string-match "%" file s))
460 (setq file (replace-match "%25" t t file)
461 s (1+ s))))
462 (while (string-match "[*\"()',=;? ]" file)
463 (let ((enc (format "%%%x" (aref file (match-beginning 0)))))
464 (setq file (replace-match enc t t file))))
404 (let ((maps browse-url-filename-alist)) 465 (let ((maps browse-url-filename-alist))
405 (while maps 466 (while maps
406 (let* ((map (car maps)) 467 (let* ((map (car maps))
407 (from-re (car map)) 468 (from-re (car map))
408 (to-string (cdr map))) 469 (to-string (cdr map)))
409 (setq maps (cdr maps)) 470 (setq maps (cdr maps))
410 (if (string-match from-re file) 471 (and (string-match from-re file)
411 (setq file (concat (substring file 0 (match-beginning 0)) 472 (setq file (replace-match to-string t t file))))))
412 to-string 473 ;; Check for EFS path
413 (substring file (match-end 0)))))))) 474 (and (string-match "^/\\([^:@]+@\\)?\\([^:]+\\):/*" file)
475 (setq file (concat "ftp://"
476 (substring file (match-beginning 2) (match-end 2))
477 "/" (substring file (match-end 0)))))
414 file) 478 file)
415 479
416(defvar browse-url-temp-file-name nil)
417(make-variable-buffer-local 'browse-url-temp-file-name)
418
419(defvar browse-url-temp-file-list '())
420
421;;;###autoload
422(defun browse-url-of-buffer (&optional buffer) 480(defun browse-url-of-buffer (&optional buffer)
423 "Ask a WWW browser to display BUFFER. 481 "Ask a WWW browser to display BUFFER.
424Display the current buffer if BUFFER is nil." 482Display the current buffer if BUFFER is nil."
425 (interactive) 483 (interactive)
426 (save-excursion 484 (save-excursion
427 (set-buffer (or buffer (current-buffer))) 485 (and buffer (set-buffer buffer))
428 (let ((file-name 486 (let ((file-name
429 (or buffer-file-name 487 (or buffer-file-name
430 (and (boundp 'dired-directory) dired-directory)))) 488 (and (boundp 'dired-directory) dired-directory))))
431 (if (null file-name) 489 (or file-name
432 (progn
433 (if (null browse-url-temp-file-name)
434 (progn 490 (progn
491 (or browse-url-temp-file-name
435 (setq browse-url-temp-file-name 492 (setq browse-url-temp-file-name
436 (make-temp-name 493 (make-temp-name
437 (expand-file-name (buffer-name) 494 (expand-file-name (buffer-name)
438 (or (getenv "TMPDIR") "/tmp")))) 495 (or (getenv "TMPDIR") "/tmp")))
439 (setq browse-url-temp-file-list 496 browse-url-temp-file-list
440 (cons browse-url-temp-file-name 497 (cons browse-url-temp-file-name
441 browse-url-temp-file-list)))) 498 browse-url-temp-file-list)))
442 (write-region (point-min) (point-max) browse-url-temp-file-name 499 (setq file-name browse-url-temp-file-name)
443 nil 'no-message))) 500 (write-region (point-min) (point-max) file-name nil 'no-message)))
444 (browse-url-of-file (or file-name browse-url-temp-file-name))))) 501 (browse-url-of-file file-name))))
445 502
446(defun browse-url-delete-temp-file (&optional temp-file-name) 503(defun browse-url-delete-temp-file (&optional temp-file-name)
447 ;; Delete browse-url-temp-file-name from the file system and from 504 ;; Delete browse-url-temp-file-name from the file system and from
@@ -467,15 +524,81 @@ Display the current buffer if BUFFER is nil."
467(add-hook 'kill-buffer-hook 'browse-url-delete-temp-file) 524(add-hook 'kill-buffer-hook 'browse-url-delete-temp-file)
468(add-hook 'kill-emacs-hook 'browse-url-delete-temp-file-list) 525(add-hook 'kill-emacs-hook 'browse-url-delete-temp-file-list)
469 526
470;;;###autoload
471(defun browse-url-of-dired-file () 527(defun browse-url-of-dired-file ()
472 "In Dired, ask a WWW browser to display the file named on this line." 528 "In Dired, ask a WWW browser to display the file named on this line."
473 (interactive) 529 (interactive)
474 (browse-url-of-file (dired-get-filename))) 530 (browse-url-of-file (dired-get-filename)))
475 531
476;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 532;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
477;; Browser-specific functions 533;; Browser-independant commands
534
535;; A generic command to call the current b-u-browser-function
536
537(defun browse-url (&rest args)
538 "Ask a WWW browser to load URL.
539Prompts for a URL, defaulting to the URL at or before point. Variable
540`browse-url-browser-function' says which browser to use."
541 (interactive (browse-url-interactive-arg "URL: "))
542 (apply browse-url-browser-function args))
543
544(defun browse-url-at-point ()
545 "Ask a WWW browser to load the URL at or before point.
546Doesn't let you edit the URL like browse-url. Variable
547`browse-url-browser-function' says which browser to use."
548 (interactive)
549 (funcall browse-url-browser-function (browse-url-url-at-point)))
550
551;; Define these if not already defined (XEmacs compatibility)
552
553(eval-and-compile
554 (or (fboundp 'event-buffer)
555 (defun event-buffer (event)
556 (window-buffer (posn-window (event-start event))))))
557
558(eval-and-compile
559 (or (fboundp 'event-point)
560 (defun event-point (event)
561 (posn-point (event-start event)))))
562
563(defun browse-url-at-mouse (event)
564 "Ask a WWW browser to load a URL clicked with the mouse.
565The URL is the one around or before the position of the mouse click
566but point is not changed. Doesn't let you edit the URL like
567browse-url. Variable `browse-url-browser-function' says which browser
568to use."
569 (interactive "e")
570 (save-excursion
571 (set-buffer (event-buffer event))
572 (goto-char (event-point event))
573 (let ((url (browse-url-url-at-point)))
574 (if (string-equal url "")
575 (error "No URL found"))
576 (funcall browse-url-browser-function url))))
577
578;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
579;; Browser-specific commands
580
581;; --- Netscape ---
582
583;; Put the correct DISPLAY value in the environment for Netscape
584;; launched from multi-display Emacs.
585
586(defun browse-url-process-environment ()
587 (let* ((device (and (fboundp 'selected-device)
588 (fboundp 'device-connection)
589 (selected-device)))
590 (display (and device (fboundp 'device-type)
591 (eq (device-type device) 'x)
592 (not (equal (device-connection device)
593 (getenv "DISPLAY"))))))
594 (if display
595 ;; Attempt to run on the correct display
596 (cons (concat "DISPLAY=" (device-connection device))
597 process-environment)
598 process-environment)))
599
478 600
601;;;###autoload
479(defun browse-url-netscape (url &optional new-window) 602(defun browse-url-netscape (url &optional new-window)
480 "Ask the Netscape WWW browser to load URL. 603 "Ask the Netscape WWW browser to load URL.
481 604
@@ -489,39 +612,52 @@ the effect of browse-url-new-window-p.
489 612
490When called non-interactively, optional second argument NEW-WINDOW is 613When called non-interactively, optional second argument NEW-WINDOW is
491used instead of browse-url-new-window-p." 614used instead of browse-url-new-window-p."
492 615 (interactive (browse-url-interactive-arg "Netscape URL: "))
493 (interactive (append (browse-url-interactive-arg "Netscape URL: ") 616 ;; URL encode any commas in the URL
494 (list (not (eq (null browse-url-new-window-p) 617 (while (string-match "," url)
495 (null current-prefix-arg)))))) 618 (setq url (replace-match "%2C" t t url)))
496 (let ((res 619 (let* ((process-environment (browse-url-process-environment))
497 (apply 'call-process browse-url-netscape-program nil nil nil 620 (process (apply 'start-process
621 (concat "netscape " url) nil
622 browse-url-netscape-command
498 (append browse-url-netscape-arguments 623 (append browse-url-netscape-arguments
499 (if new-window '("-noraise")) 624 (if new-window '("-noraise"))
500 (list "-remote" 625 (list "-remote"
501 (concat "openURL(" url 626 (concat "openURL(" url
502 (if new-window ",new-window") 627 (if new-window ",new-window")
503 ")")))) 628 ")"))))))
504 )) 629 (set-process-sentinel process
505 (if (stringp res) 630 (list 'lambda '(process change)
506 (error "netscape got signal: %s" res) 631 (list 'browse-url-netscape-sentinel 'process url)))))
507 (or (zerop res) 632
508 (progn ; Netscape not running - start it 633(defun browse-url-netscape-sentinel (process url)
634 "Handle a change to the process communicating with Netscape."
635 (or (eq (process-exit-status process) 0)
636 (let* ((process-environment (browse-url-process-environment)))
637 ;; Netscape not running - start it
509 (message "Starting Netscape...") 638 (message "Starting Netscape...")
510 (apply 'start-process "netscape" nil browse-url-netscape-program 639 (apply 'start-process (concat "netscape" url) nil
511 (append browse-url-netscape-arguments (list url)))))))) 640 browse-url-netscape-command
641 (append browse-url-netscape-startup-arguments (list url))))))
512 642
513(defun browse-url-netscape-reload () 643(defun browse-url-netscape-reload ()
514 "Ask Netscape to reload its current document." 644 "Ask Netscape to reload its current document."
515 (interactive) 645 (interactive)
516 (browse-url-netscape-command "reload")) 646 (browse-url-netscape-send "reload"))
517 647
518(defun browse-url-netscape-command (command) 648(defun browse-url-netscape-send (command)
519 "Send a remote control command to Netscape." 649 "Send a remote control command to Netscape."
520 (apply 'start-process "netscape" nil "netscape" 650 (let* ((process-environment (browse-url-process-environment)))
651 (apply 'start-process "netscape" nil
652 browse-url-netscape-command
521 (append browse-url-netscape-arguments 653 (append browse-url-netscape-arguments
522 (list "-remote" command)))) 654 (list "-remote" command)))))
655
656;; --- Mosaic ---
523 657
524(defun browse-url-mosaic (url) 658;;;###autoload
659(defun browse-url-mosaic (url &optional new-window)
660 ;; new-window ignored
525 "Ask the XMosaic WWW browser to load URL. 661 "Ask the XMosaic WWW browser to load URL.
526Default to the URL around or before point." 662Default to the URL around or before point."
527 (interactive (browse-url-interactive-arg "Mosaic URL: ")) 663 (interactive (browse-url-interactive-arg "Mosaic URL: "))
@@ -541,17 +677,42 @@ Default to the URL around or before point."
541 (save-buffer) 677 (save-buffer)
542 (kill-buffer nil) 678 (kill-buffer nil)
543 ;; Send signal SIGUSR to Mosaic 679 ;; Send signal SIGUSR to Mosaic
680 (message "Signalling Mosaic...")
544 (signal-process pid browse-url-usr1-signal) 681 (signal-process pid browse-url-usr1-signal)
545 (message "Signal sent to Mosaic")
546 ;; Or you could try: 682 ;; Or you could try:
547 ;; (call-process "kill" nil 0 nil "-USR1" (int-to-string pid)) 683 ;; (call-process "kill" nil 0 nil "-USR1" (int-to-string pid))
684 (message "Signalling Mosaic...done")
548 ) 685 )
549 ;; Mosaic not running - start it 686 ;; Mosaic not running - start it
550 (message "Starting Mosaic...") 687 (message "Starting Mosaic...")
551 (apply 'start-process "xmosaic" nil browse-url-mosaic-program 688 (apply 'start-process "xmosaic" nil "xmosaic"
552 (append browse-url-mosaic-arguments (list url))) 689 (append browse-url-mosaic-arguments (list url)))
553 (message "Starting Mosaic...done")))) 690 (message "Starting Mosaic...done"))))
554 691
692;; --- Grail ---
693
694;;;###autoload
695(defvar browse-url-grail
696 (concat (or (getenv "GRAILDIR") "~/.grail") "/user/rcgrail.py")
697 "*Location of Grail remote control client script `rcgrail.py'.
698Typically found in $GRAILDIR/rcgrail.py, or ~/.grail/user/rcgrail.py.")
699
700;;;###autoload
701(defun browse-url-grail (url)
702 "Ask the Grail WWW browser to load URL.
703Default to the URL around or before point. Runs the program in the
704variable `browse-url-grail'."
705 (interactive (browse-url-interactive-arg "Grail URL: "))
706 (message "Sending URL to Grail...")
707 (save-excursion
708 (set-buffer (get-buffer-create " *Shell Command Output*"))
709 (erase-buffer)
710 ;; don't worry about this failing.
711 (call-process browse-url-grail nil 0 nil url)
712 (message "Sending URL to Grail... done")))
713
714;; --- Mosaic using CCI ---
715
555(defun browse-url-cci (url &optional new-window) 716(defun browse-url-cci (url &optional new-window)
556 "Ask the XMosaic WWW browser to load URL. 717 "Ask the XMosaic WWW browser to load URL.
557Default to the URL around or before point. 718Default to the URL around or before point.
@@ -567,11 +728,9 @@ the effect of browse-url-new-window-p.
567 728
568When called non-interactively, optional second argument NEW-WINDOW is 729When called non-interactively, optional second argument NEW-WINDOW is
569used instead of browse-url-new-window-p." 730used instead of browse-url-new-window-p."
570 (interactive (append (browse-url-interactive-arg "Mosaic URL: ") 731 (interactive (browse-url-interactive-arg "Mosaic URL: "))
571 (list (not (eq (null browse-url-new-window-p)
572 (null current-prefix-arg))))))
573 (open-network-stream "browse-url" " *browse-url*" 732 (open-network-stream "browse-url" " *browse-url*"
574 "localhost" browse-url-CCI-port) 733 browse-url-CCI-host browse-url-CCI-port)
575 ;; Todo: start browser if fails 734 ;; Todo: start browser if fails
576 (process-send-string "browse-url" 735 (process-send-string "browse-url"
577 (concat "get url (" url ") output " 736 (concat "get url (" url ") output "
@@ -579,26 +738,57 @@ used instead of browse-url-new-window-p."
579 (process-send-string "browse-url" "disconnect\r\n") 738 (process-send-string "browse-url" "disconnect\r\n")
580 (delete-process "browse-url")) 739 (delete-process "browse-url"))
581 740
582(defun browse-url-iximosaic (url) 741;; --- IXI Mosaic ---
742
743;;;###autoload
744(defun browse-url-iximosaic (url &optional new-window)
745 ;; new-window ignored
583 "Ask the IXIMosaic WWW browser to load URL. 746 "Ask the IXIMosaic WWW browser to load URL.
584Default to the URL around or before point." 747Default to the URL around or before point."
585 (interactive (browse-url-interactive-arg "IXI Mosaic URL: ")) 748 (interactive (browse-url-interactive-arg "IXI Mosaic URL: "))
586 (start-process "tellw3b" nil "tellw3b" 749 (start-process "tellw3b" nil "tellw3b"
587 "-service WWW_BROWSER ixi_showurl " url)) 750 "-service WWW_BROWSER ixi_showurl " url))
588 751
589(defun browse-url-w3 (url) 752;; --- W3 ---
753
754;;;###autoload
755(defun browse-url-w3 (url &optional new-window)
756 ;; new-window ignored
590 "Ask the w3 WWW browser to load URL. 757 "Ask the w3 WWW browser to load URL.
591Default to the URL around or before point." 758Default to the URL around or before point."
592 (interactive (browse-url-interactive-arg "W3 URL: ")) 759 (interactive (browse-url-interactive-arg "W3 URL: "))
593 (w3-fetch url)) 760 (w3-fetch url))
594 761
595(defun browse-url-choose-browser (argument) 762;; --- Lynx in an xterm ---
596 "Decide which browser to use, then invoke it. 763
597This is the default value of `browse-url-browser-function'." 764;;;###autoload
598 (if (fboundp 'w3-fetch) 765(defun browse-url-lynx-xterm (url &optional new-window)
599 (setq browse-url-browser-function 'browse-url-w3) 766 ;; new-window ignored
600 (setq browse-url-browser-function 'browse-url-netscape)) 767 "Ask the Lynx WWW browser to load URL.
601 (funcall browse-url-browser-function argument)) 768Default to the URL around or before point. A new Lynx process is run
769in an Xterm window."
770 (interactive (browse-url-interactive-arg "Lynx URL: "))
771 (start-process (concat "lynx" url) nil "xterm" "-e" "lynx" url))
772
773(eval-when-compile (require 'term))
774
775;; --- Lynx in an Emacs "term" window ---
776
777;;;###autoload
778(defun browse-url-lynx-emacs (url &optional new-window)
779 ;; new-window ignored
780 "Ask the Lynx WWW browser to load URL.
781Default to the URL around or before point. Run a new Lynx process in
782an Emacs buffer."
783 (interactive (browse-url-interactive-arg "Lynx URL: "))
784 (let ((system-uses-terminfo t)) ; Lynx uses terminfo
785 (if (fboundp 'make-term)
786 (let ((term-term-name "vt100"))
787 (set-buffer (make-term "browse-url" "lynx" nil url))
788 (term-mode)
789 (term-char-mode)
790 (switch-to-buffer "*browse-url*"))
791 (terminal-emulator "*browse-url*" "lynx" (list url)))))
602 792
603(provide 'browse-url) 793(provide 'browse-url)
604 794