browse-url.el 64 KB

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