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