use-package-2.4/ 0000755 0001750 0001750 00000000000 13374646103 013405 5 ustar dogsleg dogsleg use-package-2.4/LICENSE 0000644 0001750 0001750 00000104514 13374646103 014417 0 ustar dogsleg dogsleg GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
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 3 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.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
. use-package-2.4/README.md 0000644 0001750 0001750 00000106667 13374646103 014704 0 ustar dogsleg dogsleg # `use-package`
[](https://gitter.im/use-package/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://travis-ci.org/jwiegley/use-package)
[](http://melpa.milkbox.net/#/use-package)
[](https://stable.melpa.org/#/use-package)
The `use-package` macro allows you to isolate package configuration in your
`.emacs` file in a way that is both performance-oriented and, well, tidy. I
created it because I have over 80 packages that I use in Emacs, and things
were getting difficult to manage. Yet with this utility my total load time is
around 2 seconds, with no loss of functionality!
Note that `use-package` is **not** a package manager! Although `use-package`
does have the useful capability to interface with package managers (see
[below](#package-installation)), its primary purpose is for the configuration
and loading of packages.
Notes for users upgrading to 2.x are located [at the bottom](#upgrading-to-2x).
## Installing use-package
Either clone from this GitHub repository or install from
[MELPA](http://melpa.milkbox.net/) (recommended).
## Getting started
Here is the simplest `use-package` declaration:
``` elisp
;; This is only needed once, near the top of the file
(eval-when-compile
;; Following line is not needed if use-package.el is in ~/.emacs.d
(add-to-list 'load-path "")
(require 'use-package))
(use-package foo)
```
This loads in the package `foo`, but only if `foo` is available on your
system. If not, a warning is logged to the `*Messages*` buffer.
Use the `:init` keyword to execute code before a package is loaded. It
accepts one or more forms, up to the next keyword:
``` elisp
(use-package foo
:init
(setq foo-variable t))
```
Similarly, `:config` can be used to execute code after a package is loaded.
In cases where loading is done lazily (see more about autoloading below), this
execution is deferred until after the autoload occurs:
``` elisp
(use-package foo
:init
(setq foo-variable t)
:config
(foo-mode 1))
```
As you might expect, you can use `:init` and `:config` together:
``` elisp
(use-package color-moccur
:commands (isearch-moccur isearch-all)
:bind (("M-s O" . moccur)
:map isearch-mode-map
("M-o" . isearch-moccur)
("M-O" . isearch-moccur-all))
:init
(setq isearch-lazy-highlight t)
:config
(use-package moccur-edit))
```
In this case, I want to autoload the commands `isearch-moccur` and
`isearch-all` from `color-moccur.el`, and bind keys both at the global level
and within the `isearch-mode-map` (see next section). When the package is
actually loaded (by using one of these commands), `moccur-edit` is also
loaded, to allow editing of the `moccur` buffer.
## Key-binding
Another common thing to do when loading a module is to bind a key to primary
commands within that module:
``` elisp
(use-package ace-jump-mode
:bind ("C-." . ace-jump-mode))
```
This does two things: first, it creates an autoload for the `ace-jump-mode`
command and defers loading of `ace-jump-mode` until you actually use it.
Second, it binds the key `C-.` to that command. After loading, you can use
`M-x describe-personal-keybindings` to see all such keybindings you've set
throughout your `.emacs` file.
A more literal way to do the exact same thing is:
``` elisp
(use-package ace-jump-mode
:commands ace-jump-mode
:init
(bind-key "C-." 'ace-jump-mode))
```
When you use the `:commands` keyword, it creates autoloads for those commands
and defers loading of the module until they are used. Since the `:init` form
is always run -- even if `ace-jump-mode` might not be on your system --
remember to restrict `:init` code to only what would succeed either way.
The `:bind` keyword takes either a cons or a list of conses:
``` elisp
(use-package hi-lock
:bind (("M-o l" . highlight-lines-matching-regexp)
("M-o r" . highlight-regexp)
("M-o w" . highlight-phrase)))
```
The `:commands` keyword likewise takes either a symbol or a list of symbols.
NOTE: Inside strings, special keys like `tab` or `F1`-`Fn` have to be written inside angle brackets, e.g. `"C-"`.
Standalone special keys (and some combinations) can be written in square brackets, e.g. `[tab]` instead of `""`. The syntax for the keybindings is similar to
the "kbd" syntax: see [https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-Rebinding.html](https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-Rebinding.html)
for more information.
Examples:
``` elisp
(use-package helm
:bind (("M-x" . helm-M-x)
("M-" . helm-find-files)
([f10] . helm-buffers-list)
([S-f10] . helm-recentf)))
```
Furthermore, [remapping commands](https://www.gnu.org/software/emacs/manual/html_node/elisp/Remapping-Commands.html)
with `:bind` and `bind-key` works as expected, because when the
binding is a vector, it is passed straight to `define-key`. So the
following example will rebind `M-q` (originally `fill-paragraph`) to
`unfill-toggle`:
``` elisp
(use-package unfill
:bind ([remap fill-paragraph] . unfill-toggle))
```
### Binding to keymaps
Normally `:bind` expects that commands are functions that will be autoloaded
from the given package. However, this does not work if one of those commands
is actually a keymap, since keymaps are not functions, and cannot be
autoloaded using Emacs' `autoload` mechanism.
To handle this case, `use-package` offers a special, limited variant of
`:bind` called `:bind-keymap`. The only difference is that the "commands"
bound to by `:bind-keymap` must be keymaps defined in the package, rather than
command functions. This is handled behind the scenes by generating custom code
that loads the package containing the keymap, and then re-executes your
keypress after the first load, to reinterpret that keypress as a prefix key.
For example:
``` elisp
(use-package projectile
:bind-keymap
("C-c p" . projectile-command-map))
```
### Binding within local keymaps
Slightly different from binding a key to a keymap, is binding a key *within* a
local keymap that only exists after the package is loaded. `use-package`
supports this with a `:map` modifier, taking the local keymap to bind to:
``` elisp
(use-package helm
:bind (:map helm-command-map
("C-c h" . helm-execute-persistent-action)))
```
The effect of this statement is to wait until `helm` has loaded, and then to
bind the key `C-c h` to `helm-execute-persistent-action` within Helm's local
keymap, `helm-mode-map`.
Multiple uses of `:map` may be specified. Any binding occurring before the
first use of `:map` are applied to the global keymap:
``` elisp
(use-package term
:bind (("C-c t" . term)
:map term-mode-map
("M-p" . term-send-up)
("M-n" . term-send-down)
:map term-raw-map
("M-o" . other-window)
("M-p" . term-send-up)
("M-n" . term-send-down)))
```
## Modes and interpreters
Similar to `:bind`, you can use `:mode` and `:interpreter` to establish a
deferred binding within the `auto-mode-alist` and `interpreter-mode-alist`
variables. The specifier to either keyword can be a cons cell, a list of cons
cells, or a string or regexp:
``` elisp
(use-package ruby-mode
:mode "\\.rb\\'"
:interpreter "ruby")
;; The package is "python" but the mode is "python-mode":
(use-package python
:mode ("\\.py\\'" . python-mode)
:interpreter ("python" . python-mode))
```
If you aren't using `:commands`, `:bind`, `:bind*`, `:bind-keymap`,
`:bind-keymap*`, `:mode`, `:interpreter`, or `:hook` (all of which imply `:defer`; see
the docstring for `use-package` for a brief description of each), you can
still defer loading with the `:defer` keyword:
``` elisp
(use-package ace-jump-mode
:defer t
:init
(autoload 'ace-jump-mode "ace-jump-mode" nil t)
(bind-key "C-." 'ace-jump-mode))
```
This does exactly the same thing as the following:
``` elisp
(use-package ace-jump-mode
:bind ("C-." . ace-jump-mode))
```
## Magic handlers
Similar to `:mode` and `:interpreter`, you can also use `:magic` and
`:magic-fallback` to cause certain function to be run if the beginning of a
file matches a given regular expression. The difference between the two is
that `:magic-fallback` has a lower priority than `:mode`. For example:
``` elisp
(use-package pdf-tools
:load-path "site-lisp/pdf-tools/lisp"
:magic ("%PDF" . pdf-view-mode)
:config
(pdf-tools-install))
```
This registers an autoloaded command for `pdf-view-mode`, defers loading of
`pdf-tools`, and runs `pdf-view-mode` if the beginning of a buffer matches the
string `"%PDF"`.
## Hooks
The `:hook` keyword allows adding functions onto hooks, here only the basename
of the hook is required. Thus, all of the following are equivalent:
``` elisp
(use-package ace-jump-mode
:hook prog-mode)
(use-package ace-jump-mode
:hook (prog-mode . ace-jump-mode))
(use-package ace-jump-mode
:commands ace-jump-mode
:init
(add-hook 'prog-mode-hook #'ace-jump-mode))
```
And likewise, when multiple hooks should be applied, the following are also
equivalent:
``` elisp
(use-package ace-jump-mode
:hook (prog-mode text-mode))
(use-package ace-jump-mode
:hook ((prog-mode text-mode) . ace-jump-mode))
(use-package ace-jump-mode
:hook ((prog-mode . ace-jump-mode)
(text-mode . ace-jump-mode)))
(use-package ace-jump-mode
:commands ace-jump-mode
:init
(add-hook 'prog-mode-hook #'ace-jump-mode)
(add-hook 'text-mode-hook #'ace-jump-mode))
```
The use of `:hook`, as with `:bind`, `:mode`, `:interpreter`, etc., causes the
functions being hooked to implicitly be read as `:commands` (meaning they will
establish interactive `autoload` definitions for that module, if not already
defined as functions), and so `:defer t` is also implied by `:hook`.
## Package customization
### Customizing variables.
The `:custom` keyword allows customization of package custom variables.
``` elisp
(use-package comint
:custom
(comint-buffer-maximum-size 20000 "Increase comint buffer size.")
(comint-prompt-read-only t "Make the prompt read only."))
```
The documentation string is not mandatory.
**NOTE**: These are only for people who wish to keep customizations with their
accompanying use-package declarations. Functionally, the only benefit over
using `setq` in a `:config` block is that customizations might execute code
when values are assigned. If you currently use `M-x customize-option` and save
to a settings file, you do not want to use this option.
### Customizing faces
The `:custom-face` keyword allows customization of package custom faces.
``` elisp
(use-package eruby-mode
:custom-face
(eruby-standard-face ((t (:slant italic)))))
```
## Notes about lazy loading
In almost all cases you don't need to manually specify `:defer t`. This is
implied whenever `:bind` or `:mode` or `:interpreter` is used. Typically, you
only need to specify `:defer` if you know for a fact that some other package
will do something to cause your package to load at the appropriate time, and
thus you would like to defer loading even though use-package isn't creating
any autoloads for you.
You can override package deferral with the `:demand` keyword. Thus, even if
you use `:bind`, using `:demand` will force loading to occur immediately and
not establish an autoload for the bound key.
## Information about package loads
When a package is loaded, and if you have `use-package-verbose` set to `t`, or
if the package takes longer than 0.1s to load, you will see a message to
indicate this loading activity in the `*Messages*` buffer. The same will
happen for configuration, or `:config` blocks that take longer than 0.1s to
execute. In general, you should keep `:init` forms as simple and quick as
possible, and put as much as you can get away with into the `:config` block.
This way, deferred loading can help your Emacs to start as quickly as
possible.
Additionally, if an error occurs while initializing or configuring a package,
this will not stop your Emacs from loading. Rather, the error will be
captured by `use-package`, and reported to a special `*Warnings*` popup
buffer, so that you can debug the situation in an otherwise functional Emacs.
## Conditional loading
You can use the `:if` keyword to predicate the loading and initialization of
modules.
For example, I only want `edit-server` running for my main,
graphical Emacs, not for other Emacsen I may start at the command line:
``` elisp
(use-package edit-server
:if window-system
:init
(add-hook 'after-init-hook 'server-start t)
(add-hook 'after-init-hook 'edit-server-start t))
```
In another example, we can load things conditional on the operating system:
``` elisp
(use-package exec-path-from-shell
:if (memq window-system '(mac ns))
:ensure t
:config
(exec-path-from-shell-initialize))
```
The `:disabled` keyword can turn off a module you're having difficulties with,
or stop loading something you're not using at the present time:
``` elisp
(use-package ess-site
:disabled
:commands R)
```
When byte-compiling your `.emacs` file, disabled declarations are omitted
from the output entirely, to accelerate startup times.
Note that `:when` is provided as an alias for `:if`, and `:unless foo` means
the same thing as `:if (not foo)`. For example, the following will also stop
`:ensure` from happening on Mac systems:
``` elisp
(when (memq window-system '(mac ns))
(use-package exec-path-from-shell
:ensure t
:config
(exec-path-from-shell-initialize)))
```
### Conditional loading before :preface
If you need to conditionalize a use-package form so that the condition occurs
before even the `:preface` is executed, simply use `when` around the
use-package form itself:
### Loading packages in sequence
Sometimes it only makes sense to configure a package after another has been
loaded, because certain variables or functions are not in scope until that
time. This can achieved using an `:after` keyword that allows a fairly rich
description of the exact conditions when loading should occur. Here is an
example:
``` elisp
(use-package hydra
:load-path "site-lisp/hydra")
(use-package ivy
:load-path "site-lisp/swiper")
(use-package ivy-hydra
:after (ivy hydra))
```
In this case, because all of these packages are demand-loaded in the order
they occur, the use of `:after` is not strictly necessary. By using it,
however, the above code becomes order-independent, without an implicit
depedence on the nature of your init file.
By default, `:after (foo bar)` is the same as `:after (:all foo bar)`, meaning
that loading of the given package will not happen until both `foo` and `bar`
have been loaded. Here are some of the other possibilities:
``` elisp
:after (foo bar)
:after (:all foo bar)
:after (:any foo bar)
:after (:all (:any foo bar) (:any baz quux))
:after (:any (:all foo bar) (:all baz quux))
```
When you nest selectors, such as `(:any (:all foo bar) (:all baz quux))`, it
means that the package will be loaded when either both `foo` and `bar` have
been loaded, or both `baz` and `quux` have been loaded.
Note: Pay attention if you set `use-package-always-defer` to t, and also use
the `:after` keyword, as you will need to specify how the declared package is
to be loaded: e.g., by some `:bind`. If you're not using one of tho mechanisms
that registers autoloads, such as `:bind` or `:hook`, and your package manager
does not provide autoloads, it's possible that without adding `:demand t` to
those declarations, your package will never be loaded.
### Prevent loading if dependencies are missing
While the `:after` keyword delays loading until the dependencies are loaded,
the somewhat simpler `:requires` keyword simply never loads the package if the
dependencies are not available at the time the `use-package` declaration is
encountered. By "available" in this context it means that `foo` is available
of `(featurep 'foo)` evaulates to a non-nil value. For example:
``` elisp
(use-package abbrev
:requires foo)
```
This is the same as:
``` elisp
(use-package abbrev
:if (featurep 'foo))
```
As a convenience, a list of such packages may be specified:
``` elisp
(use-package abbrev
:requires (foo bar baz))
```
For more complex logic, such as that supported by `:after`, simply use `:if`
and the appropriate Lisp expression.
## Byte-compiling your .emacs
Another feature of `use-package` is that it always loads every file that it
can when `.emacs` is being byte-compiled. This helps to silence spurious
warnings about unknown variables and functions.
However, there are times when this is just not enough. For those times, use
the `:defines` and `:functions` keywords to introduce dummy variable and
function declarations solely for the sake of the byte-compiler:
``` elisp
(use-package texinfo
:defines texinfo-section-list
:commands texinfo-mode
:init
(add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode)))
```
If you need to silence a missing function warning, you can use `:functions`:
``` elisp
(use-package ruby-mode
:mode "\\.rb\\'"
:interpreter "ruby"
:functions inf-ruby-keys
:config
(defun my-ruby-mode-hook ()
(require 'inf-ruby)
(inf-ruby-keys))
(add-hook 'ruby-mode-hook 'my-ruby-mode-hook))
```
### Prevent a package from loading at compile-time
Normally, `use-package` will load each package at compile time before
compiling the configuration, to ensure that any necessary symbols are in scope
to satisfy the byte-compiler. At times this can cause problems, since a
package may have special loading requirements, and all that you want to use
`use-package` for is to add a configuration to the `eval-after-load` hook. In
such cases, use the `:no-require` keyword:
``` elisp
(use-package foo
:no-require t
:config
(message "This is evaluated when `foo' is loaded"))
```
## Extending the load-path
If your package needs a directory added to the `load-path` in order to load,
use `:load-path`. This takes a symbol, a function, a string or a list of
strings. If the path is relative, it is expanded within
`user-emacs-directory`:
``` elisp
(use-package ess-site
:load-path "site-lisp/ess/lisp/"
:commands R)
```
Note that when using a symbol or a function to provide a dynamically generated
list of paths, you must inform the byte-compiler of this definition so the
value is available at byte-compilation time. This is done by using the
special form `eval-and-compile` (as opposed to `eval-when-compile`). Further,
this value is fixed at whatever was determined during compilation, to avoid
looking up the same information again on each startup:
``` elisp
(eval-and-compile
(defun ess-site-load-path ()
(shell-command "find ~ -path ess/lisp")))
(use-package ess-site
:load-path (lambda () (list (ess-site-load-path)))
:commands R)
```
## Catching errors during use-package expansion
By default, if `use-package-expand-minimally` is nil (the default),
use-package will attempts to catch and report errors that occur during
expansion of use-package declarations in your init file. Setting
`use-package-expand-minimally` to t completely disables this checking.
This behavior may be overridden locally using the `:catch` keyword. If `t` or
`nil`, it enables or disables catching errors at load time. It can also be a
function taking two arguments: the keyword being processed at the time the
error was encountered, and the error object (as generated by
`condition-case`). For example:
``` elisp
(use-package example
;; Note that errors are never trapped in the preface, since doing so would
;; hide definitions from the byte-compiler.
:preface (message "I'm here at byte-compile and load time.")
:init (message "I'm always here at startup")
:config
(message "I'm always here after the package is loaded")
(error "oops")
;; Don't try to (require 'example), this is just an example!
:no-require t
:catch (lambda (keyword err)
(message (error-message-string err))))
```
Evaluating the above form will print these messages:
```
I’m here at byte-compile and load time.
I’m always here at startup
Configuring package example...
I’m always here after the package is loaded
oops
```
## Diminishing and delighting minor modes
`use-package` also provides built-in support for the diminish and
delight utilities -- if you have them installed. Their purpose is to
remove or change minor mode strings in your mode-line.
[diminish](https://github.com/myrjola/diminish.el) is invoked with
the `:diminish` keyword, which is passed either a minor mode symbol, a
cons of the symbol and its replacement string, or just a replacement
string, in which case the minor mode symbol is guessed to be the
package name with "-mode" appended at the end:
``` elisp
(use-package abbrev
:diminish abbrev-mode
:config
(if (file-exists-p abbrev-file-name)
(quietly-read-abbrev-file)))
```
[delight](https://elpa.gnu.org/packages/delight.html) is invoked with
the `:delight` keyword, which is passed a minor mode symbol, a
replacement string or
quoted
[mode-line data](https://www.gnu.org/software/emacs/manual/html_node/elisp/Mode-Line-Data.html) (in
which case the minor mode symbol is guessed to be the package name
with "-mode" appended at the end), both of these, or several lists of
both. If no arguments are provided, the default mode name is hidden
completely.
``` elisp
;; Don't show anything for rainbow-mode.
(use-package rainbow-mode
:delight)
;; Don't show anything for auto-revert-mode, which doesn't match
;; its package name.
(use-package autorevert
:delight auto-revert-mode)
;; Remove the mode name for projectile-mode, but show the project name.
(use-package projectile
:delight '(:eval (concat " " (projectile-project-name))))
;; Completely hide visual-line-mode and change auto-fill-mode to " AF".
(use-package emacs
:delight
(auto-fill-function " AF")
(visual-line-mode))
```
## Package installation
You can use `use-package` to load packages from ELPA with `package.el`. This
is particularly useful if you share your `.emacs` among several machines; the
relevant packages are downloaded automatically once declared in your `.emacs`.
The `:ensure` keyword causes the package(s) to be installed automatically if
not already present on your system (set `(setq use-package-always-ensure t)`
if you wish this behavior to be global for all packages):
``` elisp
(use-package magit
:ensure t)
```
If you need to install a different package from the one named by
`use-package`, you can specify it like this:
``` elisp
(use-package tex
:ensure auctex)
```
Note that `:ensure` will install a package if it is not already installed, but
it does not keep it up-to-date. If you want to keep your packages updated
automatically, one option is to use
[auto-package-update](https://github.com/rranelli/auto-package-update.el),
like
``` elisp
(use-package auto-package-update
:config
(setq auto-package-update-delete-old-versions t)
(setq auto-package-update-hide-results t)
(auto-package-update-maybe))
```
Lastly, when running on Emacs 24.4 or later, use-package can pin a package to
a specific archive, allowing you to mix and match packages from different
archives. The primary use-case for this is preferring packages from the
`melpa-stable` and `gnu` archives, but using specific packages from `melpa`
when you need to track newer versions than what is available in the `stable`
archives is also a valid use-case.
By default `package.el` prefers `melpa` over `melpa-stable` due to the
versioning `(> evil-20141208.623 evil-1.0.9)`, so even if you are tracking
only a single package from `melpa`, you will need to tag all the non-`melpa`
packages with the appropriate archive. If this really annoys you, then you can
set `use-package-always-pin` to set a default.
If you want to manually keep a package updated and ignore upstream updates,
you can pin it to `manual`, which as long as there is no repository by that
name, will Just Work(tm).
`use-package` throws an error if you try to pin a package to an archive that
has not been configured using `package-archives` (apart from the magic
`manual` archive mentioned above):
```
Archive 'foo' requested for package 'bar' is not available.
```
Example:
``` elisp
(use-package company
:ensure t
:pin melpa-stable)
(use-package evil
:ensure t)
;; no :pin needed, as package.el will choose the version in melpa
(use-package adaptive-wrap
:ensure t
;; as this package is available only in the gnu archive, this is
;; technically not needed, but it helps to highlight where it
;; comes from
:pin gnu)
(use-package org
:ensure t
;; ignore org-mode from upstream and use a manually installed version
:pin manual)
```
**NOTE**: the `:pin` argument has no effect on emacs versions < 24.4.
### Usage with other package managers
By overriding `use-package-ensure-function` and/or
`use-package-pre-ensure-function`, other package managers can override
`:ensure` to use them instead of `package.el`. At the present time,
the only package manager that does this
is [`straight.el`](https://github.com/raxod502/straight.el).
## Gathering Statistics
If you'd like to see how many packages you've loaded, what stage of
initialization they've reached, and how much aggregate time they've
spent (roughly), you can enable `use-package-compute-statistics` after
loading `use-package` but before any `use-package` forms, and then run
the command `M-x use-package-report` to see the results. The buffer
displayed is a tabulated list. You can use `S` in a column to sort the
rows based on it.
## Keyword Extensions
Starting with version 2.0, `use-package` is based on an extensible
framework that makes it easy for package authors to add new keywords,
or modify the behavior of existing keywords.
Some keyword extensions are now included in the `use-package`
distribution and can be optionally installed.
### `(use-package-ensure-system-package)`
The `:ensure-system-package` keyword allows you to ensure system
binaries exist alongside your package declarations.
First, you will want to make sure `exec-path` is cognisant of all
binary package names that you would like to ensure are
installed. [`exec-path-from-shell`](https://github.com/purcell/exec-path-from-shell)
is often a good way to do this.
To enable the extension after you've loaded `use-package`:
``` elisp
(use-package use-package-ensure-system-package
:ensure t)
```
Here’s an example of usage:
``` emacs-lisp
(use-package rg
:ensure-system-package rg)
```
This will expect a global binary package to exist called `rg`. If it
does not, it will use your system package manager (using the package
[`system-packages`](https://gitlab.com/jabranham/system-packages)) to
attempt an install of a binary by the same name asyncronously. For
example, for most `macOS` users this would call: `brew install rg`.
If the package is named differently than the binary, you can use a
cons in the form of `(binary . package-name)`, i.e.:
``` emacs-lisp
(use-package rg
:ensure-system-package
(rg . ripgrep))
```
In the previous `macOS` example, this would call: `brew install
ripgrep` if `rg` was not found.
What if you want to customize the install command further?
``` emacs-lisp
(use-package tern
:ensure-system-package (tern . "npm i -g tern"))
```
`:ensure-system-package` can also take a cons where its `cdr` is a
string that will get called by `(async-shell-command)` to install if
it isn’t found.
You may also pass in a list of cons-es:
``` emacs-lisp
(use-package ruby-mode
:ensure-system-package
((rubocop . "gem install rubocop")
(ruby-lint . "gem install ruby-lint")
(ripper-tags . "gem install ripper-tags")
(pry . "gem install pry")))
```
Finally, in case the package dependency does not provide a global
executable, you can ensure packages exist by checking the presence of
a file path by providing a string like so:
``` emacs-lisp
(use-package dash-at-point
:if (eq system-type 'darwin)
:ensure-system-package
("/Applications/Dash.app" . "brew cask install dash"))
```
`:ensure-system-package` will use `system-packages-install` to install
system packages, except where a custom command has been specified, in
which case it will be executed verbatim by `async-shell-command`.
Configuration variables `system-packages-package-manager` and
`system-packages-use-sudo` will be honoured, but not for custom
commands. Custom commands should include the call to sudo in the
command if needed.
### `(use-package-chords)`
The `:chords` keyword allows you to define
[`key-chord`](http://www.emacswiki.org/emacs/key-chord.el) bindings
for `use-package` declarations in the same manner as the `:bind`
keyword.
To enable the extension:
``` elisp
(use-package use-package-chords
:ensure t
:config (key-chord-mode 1))
```
Then you can define your chord bindings in the same manner as `:bind` using a cons or a list of conses:
``` elisp
(use-package ace-jump-mode
:chords (("jj" . ace-jump-char-mode)
("jk" . ace-jump-word-mode)
("jl" . ace-jump-line-mode)))
```
### How to create an extension
#### First step: Add the keyword
The first step is to add your keyword at the right place in
`use-package-keywords`. This list determines the order in which things will
happen in the expanded code. You should never change this order, but it gives
you a framework within which to decide when your keyword should fire.
#### Second step: Create a normalizer
Define a normalizer for your keyword by defining a function named after the
keyword, for example:
``` elisp
(defun use-package-normalize/:pin (name-symbol keyword args)
(use-package-only-one (symbol-name keyword) args
(lambda (label arg)
(cond
((stringp arg) arg)
((symbolp arg) (symbol-name arg))
(t
(use-package-error
":pin wants an archive name (a string)"))))))
```
The job of the normalizer is take a list of arguments (possibly nil), and turn
it into the single argument (which could still be a list) that should appear
in the final property list used by `use-package`.
#### Third step: Create a handler
Once you have a normalizer, you must create a handler for the keyword:
``` elisp
(defun use-package-handler/:pin (name-symbol keyword archive-name rest state)
(let ((body (use-package-process-keywords name-symbol rest state)))
;; This happens at macro expansion time, not when the expanded code is
;; compiled or evaluated.
(if (null archive-name)
body
(use-package-pin-package name-symbol archive-name)
(use-package-concat
body
`((push '(,name-symbol . ,archive-name)
package-pinned-packages))))))
```
Handlers can affect the handling of keywords in two ways. First, it can
modify the `state` plist before recursively processing the remaining keywords,
to influence keywords that pay attention to the state (one example is the
state keyword `:deferred`, not to be confused with the `use-package` keyword
`:defer`). Then, once the remaining keywords have been handled and their
resulting forms returned, the handler may manipulate, extend, or just ignore
those forms.
The task of each handler is to return a *list of forms* representing code to
be inserted. It does not need to be a `progn` list, as this is handled
automatically in other places. Thus it is very common to see the idiom of
using `use-package-concat` to add new functionality before or after a code
body, so that only the minimum code necessary is emitted as the result of a
`use-package` expansion.
#### Fourth step: Test it out
After the keyword has been inserted into `use-package-keywords`, and a
normalizer and a handler defined, you can now test it by seeing how usages of
the keyword will expand. For this, use `M-x pp-macroexpand-last-sexp` with
the cursor set immediately after the `(use-package ...)` expression.
## Some timing results
On my Retina iMac, the "Mac port" variant of Emacs 24.4 loads in 0.57s, with
around 218 packages configured (nearly all of them lazy-loaded). However, I
experience no loss of functionality, just a bit of latency when I'm first
starting to use Emacs (due to the autoloading). Since I also use idle-loading
for many packages, perceived latency is typically reduced overall.
On Linux, the same configuration loads in 0.32s.
If I don't use Emacs graphically, I can test the absolute minimum times. This
is done by running:
``` bash
time emacs -l init.elc -batch --eval '(message "Hello, world!")'
```
On the Mac I see an average of 0.36s for the same configuration, and on Linux
0.26s.
# Upgrading to 2.x
## Semantics of :init is now consistent
The meaning of `:init` has been changed: It now *always* happens before
package load, whether `:config` has been deferred or not. This means that
some uses of `:init` in your configuration may need to be changed to `:config`
(in the non-deferred case). For the deferred case, the behavior is unchanged
from before.
Also, because `:init` and `:config` now mean "before" and "after", the `:pre-`
and `:post-` keywords are gone, as they should no longer be necessary.
Lastly, an effort has been made to make your Emacs start even in the presence
of use-package configuration failures. So after this change, be sure to check
your `*Messages*` buffer. Most likely, you will have several instances where
you are using `:init`, but should be using `:config` (this was the case for me
in a number of places).
## :idle has been removed
I am removing this feature for now because it can result in a nasty
inconsistency. Consider the following definition:
``` elisp
(use-package vkill
:commands vkill
:idle (some-important-configuration-here)
:bind ("C-x L" . vkill-and-helm-occur)
:init
(defun vkill-and-helm-occur ()
(interactive)
(vkill)
(call-interactively #'helm-occur))
:config
(setq vkill-show-all-processes t))
```
If I load my Emacs and wait until the idle timer fires, then this is the
sequence of events:
:init :idle :config
But if I load Emacs and immediately type C-x L without waiting for the idle
timer to fire, this is the sequence of events:
:init :config :idle
It's possible that the user could use `featurep` in their idle to test for
this case, but that's a subtlety I'd rather avoid.
## :defer now accepts an optional integer argument
`:defer [N]` causes the package to be loaded -- if it has not already been --
after `N` seconds of idle time.
``` elisp
(use-package back-button
:commands (back-button-mode)
:defer 2
:init
(setq back-button-show-toolbar-buttons nil)
:config
(back-button-mode 1))
```
## Add :preface, occurring before everything except :disabled
`:preface` can be used to establish function and variable definitions that
will 1) make the byte-compiler happy (it won't complain about functions whose
definitions are unknown because you have them within a guard block), and 2)
allow you to define code that can be used in an `:if` test.
Note that whatever is specified within `:preface` is evaluated both at load
time and at byte-compilation time, in order to ensure that definitions are
seen by both the Lisp evaluator and the byte-compiler, so you should avoid
having any side-effects in your preface, and restrict it merely to symbol
declarations and definitions.
## Add :functions, for declaring functions to the byte-compiler
What `:defines` does for variables, `:functions` does for functions.
## use-package.el is no longer needed at runtime
This means you should put the following at the top of your Emacs, to further
reduce load time:
``` elisp
(eval-when-compile
(require 'use-package))
(require 'diminish) ;; if you use :diminish
(require 'bind-key) ;; if you use any :bind variant
```
use-package-2.4/use-package-chords.el 0000644 0001750 0001750 00000002435 13374646103 017400 0 ustar dogsleg dogsleg ;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*-
;; Copyright (C) 2015-2017 Justin Talbott
;; Author: Justin Talbott
;; Keywords: convenience, tools, extensions
;; URL: https://github.com/waymondo/use-package-chords
;; Version: 0.2
;; Package-Requires: ((use-package "2.1") (bind-key "1.0") (bind-chord "0.2") (key-chord "0.6"))
;; Filename: use-package-chords.el
;; License: GNU General Public License version 3, or (at your option) any later version
;;
;;; Commentary:
;;
;; The `:chords' keyword allows you to define `key-chord' bindings for
;; `use-package' declarations in the same manner as the `:bind'
;; keyword.
;;
;;; Code:
(require 'use-package)
(require 'bind-chord)
;;;###autoload
(defalias 'use-package-autoloads/:chords 'use-package-autoloads-mode)
;;;###autoload
(defalias 'use-package-normalize/:chords 'use-package-normalize-binder)
;;;###autoload
(defun use-package-handler/:chords (name _keyword arg rest state)
"Handler for `:chords' keyword in `use-package'."
(use-package-concat
(use-package-process-keywords name rest state)
`(,(macroexpand
`(bind-chords :package ,name ,@arg)))))
(add-to-list 'use-package-keywords :chords)
(provide 'use-package-chords)
;;; use-package-chords.el ends here
use-package-2.4/.travis.yml 0000644 0001750 0001750 00000001760 13374646103 015522 0 ustar dogsleg dogsleg language: generic
sudo: false
env:
global:
- CURL="curl -fsSkL --retry 9 --retry-delay 9"
matrix:
- EMACS_VERSION=26
- EMACS_VERSION=25.3
- EMACS_VERSION=24.5
- EMACS_VERSION=24.4
- EMACS_VERSION=24.3
- EMACS_VERSION=master
install:
- $CURL -O https://github.com/npostavs/emacs-travis/releases/download/bins/emacs-bin-${EMACS_VERSION}.tar.gz
- tar xf emacs-bin-${EMACS_VERSION}.tar.gz -C /
- export EMACS=/tmp/emacs/bin/emacs
- $EMACS --version
dist: trusty
addons:
apt:
packages:
- texinfo
script:
- make
- make test
- make info
before_deploy: cd doc && make doc
deploy:
provider: pages
skip_cleanup: true
github_token: $GITHUB_TOKEN
local_dir: doc/public
on:
branch: master
condition: $EMACS_VERSION = 26
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/848b93e13f8e6ab0cc86
on_success: always
on_failure: always
on_start: always
email:
on_success: change
on_failure: always
on_start: never
use-package-2.4/use-package-delight.el 0000644 0001750 0001750 00000006323 13374646103 017536 0 ustar dogsleg dogsleg ;;; use-package-delight.el --- Support for the :delight keyword -*- lexical-binding: t; -*-
;; Copyright (C) 2012-2017 John Wiegley
;; Author: John Wiegley
;; Maintainer: John Wiegley
;; Created: 17 Jun 2012
;; Modified: 3 Dec 2017
;; Version: 1.0
;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
;; Keywords: dotemacs startup speed config package
;; URL: https://github.com/jwiegley/use-package
;; 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 3, 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.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; Provides support for the :delight keyword, which is made available by
;; default by requiring `use-package'.
;;; Code:
(require 'use-package-core)
(defun use-package-normalize-delight (name args)
"Normalize ARGS for a single call to `delight'."
(when (eq :eval (car args))
;; Handle likely common mistake.
(use-package-error ":delight mode line constructs must be quoted"))
(cond ((and (= (length args) 1)
(use-package-non-nil-symbolp (car args)))
`(,(nth 0 args) nil ,name))
((= (length args) 2)
`(,(nth 0 args) ,(nth 1 args) ,name))
((= (length args) 3)
args)
(t
(use-package-error
":delight expects `delight' arguments or a list of them"))))
;;;###autoload
(defun use-package-normalize/:delight (name _keyword args)
"Normalize arguments to delight."
(cond ((null args)
`((,(use-package-as-mode name) nil ,name)))
((and (= (length args) 1)
(use-package-non-nil-symbolp (car args)))
`((,(car args) nil ,name)))
((and (= (length args) 1)
(stringp (car args)))
`((,(use-package-as-mode name) ,(car args) ,name)))
((and (= (length args) 1)
(listp (car args))
(eq 'quote (caar args)))
`((,(use-package-as-mode name) ,@(cdar args) ,name)))
((and (= (length args) 2)
(listp (nth 1 args))
(eq 'quote (car (nth 1 args))))
`((,(car args) ,@(cdr (nth 1 args)) ,name)))
(t (mapcar
(apply-partially #'use-package-normalize-delight name)
(if (use-package-non-nil-symbolp (car args))
(list args)
args)))))
;;;###autoload
(defun use-package-handler/:delight (name _keyword args rest state)
(let ((body (use-package-process-keywords name rest state)))
(use-package-concat
body
`((if (fboundp 'delight)
(delight '(,@args)))))))
(add-to-list 'use-package-keywords :delight t)
(provide 'use-package-delight)
;;; use-package-delight.el ends here
use-package-2.4/use-package.org 0000644 0001750 0001750 00000072172 13374646103 016314 0 ustar dogsleg dogsleg #+TITLE: use-package User Manual
#+AUTHOR: John Wiegley
#+EMAIL: johnw@newartisans.com
#+DATE: 2012-2017
#+LANGUAGE: en
#+HUGO_BASE_DIR: ./doc
#+HUGO_SECTION: /
#+HUGO_MENU: :menu main
#+TEXINFO_DIR_CATEGORY: Emacs
#+TEXINFO_DIR_TITLE: use-package: (use-package).
#+TEXINFO_DIR_DESC: Declarative package configuration for Emacs.
#+SUBTITLE: for version 2.4
#+TEXINFO_DEFFN: t
#+OPTIONS: H:4 num:3 toc:2 creator:t
# Below macro is used so that both texinfo and hugo exports work
# harmoniously. For texinfo exports, the export is done using the
# scope of the whole file, so it can resolve all internal link
# references. Whereas for hugo exports, they are done only from the
# scope of a subtree (or a page of the doc site), so at the moment it
# doesn't auto-resolve Org internal links outside that scope.
# FIXME: This is just a workaround.. hope to get a better solution in
# the future.
#+MACRO: link-jump @@texinfo:@ref{$1}@@@@hugo:[$1]($2)@@
use-package is...
#+BEGIN_QUOTE
Copyright (C) 2012-2017 John Wiegley
You can redistribute this document and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either
version 3 of the License, or (at your option) any later version.
This document 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.
#+END_QUOTE
* Introduction
:PROPERTIES:
:EXPORT_FILE_NAME: _index
:EXPORT_HUGO_TYPE: homepage
:END:
The ~use-package~ macro allows you to isolate package configuration in your
~.emacs~ file in a way that is both performance-oriented and, well, tidy. I
created it because I have over 80 packages that I use in Emacs, and things
were getting difficult to manage. Yet with this utility my total load time is
around 2 seconds, with no loss of functionality!
More text to come...
* Installation
:PROPERTIES:
:EXPORT_FILE_NAME: installation
:END:
** _ :ignore:
use-package can be installed using Emacs' package manager or manually from
its development repository.
** Installing from an Elpa Archive
use-package is available from Melpa and Melpa-Stable. If you haven't used
Emacs' package manager before, then it is high time you familiarize yourself
with it by reading the documentation in the Emacs manual, see
[[info:emacs#Packages]]. Then add one of the archives to ~package-archives~:
- To use Melpa:
#+BEGIN_SRC emacs-lisp
(require 'package)
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/") t)
#+END_SRC
- To use Melpa-Stable:
#+BEGIN_SRC emacs-lisp
(require 'package)
(add-to-list 'package-archives
'("melpa-stable" . "https://stable.melpa.org/packages/") t)
#+END_SRC
Once you have added your preferred archive, you need to update the
local package list using:
#+BEGIN_EXAMPLE
M-x package-refresh-contents RET
#+END_EXAMPLE
Once you have done that, you can install use-package and its dependencies
using:
#+BEGIN_EXAMPLE
M-x package-install RET use-package RET
#+END_EXAMPLE
Now see [[*Post-Installation Tasks]].
** Installing from the Git Repository
First, use Git to clone the use-package repository:
#+BEGIN_SRC shell-script
$ git clone https://github.com/jwiegley/use-package.git ~/.emacs.d/site-lisp/use-package
$ cd ~/.emacs.d/site-lisp/use-package
#+END_SRC
Then compile the libraries and generate the info manuals:
#+BEGIN_SRC shell-script
$ make
#+END_SRC
You may need to create ~/path/to/use-package/config.mk~ with the following
content before running ~make~:
#+BEGIN_SRC makefile
LOAD_PATH = -L /path/to/use-package
#+END_SRC
Finally add this to your init file:
#+BEGIN_SRC emacs-lisp
(add-to-list 'load-path "~/.emacs.d/site-lisp/use-package")
(require 'use-package)
(with-eval-after-load 'info
(info-initialize)
(add-to-list 'Info-directory-list
"~/.emacs.d/site-lisp/use-package/"))
#+END_SRC
Note that elements of ~load-path~ should not end with a slash, while those of
~Info-directory-list~ should.
Instead of running use-package directly from the repository by adding it to
the ~load-path~, you might want to instead install it in some other directory
using ~sudo make install~ and setting ~load-path~ accordingly.
To update use-package use:
#+BEGIN_SRC shell-script
$ git pull
$ make
#+END_SRC
At times it might be necessary to run ~make clean all~ instead.
To view all available targets use ~make help~.
Now see [[*Post-Installation Tasks]].
** Post-Installation Tasks
After installing use-package you should verify that you are indeed using the
use-package release you think you are using. It's best to restart Emacs before
doing so, to make sure you are not using an outdated value for ~load-path~.
#+BEGIN_EXAMPLE
C-h v use-package-version RET
#+END_EXAMPLE
should display something like
#+BEGIN_EXAMPLE
use-package-version’s value is "2.4"
#+END_EXAMPLE
If you are completely new to use-package then see {{{link-jump(Getting
Started,/getting-started)}}}.
If you run into problems, then please see the
{{{link-jump(FAQ,/faq)}}}. Also see the {{{link-jump(Debugging
Tools,/debugging-tools)}}}.
* Getting Started
:PROPERTIES:
:EXPORT_FILE_NAME: getting-started
:END:
TODO. For now, see ~README.md~.
* Basic Concepts
~use-package~ was created for few basic reasons, each of which drove the
design in various ways. Understanding these reasons may help make some of
those decisions clearer:
1. To gather all configuration details of a package into one place, making
it easier to copy, disable, or move it elsewhere in the init file.
2. To reduce duplication and boilerplate, capturing several common practices
as mere keywords both easy and intuitive to use.
3. To make startup time of Emacs as quick as possible, without sacrificing
the quantity of add-on packages used.
4. To make it so errors encountered during startup disable only the package
raising the error, and as little else as possible, leaving a close to a
functional Emacs as possible.
5. To allow byte-compilation of one's init file so that any warnings or
errors seen are meaningful. In this way, even if byte-compilation is not
used for speed (reason 3), it can still be used as a sanity check.
* Issues/Requests
:PROPERTIES:
:EXPORT_HUGO_SECTION: issues
:EXPORT_FILE_NAME: _index
:END:
* Keywords
:PROPERTIES:
:EXPORT_FILE_NAME: keywords
:END:
** ~:after~
Sometimes it only makes sense to configure a package after another has been
loaded, because certain variables or functions are not in scope until that
time. This can achieved using an ~:after~ keyword that allows a fairly rich
description of the exact conditions when loading should occur. Here is an
example:
#+BEGIN_SRC emacs-lisp
(use-package hydra
:load-path "site-lisp/hydra")
(use-package ivy
:load-path "site-lisp/swiper")
(use-package ivy-hydra
:after (ivy hydra))
#+END_SRC
In this case, because all of these packages are demand-loaded in the order
they occur, the use of ~:after~ is not strictly necessary. By using it,
however, the above code becomes order-independent, without an implicit
depedence on the nature of your init file.
By default, ~:after (foo bar)~ is the same as ~:after (:all foo bar)~, meaning
that loading of the given package will not happen until both ~foo~ and ~bar~
have been loaded. Here are some of the other possibilities:
#+BEGIN_SRC emacs-lisp
:after (foo bar)
:after (:all foo bar)
:after (:any foo bar)
:after (:all (:any foo bar) (:any baz quux))
:after (:any (:all foo bar) (:all baz quux))
#+END_SRC
When you nest selectors, such as ~(:any (:all foo bar) (:all baz quux))~, it
means that the package will be loaded when either both ~foo~ and ~bar~ have
been loaded, or both ~baz~ and ~quux~ have been loaded.
*NOTE*: Pay attention if you set ~use-package-always-defer~ to t, and also use
the ~:after~ keyword, as you will need to specify how the declared package is
to be loaded: e.g., by some ~:bind~. If you're not using one of tho mechanisms
that registers autoloads, such as ~:bind~ or ~:hook~, and your package manager
does not provide autoloads, it's possible that without adding ~:demand t~ to
those declarations, your package will never be loaded.
** ~:bind-keymap~, ~:bind-keymap*~
Normally ~:bind~ expects that commands are functions that will be autoloaded
from the given package. However, this does not work if one of those commands
is actually a keymap, since keymaps are not functions, and cannot be
autoloaded using Emacs' ~autoload~ mechanism.
To handle this case, ~use-package~ offers a special, limited variant of
~:bind~ called ~:bind-keymap~. The only difference is that the "commands"
bound to by ~:bind-keymap~ must be keymaps defined in the package, rather than
command functions. This is handled behind the scenes by generating custom code
that loads the package containing the keymap, and then re-executes your
keypress after the first load, to reinterpret that keypress as a prefix key.
For example:
#+BEGIN_SRC emacs-lisp
(use-package projectile
:bind-keymap
("C-c p" . projectile-command-map)
#+END_SRC
** ~:bind~, ~:bind*~
Another common thing to do when loading a module is to bind a key to primary
commands within that module:
#+BEGIN_SRC emacs-lisp
(use-package ace-jump-mode
:bind ("C-." . ace-jump-mode))
#+END_SRC
This does two things: first, it creates an autoload for the ~ace-jump-mode~
command and defers loading of ~ace-jump-mode~ until you actually use it.
Second, it binds the key ~C-.~ to that command. After loading, you can use
~M-x describe-personal-keybindings~ to see all such keybindings you've set
throughout your ~.emacs~ file.
A more literal way to do the exact same thing is:
#+BEGIN_SRC emacs-lisp
(use-package ace-jump-mode
:commands ace-jump-mode
:init
(bind-key "C-." 'ace-jump-mode))
#+END_SRC
When you use the ~:commands~ keyword, it creates autoloads for those commands
and defers loading of the module until they are used. Since the ~:init~ form
is always run---even if ~ace-jump-mode~ might not be on your system---remember
to restrict ~:init~ code to only what would succeed either way.
The ~:bind~ keyword takes either a cons or a list of conses:
#+BEGIN_SRC emacs-lisp
(use-package hi-lock
:bind (("M-o l" . highlight-lines-matching-regexp)
("M-o r" . highlight-regexp)
("M-o w" . highlight-phrase)))
#+END_SRC
The ~:commands~ keyword likewise takes either a symbol or a list of symbols.
NOTE: Special keys like ~tab~ or ~F1~-~Fn~ can be written in square brackets,
i.e. ~[tab]~ instead of ~"tab"~. The syntax for the keybindings is similar to
the "kbd" syntax: see [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-Rebinding.html][the Emacs Manual]] for more information.
Examples:
#+BEGIN_SRC emacs-lisp
(use-package helm
:bind (("M-x" . helm-M-x)
("M-" . helm-find-files)
([f10] . helm-buffers-list)
([S-f10] . helm-recentf)))
#+END_SRC
*** Binding to local keymaps
Slightly different from binding a key to a keymap, is binding a key *within* a
local keymap that only exists after the package is loaded. ~use-package~
supports this with a ~:map~ modifier, taking the local keymap to bind to:
#+BEGIN_SRC emacs-lisp
(use-package helm
:bind (:map helm-command-map
("C-c h" . helm-execute-persistent-action)))
#+END_SRC
The effect of this statement is to wait until ~helm~ has loaded, and then to
bind the key ~C-c h~ to ~helm-execute-persistent-action~ within Helm's local
keymap, ~helm-mode-map~.
Multiple uses of ~:map~ may be specified. Any binding occurring before the
first use of ~:map~ are applied to the global keymap:
#+BEGIN_SRC emacs-lisp
(use-package term
:bind (("C-c t" . term)
:map term-mode-map
("M-p" . term-send-up)
("M-n" . term-send-down)
:map term-raw-map
("M-o" . other-window)
("M-p" . term-send-up)
("M-n" . term-send-down)))
#+END_SRC
** ~:commands~
** ~:preface~, ~:init~, ~:config~
Here is the simplest ~use-package~ declaration:
#+BEGIN_SRC emacs-lisp
;; This is only needed once, near the top of the file
(eval-when-compile
;; Following line is not needed if use-package.el is in ~/.emacs.d
(add-to-list 'load-path "")
(require 'use-package))
(use-package foo)
#+END_SRC
This loads in the package ~foo~, but only if ~foo~ is available on your
system. If not, a warning is logged to the ~*Messages*~ buffer. If it
succeeds, a message about ~"Loading foo"~ is logged, along with the time it
took to load, if it took over 0.1 seconds.
Use the ~:init~ keyword to execute code before a package is loaded. It
accepts one or more forms, up until the next keyword:
#+BEGIN_SRC emacs-lisp
(use-package foo
:init
(setq foo-variable t))
#+END_SRC
Similarly, ~:config~ can be used to execute code after a package is loaded.
In cases where loading is done lazily (see more about autoloading below), this
execution is deferred until after the autoload occurs:
#+BEGIN_SRC emacs-lisp
(use-package foo
:init
(setq foo-variable t)
:config
(foo-mode 1))
#+END_SRC
As you might expect, you can use ~:init~ and ~:config~ together:
#+BEGIN_SRC emacs-lisp
(use-package color-moccur
:commands (isearch-moccur isearch-all)
:bind (("M-s O" . moccur)
:map isearch-mode-map
("M-o" . isearch-moccur)
("M-O" . isearch-moccur-all))
:init
(setq isearch-lazy-highlight t)
:config
(use-package moccur-edit))
#+END_SRC
In this case, I want to autoload the commands ~isearch-moccur~ and
~isearch-all~ from ~color-moccur.el~, and bind keys both at the global level
and within the ~isearch-mode-map~ (see next section). When the package is
actually loaded (by using one of these commands), ~moccur-edit~ is also
loaded, to allow editing of the ~moccur~ buffer.
** ~:custom~
The ~:custom~ keyword allows customization of package custom variables.
#+BEGIN_SRC emacs-lisp
(use-package comint
:custom
(comint-buffer-maximum-size 20000 "Increase comint buffer size.")
(comint-prompt-read-only t "Make the prompt read only."))
#+END_SRC
The documentation string is not mandatory.
** ~:custom-face~
The ~:custom-face~ keyword allows customization of package custom faces.
#+BEGIN_SRC emacs-lisp
(use-package eruby-mode
:custom-face
(eruby-standard-face ((t (:slant italic)))))
#+END_SRC
** ~:defer~, ~:demand~
In almost all cases you don't need to manually specify ~:defer t~. This is
implied whenever ~:bind~ or ~:mode~ or ~:interpreter~ is used. Typically, you
only need to specify ~:defer~ if you know for a fact that some other package
will do something to cause your package to load at the appropriate time, and
thus you would like to defer loading even though use-package isn't creating
any autoloads for you.
You can override package deferral with the ~:demand~ keyword. Thus, even if
you use ~:bind~, using ~:demand~ will force loading to occur immediately and
not establish an autoload for the bound key.
** ~:defines~, ~:functions~
Another feature of ~use-package~ is that it always loads every file that it
can when ~.emacs~ is being byte-compiled. This helps to silence spurious
warnings about unknown variables and functions.
However, there are times when this is just not enough. For those times, use
the ~:defines~ and ~:functions~ keywords to introduce dummy variable and
function declarations solely for the sake of the byte-compiler:
#+BEGIN_SRC emacs-lisp
(use-package texinfo
:defines texinfo-section-list
:commands texinfo-mode
:init
(add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode)))
#+END_SRC
If you need to silence a missing function warning, you can use ~:functions~:
#+BEGIN_SRC emacs-lisp
(use-package ruby-mode
:mode "\\.rb\\'"
:interpreter "ruby"
:functions inf-ruby-keys
:config
(defun my-ruby-mode-hook ()
(require 'inf-ruby)
(inf-ruby-keys))
(add-hook 'ruby-mode-hook 'my-ruby-mode-hook))
#+END_SRC
** ~:diminish~, ~:delight~
~use-package~ also provides built-in support for the diminish and delight
utilities---if you have them installed. Their purpose is to remove or change
minor mode strings in your mode-line.
[[https://github.com/myrjola/diminish.el][diminish]] is invoked with the ~:diminish~ keyword, which is passed either a
minor mode symbol, a cons of the symbol and its replacement string, or just a
replacement string, in which case the minor mode symbol is guessed to be the
package name with "-mode" appended at the end:
#+BEGIN_SRC emacs-lisp
(use-package abbrev
:diminish abbrev-mode
:config
(if (file-exists-p abbrev-file-name)
(quietly-read-abbrev-file)))
#+END_SRC
[[https://elpa.gnu.org/packages/delight.html][delight]] is invoked with the ~:delight~ keyword, which is passed a minor mode
symbol, a replacement string or quoted [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Mode-Line-Data.html][mode-line data]] (in which case the minor
mode symbol is guessed to be the package name with "-mode" appended at the
end), both of these, or several lists of both. If no arguments are provided,
the default mode name is hidden completely.
#+BEGIN_SRC emacs-lisp
;; Don't show anything for rainbow-mode.
(use-package rainbow-mode
:delight)
;; Don't show anything for auto-revert-mode, which doesn't match
;; its package name.
(use-package autorevert
:delight auto-revert-mode)
;; Remove the mode name for projectile-mode, but show the project name.
(use-package projectile
:delight '(:eval (concat " " (projectile-project-name))))
;; Completely hide visual-line-mode and change auto-fill-mode to " AF".
(use-package emacs
:delight
(auto-fill-function " AF")
(visual-line-mode))
#+END_SRC
** ~:disabled~
The ~:disabled~ keyword can turn off a module you're having difficulties with,
or stop loading something you're not using at the present time:
#+BEGIN_SRC emacs-lisp
(use-package ess-site
:disabled
:commands R)
#+END_SRC
When byte-compiling your ~.emacs~ file, disabled declarations are omitted
from the output entirely, to accelerate startup times.
** ~:ensure~, ~:pin~
You can use ~use-package~ to load packages from ELPA with ~package.el~. This
is particularly useful if you share your ~.emacs~ among several machines; the
relevant packages are downloaded automatically once declared in your ~.emacs~.
The ~:ensure~ keyword causes the package(s) to be installed automatically if
not already present on your system (set ~(setq use-package-always-ensure t)~
if you wish this behavior to be global for all packages):
#+BEGIN_SRC emacs-lisp
(use-package magit
:ensure t)
#+END_SRC
If you need to install a different package from the one named by
~use-package~, you can specify it like this:
#+BEGIN_SRC emacs-lisp
(use-package tex
:ensure auctex)
#+END_SRC
Lastly, when running on Emacs 24.4 or later, use-package can pin a package to
a specific archive, allowing you to mix and match packages from different
archives. The primary use-case for this is preferring packages from the
~melpa-stable~ and ~gnu~ archives, but using specific packages from ~melpa~
when you need to track newer versions than what is available in the ~stable~
archives is also a valid use-case.
By default ~package.el~ prefers ~melpa~ over ~melpa-stable~ due to the
versioning ~(> evil-20141208.623 evil-1.0.9)~, so even if you are tracking
only a single package from ~melpa~, you will need to tag all the non-~melpa~
packages with the appropriate archive. If this really annoys you, then you can
set ~use-package-always-pin~ to set a default.
If you want to manually keep a package updated and ignore upstream updates,
you can pin it to ~manual~, which as long as there is no repository by that
name, will Just Work(tm).
~use-package~ throws an error if you try to pin a package to an archive that
has not been configured using ~package-archives~ (apart from the magic
~manual~ archive mentioned above):
#+BEGIN_SRC text-mode
Archive 'foo' requested for package 'bar' is not available.
#+END_SRC
Example:
#+BEGIN_SRC emacs-lisp
(use-package company
:ensure t
:pin melpa-stable)
(use-package evil
:ensure t)
;; no :pin needed, as package.el will choose the version in melpa
(use-package adaptive-wrap
:ensure t
;; as this package is available only in the gnu archive, this is
;; technically not needed, but it helps to highlight where it
;; comes from
:pin gnu)
(use-package org
:ensure t
;; ignore org-mode from upstream and use a manually installed version
:pin manual)
#+END_SRC
*NOTE*: the ~:pin~ argument has no effect on emacs versions < 24.4.
** ~:hook~
The ~:hook~ keyword allows adding functions onto hooks, here only the basename
of the hook is required. Thus, all of the following are equivalent:
#+BEGIN_SRC emacs-lisp
(use-package ace-jump-mode
:hook prog-mode)
(use-package ace-jump-mode
:hook (prog-mode . ace-jump-mode))
(use-package ace-jump-mode
:commands ace-jump-mode
:init
(add-hook 'prog-mode-hook #'ace-jump-mode))
#+END_SRC
And likewise, when multiple hooks should be applied, the following are also
equivalent:
#+BEGIN_SRC emacs-lisp
(use-package ace-jump-mode
:hook (prog-mode text-mode))
(use-package ace-jump-mode
:hook ((prog-mode text-mode) . ace-jump-mode))
(use-package ace-jump-mode
:hook ((prog-mode . ace-jump-mode)
(text-mode . ace-jump-mode)))
(use-package ace-jump-mode
:commands ace-jump-mode
:init
(add-hook 'prog-mode-hook #'ace-jump-mode)
(add-hook 'text-mode-hook #'ace-jump-mode))
#+END_SRC
The use of ~:hook~, as with ~:bind~, ~:mode~, ~:interpreter~, etc., causes the
functions being hooked to implicitly be read as ~:commands~ (meaning they will
establish interactive ~autoload~ definitions for that module, if not already
defined as functions), and so ~:defer t~ is also implied by ~:hook~.
** ~:if~, ~:when~, ~:unless~
You can use the ~:if~ keyword to predicate the loading and initialization of
modules.
For example, I only want ~edit-server~ running for my main, graphical Emacs,
not for other Emacsen I may start at the command line:
#+BEGIN_SRC emacs-lisp
(use-package edit-server
:if window-system
:init
(add-hook 'after-init-hook 'server-start t)
(add-hook 'after-init-hook 'edit-server-start t))
#+END_SRC
In another example, we can load things conditional on the operating system:
#+BEGIN_SRC emacs-lisp
(use-package exec-path-from-shell
:if (memq window-system '(mac ns))
:ensure t
:config
(exec-path-from-shell-initialize))
#+END_SRC
Note that ~:when~ is provided as an alias for ~:if~, and ~:unless foo~ means
the same thing as ~:if (not foo)~.
** ~:load-path~
If your package needs a directory added to the ~load-path~ in order to load,
use ~:load-path~. This takes a symbol, a function, a string or a list of
strings. If the path is relative, it is expanded within
~user-emacs-directory~:
#+BEGIN_SRC emacs-lisp
(use-package ess-site
:load-path "site-lisp/ess/lisp/"
:commands R)
#+END_SRC
Note that when using a symbol or a function to provide a dynamically generated
list of paths, you must inform the byte-compiler of this definition so the
value is available at byte-compilation time. This is done by using the special
form ~eval-and-compile~ (as opposed to ~eval-when-compile~). Further, this
value is fixed at whatever was determined during compilation, to avoid looking
up the same information again on each startup:
#+BEGIN_SRC emacs-lisp
(eval-and-compile
(defun ess-site-load-path ()
(shell-command "find ~ -path ess/lisp")))
(use-package ess-site
:load-path (lambda () (list (ess-site-load-path)))
:commands R)
#+END_SRC
** ~:mode~, ~:interpreter~
Similar to ~:bind~, you can use ~:mode~ and ~:interpreter~ to establish a
deferred binding within the ~auto-mode-alist~ and ~interpreter-mode-alist~
variables. The specifier to either keyword can be a cons cell, a list of cons
cells, or a string or regexp:
#+BEGIN_SRC emacs-lisp
(use-package ruby-mode
:mode "\\.rb\\'"
:interpreter "ruby")
;; The package is "python" but the mode is "python-mode":
(use-package python
:mode ("\\.py\\'" . python-mode)
:interpreter ("python" . python-mode))
#+END_SRC
If you aren't using ~:commands~, ~:bind~, ~:bind*~, ~:bind-keymap~,
~:bind-keymap*~, ~:mode~, or ~:interpreter~ (all of which imply ~:defer~; see
the docstring for ~use-package~ for a brief description of each), you can
still defer loading with the ~:defer~ keyword:
#+BEGIN_SRC emacs-lisp
(use-package ace-jump-mode
:defer t
:init
(autoload 'ace-jump-mode "ace-jump-mode" nil t)
(bind-key "C-." 'ace-jump-mode))
#+END_SRC
This does exactly the same thing as the following:
#+BEGIN_SRC emacs-lisp
(use-package ace-jump-mode
:bind ("C-." . ace-jump-mode))
#+END_SRC
** ~:magic~, ~:magic-fallback~
Similar to ~:mode~ and ~:interpreter~, you can also use ~:magic~ and
~:magic-fallback~ to cause certain function to be run if the beginning of a
file matches a given regular expression. The difference between the two is
that ~:magic-fallback~ has a lower priority than ~:mode~. For example:
#+BEGIN_SRC emacs-lisp
(use-package pdf-tools
:load-path "site-lisp/pdf-tools/lisp"
:magic ("%PDF" . pdf-view-mode)
:config
(pdf-tools-install))
#+END_SRC
This registers an autoloaded command for ~pdf-view-mode~, defers loading of
~pdf-tools~, and runs ~pdf-view-mode~ if the beginning of a buffer matches the
string ~"%PDF"~.
** ~:no-require~
Normally, ~use-package~ will load each package at compile time before
compiling the configuration, to ensure that any necessary symbols are in scope
to satisfy the byte-compiler. At times this can cause problems, since a
package may have special loading requirements, and all that you want to use
~use-package~ for is to add a configuration to the ~eval-after-load~ hook. In
such cases, use the ~:no-require~ keyword:
#+BEGIN_SRC emacs-lisp
(use-package foo
:no-require t
:config
(message "This is evaluated when `foo' is loaded"))
#+END_SRC
** ~:requires~
While the ~:after~ keyword delays loading until the dependencies are loaded,
the somewhat simpler ~:requires~ keyword simply never loads the package if the
dependencies are not available at the time the ~use-package~ declaration is
encountered. By "available" in this context it means that ~foo~ is available
of ~(featurep 'foo)~ evaulates to a non-nil value. For example:
#+BEGIN_SRC emacs-lisp
(use-package abbrev
:requires foo)
#+END_SRC
This is the same as:
#+BEGIN_SRC emacs-lisp
(use-package abbrev
:if (featurep 'foo))
#+END_SRC
As a convenience, a list of such packages may be specified:
#+BEGIN_SRC emacs-lisp
(use-package abbrev
:requires (foo bar baz))
#+END_SRC
For more complex logic, such as that supported by ~:after~, simply use ~:if~
and the appropriate Lisp expression.
* FAQ
:PROPERTIES:
:APPENDIX: t
:EXPORT_FILE_NAME: faq
:END:
The next two nodes lists frequently asked questions.
Please also use the {{{link-jump(Debugging Tools,/debugging-tools)}}}.
** FAQ - How to ...?
*** This is a question
This is an answer.
** FAQ - Issues and Errors
*** This is an issues
This is a description.
* Debugging Tools
:PROPERTIES:
:EXPORT_FILE_NAME: debugging-tools
:END:
TODO
Please also see the {{{link-jump(FAQ,/faq)}}}.
* Command Index
:PROPERTIES:
:APPENDIX: t
:INDEX: cp
:END:
* Function Index
:PROPERTIES:
:APPENDIX: t
:INDEX: fn
:END:
* Variable Index
:PROPERTIES:
:APPENDIX: t
:INDEX: vr
:END:
* _ Copying
:PROPERTIES:
:COPYING: t
:END:
#+BEGIN_QUOTE
Copyright (C) 2012-2017 John Wiegley
You can redistribute this document and/or modify it under the terms
of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any
later version.
This document 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.
#+END_QUOTE
* _ :ignore:
# LocalWords: ARG ARGS CONDITIONs ChangeLog DNS Dired Ediff Ediffing
# LocalWords: Elpa Emacsclient FUNC Flyspell Git Git's Gitk HOOK's
# LocalWords: IDENT Ido Junio LocalWords
# LocalWords: Melpa Propertize REF REF's RET Reflog SPC SYM Spacemacs
# LocalWords: Submodules TODO TYPEs Theming Unpulled Unpushed Unstaged
# LocalWords: Untracked WORKTREE Wip ack args async autoloads autosaving
# LocalWords: autosquash backport basename branchref builtin
# LocalWords: cdr changelog committer config customizable diff's diffstat
# LocalWords: dwim ediff ediffing editmsg emacsclient filename fixup
# LocalWords: flyspell func git's gitk gitman gitmodule gitmodules goto
# LocalWords: gpg gui ident ido init inserter inserters keymap keymaps
# LocalWords: logfile use-package maildir manpage manpages minibuffer multi mv
# LocalWords: namespace newbase nocommit notesRef popup popups posix prev
# LocalWords: propertize rebase rebased rebasing reflog repo signoff str
# LocalWords: struct subcommand submodule submodule's submodules subprocess
# LocalWords: sym texinfo theming todo topdir un unhighlighted unpulled
# LocalWords: unpushed unstage unstaged unstages unstaging untracked url
# LocalWords: versa whitespace wip workflow worktree wtree
# LocalWords: backported macOS
# Local Variables:
# eval: (require 'org-man nil t)
# eval: (require 'ox-texinfo+ nil t)
# eval: (and (require 'ox-extra nil t) (ox-extras-activate '(ignore-headlines)))
# indent-tabs-mode: nil
# org-src-preserve-indentation: nil
# End:
use-package-2.4/use-package-diminish.el 0000644 0001750 0001750 00000005364 13374646103 017726 0 ustar dogsleg dogsleg ;;; use-package-diminish.el --- Support for the :diminish keyword -*- lexical-binding: t; -*-
;; Copyright (C) 2012-2017 John Wiegley
;; Author: John Wiegley
;; Maintainer: John Wiegley
;; Created: 17 Jun 2012
;; Modified: 3 Dec 2017
;; Version: 1.0
;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
;; Keywords: dotemacs startup speed config package
;; URL: https://github.com/jwiegley/use-package
;; 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 3, 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.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; Provides support for the :diminish keyword, which is made available by
;; default by requiring `use-package'.
;;; Code:
(require 'use-package-core)
(defun use-package-normalize-diminish (name label arg &optional recursed)
"Normalize the arguments to diminish down to a list of one of two forms:
SYMBOL
(SYMBOL . STRING)"
(cond
((not arg)
(list (use-package-as-mode name)))
((use-package-non-nil-symbolp arg)
(list arg))
((stringp arg)
(list (cons (use-package-as-mode name) arg)))
((and (consp arg) (stringp (cdr arg)))
(list arg))
((and (not recursed) (listp arg) (listp (cdr arg)))
(mapcar #'(lambda (x) (car (use-package-normalize-diminish
name label x t))) arg))
(t
(use-package-error
(concat label " wants a string, symbol, "
"(symbol . string) or list of these")))))
;;;###autoload
(defun use-package-normalize/:diminish (name keyword args)
(use-package-as-one (symbol-name keyword) args
(apply-partially #'use-package-normalize-diminish name) t))
;;;###autoload
(defun use-package-handler/:diminish (name _keyword arg rest state)
(let ((body (use-package-process-keywords name rest state)))
(use-package-concat
(mapcar #'(lambda (var)
`(if (fboundp 'diminish)
,(if (consp var)
`(diminish ',(car var) ,(cdr var))
`(diminish ',var))))
arg)
body)))
(add-to-list 'use-package-keywords :diminish t)
(provide 'use-package-diminish)
;;; use-package-diminish.el ends here
use-package-2.4/use-package-ensure-system-package.el 0000644 0001750 0001750 00000005223 13374646103 022330 0 ustar dogsleg dogsleg ;;; use-package-ensure-system-package.el --- auto install system packages -*- lexical-binding: t; -*-
;; Copyright (C) 2017 Justin Talbott
;; Author: Justin Talbott
;; Keywords: convenience, tools, extensions
;; URL: https://github.com/waymondo/use-package-ensure-system-package
;; Version: 0.2
;; Package-Requires: ((use-package "2.1") (system-packages "1.0.4"))
;; Filename: use-package-ensure-system-package.el
;; License: GNU General Public License version 3, or (at your option) any later version
;;
;;; Commentary:
;;
;; The `:ensure-system-package` keyword allows you to ensure system
;; binaries exist alongside your `use-package` declarations.
;;
;;; Code:
(require 'use-package)
(require 'system-packages nil t)
(eval-when-compile
(declare-function system-packages-get-command "system-packages"))
(defun use-package-ensure-system-package-consify (arg)
"Turn `arg' into a cons of (`package-name' . `install-command')."
(cond
((stringp arg)
(cons arg `(system-packages-install ,arg)))
((symbolp arg)
(cons arg `(system-packages-install ,(symbol-name arg))))
((consp arg)
(cond
((not (cdr arg))
(use-package-ensure-system-package-consify (car arg)))
((stringp (cdr arg))
(cons (car arg) `(async-shell-command ,(cdr arg))))
(t
(cons (car arg)
`(system-packages-install ,(symbol-name (cdr arg)))))))))
;;;###autoload
(defun use-package-normalize/:ensure-system-package (_name-symbol keyword args)
"Turn `arg' into a list of cons-es of (`package-name' . `install-command')."
(use-package-only-one (symbol-name keyword) args
(lambda (_label arg)
(cond
((and (listp arg) (listp (cdr arg)))
(mapcar #'use-package-ensure-system-package-consify arg))
(t
(list (use-package-ensure-system-package-consify arg)))))))
(defun use-package-ensure-system-package-exists? (file-or-exe)
"If variable is a string, ensure the file path exists.
If it is a symbol, ensure the binary exist."
(if (stringp file-or-exe)
(file-exists-p file-or-exe)
(executable-find (symbol-name file-or-exe))))
;;;###autoload
(defun use-package-handler/:ensure-system-package (name _keyword arg rest state)
"Execute the handler for `:ensure-system-package' keyword in `use-package'."
(let ((body (use-package-process-keywords name rest state)))
(use-package-concat
(mapcar #'(lambda (cons)
`(unless (use-package-ensure-system-package-exists? ',(car cons))
,(cdr cons))) arg)
body)))
(add-to-list 'use-package-keywords :ensure-system-package t)
(provide 'use-package-ensure-system-package)
;;; use-package-ensure-system-package.el ends here
use-package-2.4/use-package-core.el 0000644 0001750 0001750 00000165475 13374646103 017064 0 ustar dogsleg dogsleg ;;; use-package-core.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*-
;; Copyright (C) 2012-2017 John Wiegley
;; Author: John Wiegley
;; Maintainer: John Wiegley
;; Created: 17 Jun 2012
;; Modified: 29 Nov 2017
;; Version: 2.4
;; Package-Requires: ((emacs "24.3"))
;; Keywords: dotemacs startup speed config package
;; URL: https://github.com/jwiegley/use-package
;; 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 3, 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.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; The `use-package' declaration macro allows you to isolate package
;; configuration in your ".emacs" in a way that is performance-oriented and,
;; well, just tidy. I created it because I have over 80 packages that I use
;; in Emacs, and things were getting difficult to manage. Yet with this
;; utility my total load time is just under 1 second, with no loss of
;; functionality!
;;
;; Please see README.md from the same repository for documentation.
;;; Code:
(require 'bytecomp)
(require 'cl-lib)
(require 'tabulated-list)
(if (and (eq emacs-major-version 24) (eq emacs-minor-version 3))
(defsubst hash-table-keys (hash-table)
"Return a list of keys in HASH-TABLE."
(cl-loop for k being the hash-keys of hash-table collect k))
(eval-when-compile (require 'subr-x)))
(eval-when-compile
(require 'regexp-opt))
(defgroup use-package nil
"A use-package declaration for simplifying your `.emacs'."
:group 'startup)
(defconst use-package-version "2.4"
"This version of use-package.")
(defcustom use-package-keywords
'(:disabled
:load-path
:requires
:defines
:functions
:preface
:if :when :unless
:no-require
:catch
:after
:custom
:custom-face
:bind
:bind*
:bind-keymap
:bind-keymap*
:interpreter
:mode
:magic
:magic-fallback
:hook
;; Any other keyword that also declares commands to be autoloaded (such as
;; :bind) must appear before this keyword.
:commands
:init
:defer
:demand
:load
;; This must occur almost last; the only forms which should appear after
;; are those that must happen directly after the config forms.
:config)
"The set of valid keywords, in the order they are processed in.
The order of this list is *very important*, so it is only
advisable to insert new keywords, never to delete or reorder
them. Further, attention should be paid to the NEWS.md if the
default order ever changes, as they may have subtle effects on
the semantics of use-package declarations and may necessitate
changing where you had inserted a new keyword earlier.
Note that `:disabled' is special in this list, as it causes
nothing at all to happen, even if the rest of the use-package
declaration is incorrect."
:type '(repeat symbol)
:group 'use-package)
(defcustom use-package-deferring-keywords
'(:bind-keymap
:bind-keymap*
:commands)
"Unless `:demand' is used, keywords in this list imply deferred loading.
The reason keywords like `:hook' are not in this list is that
they only imply deferred loading if they reference actual
function symbols that can be autoloaded from the module; whereas
the default keywords provided here always defer loading unless
otherwise requested."
:type '(repeat symbol)
:group 'use-package)
(defcustom use-package-ignore-unknown-keywords nil
"If non-nil, issue warning instead of error when unknown
keyword is encountered. The unknown keyword and its associated
arguments will be ignored in the `use-package' expansion."
:type 'boolean
:group 'use-package)
(defcustom use-package-verbose nil
"Whether to report about loading and configuration details.
If you customize this, then you should require the `use-package'
feature in files that use `use-package', even if these files only
contain compiled expansions of the macros. If you don't do so,
then the expanded macros do their job silently."
:type '(choice (const :tag "Quiet, without catching errors" errors)
(const :tag "Quiet" nil)
(const :tag "Verbose" t)
(const :tag "Debug" debug))
:group 'use-package)
(defcustom use-package-check-before-init nil
"If non-nil, check that package exists before executing its `:init' block.
This check is performed by calling `locate-library'."
:type 'boolean
:group 'use-package)
(defcustom use-package-always-defer nil
"If non-nil, assume `:defer t' unless `:demand' is used.
See also `use-package-defaults', which uses this value."
:type 'boolean
:group 'use-package)
(defcustom use-package-always-demand nil
"If non-nil, assume `:demand t' unless `:defer' is used.
See also `use-package-defaults', which uses this value."
:type 'boolean
:group 'use-package)
(defcustom use-package-defaults
'(;; this '(t) has special meaning; see `use-package-handler/:config'
(:config '(t) t)
(:init nil t)
(:catch t (lambda (name args)
(not use-package-expand-minimally)))
(:defer use-package-always-defer
(lambda (name args)
(and use-package-always-defer
(not (plist-member args :defer))
(not (plist-member args :demand)))))
(:demand use-package-always-demand
(lambda (name args)
(and use-package-always-demand
(not (plist-member args :defer))
(not (plist-member args :demand))))))
"Default values for specified `use-package' keywords.
Each entry in the alist is a list of three elements:
The first element is the `use-package' keyword.
The second is a form that can be evaluated to get the default
value. It can also be a function that will receive the name of
the use-package declaration and the keyword plist given to
`use-package', in normalized form. The value it returns should
also be in normalized form (which is sometimes *not* what one
would normally write in a `use-package' declaration, so use
caution).
The third element is a form that can be evaluated to determine
whether or not to assign a default value; if it evaluates to nil,
then the default value is not assigned even if the keyword is not
present in the `use-package' form. This third element may also be
a function, in which case it receives the name of the package (as
a symbol) and a list of keywords (in normalized form). It should
return nil or non-nil depending on whether defaulting should be
attempted."
:type `(repeat
(list (choice :tag "Keyword"
,@(mapcar #'(lambda (k) (list 'const k))
use-package-keywords))
(choice :tag "Default value" sexp function)
(choice :tag "Enable if non-nil" sexp function)))
:group 'use-package)
(defcustom use-package-merge-key-alist
'((:if . (lambda (new old) `(and ,new ,old)))
(:after . (lambda (new old) `(:all ,new ,old)))
(:defer . (lambda (new old) old))
(:bind . (lambda (new old) (append new (list :break) old))))
"Alist of keys and the functions used to merge multiple values.
For example, if the following form is provided:
(use-package foo :if pred1 :if pred2)
Then based on the above defaults, the merged result will be:
(use-package foo :if (and pred1 pred2))
This is done so that, at the stage of invoking handlers, each
handler is called only once."
:type `(repeat
(cons (choice :tag "Keyword"
,@(mapcar #'(lambda (k) (list 'const k))
use-package-keywords)
(const :tag "Any" t))
function))
:group 'use-package)
(defcustom use-package-hook-name-suffix "-hook"
"Text append to the name of hooks mentioned by :hook.
Set to nil if you don't want this to happen; it's only a
convenience."
:type '(choice string (const :tag "No suffix" nil))
:group 'use-package)
(defcustom use-package-minimum-reported-time 0.1
"Minimal load time that will be reported.
Note that `use-package-verbose' has to be set to a non-nil value
for anything to be reported at all."
:type 'number
:group 'use-package)
(defcustom use-package-inject-hooks nil
"If non-nil, add hooks to the `:init' and `:config' sections.
In particular, for a given package `foo', the following hooks
become available:
`use-package--foo--pre-init-hook'
`use-package--foo--post-init-hook'
`use-package--foo--pre-config-hook'
`use-package--foo--post-config-hook'
This way, you can add to these hooks before evaluation of a
`use-package` declaration, and exercise some control over what
happens.
NOTE: These hooks are run even if the user does not specify an
`:init' or `:config' block, and they will happen at the regular
time when initialization and configuration would have been
performed.
NOTE: If the `pre-init' hook return a nil value, that block's
user-supplied configuration is not evaluated, so be certain to
return t if you only wish to add behavior to what the user had
specified."
:type 'boolean
:group 'use-package)
(defcustom use-package-expand-minimally nil
"If non-nil, make the expanded code as minimal as possible.
This disables:
- Printing to the *Messages* buffer of slowly-evaluating forms
- Capturing of load errors (normally redisplayed as warnings)
- Conditional loading of packages (load failures become errors)
The main advantage to this variable is that, if you know your
configuration works, it will make the byte-compiled file as
minimal as possible. It can also help with reading macro-expanded
definitions, to understand the main intent of what's happening."
:type 'boolean
:group 'use-package)
(defcustom use-package-form-regexp-eval
`(concat ,(eval-when-compile
(concat "^\\s-*("
(regexp-opt '("use-package" "require") t)
"\\s-+\\("))
(or (bound-and-true-p lisp-mode-symbol-regexp)
"\\(?:\\sw\\|\\s_\\|\\\\.\\)+") "\\)")
"Sexp providing regexp for finding use-package forms in user files.
This is used by `use-package-jump-to-package-form' and
`use-package-enable-imenu-support'."
:type 'sexp
:group 'use-package)
(defcustom use-package-enable-imenu-support nil
"If non-nil, cause imenu to see `use-package' declarations.
This is done by adjusting `lisp-imenu-generic-expression' to
include support for finding `use-package' and `require' forms.
Must be set before loading use-package."
:type 'boolean
:set
#'(lambda (_sym value)
(eval-after-load 'lisp-mode
(if value
`(add-to-list 'lisp-imenu-generic-expression
(list "Packages" ,use-package-form-regexp-eval 2))
`(setq lisp-imenu-generic-expression
(remove (list "Packages" ,use-package-form-regexp-eval 2)
lisp-imenu-generic-expression)))))
:group 'use-package)
(defconst use-package-font-lock-keywords
'(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
(1 font-lock-keyword-face)
(2 font-lock-constant-face nil t))))
(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords)
(defcustom use-package-compute-statistics nil
"If non-nil, compute statistics concerned use-package declarations.
View the statistical report using `use-package-report'. Note that
if this option is enabled, you must require `use-package' in your
user init file at loadup time, or you will see errors concerning
undefined variables."
:type 'boolean
:group 'use-package)
(defvar use-package-statistics (make-hash-table))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Utility functions
;;
(defsubst use-package-error (msg)
"Report MSG as an error, so the user knows it came from this package."
(error "use-package: %s" msg))
(defsubst use-package-concat (&rest elems)
"Delete all empty lists from ELEMS (nil or (list nil)), and append them."
(apply #'append (delete nil (delete (list nil) elems))))
(defsubst use-package-non-nil-symbolp (sym)
(and sym (symbolp sym)))
(defsubst use-package-as-symbol (string-or-symbol)
"If STRING-OR-SYMBOL is already a symbol, return it. Otherwise
convert it to a symbol and return that."
(if (symbolp string-or-symbol) string-or-symbol
(intern string-or-symbol)))
(defsubst use-package-as-string (string-or-symbol)
"If STRING-OR-SYMBOL is already a string, return it. Otherwise
convert it to a string and return that."
(if (stringp string-or-symbol) string-or-symbol
(symbol-name string-or-symbol)))
(defsubst use-package-regex-p (re)
"Return t if RE is some regexp-like thing."
(or (and (listp re) (eq (car re) 'rx))
(stringp re)))
(defun use-package-normalize-regex (re)
"Given some regexp-like thing in RE, resolve to a regular expression."
(cond
((and (listp re) (eq (car re) 'rx)) (eval re))
((stringp re) re)
(t (error "Not recognized as regular expression: %s" re))))
(defsubst use-package-is-pair (x car-pred cdr-pred)
"Return non-nil if X is a cons satisfying the given predicates.
CAR-PRED and CDR-PRED are applied to X's `car' and `cdr',
respectively."
(and (consp x)
(funcall car-pred (car x))
(funcall cdr-pred (cdr x))))
(defun use-package-as-mode (string-or-symbol)
"If STRING-OR-SYMBOL ends in `-mode' (or its name does), return
it as a symbol. Otherwise, return it as a symbol with `-mode'
appended."
(let ((string (use-package-as-string string-or-symbol)))
(intern (if (string-match "-mode\\'" string)
string
(concat string "-mode")))))
(defsubst use-package-load-name (name &optional noerror)
"Return a form which will load or require NAME.
It does the right thing no matter if NAME is a string or symbol.
Argument NOERROR means to indicate load failures as a warning."
(if (stringp name)
`(load ,name ,noerror)
`(require ',name nil ,noerror)))
(defun use-package-hook-injector (name-string keyword body)
"Wrap pre/post hook injections around the given BODY for KEYWORD.
The BODY is a list of forms, so `((foo))' if only `foo' is being called."
(if (not use-package-inject-hooks)
body
(let ((keyword-name (substring (format "%s" keyword) 1)))
`((when (run-hook-with-args-until-failure
',(intern (concat "use-package--" name-string
"--pre-" keyword-name "-hook")))
,@body
(run-hooks
',(intern (concat "use-package--" name-string
"--post-" keyword-name "-hook"))))))))
(defun use-package-with-elapsed-timer (text body)
"BODY is a list of forms, so `((foo))' if only `foo' is being called."
(declare (indent 1))
(if use-package-expand-minimally
body
(let ((nowvar (make-symbol "now")))
(if (bound-and-true-p use-package-verbose)
`((let ((,nowvar (current-time)))
(message "%s..." ,text)
(prog1
,(macroexp-progn body)
(let ((elapsed
(float-time (time-subtract (current-time) ,nowvar))))
(if (> elapsed ,use-package-minimum-reported-time)
(message "%s...done (%.3fs)" ,text elapsed)
(message "%s...done" ,text))))))
body))))
(put 'use-package-with-elapsed-timer 'lisp-indent-function 1)
(defun use-package-require (name &optional no-require body)
(if use-package-expand-minimally
(use-package-concat
(unless no-require
(list (use-package-load-name name)))
body)
(if no-require
body
(use-package-with-elapsed-timer
(format "Loading package %s" name)
`((if (not ,(use-package-load-name name t))
(display-warning 'use-package
(format "Cannot load %s" ',name)
:error)
,@body))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Property lists
;;
(defun use-package-plist-delete (plist property)
"Delete PROPERTY from PLIST.
This is in contrast to merely setting it to 0."
(let (p)
(while plist
(if (not (eq property (car plist)))
(setq p (plist-put p (car plist) (nth 1 plist))))
(setq plist (cddr plist)))
p))
(defun use-package-plist-delete-first (plist property)
"Delete PROPERTY from PLIST.
This is in contrast to merely setting it to 0."
(let (p)
(while plist
(if (eq property (car plist))
(setq p (nconc p (cddr plist))
plist nil)
(setq p (nconc p (list (car plist) (cadr plist)))
plist (cddr plist))))
p))
(defsubst use-package-plist-maybe-put (plist property value)
"Add a VALUE for PROPERTY to PLIST, if it does not already exist."
(if (plist-member plist property)
plist
(plist-put plist property value)))
(defsubst use-package-plist-cons (plist property value)
"Cons VALUE onto the head of the list at PROPERTY in PLIST."
(plist-put plist property (cons value (plist-get plist property))))
(defsubst use-package-plist-append (plist property value)
"Append VALUE onto the front of the list at PROPERTY in PLIST."
(plist-put plist property (append value (plist-get plist property))))
(defun use-package-split-list (pred xs)
(let ((ys (list nil)) (zs (list nil)) flip)
(cl-dolist (x xs)
(if flip
(nconc zs (list x))
(if (funcall pred x)
(progn
(setq flip t)
(nconc zs (list x)))
(nconc ys (list x)))))
(cons (cdr ys) (cdr zs))))
(defun use-package-split-list-at-keys (key lst)
(and lst
(let ((xs (use-package-split-list (apply-partially #'eq key) lst)))
(cons (car xs) (use-package-split-list-at-keys key (cddr xs))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Keywords
;;
(defun use-package-keyword-index (keyword)
(cl-loop named outer
with index = 0
for k in use-package-keywords do
(if (eq k keyword)
(cl-return-from outer index))
(cl-incf index)))
(defun use-package-normalize-plist (name input &optional plist merge-function)
"Given a pseudo-plist, normalize it to a regular plist.
The normalized key/value pairs from input are added to PLIST,
extending any keys already present."
(if (null input)
plist
(let* ((keyword (car input))
(xs (use-package-split-list #'keywordp (cdr input)))
(args (car xs))
(tail (cdr xs))
(normalizer
(intern-soft (concat "use-package-normalize/"
(symbol-name keyword))))
(arg (and (functionp normalizer)
(funcall normalizer name keyword args)))
(error-string (format "Unrecognized keyword: %s" keyword)))
(if (memq keyword use-package-keywords)
(progn
(setq plist (use-package-normalize-plist
name tail plist merge-function))
(plist-put plist keyword
(if (plist-member plist keyword)
(funcall merge-function keyword arg
(plist-get plist keyword))
arg)))
(if use-package-ignore-unknown-keywords
(progn
(display-warning 'use-package error-string)
(use-package-normalize-plist
name tail plist merge-function))
(use-package-error error-string))))))
(defun use-package-unalias-keywords (_name args)
(setq args (cl-nsubstitute :if :when args))
(let (temp)
(while (setq temp (plist-get args :unless))
(setq args (use-package-plist-delete-first args :unless)
args (append args `(:if (not ,temp))))))
args)
(defun use-package-merge-keys (key new old)
(let ((merger (assq key use-package-merge-key-alist)))
(if merger
(funcall (cdr merger) new old)
(append new old))))
(defun use-package-sort-keywords (plist)
(let (plist-grouped)
(while plist
(push (cons (car plist) (cadr plist))
plist-grouped)
(setq plist (cddr plist)))
(let (result)
(cl-dolist
(x
(nreverse
(sort plist-grouped
#'(lambda (l r) (< (use-package-keyword-index (car l))
(use-package-keyword-index (car r)))))))
(setq result (cons (car x) (cons (cdr x) result))))
result)))
(defun use-package-normalize-keywords (name args)
(let* ((name-symbol (if (stringp name) (intern name) name))
(name-string (symbol-name name-symbol)))
;; The function `elisp--local-variables' inserts this unbound variable into
;; macro forms to determine the locally bound variables for
;; `elisp-completion-at-point'. It ends up throwing a lot of errors since it
;; can occupy the position of a keyword (or look like a second argument to a
;; keyword that takes one). Deleting it when it's at the top level should be
;; harmless since there should be no locally bound variables to discover
;; here anyway.
(setq args (delq 'elisp--witness--lisp args))
;; Reduce the set of keywords down to its most fundamental expression.
(setq args (use-package-unalias-keywords name-symbol args))
;; Normalize keyword values, coalescing multiple occurrences.
(setq args (use-package-normalize-plist name-symbol args nil
#'use-package-merge-keys))
;; Add default values for keywords not specified, when applicable.
(cl-dolist (spec use-package-defaults)
(when (let ((func (nth 2 spec)))
(if (and func (functionp func))
(funcall func name args)
(eval func)))
(setq args (use-package-plist-maybe-put
args (nth 0 spec)
(let ((func (nth 1 spec)))
(if (and func (functionp func))
(funcall func name args)
(eval func)))))))
;; Determine any autoloads implied by the keywords used.
(let ((iargs args)
commands)
(while iargs
(when (keywordp (car iargs))
(let ((autoloads
(intern-soft (concat "use-package-autoloads/"
(symbol-name (car iargs))))))
(when (functionp autoloads)
(setq commands
;; jww (2017-12-07): Right now we just ignored the type of
;; the autoload being requested, and assume they are all
;; `command'.
(append (mapcar
#'car
(funcall autoloads name-symbol (car iargs)
(cadr iargs)))
commands)))))
(setq iargs (cddr iargs)))
(when commands
(setq args
;; Like `use-package-plist-append', but removing duplicates.
(plist-put args :commands
(delete-dups
(append commands (plist-get args :commands)))))))
;; If byte-compiling, pre-load the package so all its symbols are in
;; scope. This is done by prepending statements to the :preface.
(when (bound-and-true-p byte-compile-current-file)
(setq args
(use-package-plist-append
args :preface
(use-package-concat
(mapcar #'(lambda (var) `(defvar ,var))
(plist-get args :defines))
(mapcar #'(lambda (fn) `(declare-function ,fn ,name-string))
(plist-get args :functions))
`((eval-when-compile
(with-demoted-errors
,(format "Cannot load %s: %%S" name-string)
,(when (eq use-package-verbose 'debug)
`(message ,(format "Compiling package %s" name-string)))
,(unless (plist-get args :no-require)
`(load ,name-string nil t)))))))))
;; Certain keywords imply :defer, if :demand was not specified.
(when (and (not (plist-member args :demand))
(not (plist-member args :defer))
(not (or (equal '(t) (plist-get args :load))
(equal (list (use-package-as-string name))
(mapcar #'use-package-as-string
(plist-get args :load)))))
(cl-some #'identity
(mapcar (apply-partially #'plist-member args)
use-package-deferring-keywords)))
(setq args (append args '(:defer t))))
;; The :load keyword overrides :no-require
(when (and (plist-member args :load)
(plist-member args :no-require))
(setq args (use-package-plist-delete args :no-require)))
;; If at this point no :load, :defer or :no-require has been seen, then
;; :load the package itself.
(when (and (not (plist-member args :load))
(not (plist-member args :defer))
(not (plist-member args :no-require)))
(setq args (append args `(:load (,name)))))
;; Sort the list of keywords based on the order of `use-package-keywords'.
(use-package-sort-keywords args)))
(defun use-package-process-keywords (name plist &optional state)
"Process the next keyword in the free-form property list PLIST.
The values in the PLIST have each been normalized by the function
use-package-normalize/KEYWORD (minus the colon).
STATE is a property list that the function may modify and/or
query. This is useful if a package defines multiple keywords and
wishes them to have some kind of stateful interaction.
Unless the KEYWORD being processed intends to ignore remaining
keywords, it must call this function recursively, passing in the
plist with its keyword and argument removed, and passing in the
next value for the STATE."
(declare (indent 1))
(unless (null plist)
(let* ((keyword (car plist))
(arg (cadr plist))
(rest (cddr plist)))
(unless (keywordp keyword)
(use-package-error (format "%s is not a keyword" keyword)))
(let* ((handler (concat "use-package-handler/" (symbol-name keyword)))
(handler-sym (intern handler)))
(if (functionp handler-sym)
(funcall handler-sym name keyword arg rest state)
(use-package-error
(format "Keyword handler not defined: %s" handler)))))))
(put 'use-package-process-keywords 'lisp-indent-function 'defun)
(defun use-package-list-insert (elem xs &optional anchor after test)
"Insert ELEM into the list XS.
If ANCHOR is also a keyword, place the new KEYWORD before that
one.
If AFTER is non-nil, insert KEYWORD either at the end of the
keywords list, or after the ANCHOR if one has been provided.
If TEST is non-nil, it is the test used to compare ELEM to list
elements. The default is `eq'.
The modified list is returned. The original list is not modified."
(let (result)
(dolist (k xs)
(if (funcall (or test #'eq) k anchor)
(if after
(setq result (cons k result)
result (cons elem result))
(setq result (cons elem result)
result (cons k result)))
(setq result (cons k result))))
(if anchor
(nreverse result)
(if after
(nreverse (cons elem result))
(cons elem (nreverse result))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Argument Processing
;;
(defun use-package-only-one (label args f)
"Call F on the first member of ARGS if it has exactly one element."
(declare (indent 1))
(cond
((and (listp args) (listp (cdr args))
(= (length args) 1))
(funcall f label (car args)))
(t
(use-package-error
(concat label " wants exactly one argument")))))
(put 'use-package-only-one 'lisp-indent-function 'defun)
(defun use-package-as-one (label args f &optional allow-empty)
"Call F on the first element of ARGS if it has one element, or all of ARGS.
If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list."
(declare (indent 1))
(if (if args
(and (listp args) (listp (cdr args)))
allow-empty)
(if (= (length args) 1)
(funcall f label (car args))
(funcall f label args))
(use-package-error
(concat label " wants a non-empty list"))))
(put 'use-package-as-one 'lisp-indent-function 'defun)
(defun use-package-memoize (f arg)
"Ensure the macro-expansion of F applied to ARG evaluates ARG
no more than once."
(let ((loaded (cl-gentemp "use-package--loaded"))
(result (cl-gentemp "use-package--result"))
(next (cl-gentemp "use-package--next")))
`((defvar ,loaded nil)
(defvar ,result nil)
(defvar ,next #'(lambda () (if ,loaded ,result
(setq ,loaded t ,result ,arg))))
,@(funcall f `((funcall ,next))))))
(defsubst use-package-normalize-value (_label arg)
"Normalize the Lisp value given by ARG.
The argument LABEL is ignored."
(cond ((null arg) nil)
((eq t arg) t)
((use-package-non-nil-symbolp arg)
`(symbol-value ',arg))
((functionp arg)
`(funcall #',arg))
(t arg)))
(defun use-package-normalize-symbols (label arg &optional recursed)
"Normalize a list of symbols."
(cond
((use-package-non-nil-symbolp arg)
(list arg))
((and (not recursed) (listp arg) (listp (cdr arg)))
(mapcar #'(lambda (x) (car (use-package-normalize-symbols label x t))) arg))
(t
(use-package-error
(concat label " wants a symbol, or list of symbols")))))
(defun use-package-normalize-symlist (_name keyword args)
(use-package-as-one (symbol-name keyword) args
#'use-package-normalize-symbols))
(defun use-package-normalize-recursive-symbols (label arg)
"Normalize a list of symbols."
(cond
((use-package-non-nil-symbolp arg)
arg)
((and (listp arg) (listp (cdr arg)))
(mapcar #'(lambda (x) (use-package-normalize-recursive-symbols label x))
arg))
(t
(use-package-error
(concat label " wants a symbol, or nested list of symbols")))))
(defun use-package-normalize-recursive-symlist (_name keyword args)
(use-package-as-one (symbol-name keyword) args
#'use-package-normalize-recursive-symbols))
(defun use-package-normalize-paths (label arg &optional recursed)
"Normalize a list of filesystem paths."
(cond
((and arg (or (use-package-non-nil-symbolp arg) (functionp arg)))
(let ((value (use-package-normalize-value label arg)))
(use-package-normalize-paths label (eval value))))
((stringp arg)
(let ((path (if (file-name-absolute-p arg)
arg
(expand-file-name arg user-emacs-directory))))
(list path)))
((and (not recursed) (listp arg) (listp (cdr arg)))
(mapcar #'(lambda (x)
(car (use-package-normalize-paths label x t))) arg))
(t
(use-package-error
(concat label " wants a directory path, or list of paths")))))
(defun use-package-normalize-predicate (_name keyword args)
(if (null args)
t
(use-package-only-one (symbol-name keyword) args
#'use-package-normalize-value)))
(defun use-package-normalize-form (label args)
"Given a list of forms, return it wrapped in `progn'."
(unless (listp (car args))
(use-package-error (concat label " wants a sexp or list of sexps")))
(mapcar #'(lambda (form)
(if (and (consp form)
(memq (car form)
'(use-package bind-key bind-key*
unbind-key bind-keys bind-keys*)))
(macroexpand form)
form)) args))
(defun use-package-normalize-forms (_name keyword args)
(use-package-normalize-form (symbol-name keyword) args))
(defun use-package-normalize-pairs
(key-pred val-pred name label arg &optional recursed)
"Normalize a list of pairs.
KEY-PRED and VAL-PRED are predicates recognizing valid keys and
values, respectively.
If RECURSED is non-nil, recurse into sublists."
(cond
((funcall key-pred arg)
(list (cons arg (use-package-as-symbol name))))
((use-package-is-pair arg key-pred val-pred)
(list arg))
((and (not recursed) (listp arg) (listp (cdr arg)))
(let (last-item)
(mapcar
#'(lambda (x)
(prog1
(let ((ret (use-package-normalize-pairs
key-pred val-pred name label x t)))
(if (and (listp ret)
(not (keywordp last-item)))
(car ret)
ret))
(setq last-item x))) arg)))
(t arg)))
(defun use-package-recognize-function (v &optional binding additional-pred)
"A predicate that recognizes functional constructions:
nil
sym
'sym
(quote sym)
#'sym
(function sym)
(lambda () ...)
'(lambda () ...)
(quote (lambda () ...))
#'(lambda () ...)
(function (lambda () ...))"
(or (if binding
(symbolp v)
(use-package-non-nil-symbolp v))
(and (listp v)
(memq (car v) '(quote function))
(use-package-non-nil-symbolp (cadr v)))
(if binding (commandp v) (functionp v))
(and additional-pred
(funcall additional-pred v))))
(defun use-package-normalize-function (v)
"Reduce functional constructions to one of two normal forms:
sym
#'(lambda () ...)"
(cond ((symbolp v) v)
((and (listp v)
(memq (car v) '(quote function))
(use-package-non-nil-symbolp (cadr v)))
(cadr v))
((and (consp v)
(eq 'lambda (car v)))
v)
((and (listp v)
(memq (car v) '(quote function))
(eq 'lambda (car (cadr v))))
(cadr v))
(t v)))
(defun use-package-normalize-commands (args)
"Map over ARGS of the form ((_ . F) ...), normalizing functional F's."
(mapcar #'(lambda (x)
(if (consp x)
(cons (car x) (use-package-normalize-function (cdr x)))
x))
args))
(defun use-package-normalize-mode (name keyword args)
"Normalize arguments for keywords which add regexp/mode pairs to an alist."
(use-package-as-one (symbol-name keyword) args
(apply-partially #'use-package-normalize-pairs
#'use-package-regex-p
#'use-package-recognize-function
name)))
(defun use-package-autoloads-mode (_name _keyword args)
(mapcar
#'(lambda (x) (cons (cdr x) 'command))
(cl-remove-if-not #'(lambda (x)
(and (consp x)
(use-package-non-nil-symbolp (cdr x))))
args)))
(defun use-package-handle-mode (name alist args rest state)
"Handle keywords which add regexp/mode pairs to an alist."
(use-package-concat
(use-package-process-keywords name rest state)
(mapcar
#'(lambda (thing)
`(add-to-list
',alist
',(cons (use-package-normalize-regex (car thing))
(cdr thing))))
(use-package-normalize-commands args))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Statistics
;;
(defun use-package-reset-statistics ()
(interactive)
(setq use-package-statistics (make-hash-table)))
(defun use-package-statistics-status (package)
"Return loading configuration status of PACKAGE statistics."
(cond ((gethash :config package) "Configured")
((gethash :init package) "Initialized")
((gethash :preface package) "Prefaced")
((gethash :use-package package) "Declared")))
(defun use-package-statistics-last-event (package)
"Return the date when PACKAGE's status last changed.
The date is returned as a string."
(format-time-string "%Y-%m-%d %a %H:%M"
(or (gethash :config package)
(gethash :init package)
(gethash :preface package)
(gethash :use-package package))))
(defun use-package-statistics-time (package)
"Return the time is took for PACKAGE to load."
(+ (float-time (gethash :config-secs package '(0 0 0 0)))
(float-time (gethash :init-secs package '(0 0 0 0)))
(float-time (gethash :preface-secs package '(0 0 0 0)))
(float-time (gethash :use-package-secs package '(0 0 0 0)))))
(defun use-package-statistics-convert (package)
"Return information about PACKAGE.
The information is formatted in a way suitable for
`use-package-statistics-mode'."
(let ((statistics (gethash package use-package-statistics)))
(list
package
(vector
(symbol-name package)
(use-package-statistics-status statistics)
(use-package-statistics-last-event statistics)
(format "%.2f" (use-package-statistics-time statistics))))))
(defun use-package-report ()
"Show current statistics gathered about use-package declarations.
In the table that's generated, the status field has the following
meaning:
Configured :config has been processed (the package is loaded!)
Initialized :init has been processed (load status unknown)
Prefaced :preface has been processed
Declared the use-package declaration was seen"
(interactive)
(with-current-buffer (get-buffer-create "*use-package statistics*")
(setq tabulated-list-entries
(mapcar #'use-package-statistics-convert
(hash-table-keys use-package-statistics)))
(use-package-statistics-mode)
(tabulated-list-print)
(display-buffer (current-buffer))))
(define-derived-mode use-package-statistics-mode tabulated-list-mode
"use-package statistics"
"Show current statistics gathered about use-package declarations."
(setq tabulated-list-format
;; The sum of column width is 80 caracters:
#[("Package" 25 t)
("Status" 13 t)
("Last Event" 23 t)
("Time" 10 t)])
(tabulated-list-init-header))
(defun use-package-statistics-gather (keyword name after)
(let* ((hash (gethash name use-package-statistics
(make-hash-table)))
(before (and after (gethash keyword hash (current-time)))))
(puthash keyword (current-time) hash)
(when after
(puthash (intern (concat (symbol-name keyword) "-secs"))
(time-subtract (current-time) before) hash))
(puthash name hash use-package-statistics)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Handlers
;;
;;;; :disabled
;; Don't alias this to `ignore', as that will cause the resulting
;; function to be interactive.
(defun use-package-normalize/:disabled (_name _keyword _arg)
"Do nothing, return nil.")
(defun use-package-handler/:disabled (name _keyword _arg rest state)
(use-package-process-keywords name rest state))
;;;; :if, :when and :unless
(defun use-package-normalize-test (_name keyword args)
(use-package-only-one (symbol-name keyword) args
#'use-package-normalize-value))
(defalias 'use-package-normalize/:if 'use-package-normalize-test)
(defun use-package-handler/:if (name _keyword pred rest state)
(let ((body (use-package-process-keywords name rest state)))
`((when ,pred ,@body))))
(defalias 'use-package-normalize/:when 'use-package-normalize-test)
(defalias 'use-package-handler/:when 'use-package-handler/:if)
(defalias 'use-package-normalize/:unless 'use-package-normalize-test)
(defun use-package-handler/:unless (name _keyword pred rest state)
(let ((body (use-package-process-keywords name rest state)))
`((unless ,pred ,@body))))
;;;; :requires
(defalias 'use-package-normalize/:requires 'use-package-normalize-symlist)
(defun use-package-handler/:requires (name _keyword requires rest state)
(let ((body (use-package-process-keywords name rest state)))
(if (null requires)
body
`((when ,(if (> (length requires) 1)
`(not (member nil (mapcar #'featurep ',requires)))
`(featurep ',(car requires)))
,@body)))))
;;;; :load-path
(defun use-package-normalize/:load-path (_name keyword args)
(use-package-as-one (symbol-name keyword) args
#'use-package-normalize-paths))
(defun use-package-handler/:load-path (name _keyword arg rest state)
(let ((body (use-package-process-keywords name rest state)))
(use-package-concat
(mapcar #'(lambda (path)
`(eval-and-compile (add-to-list 'load-path ,path)))
arg)
body)))
;;;; :no-require
(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate)
(defun use-package-handler/:no-require (name _keyword _arg rest state)
(use-package-process-keywords name rest state))
;;;; :defines
(defalias 'use-package-normalize/:defines 'use-package-normalize-symlist)
(defun use-package-handler/:defines (name _keyword _arg rest state)
(use-package-process-keywords name rest state))
;;;; :functions
(defalias 'use-package-normalize/:functions 'use-package-normalize-symlist)
(defun use-package-handler/:functions (name _keyword _arg rest state)
(use-package-process-keywords name rest state))
;;;; :preface
(defalias 'use-package-normalize/:preface 'use-package-normalize-forms)
(defun use-package-handler/:preface (name _keyword arg rest state)
(let ((body (use-package-process-keywords name rest state)))
(use-package-concat
(when use-package-compute-statistics
`((use-package-statistics-gather :preface ',name nil)))
(when arg
`((eval-and-compile ,@arg)))
body
(when use-package-compute-statistics
`((use-package-statistics-gather :preface ',name t))))))
;;;; :catch
(defvar use-package--form)
(defvar use-package--hush-function #'(lambda (_keyword body) body))
(defsubst use-package-hush (context keyword body)
`((condition-case-unless-debug err
,(macroexp-progn body)
(error (funcall ,context ,keyword err)))))
(defun use-package-normalize/:catch (_name keyword args)
(if (null args)
t
(use-package-only-one (symbol-name keyword) args
use-package--hush-function)))
(defun use-package-handler/:catch (name keyword arg rest state)
(let* ((context (cl-gentemp "use-package--warning")))
(cond
((not arg)
(use-package-process-keywords name rest state))
((eq arg t)
`((defvar ,context
#'(lambda (keyword err)
(let ((msg (format "%s/%s: %s" ',name keyword
(error-message-string err))))
,@(when (eq use-package-verbose 'debug)
`((with-current-buffer
(get-buffer-create "*use-package*")
(goto-char (point-max))
(insert "-----\n" msg ,use-package--form)
(emacs-lisp-mode))
(setq msg
(concat msg
" (see the *use-package* buffer)"))))
(display-warning 'use-package msg :error))))
,@(let ((use-package--hush-function
(apply-partially #'use-package-hush context)))
(funcall use-package--hush-function keyword
(use-package-process-keywords name rest state)))))
((functionp arg)
`((defvar ,context ,arg)
,@(let ((use-package--hush-function
(apply-partially #'use-package-hush context)))
(funcall use-package--hush-function keyword
(use-package-process-keywords name rest state)))))
(t
(use-package-error "The :catch keyword expects 't' or a function")))))
;;;; :interpreter
(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode)
(defalias 'use-package-autoloads/:interpreter 'use-package-autoloads-mode)
(defun use-package-handler/:interpreter (name _keyword arg rest state)
(use-package-handle-mode name 'interpreter-mode-alist arg rest state))
;;;; :mode
(defalias 'use-package-normalize/:mode 'use-package-normalize-mode)
(defalias 'use-package-autoloads/:mode 'use-package-autoloads-mode)
(defun use-package-handler/:mode (name _keyword arg rest state)
(use-package-handle-mode name 'auto-mode-alist arg rest state))
;;;; :magic
(defalias 'use-package-normalize/:magic 'use-package-normalize-mode)
(defalias 'use-package-autoloads/:magic 'use-package-autoloads-mode)
(defun use-package-handler/:magic (name _keyword arg rest state)
(use-package-handle-mode name 'magic-mode-alist arg rest state))
;;;; :magic-fallback
(defalias 'use-package-normalize/:magic-fallback 'use-package-normalize-mode)
(defalias 'use-package-autoloads/:magic-fallback 'use-package-autoloads-mode)
(defun use-package-handler/:magic-fallback (name _keyword arg rest state)
(use-package-handle-mode name 'magic-fallback-mode-alist arg rest state))
;;;; :hook
(defun use-package-normalize/:hook (name keyword args)
(use-package-as-one (symbol-name keyword) args
#'(lambda (label arg)
(unless (or (use-package-non-nil-symbolp arg) (consp arg))
(use-package-error
(concat label " a or ( . )"
" or list of these")))
(use-package-normalize-pairs
#'(lambda (k)
(or (use-package-non-nil-symbolp k)
(and k (let ((every t))
(while (and every k)
(if (and (consp k)
(use-package-non-nil-symbolp (car k)))
(setq k (cdr k))
(setq every nil)))
every))))
#'use-package-recognize-function
name label arg))))
(defalias 'use-package-autoloads/:hook 'use-package-autoloads-mode)
(defun use-package-handler/:hook (name _keyword args rest state)
"Generate use-package custom keyword code."
(use-package-concat
(use-package-process-keywords name rest state)
(cl-mapcan
#'(lambda (def)
(let ((syms (car def))
(fun (cdr def)))
(when fun
(mapcar
#'(lambda (sym)
`(add-hook
(quote ,(intern
(concat (symbol-name sym)
use-package-hook-name-suffix)))
(function ,fun)))
(if (use-package-non-nil-symbolp syms) (list syms) syms)))))
(use-package-normalize-commands args))))
;;;; :commands
(defalias 'use-package-normalize/:commands 'use-package-normalize-symlist)
(defun use-package-handler/:commands (name _keyword arg rest state)
(use-package-concat
;; Since we deferring load, establish any necessary autoloads, and also
;; keep the byte-compiler happy.
(let ((name-string (use-package-as-string name)))
(cl-mapcan
#'(lambda (command)
(when (symbolp command)
(append
(unless (plist-get state :demand)
`((unless (fboundp ',command)
(autoload #',command ,name-string nil t))))
(when (bound-and-true-p byte-compile-current-file)
`((eval-when-compile
(declare-function ,command ,name-string)))))))
(delete-dups arg)))
(use-package-process-keywords name rest state)))
;;;; :defer
(defalias 'use-package-normalize/:defer 'use-package-normalize-predicate)
(defun use-package-handler/:defer (name _keyword arg rest state)
(let ((body (use-package-process-keywords name rest state)))
(use-package-concat
;; Load the package after a set amount of idle time, if the argument to
;; `:defer' was a number.
(when (numberp arg)
`((run-with-idle-timer ,arg nil #'require
',(use-package-as-symbol name) nil t)))
(if (or (not arg) (null body))
body
`((eval-after-load ',name ',(macroexp-progn body)))))))
;;;; :after
(defun use-package-normalize/:after (name keyword args)
(setq args (use-package-normalize-recursive-symlist name keyword args))
(if (consp args)
args
(list args)))
(defun use-package-after-count-uses (features*)
"Count the number of time the body would appear in the result."
(cond ((use-package-non-nil-symbolp features*)
1)
((and (consp features*)
(memq (car features*) '(:or :any)))
(let ((num 0))
(cl-dolist (next (cdr features*))
(setq num (+ num (use-package-after-count-uses next))))
num))
((and (consp features*)
(memq (car features*) '(:and :all)))
(apply #'max (mapcar #'use-package-after-count-uses
(cdr features*))))
((listp features*)
(use-package-after-count-uses (cons :all features*)))))
(defun use-package-require-after-load (features* body)
"Generate `eval-after-load' statements to represents FEATURES*.
FEATURES* is a list containing keywords `:and' and `:all', where
no keyword implies `:all'."
(cond
((use-package-non-nil-symbolp features*)
`((eval-after-load ',features* ',(macroexp-progn body))))
((and (consp features*)
(memq (car features*) '(:or :any)))
(cl-mapcan #'(lambda (x) (use-package-require-after-load x body))
(cdr features*)))
((and (consp features*)
(memq (car features*) '(:and :all)))
(cl-dolist (next (cdr features*))
(setq body (use-package-require-after-load next body)))
body)
((listp features*)
(use-package-require-after-load (cons :all features*) body))))
(defun use-package-handler/:after (name _keyword arg rest state)
(let ((body (use-package-process-keywords name rest state))
(uses (use-package-after-count-uses arg)))
(if (or (null uses) (null body))
body
(if (<= uses 1)
(use-package-require-after-load arg body)
(use-package-memoize
(apply-partially #'use-package-require-after-load arg)
(macroexp-progn body))))))
;;;; :demand
(defalias 'use-package-normalize/:demand 'use-package-normalize-predicate)
(defun use-package-handler/:demand (name _keyword _arg rest state)
(use-package-process-keywords name rest state))
;;;; :custom
(defun use-package-normalize/:custom (_name keyword args)
"Normalize use-package custom keyword."
(use-package-as-one (symbol-name keyword) args
#'(lambda (label arg)
(unless (listp arg)
(use-package-error
(concat label " a ( [comment])"
" or list of these")))
(if (use-package-non-nil-symbolp (car arg))
(list arg)
arg))))
(defun use-package-handler/:custom (name _keyword args rest state)
"Generate use-package custom keyword code."
(use-package-concat
(mapcar
#'(lambda (def)
(let ((variable (nth 0 def))
(value (nth 1 def))
(comment (nth 2 def)))
(unless (and comment (stringp comment))
(setq comment (format "Customized with use-package %s" name)))
`(customize-set-variable (quote ,variable) ,value ,comment)))
args)
(use-package-process-keywords name rest state)))
;;;; :custom-face
(defun use-package-normalize/:custom-face (name-symbol _keyword arg)
"Normalize use-package custom-face keyword."
(let ((error-msg
(format "%s wants a ( ) or list of these"
name-symbol)))
(unless (listp arg)
(use-package-error error-msg))
(cl-dolist (def arg arg)
(unless (listp def)
(use-package-error error-msg))
(let ((face (nth 0 def))
(spec (nth 1 def)))
(when (or (not face)
(not spec)
(> (length def) 2))
(use-package-error error-msg))))))
(defun use-package-handler/:custom-face (name _keyword args rest state)
"Generate use-package custom-face keyword code."
(use-package-concat
(mapcar #'(lambda (def) `(custom-set-faces (quote ,def))) args)
(use-package-process-keywords name rest state)))
;;;; :init
(defalias 'use-package-normalize/:init 'use-package-normalize-forms)
(defun use-package-handler/:init (name _keyword arg rest state)
(use-package-concat
(when use-package-compute-statistics
`((use-package-statistics-gather :init ',name nil)))
(let ((init-body
(use-package-hook-injector (use-package-as-string name)
:init arg)))
(when init-body
(funcall use-package--hush-function :init
(if use-package-check-before-init
`((when (locate-library ,(use-package-as-string name))
,@init-body))
init-body))))
(use-package-process-keywords name rest state)
(when use-package-compute-statistics
`((use-package-statistics-gather :init ',name t)))))
;;;; :load
(defun use-package-normalize/:load (name keyword args)
(setq args (use-package-normalize-recursive-symlist name keyword args))
(if (consp args)
args
(list args)))
(defun use-package-handler/:load (name _keyword arg rest state)
(let ((body (use-package-process-keywords name rest state)))
(cl-dolist (pkg arg)
(setq body (use-package-require (if (eq t pkg) name pkg) nil body)))
body))
;;;; :config
(defalias 'use-package-normalize/:config 'use-package-normalize-forms)
(defun use-package-handler/:config (name _keyword arg rest state)
(let* ((body (use-package-process-keywords name rest state))
(name-symbol (use-package-as-symbol name)))
(use-package-concat
(when use-package-compute-statistics
`((use-package-statistics-gather :config ',name nil)))
(if (or (null arg) (equal arg '(t)))
body
(use-package-with-elapsed-timer
(format "Configuring package %s" name-symbol)
(funcall use-package--hush-function :config
(use-package-concat
(use-package-hook-injector
(symbol-name name-symbol) :config arg)
body
(list t)))))
(when use-package-compute-statistics
`((use-package-statistics-gather :config ',name t))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; The main macro
;;
(defmacro use-package-core (name args)
`(let* ((args* (use-package-normalize-keywords ,name ,args))
(use-package--form
(if (eq use-package-verbose 'debug)
(concat "\n\n"
(pp-to-string `(use-package ,name ,@,args))
"\n -->\n\n"
(pp-to-string `(use-package ,name ,@args*))
"\n ==>\n\n"
(pp-to-string
(macroexp-progn
(let ((use-package-verbose 'errors)
(use-package-expand-minimally t))
(use-package-process-keywords name args*
(and (plist-get args* :demand)
(list :demand t)))))))
"")))
(use-package-process-keywords name args*
(and (plist-get args* :demand)
(list :demand t)))))
;;;###autoload
(defmacro use-package (name &rest args)
"Declare an Emacs package by specifying a group of configuration options.
For full documentation, please see the README file that came with
this file. Usage:
(use-package package-name
[:keyword [option]]...)
:init Code to run before PACKAGE-NAME has been loaded.
:config Code to run after PACKAGE-NAME has been loaded. Note that
if loading is deferred for any reason, this code does not
execute until the lazy load has occurred.
:preface Code to be run before everything except `:disabled'; this
can be used to define functions for use in `:if', or that
should be seen by the byte-compiler.
:mode Form to be added to `auto-mode-alist'.
:magic Form to be added to `magic-mode-alist'.
:magic-fallback Form to be added to `magic-fallback-mode-alist'.
:interpreter Form to be added to `interpreter-mode-alist'.
:commands Define autoloads for commands that will be defined by the
package. This is useful if the package is being lazily
loaded, and you wish to conditionally call functions in your
`:init' block that are defined in the package.
:bind Bind keys, and define autoloads for the bound commands.
:bind* Bind keys, and define autoloads for the bound commands,
*overriding all minor mode bindings*.
:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the
package. This is like `:bind', but for keymaps.
:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings
:defer Defer loading of a package -- this is implied when using
`:commands', `:bind', `:bind*', `:mode', `:magic',
`:magic-fallback', or `:interpreter'. This can be an integer,
to force loading after N seconds of idle time, if the package
has not already been loaded.
:after Defer loading of a package until after any of the named
features are loaded.
:demand Prevent deferred loading in all cases.
:if EXPR Initialize and load only if EXPR evaluates to a non-nil value.
:disabled The package is ignored completely if this keyword is present.
:defines Declare certain variables to silence the byte-compiler.
:functions Declare certain functions to silence the byte-compiler.
:load-path Add to the `load-path' before attempting to load the package.
:diminish Support for diminish.el (if installed).
:delight Support for delight.el (if installed).
:custom Call `customize-set-variable' with each variable definition.
:custom-face Call `customize-set-faces' with each face definition.
:ensure Loads the package using package.el if necessary.
:pin Pin the package to an archive."
(declare (indent 1))
(unless (memq :disabled args)
(macroexp-progn
(use-package-concat
(when use-package-compute-statistics
`((use-package-statistics-gather :use-package ',name nil)))
(if (eq use-package-verbose 'errors)
(use-package-core name args)
(condition-case-unless-debug err
(use-package-core name args)
(error
(ignore
(display-warning
'use-package
(format "Failed to parse package %s: %s"
name (error-message-string err)) :error)))))
(when use-package-compute-statistics
`((use-package-statistics-gather :use-package ',name t)))))))
(put 'use-package 'lisp-indent-function 'defun)
(provide 'use-package-core)
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
;;; use-package-core.el ends here
use-package-2.4/use-package.el 0000644 0001750 0001750 00000003742 13374646103 016122 0 ustar dogsleg dogsleg ;;; use-package.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*-
;; Copyright (C) 2012-2017 John Wiegley
;; Author: John Wiegley
;; Maintainer: John Wiegley
;; Created: 17 Jun 2012
;; Modified: 29 Nov 2017
;; Version: 2.4
;; Package-Requires: ((emacs "24.3") (bind-key "2.4"))
;; Keywords: dotemacs startup speed config package
;; URL: https://github.com/jwiegley/use-package
;; 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 3, 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.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; The `use-package' declaration macro allows you to isolate package
;; configuration in your ".emacs" in a way that is performance-oriented and,
;; well, just tidy. I created it because I have over 80 packages that I use
;; in Emacs, and things were getting difficult to manage. Yet with this
;; utility my total load time is just under 1 second, with no loss of
;; functionality!
;;
;; Please see README.md from the same repository for documentation.
;;; Code:
(require 'use-package-core)
(require 'use-package-bind-key)
(require 'use-package-diminish)
(require 'use-package-delight)
(require 'use-package-ensure)
(declare-function use-package-jump-to-package-form "use-package-jump")
(autoload #'use-package-jump-to-package-form "use-package-jump" nil t)
(provide 'use-package)
;;; use-package.el ends here
use-package-2.4/doc/ 0000755 0001750 0001750 00000000000 13412453075 014147 5 ustar dogsleg dogsleg use-package-2.4/doc/static/ 0000755 0001750 0001750 00000000000 13374646103 015441 5 ustar dogsleg dogsleg use-package-2.4/doc/static/favicon-16x16.png 0000644 0001750 0001750 00000000432 13374646103 020356 0 ustar dogsleg dogsleg PNG
IHDR a tEXtSoftware Adobe ImageReadyqe<