package.el 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735
  1. ;;; package.el --- Simple package system for Emacs
  2. ;; Copyright (C) 2007-2011 Free Software Foundation, Inc.
  3. ;; Author: Tom Tromey <tromey@redhat.com>
  4. ;; Created: 10 Mar 2007
  5. ;; Version: 0.9
  6. ;; Keywords: tools
  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, or (at your option)
  11. ;; 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; see the file COPYING. If not, write to the
  18. ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  19. ;; Boston, MA 02110-1301, USA.
  20. ;;; Change Log:
  21. ;; 2 Apr 2007 - now using ChangeLog file
  22. ;; 15 Mar 2007 - updated documentation
  23. ;; 14 Mar 2007 - Changed how obsolete packages are handled
  24. ;; 13 Mar 2007 - Wrote package-install-from-buffer
  25. ;; 12 Mar 2007 - Wrote package-menu mode
  26. ;;; Commentary:
  27. ;; The idea behind package.el is to be able to download packages and
  28. ;; install them. Packages are versioned and have versioned
  29. ;; dependencies. Furthermore, this supports built-in packages which
  30. ;; may or may not be newer than user-specified packages. This makes
  31. ;; it possible to upgrade Emacs and automatically disable packages
  32. ;; which have moved from external to core. (Note though that we don't
  33. ;; currently register any of these, so this feature does not actually
  34. ;; work.)
  35. ;; A package is described by its name and version. The distribution
  36. ;; format is either a tar file or a single .el file.
  37. ;; A tar file should be named "NAME-VERSION.tar". The tar file must
  38. ;; unpack into a directory named after the package and version:
  39. ;; "NAME-VERSION". It must contain a file named "PACKAGE-pkg.el"
  40. ;; which consists of a call to define-package. It may also contain a
  41. ;; "dir" file and the info files it references.
  42. ;; A .el file is named "NAME-VERSION.el" in the remote archive, but is
  43. ;; installed as simply "NAME.el" in a directory named "NAME-VERSION".
  44. ;; The downloader downloads all dependent packages. By default,
  45. ;; packages come from the official GNU sources, but others may be
  46. ;; added by customizing the `package-archives' alist. Packages get
  47. ;; byte-compiled at install time.
  48. ;; At activation time we will set up the load-path and the info path,
  49. ;; and we will load the package's autoloads. If a package's
  50. ;; dependencies are not available, we will not activate that package.
  51. ;; Conceptually a package has multiple state transitions:
  52. ;;
  53. ;; * Download. Fetching the package from ELPA.
  54. ;; * Install. Untar the package, or write the .el file, into
  55. ;; ~/.emacs.d/elpa/ directory.
  56. ;; * Byte compile. Currently this phase is done during install,
  57. ;; but we may change this.
  58. ;; * Activate. Evaluate the autoloads for the package to make it
  59. ;; available to the user.
  60. ;; * Load. Actually load the package and run some code from it.
  61. ;; Other external functions you may want to use:
  62. ;;
  63. ;; M-x list-packages
  64. ;; Enters a mode similar to buffer-menu which lets you manage
  65. ;; packages. You can choose packages for install (mark with "i",
  66. ;; then "x" to execute) or deletion (not implemented yet), and you
  67. ;; can see what packages are available. This will automatically
  68. ;; fetch the latest list of packages from ELPA.
  69. ;;
  70. ;; M-x package-list-packages-no-fetch
  71. ;; Like package-list-packages, but does not automatically fetch the
  72. ;; new list of packages.
  73. ;;
  74. ;; M-x package-install-from-buffer
  75. ;; Install a package consisting of a single .el file that appears
  76. ;; in the current buffer. This only works for packages which
  77. ;; define a Version header properly; package.el also supports the
  78. ;; extension headers Package-Version (in case Version is an RCS id
  79. ;; or similar), and Package-Requires (if the package requires other
  80. ;; packages).
  81. ;;
  82. ;; M-x package-install-file
  83. ;; Install a package from the indicated file. The package can be
  84. ;; either a tar file or a .el file. A tar file must contain an
  85. ;; appropriately-named "-pkg.el" file; a .el file must be properly
  86. ;; formatted as with package-install-from-buffer.
  87. ;;; Thanks:
  88. ;;; (sorted by sort-lines):
  89. ;; Jim Blandy <jimb@red-bean.com>
  90. ;; Karl Fogel <kfogel@red-bean.com>
  91. ;; Kevin Ryde <user42@zip.com.au>
  92. ;; Lawrence Mitchell
  93. ;; Michael Olson <mwolson@member.fsf.org>
  94. ;; Sebastian Tennant <sebyte@smolny.plus.com>
  95. ;; Stefan Monnier <monnier@iro.umontreal.ca>
  96. ;; Vinicius Jose Latorre <viniciusjl@ig.com.br>
  97. ;; Phil Hagelberg <phil@hagelb.org>
  98. ;;; ToDo:
  99. ;; - putting info dirs at the start of the info path means
  100. ;; users see a weird ordering of categories. OTOH we want to
  101. ;; override later entries. maybe emacs needs to enforce
  102. ;; the standard layout?
  103. ;; - put bytecode in a separate directory tree
  104. ;; - perhaps give users a way to recompile their bytecode
  105. ;; or do it automatically when emacs changes
  106. ;; - give users a way to know whether a package is installed ok
  107. ;; - give users a way to view a package's documentation when it
  108. ;; only appears in the .el
  109. ;; - use/extend checkdoc so people can tell if their package will work
  110. ;; - "installed" instead of a blank in the status column
  111. ;; - tramp needs its files to be compiled in a certain order.
  112. ;; how to handle this? fix tramp?
  113. ;; - on emacs 21 we don't kill the -autoloads.el buffer. what about 22?
  114. ;; - maybe we need separate .elc directories for various emacs versions
  115. ;; and also emacs-vs-xemacs. That way conditional compilation can
  116. ;; work. But would this break anything?
  117. ;; - should store the package's keywords in archive-contents, then
  118. ;; let the users filter the package-menu by keyword. See
  119. ;; finder-by-keyword. (We could also let people view the
  120. ;; Commentary, but it isn't clear how useful this is.)
  121. ;; - William Xu suggests being able to open a package file without
  122. ;; installing it
  123. ;; - Interface with desktop.el so that restarting after an install
  124. ;; works properly
  125. ;; - Implement M-x package-upgrade, to upgrade any/all existing packages
  126. ;; - Use hierarchical layout. PKG/etc PKG/lisp PKG/info
  127. ;; ... except maybe lisp?
  128. ;; - It may be nice to have a macro that expands to the package's
  129. ;; private data dir, aka ".../etc". Or, maybe data-directory
  130. ;; needs to be a list (though this would be less nice)
  131. ;; a few packages want this, eg sokoban
  132. ;; - package menu needs:
  133. ;; ability to know which packages are built-in & thus not deletable
  134. ;; it can sometimes print odd results, like 0.3 available but 0.4 active
  135. ;; why is that?
  136. ;; - Allow multiple versions on the server...?
  137. ;; [ why bother? ]
  138. ;; - Don't install a package which will invalidate dependencies overall
  139. ;; - Allow something like (or (>= emacs 21.0) (>= xemacs 21.5))
  140. ;; [ currently thinking, why bother.. KISS ]
  141. ;; - Allow optional package dependencies
  142. ;; then if we require 'bbdb', bbdb-specific lisp in lisp/bbdb
  143. ;; and just don't compile to add to load path ...?
  144. ;; - Have a list of archive URLs? [ maybe there's no point ]
  145. ;; - David Kastrup pointed out on the xemacs list that for GPL it
  146. ;; is friendlier to ship the source tree. We could "support" that
  147. ;; by just having a "src" subdir in the package. This isn't ideal
  148. ;; but it probably is not worth trying to support random source
  149. ;; tree layouts, build schemes, etc.
  150. ;; - Our treatment of the info path is somewhat bogus
  151. ;; - perhaps have an "unstable" tree in ELPA as well as a stable one
  152. ;;; Code:
  153. (defgroup package nil
  154. "Manager for Emacs Lisp packages."
  155. :group 'applications
  156. :version "24.1")
  157. ;;;###autoload
  158. (defcustom package-enable-at-startup t
  159. "Whether to activate installed packages when Emacs starts.
  160. If non-nil, packages are activated after reading the init file
  161. and before `after-init-hook'. Activation is not done if
  162. `user-init-file' is nil (e.g. Emacs was started with \"-q\").
  163. Even if the value is nil, you can type \\[package-initialize] to
  164. activate the package system at any time."
  165. :type 'boolean
  166. :group 'package
  167. :version "24.1")
  168. (defcustom package-load-list '(all)
  169. "List of packages for `package-initialize' to load.
  170. Each element in this list should be a list (NAME VERSION), or the
  171. symbol `all'. The symbol `all' says to load the latest installed
  172. versions of all packages not specified by other elements.
  173. For an element (NAME VERSION), NAME is a package name (a symbol).
  174. VERSION should be t, a string, or nil.
  175. If VERSION is t, all versions are loaded, though obsolete ones
  176. will be put in `package-obsolete-alist' and not activated.
  177. If VERSION is a string, only that version is ever loaded.
  178. Any other version, even if newer, is silently ignored.
  179. Hence, the package is \"held\" at that version.
  180. If VERSION is nil, the package is not loaded (it is \"disabled\")."
  181. :type '(repeat symbol)
  182. :risky t
  183. :group 'package
  184. :version "24.1")
  185. (defvar Info-directory-list)
  186. (declare-function info-initialize "info" ())
  187. (declare-function url-http-parse-response "url-http" ())
  188. (declare-function lm-header "lisp-mnt" (header))
  189. (declare-function lm-commentary "lisp-mnt" (&optional file))
  190. (defvar url-http-end-of-headers)
  191. (defcustom package-archives '(("gnu" . "http://elpa.gnu.org/packages/"))
  192. "An alist of archives from which to fetch.
  193. The default value points to the GNU Emacs package repository.
  194. Each element has the form (ID . LOCATION).
  195. ID is an archive name, as a string.
  196. LOCATION specifies the base location for the archive.
  197. If it starts with \"http:\", it is treated as a HTTP URL;
  198. otherwise it should be an absolute directory name.
  199. (Other types of URL are currently not supported.)"
  200. :type '(alist :key-type (string :tag "Archive name")
  201. :value-type (string :tag "URL or directory name"))
  202. :risky t
  203. :group 'package
  204. :version "24.1")
  205. (defconst package-archive-version 1
  206. "Version number of the package archive understood by this file.
  207. Lower version numbers than this will probably be understood as well.")
  208. (defconst package-el-version "1.0"
  209. "Version of package.el.")
  210. ;; We don't prime the cache since it tends to get out of date.
  211. (defvar package-archive-contents nil
  212. "Cache of the contents of the Emacs Lisp Package Archive.
  213. This is an alist mapping package names (symbols) to package
  214. descriptor vectors. These are like the vectors for `package-alist'
  215. but have extra entries: one which is 'tar for tar packages and
  216. 'single for single-file packages, and one which is the name of
  217. the archive from which it came.")
  218. (put 'package-archive-contents 'risky-local-variable t)
  219. (defcustom package-user-dir (locate-user-emacs-file "elpa")
  220. "Directory containing the user's Emacs Lisp packages.
  221. The directory name should be absolute.
  222. Apart from this directory, Emacs also looks for system-wide
  223. packages in `package-directory-list'."
  224. :type 'directory
  225. :risky t
  226. :group 'package
  227. :version "24.1")
  228. (defcustom package-directory-list
  229. ;; Defaults are subdirs named "elpa" in the site-lisp dirs.
  230. (let (result)
  231. (dolist (f load-path)
  232. (and (stringp f)
  233. (equal (file-name-nondirectory f) "site-lisp")
  234. (push (expand-file-name "elpa" f) result)))
  235. (nreverse result))
  236. "List of additional directories containing Emacs Lisp packages.
  237. Each directory name should be absolute.
  238. These directories contain packages intended for system-wide; in
  239. contrast, `package-user-dir' contains packages for personal use."
  240. :type '(repeat directory)
  241. :risky t
  242. :group 'package
  243. :version "24.1")
  244. ;; The value is precomputed in finder-inf.el, but don't load that
  245. ;; until it's needed (i.e. when `package-intialize' is called).
  246. (defvar package--builtins nil
  247. "Alist of built-in packages.
  248. The actual value is initialized by loading the library
  249. `finder-inf'; this is not done until it is needed, e.g. by the
  250. function `package-built-in-p'.
  251. Each element has the form (PKG . DESC), where PKG is a package
  252. name (a symbol) and DESC is a vector that describes the package.
  253. The vector DESC has the form [VERSION REQS DOCSTRING].
  254. VERSION is a version list.
  255. REQS is a list of packages (symbols) required by the package.
  256. DOCSTRING is a brief description of the package.")
  257. (put 'package--builtins 'risky-local-variable t)
  258. (defvar package-alist nil
  259. "Alist of all packages available for activation.
  260. Each element has the form (PKG . DESC), where PKG is a package
  261. name (a symbol) and DESC is a vector that describes the package.
  262. The vector DESC has the form [VERSION REQS DOCSTRING].
  263. VERSION is a version list.
  264. REQS is a list of packages (symbols) required by the package.
  265. DOCSTRING is a brief description of the package.
  266. This variable is set automatically by `package-load-descriptor',
  267. called via `package-initialize'. To change which packages are
  268. loaded and/or activated, customize `package-load-list'.")
  269. (put 'package-archive-contents 'risky-local-variable t)
  270. (defvar package-activated-list nil
  271. "List of the names of currently activated packages.")
  272. (put 'package-activated-list 'risky-local-variable t)
  273. (defvar package-obsolete-alist nil
  274. "Representation of obsolete packages.
  275. Like `package-alist', but maps package name to a second alist.
  276. The inner alist is keyed by version.")
  277. (put 'package-obsolete-alist 'risky-local-variable t)
  278. (defconst package-subdirectory-regexp
  279. "\\`\\([^.].*?\\)-\\([0-9]+\\(?:[.][0-9]+\\|\\(?:pre\\|beta\\|alpha\\)[0-9]+\\)*\\)\\'"
  280. "Regular expression matching the name of a package subdirectory.
  281. The first subexpression is the package name.
  282. The second subexpression is the version string.")
  283. (defun package-version-join (vlist)
  284. "Return the version string corresponding to the list VLIST.
  285. This is, approximately, the inverse of `version-to-list'.
  286. \(Actually, it returns only one of the possible inverses, since
  287. `version-to-list' is a many-to-one operation.)"
  288. (if (null vlist)
  289. ""
  290. (let ((str-list (list "." (int-to-string (car vlist)))))
  291. (dolist (num (cdr vlist))
  292. (cond
  293. ((>= num 0)
  294. (push (int-to-string num) str-list)
  295. (push "." str-list))
  296. ((< num -3)
  297. (error "Invalid version list `%s'" vlist))
  298. (t
  299. ;; pre, or beta, or alpha
  300. (cond ((equal "." (car str-list))
  301. (pop str-list))
  302. ((not (string-match "[0-9]+" (car str-list)))
  303. (error "Invalid version list `%s'" vlist)))
  304. (push (cond ((= num -1) "pre")
  305. ((= num -2) "beta")
  306. ((= num -3) "alpha"))
  307. str-list))))
  308. (if (equal "." (car str-list))
  309. (pop str-list))
  310. (apply 'concat (nreverse str-list)))))
  311. (defun package-strip-version (dirname)
  312. "Strip the version from a combined package name and version.
  313. E.g., if given \"quux-23.0\", will return \"quux\""
  314. (if (string-match package-subdirectory-regexp dirname)
  315. (match-string 1 dirname)))
  316. (defun package-load-descriptor (dir package)
  317. "Load the description file in directory DIR for package PACKAGE.
  318. Here, PACKAGE is a string of the form NAME-VER, where NAME is the
  319. package name and VER is its version."
  320. (let* ((pkg-dir (expand-file-name package dir))
  321. (pkg-file (expand-file-name
  322. (concat (package-strip-version package) "-pkg")
  323. pkg-dir)))
  324. (when (and (file-directory-p pkg-dir)
  325. (file-exists-p (concat pkg-file ".el")))
  326. (load pkg-file nil t))))
  327. (defun package-load-all-descriptors ()
  328. "Load descriptors for installed Emacs Lisp packages.
  329. This looks for package subdirectories in `package-user-dir' and
  330. `package-directory-list'. The variable `package-load-list'
  331. controls which package subdirectories may be loaded.
  332. In each valid package subdirectory, this function loads the
  333. description file containing a call to `define-package', which
  334. updates `package-alist' and `package-obsolete-alist'."
  335. (let ((all (memq 'all package-load-list))
  336. name version force)
  337. (dolist (dir (cons package-user-dir package-directory-list))
  338. (when (file-directory-p dir)
  339. (dolist (subdir (directory-files dir))
  340. (when (and (file-directory-p (expand-file-name subdir dir))
  341. (string-match package-subdirectory-regexp subdir))
  342. (setq name (intern (match-string 1 subdir))
  343. version (match-string 2 subdir)
  344. force (assq name package-load-list))
  345. (when (cond
  346. ((null force)
  347. all) ; not in package-load-list
  348. ((null (setq force (cadr force)))
  349. nil) ; disabled
  350. ((eq force t)
  351. t)
  352. ((stringp force) ; held
  353. (version-list-= (version-to-list version)
  354. (version-to-list force)))
  355. (t
  356. (error "Invalid element in `package-load-list'")))
  357. (package-load-descriptor dir subdir))))))))
  358. (defsubst package-desc-vers (desc)
  359. "Extract version from a package description vector."
  360. (aref desc 0))
  361. (defsubst package-desc-reqs (desc)
  362. "Extract requirements from a package description vector."
  363. (aref desc 1))
  364. (defsubst package-desc-doc (desc)
  365. "Extract doc string from a package description vector."
  366. (aref desc 2))
  367. (defsubst package-desc-kind (desc)
  368. "Extract the kind of download from an archive package description vector."
  369. (aref desc 3))
  370. (defun package--dir (name version)
  371. "Return the directory where a package is installed, or nil if none.
  372. NAME and VERSION are both strings."
  373. (let* ((subdir (concat name "-" version))
  374. (dir-list (cons package-user-dir package-directory-list))
  375. pkg-dir)
  376. (while dir-list
  377. (let ((subdir-full (expand-file-name subdir (car dir-list))))
  378. (if (file-directory-p subdir-full)
  379. (setq pkg-dir subdir-full
  380. dir-list nil)
  381. (setq dir-list (cdr dir-list)))))
  382. pkg-dir))
  383. (defun package-activate-1 (package pkg-vec)
  384. (let* ((name (symbol-name package))
  385. (version-str (package-version-join (package-desc-vers pkg-vec)))
  386. (pkg-dir (package--dir name version-str)))
  387. (unless pkg-dir
  388. (error "Internal error: unable to find directory for `%s-%s'"
  389. name version-str))
  390. ;; Add info node.
  391. (when (file-exists-p (expand-file-name "dir" pkg-dir))
  392. ;; FIXME: not the friendliest, but simple.
  393. (require 'info)
  394. (info-initialize)
  395. (push pkg-dir Info-directory-list))
  396. ;; Add to load path, add autoloads, and activate the package.
  397. (push pkg-dir load-path)
  398. (load (expand-file-name (concat name "-autoloads") pkg-dir) nil t)
  399. (push package package-activated-list)
  400. ;; Don't return nil.
  401. t))
  402. (defun package-built-in-p (package &optional version)
  403. "Return true if PACKAGE, of VERSION or newer, is built-in to Emacs."
  404. (require 'finder-inf nil t) ; For `package--builtins'.
  405. (let ((elt (assq package package--builtins)))
  406. (and elt (version-list-<= version (package-desc-vers (cdr elt))))))
  407. ;; This function goes ahead and activates a newer version of a package
  408. ;; if an older one was already activated. This is not ideal; we'd at
  409. ;; least need to check to see if the package has actually been loaded,
  410. ;; and not merely activated.
  411. (defun package-activate (package version)
  412. "Activate package PACKAGE, of version VERSION or newer.
  413. If PACKAGE has any dependencies, recursively activate them.
  414. Return nil if the package could not be activated."
  415. (let ((pkg-vec (cdr (assq package package-alist)))
  416. available-version found)
  417. ;; Check if PACKAGE is available in `package-alist'.
  418. (when pkg-vec
  419. (setq available-version (package-desc-vers pkg-vec)
  420. found (version-list-<= version available-version)))
  421. (cond
  422. ;; If no such package is found, maybe it's built-in.
  423. ((null found)
  424. (package-built-in-p package version))
  425. ;; If the package is already activated, just return t.
  426. ((memq package package-activated-list)
  427. t)
  428. ;; Otherwise, proceed with activation.
  429. (t
  430. (let ((fail (catch 'dep-failure
  431. ;; Activate its dependencies recursively.
  432. (dolist (req (package-desc-reqs pkg-vec))
  433. (unless (package-activate (car req) (cadr req))
  434. (throw 'dep-failure req))))))
  435. (if fail
  436. (warn "Unable to activate package `%s'.
  437. Required package `%s-%s' is unavailable"
  438. package (car fail) (package-version-join (cadr fail)))
  439. ;; If all goes well, activate the package itself.
  440. (package-activate-1 package pkg-vec)))))))
  441. (defun package-mark-obsolete (package pkg-vec)
  442. "Put package on the obsolete list, if not already there."
  443. (let ((elt (assq package package-obsolete-alist)))
  444. (if elt
  445. ;; If this obsolete version does not exist in the list, update
  446. ;; it the list.
  447. (unless (assoc (package-desc-vers pkg-vec) (cdr elt))
  448. (setcdr elt (cons (cons (package-desc-vers pkg-vec) pkg-vec)
  449. (cdr elt))))
  450. ;; Make a new association.
  451. (push (cons package (list (cons (package-desc-vers pkg-vec)
  452. pkg-vec)))
  453. package-obsolete-alist))))
  454. (defun define-package (name-string version-string
  455. &optional docstring requirements
  456. &rest extra-properties)
  457. "Define a new package.
  458. NAME-STRING is the name of the package, as a string.
  459. VERSION-STRING is the version of the package, as a list of
  460. integers of the form produced by `version-to-list'.
  461. DOCSTRING is a short description of the package, a string.
  462. REQUIREMENTS is a list of dependencies on other packages.
  463. Each requirement is of the form (OTHER-PACKAGE \"VERSION\").
  464. EXTRA-PROPERTIES is currently unused."
  465. (let* ((name (intern name-string))
  466. (version (version-to-list version-string))
  467. (new-pkg-desc
  468. (cons name
  469. (vector version
  470. (mapcar
  471. (lambda (elt)
  472. (list (car elt)
  473. (version-to-list (car (cdr elt)))))
  474. requirements)
  475. docstring)))
  476. (old-pkg (assq name package-alist)))
  477. (cond
  478. ;; If there's no old package, just add this to `package-alist'.
  479. ((null old-pkg)
  480. (push new-pkg-desc package-alist))
  481. ((version-list-< (package-desc-vers (cdr old-pkg)) version)
  482. ;; Remove the old package and declare it obsolete.
  483. (package-mark-obsolete name (cdr old-pkg))
  484. (setq package-alist (cons new-pkg-desc
  485. (delq old-pkg package-alist))))
  486. ;; You can have two packages with the same version, e.g. one in
  487. ;; the system package directory and one in your private
  488. ;; directory. We just let the first one win.
  489. ((not (version-list-= (package-desc-vers (cdr old-pkg)) version))
  490. ;; The package is born obsolete.
  491. (package-mark-obsolete name (cdr new-pkg-desc))))))
  492. ;; From Emacs 22.
  493. (defun package-autoload-ensure-default-file (file)
  494. "Make sure that the autoload file FILE exists and if not create it."
  495. (unless (file-exists-p file)
  496. (write-region
  497. (concat ";;; " (file-name-nondirectory file)
  498. " --- automatically extracted autoloads\n"
  499. ";;\n"
  500. ";;; Code:\n\n"
  501. " \n;; Local Variables:\n"
  502. ";; version-control: never\n"
  503. ";; no-byte-compile: t\n"
  504. ";; no-update-autoloads: t\n"
  505. ";; End:\n"
  506. ";;; " (file-name-nondirectory file)
  507. " ends here\n")
  508. nil file))
  509. file)
  510. (defun package-generate-autoloads (name pkg-dir)
  511. (let* ((auto-name (concat name "-autoloads.el"))
  512. (ignore-name (concat name "-pkg.el"))
  513. (generated-autoload-file (expand-file-name auto-name pkg-dir))
  514. (version-control 'never))
  515. (require 'autoload)
  516. (unless (fboundp 'autoload-ensure-default-file)
  517. (package-autoload-ensure-default-file generated-autoload-file))
  518. (update-directory-autoloads pkg-dir)))
  519. (defun package-untar-buffer ()
  520. "Untar the current buffer.
  521. This uses `tar-untar-buffer' if it is available.
  522. Otherwise it uses an external `tar' program.
  523. `default-directory' should be set by the caller."
  524. (require 'tar-mode)
  525. (if (fboundp 'tar-untar-buffer)
  526. (progn
  527. ;; tar-mode messes with narrowing, so we just let it have the
  528. ;; whole buffer to play with.
  529. (delete-region (point-min) (point))
  530. (tar-mode)
  531. (tar-untar-buffer))
  532. ;; FIXME: check the result.
  533. (call-process-region (point) (point-max) "tar" nil '(nil nil) nil
  534. "xf" "-")))
  535. (defun package-unpack (name version)
  536. (let ((pkg-dir (expand-file-name (concat (symbol-name name) "-" version)
  537. package-user-dir)))
  538. (make-directory package-user-dir t)
  539. ;; FIXME: should we delete PKG-DIR if it exists?
  540. (let* ((default-directory (file-name-as-directory package-user-dir)))
  541. (package-untar-buffer)
  542. (package-generate-autoloads (symbol-name name) pkg-dir)
  543. (let ((load-path (cons pkg-dir load-path)))
  544. (byte-recompile-directory pkg-dir 0 t)))))
  545. (defun package--write-file-no-coding (file-name)
  546. (let ((buffer-file-coding-system 'no-conversion))
  547. (write-region (point-min) (point-max) file-name)))
  548. (defun package-unpack-single (file-name version desc requires)
  549. "Install the contents of the current buffer as a package."
  550. ;; Special case "package".
  551. (if (string= file-name "package")
  552. (package--write-file-no-coding
  553. (expand-file-name (concat file-name ".el") package-user-dir))
  554. (let* ((pkg-dir (expand-file-name (concat file-name "-"
  555. (package-version-join
  556. (version-to-list version)))
  557. package-user-dir))
  558. (el-file (expand-file-name (concat file-name ".el") pkg-dir))
  559. (pkg-file (expand-file-name (concat file-name "-pkg.el") pkg-dir)))
  560. (make-directory pkg-dir t)
  561. (package--write-file-no-coding el-file)
  562. (let ((print-level nil)
  563. (print-length nil))
  564. (write-region
  565. (concat
  566. (prin1-to-string
  567. (list 'define-package
  568. file-name
  569. version
  570. desc
  571. (list 'quote
  572. ;; Turn version lists into string form.
  573. (mapcar
  574. (lambda (elt)
  575. (list (car elt)
  576. (package-version-join (cadr elt))))
  577. requires))))
  578. "\n")
  579. nil
  580. pkg-file
  581. nil nil nil 'excl))
  582. (package-generate-autoloads file-name pkg-dir)
  583. (let ((load-path (cons pkg-dir load-path)))
  584. (byte-recompile-directory pkg-dir 0 t)))))
  585. (defmacro package--with-work-buffer (location file &rest body)
  586. "Run BODY in a buffer containing the contents of FILE at LOCATION.
  587. LOCATION is the base location of a package archive, and should be
  588. one of the URLs (or file names) specified in `package-archives'.
  589. FILE is the name of a file relative to that base location.
  590. This macro retrieves FILE from LOCATION into a temporary buffer,
  591. and evaluates BODY while that buffer is current. This work
  592. buffer is killed afterwards. Return the last value in BODY."
  593. `(let* ((http (string-match "\\`http:" ,location))
  594. (buffer
  595. (if http
  596. (url-retrieve-synchronously (concat ,location ,file))
  597. (generate-new-buffer "*package work buffer*"))))
  598. (prog1
  599. (with-current-buffer buffer
  600. (if http
  601. (progn (package-handle-response)
  602. (re-search-forward "^$" nil 'move)
  603. (forward-char)
  604. (delete-region (point-min) (point)))
  605. (unless (file-name-absolute-p ,location)
  606. (error "Archive location %s is not an absolute file name"
  607. ,location))
  608. (insert-file-contents (expand-file-name ,file ,location)))
  609. ,@body)
  610. (kill-buffer buffer))))
  611. (defun package-handle-response ()
  612. "Handle the response from a `url-retrieve-synchronously' call.
  613. Parse the HTTP response and throw if an error occurred.
  614. The url package seems to require extra processing for this.
  615. This should be called in a `save-excursion', in the download buffer.
  616. It will move point to somewhere in the headers."
  617. ;; We assume HTTP here.
  618. (require 'url-http)
  619. (let ((response (url-http-parse-response)))
  620. (when (or (< response 200) (>= response 300))
  621. (error "Error during download request:%s"
  622. (buffer-substring-no-properties (point) (progn
  623. (end-of-line)
  624. (point)))))))
  625. (defun package-download-single (name version desc requires)
  626. "Download and install a single-file package."
  627. (let ((location (package-archive-base name))
  628. (file (concat (symbol-name name) "-" version ".el")))
  629. (package--with-work-buffer location file
  630. (package-unpack-single (symbol-name name) version desc requires))))
  631. (defun package-download-tar (name version)
  632. "Download and install a tar package."
  633. (let ((location (package-archive-base name))
  634. (file (concat (symbol-name name) "-" version ".tar")))
  635. (package--with-work-buffer location file
  636. (package-unpack name version))))
  637. (defun package-installed-p (package &optional min-version)
  638. "Return true if PACKAGE, of VERSION or newer, is installed.
  639. Built-in packages also qualify."
  640. (let ((pkg-desc (assq package package-alist)))
  641. (if pkg-desc
  642. (version-list-<= min-version
  643. (package-desc-vers (cdr pkg-desc)))
  644. ;; Also check built-in packages.
  645. (package-built-in-p package min-version))))
  646. (defun package-compute-transaction (package-list requirements)
  647. "Return a list of packages to be installed, including PACKAGE-LIST.
  648. PACKAGE-LIST should be a list of package names (symbols).
  649. REQUIREMENTS should be a list of additional requirements; each
  650. element in this list should have the form (PACKAGE VERSION),
  651. where PACKAGE is a package name and VERSION is the required
  652. version of that package (as a list).
  653. This function recursively computes the requirements of the
  654. packages in REQUIREMENTS, and returns a list of all the packages
  655. that must be installed. Packages that are already installed are
  656. not included in this list."
  657. (dolist (elt requirements)
  658. (let* ((next-pkg (car elt))
  659. (next-version (cadr elt)))
  660. (unless (package-installed-p next-pkg next-version)
  661. ;; A package is required, but not installed. It might also be
  662. ;; blocked via `package-load-list'.
  663. (let ((pkg-desc (assq next-pkg package-archive-contents))
  664. hold)
  665. (when (setq hold (assq next-pkg package-load-list))
  666. (setq hold (cadr hold))
  667. (cond ((eq hold nil)
  668. (error "Required package '%s' is disabled"
  669. (symbol-name next-pkg)))
  670. ((null (stringp hold))
  671. (error "Invalid element in `package-load-list'"))
  672. ((version-list-< (version-to-list hold) next-version)
  673. (error "Package `%s' held at version %s, \
  674. but version %s required"
  675. (symbol-name next-pkg) hold
  676. (package-version-join next-version)))))
  677. (unless pkg-desc
  678. (error "Package `%s-%s' is unavailable"
  679. (symbol-name next-pkg)
  680. (package-version-join next-version)))
  681. (unless (version-list-<= next-version
  682. (package-desc-vers (cdr pkg-desc)))
  683. (error
  684. "Need package `%s-%s', but only %s is available"
  685. (symbol-name next-pkg) (package-version-join next-version)
  686. (package-version-join (package-desc-vers (cdr pkg-desc)))))
  687. ;; Only add to the transaction if we don't already have it.
  688. (unless (memq next-pkg package-list)
  689. (push next-pkg package-list))
  690. (setq package-list
  691. (package-compute-transaction package-list
  692. (package-desc-reqs
  693. (cdr pkg-desc))))))))
  694. package-list)
  695. (defun package-read-from-string (str)
  696. "Read a Lisp expression from STR.
  697. Signal an error if the entire string was not used."
  698. (let* ((read-data (read-from-string str))
  699. (more-left
  700. (condition-case nil
  701. ;; The call to `ignore' suppresses a compiler warning.
  702. (progn (ignore (read-from-string
  703. (substring str (cdr read-data))))
  704. t)
  705. (end-of-file nil))))
  706. (if more-left
  707. (error "Can't read whole string")
  708. (car read-data))))
  709. (defun package--read-archive-file (file)
  710. "Re-read archive file FILE, if it exists.
  711. Will return the data from the file, or nil if the file does not exist.
  712. Will throw an error if the archive version is too new."
  713. (let ((filename (expand-file-name file package-user-dir)))
  714. (when (file-exists-p filename)
  715. (with-temp-buffer
  716. (insert-file-contents-literally filename)
  717. (let ((contents (read (current-buffer))))
  718. (if (> (car contents) package-archive-version)
  719. (error "Package archive version %d is higher than %d"
  720. (car contents) package-archive-version))
  721. (cdr contents))))))
  722. (defun package-read-all-archive-contents ()
  723. "Re-read `archive-contents', if it exists.
  724. If successful, set `package-archive-contents'."
  725. (setq package-archive-contents nil)
  726. (dolist (archive package-archives)
  727. (package-read-archive-contents (car archive))))
  728. (defun package-read-archive-contents (archive)
  729. "Re-read archive contents for ARCHIVE.
  730. If successful, set the variable `package-archive-contents'.
  731. If the archive version is too new, signal an error."
  732. ;; Version 1 of 'archive-contents' is identical to our internal
  733. ;; representation.
  734. (let* ((dir (concat "archives/" archive))
  735. (contents-file (concat dir "/archive-contents"))
  736. contents)
  737. (when (setq contents (package--read-archive-file contents-file))
  738. (dolist (package contents)
  739. (package--add-to-archive-contents package archive)))))
  740. (defun package--add-to-archive-contents (package archive)
  741. "Add the PACKAGE from the given ARCHIVE if necessary.
  742. Also, add the originating archive to the end of the package vector."
  743. (let* ((name (car package))
  744. (version (aref (cdr package) 0))
  745. (entry (cons (car package)
  746. (vconcat (cdr package) (vector archive))))
  747. (existing-package (cdr (assq name package-archive-contents))))
  748. (when (or (not existing-package)
  749. (version-list-< (aref existing-package 0) version))
  750. (add-to-list 'package-archive-contents entry))))
  751. (defun package-download-transaction (package-list)
  752. "Download and install all the packages in PACKAGE-LIST.
  753. PACKAGE-LIST should be a list of package names (symbols).
  754. This function assumes that all package requirements in
  755. PACKAGE-LIST are satisfied, i.e. that PACKAGE-LIST is computed
  756. using `package-compute-transaction'."
  757. (dolist (elt package-list)
  758. (let* ((desc (cdr (assq elt package-archive-contents)))
  759. ;; As an exception, if package is "held" in
  760. ;; `package-load-list', download the held version.
  761. (hold (cadr (assq elt package-load-list)))
  762. (v-string (or (and (stringp hold) hold)
  763. (package-version-join (package-desc-vers desc))))
  764. (kind (package-desc-kind desc)))
  765. (cond
  766. ((eq kind 'tar)
  767. (package-download-tar elt v-string))
  768. ((eq kind 'single)
  769. (package-download-single elt v-string
  770. (package-desc-doc desc)
  771. (package-desc-reqs desc)))
  772. (t
  773. (error "Unknown package kind: %s" (symbol-name kind)))))))
  774. ;;;###autoload
  775. (defun package-install (name)
  776. "Install the package named NAME.
  777. Interactively, prompt for the package name.
  778. The package is found on one of the archives in `package-archives'."
  779. (interactive
  780. (list (intern (completing-read "Install package: "
  781. (mapcar (lambda (elt)
  782. (cons (symbol-name (car elt))
  783. nil))
  784. package-archive-contents)
  785. nil t))))
  786. (let ((pkg-desc (assq name package-archive-contents)))
  787. (unless pkg-desc
  788. (error "Package `%s' is not available for installation"
  789. (symbol-name name)))
  790. (package-download-transaction
  791. (package-compute-transaction (list name)
  792. (package-desc-reqs (cdr pkg-desc)))))
  793. ;; Try to activate it.
  794. (package-initialize))
  795. (defun package-strip-rcs-id (str)
  796. "Strip RCS version ID from the version string STR.
  797. If the result looks like a dotted numeric version, return it.
  798. Otherwise return nil."
  799. (when str
  800. (when (string-match "\\`[ \t]*[$]Revision:[ \t]+" str)
  801. (setq str (substring str (match-end 0))))
  802. (condition-case nil
  803. (if (version-to-list str)
  804. str)
  805. (error nil))))
  806. (defun package-buffer-info ()
  807. "Return a vector describing the package in the current buffer.
  808. The vector has the form
  809. [FILENAME REQUIRES DESCRIPTION VERSION COMMENTARY]
  810. FILENAME is the file name, a string, sans the \".el\" extension.
  811. REQUIRES is a requires list, or nil.
  812. DESCRIPTION is the package description, a string.
  813. VERSION is the version, a string.
  814. COMMENTARY is the commentary section, a string, or nil if none.
  815. If the buffer does not contain a conforming package, signal an
  816. error. If there is a package, narrow the buffer to the file's
  817. boundaries."
  818. (goto-char (point-min))
  819. (unless (re-search-forward "^;;; \\([^ ]*\\)\\.el --- \\(.*\\)$" nil t)
  820. (error "Packages lacks a file header"))
  821. (let ((file-name (match-string-no-properties 1))
  822. (desc (match-string-no-properties 2))
  823. (start (line-beginning-position)))
  824. (unless (search-forward (concat ";;; " file-name ".el ends here"))
  825. (error "Package lacks a terminating comment"))
  826. ;; Try to include a trailing newline.
  827. (forward-line)
  828. (narrow-to-region start (point))
  829. (require 'lisp-mnt)
  830. ;; Use some headers we've invented to drive the process.
  831. (let* ((requires-str (lm-header "package-requires"))
  832. (requires (if requires-str
  833. (package-read-from-string requires-str)))
  834. ;; Prefer Package-Version; if defined, the package author
  835. ;; probably wants us to use it. Otherwise try Version.
  836. (pkg-version
  837. (or (package-strip-rcs-id (lm-header "package-version"))
  838. (package-strip-rcs-id (lm-header "version"))))
  839. (commentary (lm-commentary)))
  840. (unless pkg-version
  841. (error
  842. "Package lacks a \"Version\" or \"Package-Version\" header"))
  843. ;; Turn string version numbers into list form.
  844. (setq requires
  845. (mapcar
  846. (lambda (elt)
  847. (list (car elt)
  848. (version-to-list (car (cdr elt)))))
  849. requires))
  850. (vector file-name requires desc pkg-version commentary))))
  851. (defun package-tar-file-info (file)
  852. "Find package information for a tar file.
  853. FILE is the name of the tar file to examine.
  854. The return result is a vector like `package-buffer-info'."
  855. (let ((default-directory (file-name-directory file))
  856. (file (file-name-nondirectory file)))
  857. (unless (string-match "^\\(.+\\)-\\([0-9.]+\\)\\.tar$" file)
  858. (error "Invalid package name `%s'" file))
  859. (let* ((pkg-name (match-string-no-properties 1 file))
  860. (pkg-version (match-string-no-properties 2 file))
  861. ;; Extract the package descriptor.
  862. (pkg-def-contents (shell-command-to-string
  863. ;; Requires GNU tar.
  864. (concat "tar -xOf " file " "
  865. pkg-name "-" pkg-version "/"
  866. pkg-name "-pkg.el")))
  867. (pkg-def-parsed (package-read-from-string pkg-def-contents)))
  868. (unless (eq (car pkg-def-parsed) 'define-package)
  869. (error "No `define-package' sexp is present in `%s-pkg.el'" pkg-name))
  870. (let ((name-str (nth 1 pkg-def-parsed))
  871. (version-string (nth 2 pkg-def-parsed))
  872. (docstring (nth 3 pkg-def-parsed))
  873. (requires (nth 4 pkg-def-parsed))
  874. (readme (shell-command-to-string
  875. ;; Requires GNU tar.
  876. (concat "tar -xOf " file " "
  877. pkg-name "-" pkg-version "/README"))))
  878. (unless (equal pkg-version version-string)
  879. (error "Package has inconsistent versions"))
  880. (unless (equal pkg-name name-str)
  881. (error "Package has inconsistent names"))
  882. ;; Kind of a hack.
  883. (if (string-match ": Not found in archive" readme)
  884. (setq readme nil))
  885. ;; Turn string version numbers into list form.
  886. (if (eq (car requires) 'quote)
  887. (setq requires (car (cdr requires))))
  888. (setq requires
  889. (mapcar (lambda (elt)
  890. (list (car elt)
  891. (version-to-list (cadr elt))))
  892. requires))
  893. (vector pkg-name requires docstring version-string readme)))))
  894. ;;;###autoload
  895. (defun package-install-from-buffer (pkg-info type)
  896. "Install a package from the current buffer.
  897. When called interactively, the current buffer is assumed to be a
  898. single .el file that follows the packaging guidelines; see info
  899. node `(elisp)Packaging'.
  900. When called from Lisp, PKG-INFO is a vector describing the
  901. information, of the type returned by `package-buffer-info'; and
  902. TYPE is the package type (either `single' or `tar')."
  903. (interactive (list (package-buffer-info) 'single))
  904. (save-excursion
  905. (save-restriction
  906. (let* ((file-name (aref pkg-info 0))
  907. (requires (aref pkg-info 1))
  908. (desc (if (string= (aref pkg-info 2) "")
  909. "No description available."
  910. (aref pkg-info 2)))
  911. (pkg-version (aref pkg-info 3)))
  912. ;; Download and install the dependencies.
  913. (let ((transaction (package-compute-transaction nil requires)))
  914. (package-download-transaction transaction))
  915. ;; Install the package itself.
  916. (cond
  917. ((eq type 'single)
  918. (package-unpack-single file-name pkg-version desc requires))
  919. ((eq type 'tar)
  920. (package-unpack (intern file-name) pkg-version))
  921. (t
  922. (error "Unknown type: %s" (symbol-name type))))
  923. ;; Try to activate it.
  924. (package-initialize)))))
  925. ;;;###autoload
  926. (defun package-install-file (file)
  927. "Install a package from a file.
  928. The file can either be a tar file or an Emacs Lisp file."
  929. (interactive "fPackage file name: ")
  930. (with-temp-buffer
  931. (insert-file-contents-literally file)
  932. (cond
  933. ((string-match "\\.el$" file)
  934. (package-install-from-buffer (package-buffer-info) 'single))
  935. ((string-match "\\.tar$" file)
  936. (package-install-from-buffer (package-tar-file-info file) 'tar))
  937. (t (error "Unrecognized extension `%s'" (file-name-extension file))))))
  938. (defun package-delete (name version)
  939. (let ((dir (package--dir name version)))
  940. (if (string-equal (file-name-directory dir)
  941. (file-name-as-directory
  942. (expand-file-name package-user-dir)))
  943. (progn
  944. (delete-directory dir t t)
  945. (message "Package `%s-%s' deleted." name version))
  946. ;; Don't delete "system" packages
  947. (error "Package `%s-%s' is a system package, not deleting"
  948. name version))))
  949. (defun package-archive-base (name)
  950. "Return the archive containing the package NAME."
  951. (let ((desc (cdr (assq (intern-soft name) package-archive-contents))))
  952. (cdr (assoc (aref desc (- (length desc) 1)) package-archives))))
  953. (defun package--download-one-archive (archive file)
  954. "Retrieve an archive file FILE from ARCHIVE, and cache it.
  955. ARCHIVE should be a cons cell of the form (NAME . LOCATION),
  956. similar to an entry in `package-alist'. Save the cached copy to
  957. \"archives/NAME/archive-contents\" in `package-user-dir'."
  958. (let* ((dir (expand-file-name "archives" package-user-dir))
  959. (dir (expand-file-name (car archive) dir)))
  960. (package--with-work-buffer (cdr archive) file
  961. ;; Read the retrieved buffer to make sure it is valid (e.g. it
  962. ;; may fetch a URL redirect page).
  963. (when (listp (read buffer))
  964. (make-directory dir t)
  965. (setq buffer-file-name (expand-file-name file dir))
  966. (let ((version-control 'never))
  967. (save-buffer))))))
  968. (defun package-refresh-contents ()
  969. "Download the ELPA archive description if needed.
  970. This informs Emacs about the latest versions of all packages, and
  971. makes them available for download."
  972. (interactive)
  973. (unless (file-exists-p package-user-dir)
  974. (make-directory package-user-dir t))
  975. (dolist (archive package-archives)
  976. (condition-case-no-debug nil
  977. (package--download-one-archive archive "archive-contents")
  978. (error (message "Failed to download `%s' archive."
  979. (car archive)))))
  980. (package-read-all-archive-contents))
  981. (defvar package--initialized nil)
  982. ;;;###autoload
  983. (defun package-initialize (&optional no-activate)
  984. "Load Emacs Lisp packages, and activate them.
  985. The variable `package-load-list' controls which packages to load.
  986. If optional arg NO-ACTIVATE is non-nil, don't activate packages."
  987. (interactive)
  988. (setq package-alist nil
  989. package-obsolete-alist nil)
  990. (package-load-all-descriptors)
  991. (package-read-all-archive-contents)
  992. (unless no-activate
  993. (dolist (elt package-alist)
  994. (package-activate (car elt) (package-desc-vers (cdr elt)))))
  995. (setq package--initialized t))
  996. ;;;; Package description buffer.
  997. ;;;###autoload
  998. (defun describe-package (package)
  999. "Display the full documentation of PACKAGE (a symbol)."
  1000. (interactive
  1001. (let* ((guess (function-called-at-point))
  1002. packages val)
  1003. (require 'finder-inf nil t)
  1004. ;; Load the package list if necessary (but don't activate them).
  1005. (unless package--initialized
  1006. (package-initialize t))
  1007. (setq packages (append (mapcar 'car package-alist)
  1008. (mapcar 'car package-archive-contents)
  1009. (mapcar 'car package--builtins)))
  1010. (unless (memq guess packages)
  1011. (setq guess nil))
  1012. (setq packages (mapcar 'symbol-name packages))
  1013. (setq val
  1014. (completing-read (if guess
  1015. (format "Describe package (default %s): "
  1016. guess)
  1017. "Describe package: ")
  1018. packages nil t nil nil guess))
  1019. (list (if (equal val "") guess (intern val)))))
  1020. (if (or (null package) (not (symbolp package)))
  1021. (message "No package specified")
  1022. (help-setup-xref (list #'describe-package package)
  1023. (called-interactively-p 'interactive))
  1024. (with-help-window (help-buffer)
  1025. (with-current-buffer standard-output
  1026. (describe-package-1 package)))))
  1027. (defun describe-package-1 (package)
  1028. (require 'lisp-mnt)
  1029. (let ((package-name (symbol-name package))
  1030. (built-in (assq package package--builtins))
  1031. desc pkg-dir reqs version installable)
  1032. (prin1 package)
  1033. (princ " is ")
  1034. (cond
  1035. ;; Loaded packages are in `package-alist'.
  1036. ((setq desc (cdr (assq package package-alist)))
  1037. (setq version (package-version-join (package-desc-vers desc)))
  1038. (if (setq pkg-dir (package--dir package-name version))
  1039. (insert "an installed package.\n\n")
  1040. ;; This normally does not happen.
  1041. (insert "a deleted package.\n\n")))
  1042. ;; Available packages are in `package-archive-contents'.
  1043. ((setq desc (cdr (assq package package-archive-contents)))
  1044. (setq version (package-version-join (package-desc-vers desc))
  1045. installable t)
  1046. (if built-in
  1047. (insert "a built-in package.\n\n")
  1048. (insert "an uninstalled package.\n\n")))
  1049. (built-in
  1050. (setq desc (cdr built-in)
  1051. version (package-version-join (package-desc-vers desc)))
  1052. (insert "a built-in package.\n\n"))
  1053. (t
  1054. (insert "an orphan package.\n\n")))
  1055. (insert " " (propertize "Status" 'font-lock-face 'bold) ": ")
  1056. (cond (pkg-dir
  1057. (insert (propertize "Installed"
  1058. 'font-lock-face 'font-lock-comment-face))
  1059. (insert " in `")
  1060. ;; Todo: Add button for uninstalling.
  1061. (help-insert-xref-button (file-name-as-directory pkg-dir)
  1062. 'help-package-def pkg-dir)
  1063. (if built-in
  1064. (insert "',\n shadowing a "
  1065. (propertize "built-in package"
  1066. 'font-lock-face 'font-lock-builtin-face)
  1067. ".")
  1068. (insert "'.")))
  1069. (installable
  1070. (if built-in
  1071. (insert (propertize "Built-in." 'font-lock-face 'font-lock-builtin-face)
  1072. " Alternate version available -- ")
  1073. (insert "Available -- "))
  1074. (let ((button-text (if (display-graphic-p) "Install" "[Install]"))
  1075. (button-face (if (display-graphic-p)
  1076. '(:box (:line-width 2 :color "dark grey")
  1077. :background "light grey"
  1078. :foreground "black")
  1079. 'link)))
  1080. (insert-text-button button-text 'face button-face 'follow-link t
  1081. 'package-symbol package
  1082. 'action 'package-install-button-action)))
  1083. (built-in
  1084. (insert (propertize "Built-in." 'font-lock-face 'font-lock-builtin-face)))
  1085. (t (insert "Deleted.")))
  1086. (insert "\n")
  1087. (and version (> (length version) 0)
  1088. (insert " "
  1089. (propertize "Version" 'font-lock-face 'bold) ": " version "\n"))
  1090. (setq reqs (if desc (package-desc-reqs desc)))
  1091. (when reqs
  1092. (insert " " (propertize "Requires" 'font-lock-face 'bold) ": ")
  1093. (let ((first t)
  1094. name vers text)
  1095. (dolist (req reqs)
  1096. (setq name (car req)
  1097. vers (cadr req)
  1098. text (format "%s-%s" (symbol-name name)
  1099. (package-version-join vers)))
  1100. (cond (first (setq first nil))
  1101. ((>= (+ 2 (current-column) (length text))
  1102. (window-width))
  1103. (insert ",\n "))
  1104. (t (insert ", ")))
  1105. (help-insert-xref-button text 'help-package name))
  1106. (insert "\n")))
  1107. (insert " " (propertize "Summary" 'font-lock-face 'bold)
  1108. ": " (if desc (package-desc-doc desc)) "\n\n")
  1109. (if built-in
  1110. ;; For built-in packages, insert the commentary.
  1111. (let ((fn (locate-file (concat package-name ".el") load-path
  1112. load-file-rep-suffixes))
  1113. (opoint (point)))
  1114. (insert (or (lm-commentary fn) ""))
  1115. (save-excursion
  1116. (goto-char opoint)
  1117. (when (re-search-forward "^;;; Commentary:\n" nil t)
  1118. (replace-match ""))
  1119. (while (re-search-forward "^\\(;+ ?\\)" nil t)
  1120. (replace-match ""))))
  1121. (let ((readme (expand-file-name (concat package-name "-readme.txt")
  1122. package-user-dir))
  1123. readme-string)
  1124. ;; For elpa packages, try downloading the commentary. If that
  1125. ;; fails, try an existing readme file in `package-user-dir'.
  1126. (cond ((condition-case nil
  1127. (package--with-work-buffer (package-archive-base package)
  1128. (concat package-name "-readme.txt")
  1129. (setq buffer-file-name
  1130. (expand-file-name readme package-user-dir))
  1131. (let ((version-control 'never))
  1132. (save-buffer))
  1133. (setq readme-string (buffer-string))
  1134. t)
  1135. (error nil))
  1136. (insert readme-string))
  1137. ((file-readable-p readme)
  1138. (insert-file-contents readme)
  1139. (goto-char (point-max))))))))
  1140. (defun package-install-button-action (button)
  1141. (let ((package (button-get button 'package-symbol)))
  1142. (when (y-or-n-p (format "Install package `%s'? " package))
  1143. (package-install package)
  1144. (revert-buffer nil t)
  1145. (goto-char (point-min)))))
  1146. ;;;; Package menu mode.
  1147. (defvar package-menu-mode-map
  1148. (let ((map (copy-keymap special-mode-map))
  1149. (menu-map (make-sparse-keymap "Package")))
  1150. (set-keymap-parent map button-buffer-map)
  1151. (define-key map "\C-m" 'package-menu-describe-package)
  1152. (define-key map "n" 'next-line)
  1153. (define-key map "p" 'previous-line)
  1154. (define-key map "u" 'package-menu-mark-unmark)
  1155. (define-key map "\177" 'package-menu-backup-unmark)
  1156. (define-key map "d" 'package-menu-mark-delete)
  1157. (define-key map "i" 'package-menu-mark-install)
  1158. (define-key map "r" 'package-menu-refresh)
  1159. (define-key map "~" 'package-menu-mark-obsolete-for-deletion)
  1160. (define-key map "x" 'package-menu-execute)
  1161. (define-key map "h" 'package-menu-quick-help)
  1162. (define-key map "?" 'package-menu-describe-package)
  1163. (define-key map [follow-link] 'mouse-face)
  1164. (define-key map [mouse-2] 'mouse-select-window)
  1165. (define-key map [menu-bar package-menu] (cons "Package" menu-map))
  1166. (define-key menu-map [mq]
  1167. '(menu-item "Quit" quit-window
  1168. :help "Quit package selection"))
  1169. (define-key menu-map [s1] '("--"))
  1170. (define-key menu-map [mn]
  1171. '(menu-item "Next" next-line
  1172. :help "Next Line"))
  1173. (define-key menu-map [mp]
  1174. '(menu-item "Previous" previous-line
  1175. :help "Previous Line"))
  1176. (define-key menu-map [s2] '("--"))
  1177. (define-key menu-map [mu]
  1178. '(menu-item "Unmark" package-menu-mark-unmark
  1179. :help "Clear any marks on a package and move to the next line"))
  1180. (define-key menu-map [munm]
  1181. '(menu-item "Unmark backwards" package-menu-backup-unmark
  1182. :help "Back up one line and clear any marks on that package"))
  1183. (define-key menu-map [md]
  1184. '(menu-item "Mark for deletion" package-menu-mark-delete
  1185. :help "Mark a package for deletion and move to the next line"))
  1186. (define-key menu-map [mi]
  1187. '(menu-item "Mark for install" package-menu-mark-install
  1188. :help "Mark a package for installation and move to the next line"))
  1189. (define-key menu-map [s3] '("--"))
  1190. (define-key menu-map [mg]
  1191. '(menu-item "Update package list" revert-buffer
  1192. :help "Update the list of packages"))
  1193. (define-key menu-map [mr]
  1194. '(menu-item "Refresh package list" package-menu-refresh
  1195. :help "Download the ELPA archive"))
  1196. (define-key menu-map [s4] '("--"))
  1197. (define-key menu-map [mt]
  1198. '(menu-item "Mark obsolete packages" package-menu-mark-obsolete-for-deletion
  1199. :help "Mark all obsolete packages for deletion"))
  1200. (define-key menu-map [mx]
  1201. '(menu-item "Execute actions" package-menu-execute
  1202. :help "Perform all the marked actions"))
  1203. (define-key menu-map [s5] '("--"))
  1204. (define-key menu-map [mh]
  1205. '(menu-item "Help" package-menu-quick-help
  1206. :help "Show short key binding help for package-menu-mode"))
  1207. (define-key menu-map [mc]
  1208. '(menu-item "View Commentary" package-menu-view-commentary
  1209. :help "Display information about this package"))
  1210. map)
  1211. "Local keymap for `package-menu-mode' buffers.")
  1212. (defvar package-menu-sort-button-map
  1213. (let ((map (make-sparse-keymap)))
  1214. (define-key map [header-line mouse-1] 'package-menu-sort-by-column)
  1215. (define-key map [header-line mouse-2] 'package-menu-sort-by-column)
  1216. (define-key map [follow-link] 'mouse-face)
  1217. map)
  1218. "Local keymap for package menu sort buttons.")
  1219. (put 'package-menu-mode 'mode-class 'special)
  1220. (define-derived-mode package-menu-mode special-mode "Package Menu"
  1221. "Major mode for browsing a list of packages.
  1222. Letters do not insert themselves; instead, they are commands.
  1223. \\<package-menu-mode-map>
  1224. \\{package-menu-mode-map}"
  1225. (setq truncate-lines t)
  1226. (setq buffer-read-only t)
  1227. (set (make-local-variable 'revert-buffer-function) 'package-menu-revert)
  1228. (setq header-line-format
  1229. (mapconcat
  1230. (lambda (pair)
  1231. (let ((column (car pair))
  1232. (name (cdr pair)))
  1233. (concat
  1234. ;; Insert a space that aligns the button properly.
  1235. (propertize " " 'display (list 'space :align-to column)
  1236. 'face 'fixed-pitch)
  1237. ;; Set up the column button.
  1238. (propertize name
  1239. 'column-name name
  1240. 'help-echo "mouse-1: sort by column"
  1241. 'mouse-face 'highlight
  1242. 'keymap package-menu-sort-button-map))))
  1243. ;; We take a trick from buff-menu and have a dummy leading
  1244. ;; space to align the header line with the beginning of the
  1245. ;; text. This doesn't really work properly on Emacs 21, but
  1246. ;; it is close enough.
  1247. '((0 . "")
  1248. (2 . "Package")
  1249. (20 . "Version")
  1250. (32 . "Status")
  1251. (43 . "Description"))
  1252. "")))
  1253. (defun package-menu-refresh ()
  1254. "Download the Emacs Lisp package archive.
  1255. This fetches the contents of each archive specified in
  1256. `package-archives', and then refreshes the package menu."
  1257. (interactive)
  1258. (unless (eq major-mode 'package-menu-mode)
  1259. (error "The current buffer is not a Package Menu"))
  1260. (package-refresh-contents)
  1261. (package--generate-package-list))
  1262. (defun package-menu-revert (&optional arg noconfirm)
  1263. "Update the list of packages.
  1264. This function is the `revert-buffer-function' for Package Menu
  1265. buffers. The arguments are ignored."
  1266. (interactive)
  1267. (unless (eq major-mode 'package-menu-mode)
  1268. (error "The current buffer is not a Package Menu"))
  1269. (package--generate-package-list))
  1270. (defun package-menu-describe-package ()
  1271. "Describe the package in the current line."
  1272. (interactive)
  1273. (let ((name (package-menu-get-package)))
  1274. (if name
  1275. (describe-package (intern name))
  1276. (message "No package on this line"))))
  1277. (defun package-menu-mark-internal (what)
  1278. (unless (eobp)
  1279. (let ((buffer-read-only nil))
  1280. (beginning-of-line)
  1281. (delete-char 1)
  1282. (insert what)
  1283. (forward-line))))
  1284. ;; fixme numeric argument
  1285. (defun package-menu-mark-delete (num)
  1286. "Mark a package for deletion and move to the next line."
  1287. (interactive "p")
  1288. (if (string-equal (package-menu-get-status) "installed")
  1289. (package-menu-mark-internal "D")
  1290. (forward-line)))
  1291. (defun package-menu-mark-install (num)
  1292. "Mark a package for installation and move to the next line."
  1293. (interactive "p")
  1294. (if (string-equal (package-menu-get-status) "available")
  1295. (package-menu-mark-internal "I")
  1296. (forward-line)))
  1297. (defun package-menu-mark-unmark (num)
  1298. "Clear any marks on a package and move to the next line."
  1299. (interactive "p")
  1300. (package-menu-mark-internal " "))
  1301. (defun package-menu-backup-unmark ()
  1302. "Back up one line and clear any marks on that package."
  1303. (interactive)
  1304. (forward-line -1)
  1305. (package-menu-mark-internal " ")
  1306. (forward-line -1))
  1307. (defun package-menu-mark-obsolete-for-deletion ()
  1308. "Mark all obsolete packages for deletion."
  1309. (interactive)
  1310. (save-excursion
  1311. (goto-char (point-min))
  1312. (forward-line 2)
  1313. (while (not (eobp))
  1314. (if (looking-at ".*\\s obsolete\\s ")
  1315. (package-menu-mark-internal "D")
  1316. (forward-line 1)))))
  1317. (defun package-menu-quick-help ()
  1318. "Show short key binding help for package-menu-mode."
  1319. (interactive)
  1320. (message "n-ext, i-nstall, d-elete, u-nmark, x-ecute, r-efresh, h-elp"))
  1321. (define-obsolete-function-alias
  1322. 'package-menu-view-commentary 'package-menu-describe-package "24.1")
  1323. ;; Return the name of the package on the current line.
  1324. (defun package-menu-get-package ()
  1325. (save-excursion
  1326. (beginning-of-line)
  1327. (if (looking-at ". \\([^ \t]*\\)")
  1328. (match-string-no-properties 1))))
  1329. ;; Return the version of the package on the current line.
  1330. (defun package-menu-get-version ()
  1331. (save-excursion
  1332. (beginning-of-line)
  1333. (if (looking-at ". [^ \t]*[ \t]*\\([0-9.]*\\)")
  1334. (match-string 1))))
  1335. (defun package-menu-get-status ()
  1336. (save-excursion
  1337. (if (looking-at ". [^ \t]*[ \t]*[^ \t]*[ \t]*\\([^ \t]*\\)")
  1338. (match-string 1)
  1339. "")))
  1340. (defun package-menu-execute ()
  1341. "Perform marked Package Menu actions.
  1342. Packages marked for installation are downloaded and installed;
  1343. packages marked for deletion are removed."
  1344. (interactive)
  1345. (let (install-list delete-list cmd)
  1346. (save-excursion
  1347. (goto-char (point-min))
  1348. (while (not (eobp))
  1349. (setq cmd (char-after))
  1350. (cond
  1351. ((eq cmd ?\s) t)
  1352. ((eq cmd ?D)
  1353. (push (cons (package-menu-get-package)
  1354. (package-menu-get-version))
  1355. delete-list))
  1356. ((eq cmd ?I)
  1357. (push (package-menu-get-package) install-list)))
  1358. (forward-line)))
  1359. ;; Delete packages, prompting if necessary.
  1360. (when delete-list
  1361. (if (yes-or-no-p
  1362. (if (= (length delete-list) 1)
  1363. (format "Delete package `%s-%s'? "
  1364. (caar delete-list)
  1365. (cdr (car delete-list)))
  1366. (format "Delete these %d packages (%s)? "
  1367. (length delete-list)
  1368. (mapconcat (lambda (elt)
  1369. (concat (car elt) "-" (cdr elt)))
  1370. delete-list
  1371. ", "))))
  1372. (dolist (elt delete-list)
  1373. (condition-case-no-debug err
  1374. (package-delete (car elt) (cdr elt))
  1375. (error (message (cadr err)))))
  1376. (error "Aborted")))
  1377. (when install-list
  1378. (if (yes-or-no-p
  1379. (if (= (length install-list) 1)
  1380. (format "Install package `%s'? " (car install-list))
  1381. (format "Install these %d packages (%s)? "
  1382. (length install-list)
  1383. (mapconcat 'identity install-list ", "))))
  1384. (dolist (elt install-list)
  1385. (package-install (intern elt)))))
  1386. ;; If we deleted anything, regenerate `package-alist'. This is done
  1387. ;; automatically if we installed a package.
  1388. (and delete-list (null install-list)
  1389. (package-initialize))
  1390. (if (or delete-list install-list)
  1391. (package-menu-revert)
  1392. (message "No operations specified."))))
  1393. (defun package-print-package (package version key desc)
  1394. (let ((face
  1395. (cond ((string= key "built-in") 'font-lock-builtin-face)
  1396. ((string= key "available") 'default)
  1397. ((string= key "held") 'font-lock-constant-face)
  1398. ((string= key "disabled") 'font-lock-warning-face)
  1399. ((string= key "installed") 'font-lock-comment-face)
  1400. (t ; obsolete, but also the default.
  1401. 'font-lock-warning-face))))
  1402. (insert (propertize " " 'font-lock-face face))
  1403. (insert-text-button (symbol-name package)
  1404. 'face 'link
  1405. 'follow-link t
  1406. 'package-symbol package
  1407. 'action (lambda (button)
  1408. (describe-package
  1409. (button-get button 'package-symbol))))
  1410. (indent-to 20 1)
  1411. (insert (propertize (package-version-join version) 'font-lock-face face))
  1412. (indent-to 32 1)
  1413. (insert (propertize key 'font-lock-face face))
  1414. ;; FIXME: this 'when' is bogus...
  1415. (when desc
  1416. (indent-to 43 1)
  1417. (let ((opoint (point)))
  1418. (insert (propertize desc 'font-lock-face face))
  1419. (upcase-region opoint (min (point) (1+ opoint)))))
  1420. (insert "\n")))
  1421. (defun package-list-maybe-add (package version status description result)
  1422. (unless (assoc (cons package version) result)
  1423. (push (list (cons package version) status description) result))
  1424. result)
  1425. (defvar package-menu-package-list nil
  1426. "List of packages to display in the Package Menu buffer.
  1427. A value of nil means to display all packages.")
  1428. (defvar package-menu-sort-key nil
  1429. "Sort key for the current Package Menu buffer.")
  1430. (defun package--generate-package-list ()
  1431. "Populate the current Package Menu buffer."
  1432. (let ((inhibit-read-only t)
  1433. info-list name desc hold builtin)
  1434. (erase-buffer)
  1435. ;; List installed packages
  1436. (dolist (elt package-alist)
  1437. (setq name (car elt))
  1438. (when (or (null package-menu-package-list)
  1439. (memq name package-menu-package-list))
  1440. (setq desc (cdr elt)
  1441. hold (cadr (assq name package-load-list)))
  1442. (setq info-list
  1443. (package-list-maybe-add
  1444. name (package-desc-vers desc)
  1445. ;; FIXME: it turns out to be tricky to see if this
  1446. ;; package is presently activated.
  1447. (if (stringp hold) "held" "installed")
  1448. (package-desc-doc desc)
  1449. info-list))))
  1450. ;; List built-in packages
  1451. (dolist (elt package--builtins)
  1452. (setq name (car elt))
  1453. (when (and (not (eq name 'emacs)) ; Hide the `emacs' package.
  1454. (or (null package-menu-package-list)
  1455. (memq name package-menu-package-list)))
  1456. (setq desc (cdr elt))
  1457. (setq info-list
  1458. (package-list-maybe-add
  1459. name (package-desc-vers desc)
  1460. "built-in"
  1461. (package-desc-doc desc)
  1462. info-list))))
  1463. ;; List available and disabled packages
  1464. (dolist (elt package-archive-contents)
  1465. (setq name (car elt)
  1466. desc (cdr elt)
  1467. hold (assq name package-load-list))
  1468. (when (or (null package-menu-package-list)
  1469. (memq name package-menu-package-list))
  1470. (setq info-list
  1471. (package-list-maybe-add name
  1472. (package-desc-vers desc)
  1473. (if (and hold (null (cadr hold)))
  1474. "disabled"
  1475. "available")
  1476. (package-desc-doc (cdr elt))
  1477. info-list))))
  1478. ;; List obsolete packages
  1479. (mapc (lambda (elt)
  1480. (mapc (lambda (inner-elt)
  1481. (setq info-list
  1482. (package-list-maybe-add (car elt)
  1483. (package-desc-vers
  1484. (cdr inner-elt))
  1485. "obsolete"
  1486. (package-desc-doc
  1487. (cdr inner-elt))
  1488. info-list)))
  1489. (cdr elt)))
  1490. package-obsolete-alist)
  1491. (setq info-list
  1492. (sort info-list
  1493. (cond ((string= package-menu-sort-key "Package")
  1494. 'package-menu--name-predicate)
  1495. ((string= package-menu-sort-key "Version")
  1496. 'package-menu--version-predicate)
  1497. ((string= package-menu-sort-key "Description")
  1498. 'package-menu--description-predicate)
  1499. (t ; By default, sort by package status
  1500. 'package-menu--status-predicate))))
  1501. (dolist (elt info-list)
  1502. (package-print-package (car (car elt))
  1503. (cdr (car elt))
  1504. (car (cdr elt))
  1505. (car (cdr (cdr elt)))))
  1506. (goto-char (point-min))
  1507. (set-buffer-modified-p nil)
  1508. (current-buffer)))
  1509. (defun package-menu--version-predicate (left right)
  1510. (let ((vleft (or (cdr (car left)) '(0)))
  1511. (vright (or (cdr (car right)) '(0))))
  1512. (if (version-list-= vleft vright)
  1513. (package-menu--name-predicate left right)
  1514. (version-list-< vleft vright))))
  1515. (defun package-menu--status-predicate (left right)
  1516. (let ((sleft (cadr left))
  1517. (sright (cadr right)))
  1518. (cond ((string= sleft sright)
  1519. (package-menu--name-predicate left right))
  1520. ((string= sleft "available") t)
  1521. ((string= sright "available") nil)
  1522. ((string= sleft "installed") t)
  1523. ((string= sright "installed") nil)
  1524. ((string= sleft "held") t)
  1525. ((string= sright "held") nil)
  1526. ((string= sleft "built-in") t)
  1527. ((string= sright "built-in") nil)
  1528. ((string= sleft "obsolete") t)
  1529. ((string= sright "obsolete") nil)
  1530. (t (string< sleft sright)))))
  1531. (defun package-menu--description-predicate (left right)
  1532. (let ((sleft (car (cddr left)))
  1533. (sright (car (cddr right))))
  1534. (if (string= sleft sright)
  1535. (package-menu--name-predicate left right)
  1536. (string< sleft sright))))
  1537. (defun package-menu--name-predicate (left right)
  1538. (string< (symbol-name (caar left))
  1539. (symbol-name (caar right))))
  1540. (defun package-menu-sort-by-column (&optional e)
  1541. "Sort the package menu by the column of the mouse click E."
  1542. (interactive "e")
  1543. (let* ((pos (event-start e))
  1544. (obj (posn-object pos))
  1545. (col (if obj
  1546. (get-text-property (cdr obj) 'column-name (car obj))
  1547. (get-text-property (posn-point pos) 'column-name)))
  1548. (buf (window-buffer (posn-window (event-start e)))))
  1549. (with-current-buffer buf
  1550. (when (eq major-mode 'package-menu-mode)
  1551. (setq package-menu-sort-key col)
  1552. (package--generate-package-list)))))
  1553. (defun package--list-packages (&optional packages)
  1554. "Generate and pop to the *Packages* buffer.
  1555. Optional PACKAGES is a list of names of packages (symbols) to
  1556. list; the default is to display everything in `package-alist'."
  1557. (require 'finder-inf nil t)
  1558. (let ((buf (get-buffer-create "*Packages*")))
  1559. (with-current-buffer buf
  1560. (package-menu-mode)
  1561. (set (make-local-variable 'package-menu-package-list) packages)
  1562. (set (make-local-variable 'package-menu-sort-key) nil)
  1563. (package--generate-package-list))
  1564. ;; The package menu buffer has keybindings. If the user types
  1565. ;; `M-x list-packages', that suggests it should become current.
  1566. (switch-to-buffer buf)))
  1567. ;;;###autoload
  1568. (defun list-packages ()
  1569. "Display a list of packages.
  1570. Fetches the updated list of packages before displaying.
  1571. The list is displayed in a buffer named `*Packages*'."
  1572. (interactive)
  1573. ;; Initialize the package system if necessary.
  1574. (unless package--initialized
  1575. (package-initialize t))
  1576. (package-refresh-contents)
  1577. (package--list-packages))
  1578. ;;;###autoload
  1579. (defalias 'package-list-packages 'list-packages)
  1580. (defun package-list-packages-no-fetch ()
  1581. "Display a list of packages.
  1582. Does not fetch the updated list of packages before displaying.
  1583. The list is displayed in a buffer named `*Packages*'."
  1584. (interactive)
  1585. (package--list-packages))
  1586. (provide 'package)
  1587. ;;; package.el ends here