Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
8.7 KiB

  1. ;;; paradox.el --- A modern Packages Menu. Colored, with package ratings, and customizable. -*- lexical-binding:t -*-
  2. ;; Copyright (C) 2014-2015 Artur Malabarba <emacs@endlessparentheses.com>
  3. ;; Author: Artur Malabarba <emacs@endlessparentheses.com>
  4. ;; URL: https://github.com/Malabarba/paradox
  5. ;; Version: 2.5.4
  6. ;; Keywords: package packages
  7. ;; Package-Requires: ((emacs "24.4") (seq "1.7") (let-alist "1.0.3") (spinner "1.7.3") (hydra "0.13.2"))
  8. ;; Prefix: paradox
  9. ;; Separator: -
  10. ;;; Commentary:
  11. ;;
  12. ;; Paradox can be installed from Melpa with M-x `package-install' RET
  13. ;; paradox.
  14. ;; It can also be installed manually in the usual way, just be mindful of
  15. ;; the dependencies.
  16. ;;
  17. ;; To use it, simply call M-x `paradox-list-packages' (instead of the
  18. ;; regular `list-packages').
  19. ;; This will give you most features out of the box. If you want to be
  20. ;; able to star packages as well, just configure the
  21. ;; `paradox-github-token' variable then call `paradox-list-packages'
  22. ;; again.
  23. ;;
  24. ;; If you'd like to stop using Paradox, you may call `paradox-disable'
  25. ;; and go back to using the regular `list-packages'.
  26. ;;
  27. ;; ## Current Features ##
  28. ;;
  29. ;; ### Several Improvements ###
  30. ;;
  31. ;; Paradox implements many small improvements to the package menu
  32. ;; itself. They all work out of the box and are completely customizable!
  33. ;; *(Also, hit `h' to see all keys.)*
  34. ;;
  35. ;; * Visit the package's homepage with `v' (or just use the provided buttons).
  36. ;; * Shortcuts for package filtering:
  37. ;; * <f r> filters by regexp (`occur');
  38. ;; * <f u> display only packages with upgrades;
  39. ;; * <f k> filters by keyword.
  40. ;; * `hl-line-mode' enabled by default.
  41. ;; * Display useful information on the mode-line and cleanup a bunch of
  42. ;; useless stuff.
  43. ;; * **Customization!** Just call M-x `paradox-customize' to see what you can
  44. ;; do.
  45. ;; * Customize column widths.
  46. ;; * Customize faces (`paradox-star-face', `paradox-status-face-alist' and `paradox-archive-face').
  47. ;; * Customize local variables.
  48. ;;
  49. ;; ### Package Ratings ###
  50. ;;
  51. ;; Paradox also integrates with
  52. ;; **GitHub Stars**, which works as **rough** package rating system.
  53. ;; That is, Paradox package menu will:
  54. ;;
  55. ;; 1. Display the number of GitHub Stars each package has (assuming it's
  56. ;; in a github repo, of course);
  57. ;; 2. Possibly automatically star packages you install, and unstar
  58. ;; packages you delete (you will be asked the first time whether you
  59. ;; want this);
  60. ;; 3. Let you star and unstar packages by hitting the `s' key;
  61. ;; 4. Let you star all packages you have installed with M-x `paradox-star-all-installed-packages'.
  62. ;;
  63. ;; Item **1.** will work out of the box, the other items obviously
  64. ;; require a github account (Paradox will help you generate a token the
  65. ;; first time you call `paradox-list-packages').
  66. ;;
  67. ;; ## How Star Displaying Works ##
  68. ;;
  69. ;; We generate a map of Package Name -> Repository from
  70. ;; [Melpa](https://github.com/milkypostman/melpa.git)'s `recipe'
  71. ;; directory, some repos may correspond to more than one package.
  72. ;; This map is used count the stars a given package has.
  73. ;; _This doesn't mean you need Melpa to see the star counts, the numbers
  74. ;; will be displayed regardless of what archives you use._
  75. ;;
  76. ;; Currently, packages that are not hosted on GitHub are listed with a
  77. ;; blank star count, which is clearly different from 0-star packages
  78. ;; (which are displayed with a 0, obviously).
  79. ;; If you know of an alternative that could be used for these packages,
  80. ;; [open an issue](https://github.com/Bruce-Connor/paradox/issues/new)
  81. ;; here, I'd love to hear.
  82. ;;; License:
  83. ;;
  84. ;; This file is NOT part of GNU Emacs.
  85. ;;
  86. ;; This program is free software; you can redistribute it and/or
  87. ;; modify it under the terms of the GNU General Public License
  88. ;; as published by the Free Software Foundation; either version 2
  89. ;; of the License, or (at your option) any later version.
  90. ;;
  91. ;; This program is distributed in the hope that it will be useful,
  92. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  93. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  94. ;; GNU General Public License for more details.
  95. ;;; Code:
  96. (require 'package)
  97. (require 'cl-lib)
  98. (require 'paradox-core)
  99. (require 'paradox-execute)
  100. (require 'paradox-menu)
  101. (defconst paradox-version "2.5.4" "Version of the paradox.el package.")
  102. (defun paradox-bug-report ()
  103. "Opens github issues page in a web browser. Please send any bugs you find.
  104. Please include your Emacs and paradox versions."
  105. (interactive)
  106. (message "Your paradox-version is: %s, and your emacs version is: %s.\nPlease include this in your report!"
  107. paradox-version emacs-version)
  108. (browse-url "https://github.com/Bruce-Connor/paradox/issues/new"))
  109. (defun paradox-customize ()
  110. "Open the customization menu in the `paradox' group."
  111. (interactive)
  112. (customize-group 'paradox t))
  113. (defgroup paradox nil
  114. "Customization group for paradox."
  115. :prefix "paradox-"
  116. :group 'emacs
  117. :package-version '(paradox . "0.1"))
  118. ;;; External Commands
  119. ;;;###autoload
  120. (defun paradox-list-packages (no-fetch)
  121. "Improved version of `package-list-packages'. The heart of Paradox.
  122. Function is equivalent to `package-list-packages' (including the
  123. prefix NO-FETCH), but the resulting Package Menu is improved in
  124. several ways.
  125. Among them:
  126. 1. Uses `paradox-menu-mode', which has more functionality and
  127. keybinds than `package-menu-mode'.
  128. 2. Uses some font-locking to improve readability.
  129. 3. Optionally shows the number GitHub stars and Melpa downloads
  130. for packages.
  131. 4. Adds useful information in the mode-line."
  132. (interactive "P")
  133. (when (paradox--check-github-token)
  134. (paradox-enable)
  135. (let ((is-25 (fboundp 'package--with-response-buffer)))
  136. (unless no-fetch
  137. (if is-25
  138. (add-to-list 'package--downloads-in-progress 'paradox--data)
  139. (paradox--refresh-remote-data)))
  140. (package-list-packages no-fetch)
  141. (unless no-fetch
  142. (when (stringp paradox-github-token)
  143. (paradox--refresh-user-starred-list
  144. (bound-and-true-p package-menu-async)))
  145. (when is-25
  146. (paradox--refresh-remote-data))))))
  147. ;;;###autoload
  148. (defun paradox-upgrade-packages (&optional no-fetch)
  149. "Upgrade all packages. No questions asked.
  150. This function is equivalent to `list-packages', followed by a
  151. `package-menu-mark-upgrades' and a `package-menu-execute'. Except
  152. the user isn't asked to confirm deletion of packages.
  153. If `paradox-execute-asynchronously' is non-nil, part of this
  154. operation may be performed in the background.
  155. The NO-FETCH prefix argument is passed to `list-packages'. It
  156. prevents re-download of information about new versions. It does
  157. not prevent downloading the actual packages (obviously)."
  158. (interactive "P")
  159. (save-window-excursion
  160. (let ((package-menu-async nil))
  161. (paradox-list-packages no-fetch))
  162. (package-menu-mark-upgrades)
  163. (paradox-menu-execute 'noquery)))
  164. ;;;###autoload
  165. (defun paradox-enable ()
  166. "Enable paradox, overriding the default package-menu."
  167. (interactive)
  168. (when (and (fboundp 'package--update-downloads-in-progress)
  169. (not (fboundp 'package--with-response-buffer)))
  170. (message "[Paradox] Your Emacs snapshot is outdated, please install a more recent one.")
  171. (setq package-menu-async nil))
  172. (paradox--override-definition 'package-menu--print-info 'paradox--print-info)
  173. (when (fboundp 'package-menu--print-info-simple)
  174. (paradox--override-definition 'package-menu--print-info-simple 'paradox--print-info))
  175. (paradox--override-definition 'package-menu--generate 'paradox--generate-menu)
  176. ;; Tough it may not look like it, this is totally necessary too.
  177. (paradox--override-definition 'package-menu-mode 'paradox-menu-mode)
  178. (paradox--core-enable))
  179. ;;;###autoload
  180. (defun paradox-require (feature &optional filename noerror package refresh)
  181. "Like `require', but also install FEATURE if it is absent.
  182. FILENAME is passed to `require'.
  183. If NOERROR is non-nil, don't complain if the feature couldn't be
  184. installed, just return nil.
  185. - If FEATURE is present, `require' it and return t.
  186. - If FEATURE is not present, install PACKAGE with `package-install'.
  187. If PACKAGE is nil, assume FEATURE is the package name.
  188. After installation, `require' FEATURE.
  189. By default, the current package database is only updated if it is
  190. empty. Passing a non-nil REFRESH argument forces this update."
  191. (or (require feature filename t)
  192. (let ((package (or package
  193. (if (stringp feature)
  194. (intern feature)
  195. feature))))
  196. (require 'package)
  197. (unless (and package-archive-contents (null refresh))
  198. (package-refresh-contents))
  199. (and (condition-case e
  200. (package-install package)
  201. (error (if noerror nil (error (cadr e)))))
  202. (require feature filename noerror)))))
  203. (provide 'paradox)
  204. ;;; paradox.el ends here