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