emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 85bec8d: * externals-list: Convert multishell, pcaed, and


From: Stefan Monnier
Subject: [elpa] master 85bec8d: * externals-list: Convert multishell, pcaed, and swiper to :external
Date: Sun, 29 Nov 2020 23:20:54 -0500 (EST)

branch: master
commit 85bec8db6406bea80d89fcdc1493428f0b85f7dc
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    * externals-list: Convert multishell, pcaed, and swiper to :external
---
 externals-list                            |    5 +-
 packages/multishell/.gitignore            |    2 -
 packages/multishell/LICENSE               |  674 ------------
 packages/multishell/README.md             |   57 -
 packages/multishell/getting-to-a-shell.md |   41 -
 packages/multishell/multishell-list.el    |  314 ------
 packages/multishell/multishell.el         |  846 ---------------
 packages/paced/.bzrignore                 |    8 -
 packages/paced/.elpaignore                |    5 -
 packages/paced/COPYING                    |  674 ------------
 packages/paced/Project.ede                |   48 -
 packages/paced/dir                        |   19 -
 packages/paced/paced-async.el             |  111 --
 packages/paced/paced-tests.el             |  507 ---------
 packages/paced/paced.el                   | 1356 -----------------------
 packages/paced/paced.info                 | 1029 ------------------
 packages/paced/paced.org                  |  783 --------------
 packages/paced/test-files/first.txt       |    1 -
 packages/paced/test-files/fourth.org      |    2 -
 packages/paced/test-files/second.cpp      |    1 -
 packages/paced/test-files/third.org       |    1 -
 packages/paced/test.mk                    |   27 -
 packages/swiper/swiper.el                 | 1673 -----------------------------
 23 files changed, 4 insertions(+), 8180 deletions(-)

diff --git a/externals-list b/externals-list
index df04b9a..808e5bc 100644
--- a/externals-list
+++ b/externals-list
@@ -139,6 +139,7 @@
  ("mmm-mode"            :external "https://github.com/purcell/mmm-mode.git";)
  ("modus-operandi-theme":external 
"https://gitlab.com/protesilaos/modus-themes";)
  ("modus-vivendi-theme"        :external 
"https://gitlab.com/protesilaos/modus-themes";)
+ ("multishell"         :external 
"https://github.com/kenmanheimer/EmacsMultishell";)
  ("muse"               :external "https://github.com/alexott/muse";) ;FIXME: 
Not nearly in-sync
  ("myers"              :external nil)
  ("nameless"           :external "https://github.com/Malabarba/Nameless";)
@@ -153,6 +154,7 @@
  ;;FIXME:("org"                :external ??) ;; Need to introduce snapshots!!
  ("orgalist"            :external nil)
  ("org-edna"           :external 
"https://savannah.nongnu.org/projects/org-edna-el";) ;URL?
+ ("paced"              :external 
"bzr::bzr://bzr.savannah.nongnu.org/paced-el/trunk")
  ("pabbrev"             :external "https://github.com/phillord/pabbrev.git";)
  ("parsec"              :external 
"https://github.com/cute-jumper/parsec.el.git";)
  ("peg"                        :external) ;Was in 
"https://github.com/ellerh/peg.el";
@@ -201,10 +203,11 @@
  ("sql-smie"            :external nil)
  ("ssh-deploy"         :external 
"https://github.com/cjohansson/emacs-ssh-deploy";)
  ("svg"                        :core ("lisp/svg.el"))
+ ("swiper"             :external "https://github.com/abo-abo/swiper";)
  ("system-packages"    :external 
"https://gitlab.com/jabranham/system-packages";)
  ("temp-buffer-browse"  :external 
"https://github.com/leoliu/temp-buffer-browse";)
  ("test-simple"         :external "https://github.com/rocky/emacs-test-simple";)
- ("timerfunctions" :external nil)
+ ("timerfunctions"     :external nil)
  ("undo-tree"          :external "http://www.dr-qubit.org/git/undo-tree.git";)
  ("uni-confusables"    :external nil)
  ("url-http-ntlm"      :external nil)
diff --git a/packages/multishell/.gitignore b/packages/multishell/.gitignore
deleted file mode 100644
index 1c17549..0000000
--- a/packages/multishell/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# Compiled
-*.elc
diff --git a/packages/multishell/LICENSE b/packages/multishell/LICENSE
deleted file mode 100644
index ef7e7ef..0000000
--- a/packages/multishell/LICENSE
+++ /dev/null
@@ -1,674 +0,0 @@
-GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- 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.
-
-    {one line to give the program's name and a brief idea of what it does.}
-    Copyright (C) {year}  {name of author}
-
-    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 <http://www.gnu.org/licenses/>.
-
-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:
-
-    {project}  Copyright (C) {year}  {fullname}
-    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
-<http://www.gnu.org/licenses/>.
-
-  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
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/packages/multishell/README.md b/packages/multishell/README.md
deleted file mode 100644
index 4004e51..0000000
--- a/packages/multishell/README.md
+++ /dev/null
@@ -1,57 +0,0 @@
-multishell.el
-=============
-
-Facilitate use of multiple local and remote Emacs shell buffers.
-
-Multishell is available via Emacs package manager, [in 
ELPA](https://elpa.gnu.org/packages/multishell.html). Install "multishell" from 
the `M-x package-list-packages` listing.
-
-I use the emacs shell a *lot*, including separate shells for separate
-project, and more shells for access to remote systems (which I do a lot, as
-a systems administrator). On top of emacs' powerful shell and tramp
-facilities, use a `multishell` (customization-activated) key binding to:
-
-* Get to the input point from wherever you are in a shell buffer,
-  ... or to any of your shell buffers, from anywhere inside emacs.
-
-* Use universal arguments to launch and choose among alternate shell buffers,
-  ... and change which is the current default.
-
-* Easily restart disconnected shells, or shells from prior sessions
-  ... the latter from Emacs builtin savehist minibuf history persistence
-
-* Append a path to a new shell name to launch a shell in that directory,
-  ... and use a path with Emacs tramp syntax to launch a remote shell -
-  for example:
-
-  * `#root/sudo:root@localhost:/etc` for a buffer named "#root" with a
-    root shell starting in /etc.
-
-  * `/ssh:example.net:/` for a shell buffer in / on example.net.
-    The buffer will be named "*example.net*".
-
-  * `#ex/ssh:example.net|sudo:root@example.net:/etc` for a root shell
-    starting in /etc on example.net named "*#ex*".
-
-  * `interior/ssh:gateway.corp.com|ssh:interior.corp.com:` to go via
-    gateway.corp.com to your homedir on interior.corp.com.  The buffer
-    will be named "*interior*". You could append a sudo hop, and so on.
-
-* Thanks to tramp, file visits from the shell will seamlessly be on the
-  host where the shell is running, in the auspices of the target account.
-
-See the `multishell-pop-to-shell` docstring (in
-[multishell.el](multishell.el)) for details, and
-[getting-to-a-shell.md](getting-to-a-shell.md) for the nitty-gritty
-decision tree that determines where the keybinding according to the various
-conditions.
-
-Customize-group `multishell' to select and activate a keybinding and set
-various behaviors. Customize-group `savehist' to preserve buffer
-names/paths across emacs restarts.
-
-Please use
-[the multishell repository](https://github.com/kenmanheimer/EmacsMultishell)
-issue tracker to report problems, suggestions, etc.
-
-See the [multishell.el](multishell.el) file commentary for a change log and
-Todo list.
diff --git a/packages/multishell/getting-to-a-shell.md 
b/packages/multishell/getting-to-a-shell.md
deleted file mode 100644
index a2ad649..0000000
--- a/packages/multishell/getting-to-a-shell.md
+++ /dev/null
@@ -1,41 +0,0 @@
-Multishell enables you to get to the input prompt in the shell you want
-with as few keystrokes as possible.
-
-* One keybinding, unmodified, gets you to the your current default shell, if
-  not in a shell, or to the input prompt of the current shell, if you're in
-  one.
-
-* Use the universal argument to select a specific shell buffer, wherever
-  point happens to be residing. Enter an empty line to the prompt to go to
-  your current default shell, or use completing read to go to a shell from
-  your multishell history, or start a new shell at the path you specify -
-  including remote paths, using tramp syntax. (See the
-  multishell-pop-to-shell docstring in [multishell.el](multishell.el) for
-  details.)
-
-* Use a doubled universal argument to set the shell you choose to be the
-  current default. (The prompt will indicate that mode with a "<==".)
-
-Here's the decision tree:
-
-* No universal argument - use:
-
-  * From-buffer is shell buffer: use from-buffer current name/path
-    - if shell/connection is stopped, restart/reconnect
-    - if not at input prompt, go there
-  * From-buffer is not shell buffer: 
-    - Go to multishell-primary-name current name/path, creating or
-      restarting and/or reconnecting if that shell is not currently running.
-
-* Universal argument provided - use:
-
-  - No name is specified - use current multishell-primary-name path
-  * Name is specified - use named buffer (creating if not already present):
-    * Path is also specified:
-      - shell is running - ignore new path
-      - shell will be started or restarted - use new path
-    * No path is specified:
-      - Name has history: use path from history
-      - Name has no history: use path that target buffer already has or 
inherits
-    - If the universal argument is doubled, set the selected shell as the
-      default one, going forwards.
diff --git a/packages/multishell/multishell-list.el 
b/packages/multishell/multishell-list.el
deleted file mode 100644
index 5cecae0..0000000
--- a/packages/multishell/multishell-list.el
+++ /dev/null
@@ -1,314 +0,0 @@
-;;; multishell-list.el --- tabulated-list-mode for multishell shell buffers  
-*- lexical-binding:t -*-
-
-;; Copyright (C) 2016-2020 Free Software Foundation, Inc. and Ken Manheimer
-
-;; Author: Ken Manheimer <ken.manheimer@gmail.com>
-;; Version: 1.1.8
-;; Created: 2016 -- first public availability
-;; Keywords: processes
-;; URL: https://github.com/kenmanheimer/EmacsMultishell
-
-;; See multishell.el for commentary, change log, etc.
-
-(require 'tabulated-list)
-(require 'multishell)
-(eval-when-compile (require 'cl-lib))
-
-(defgroup multishell-list nil
-  "Show a menu of all shell buffers in a buffer."
-  :group 'multishell)
-
-(defface multishell-list-name
-  '((t (:weight bold)))
-  "Face for shell names in the Multishell List."
-  :group 'multishell-list)
-
-(defun multishell-list-open-pop (&optional arg)
-  "Pop to current entry's shell in separate window.
-
-The shell is started if it's not already going, unless this is
-invoked with optional `universal-argument'. In that case we
-pop to the buffer but don't change its run state."
-  (interactive "P")
-  (let ((list-buffer (current-buffer))
-        (entry (tabulated-list-get-id)))
-    (if arg
-        (pop-to-buffer
-         (multishell-bracket (multishell-name-from-entry entry)))
-      (multishell-list-dispatch-selected entry t))
-    (with-current-buffer list-buffer
-      (revert-buffer)
-      (multishell-list-goto-item-by-entry entry))))
-
-(defun multishell-list-open-as-default ()
-  "Pop to current entry's shell, and set as the default shell."
-  (interactive)
-  (let ((list-buffer (current-buffer))
-        (entry (tabulated-list-get-id)))
-    (message "%s <==" (multishell-name-from-entry entry))
-    (multishell-list-dispatch-selected entry t t)
-    (with-current-buffer list-buffer
-      (revert-buffer)
-      (multishell-list-goto-item-by-entry entry))))
-
-(defun multishell-list-open-here (&optional arg)
-  "Switch to current entry's shell buffer.
-
-The shell is started if it's not already going, unless this is
-invoked with optional `universal-argument'. In that case we
-switch to the buffer but don't activate (or deactivate) it it."
-  (interactive "P")
-  (let* ((list-buffer (current-buffer))
-         (entry  (tabulated-list-get-id)))
-    (if arg
-        (switch-to-buffer
-         (multishell-bracket (multishell-name-from-entry entry)))
-      (multishell-list-dispatch-selected entry nil))
-    (with-current-buffer list-buffer
-      (revert-buffer))))
-
-(defun multishell-list-delete (&optional _arg)
-  "Remove current shell entry, and prompt for buffer-removal if present."
-  (interactive)
-  (let* ((entry (tabulated-list-get-id))
-         (name (multishell-name-from-entry entry))
-         (name-bracketed (multishell-bracket name))
-         (buffer (get-buffer name-bracketed)))
-    (when (multishell-delete-history-name name)
-      (and buffer
-           ;; If the process is live, let shell-mode get confirmation:
-           (or (comint-check-proc (current-buffer))
-               (y-or-n-p (format "Kill buffer %s? " name-bracketed)))
-           (kill-buffer name-bracketed)))
-    (tabulated-list-delete-entry)))
-
-(defun multishell-list-edit-entry (&optional arg)
-  "Edit the value of current shell entry.
-
-Submitting the change will not launch the entry, unless this is
-invoked with optional `universal-argument'. In the latter case,
-submitting the entry will pop to the shell in a new window,
-starting it if it's not already going."
-
-  (interactive "P")
-  (let* ((list-buffer (current-buffer))
-         (entry (tabulated-list-get-id))
-         (name (multishell-name-from-entry entry))
-         (revised (multishell-read-unbracketed-entry
-                   (format "Edit shell spec for %s: " name)
-                   entry
-                   'no-record))
-         (revised-name (multishell-name-from-entry revised))
-         buffer)
-    (when (not (string= revised entry))
-      (multishell-replace-entry entry revised)
-      (when (and (not (string= name revised-name))
-                 (setq buffer (get-buffer (multishell-bracket name))))
-        (with-current-buffer buffer
-          (rename-buffer (multishell-bracket revised-name)))))
-    (when arg
-      (multishell-list-dispatch-selected revised-name t))
-    (with-current-buffer list-buffer
-      (revert-buffer)
-      (multishell-list-goto-item-by-entry revised))))
-
-(defun multishell-list-clone-entry (&optional arg)
-  "Create a new list entry, edited from the current one, ready to launch.
-
-If you provide an optional `universal-argument', the new entry
-will be launched when it's created.
-
-The already existing original entry is left untouched."
-  (interactive "P")
-  (let* ((prototype (tabulated-list-get-id))
-         (name (multishell-name-from-entry prototype))
-         (new (multishell-read-unbracketed-entry
-               (format "Clone new shell spec from %s: " name)
-               prototype
-               'no-record))
-         (new-name (multishell-name-from-entry new))
-         (new-path (cadr (multishell-split-entry new))))
-    (when (not (string= new prototype))
-      (multishell-register-name-to-path new-name new-path)
-      (revert-buffer)
-      (multishell-list-goto-item-by-entry new)
-      (when arg
-        (multishell-list-dispatch-selected new-name t)))))
-
-(defun multishell-list-mouse-select (event)
-  "Select the shell whose line is clicked."
-  (interactive "e")
-  (select-window (posn-window (event-end event)))
-  (let ((entry (tabulated-list-get-id (posn-point (event-end event)))))
-    (multishell-list-dispatch-selected entry nil)))
-
-(defun multishell-list-dispatch-selected (entry pop &optional set-primary)
-  "Go to multishell ENTRY, popping to window if POP is non-nil.
-
-Optional arg SET-PRIMARY non-nil sets `multishell-primary-name' to entry.
-
-Provide for concluding minibuffer interaction if we're in completing mode."
-  (let ((set-primary-as-arg (and set-primary '(16))))
-    (if multishell-completing-read
-        ;; In multishell completing-read, arrange to conclude minibuffer input:
-        (throw 'multishell-minibuffer-exit (list entry pop set-primary-as-arg))
-      (multishell-pop-to-shell set-primary-as-arg entry (not pop)))))
-
-(defun multishell-list-placeholder (value default)
-  "Return VALUE if non-empty string, else DEFAULT."
-  (if (or (not value) (string= value ""))
-      default
-    value))
-(defconst multishell-list-active-flag "+")
-(defconst multishell-list-inactive-flag ".")
-(defconst multishell-list-absent-flag "x")
-
-(defun multishell-list-entries ()
-  "Generate multishell name/path-spec entries list for tabulated-list."
-  (let ((recency 0))
-    (mapcar #'(lambda (entry)
-                (setq recency (1+ recency))
-                (let* ((splat (multishell-split-entry entry))
-                       (name (car splat))
-                       (buffer (and name
-                                    (get-buffer
-                                     (multishell-bracket name))))
-                       (status (cond ((not buffer)
-                                      multishell-list-absent-flag)
-                                     ((comint-check-proc buffer)
-                                      multishell-list-active-flag)
-                                     (t multishell-list-inactive-flag)))
-                       (rest (cadr splat))
-                       (dir (and rest (or (file-remote-p rest 'localname)
-                                          rest)))
-                       (hops (and dir
-                                  (file-remote-p rest 'localname)
-                                  (substring
-                                   rest 0 (- (length rest) (length dir))))))
-                  (when (not name)
-                    (setq name (multishell-name-from-entry entry)))
-                  (list entry
-                        (vector (format "%d" recency)
-                                status
-                                (multishell-list--decorate-name name)
-                                (multishell-list-placeholder hops "-")
-                                (multishell-list-placeholder dir "~")))))
-            (multishell-all-entries))))
-
-(defun multishell-list-goto-item-by-entry (entry)
-  "Position at beginning of line of tabulated list item for ENTRY."
-  (goto-char (point-min))
-  (while (and (not (eobp))
-              (not (string= (tabulated-list-get-id) entry)))
-    (forward-line 1)))
-
-(define-obsolete-function-alias 'multishell-collate-row-strings-as-numbers
-  #'multishell-list--collate-row-strings-as-numbers "multishell 1.1.6")
-(defun multishell-list--collate-row-strings-as-numbers (a b)
-  (let ((a (aref (cadr a) 0))
-        (b (aref (cadr b) 0)))
-    (> (string-to-number a) (string-to-number b))))
-
-(defun multishell-list--decorate-name (name)
-  (propertize name
-              'font-lock-face 'multishell-list-name
-              'mouse-face 'highlight))
-
-(defvar multishell-list-mode-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map tabulated-list-mode-map)
-    (define-key map (kbd "c") 'multishell-list-clone-entry)
-    (define-key map (kbd "d") 'multishell-list-delete)
-    (define-key map (kbd "\C-k") 'multishell-list-delete)
-    (define-key map (kbd "k") 'multishell-list-delete)
-    (define-key map (kbd "e") 'multishell-list-edit-entry)
-    (define-key map (kbd "o") 'multishell-list-open-pop)
-    (define-key map (kbd " ") 'multishell-list-open-pop)
-    (define-key map (kbd "O") 'multishell-list-open-as-default)
-    (define-key map (kbd "RET") 'multishell-list-open-here)
-    (define-key map [mouse-2] 'multishell-list-mouse-select)
-    (define-key map [follow-link] 'mouse-face)
-    map))
-(define-derived-mode multishell-list-mode
-    tabulated-list-mode "Shells"
-  "Major mode for listing current and historically registered shells.
-
-Initial sort is from most to least recently used:
-
-- First active shells, flagged with `+' a plus sign
-- Then, inactive shells, flagged with `.' a period
-- Then historical shells that currently have no buffer, flagged with `x' an ex
-
-\\{multishell-list-mode-map\}"
-  (setq tabulated-list-format
-        [;; (name width sort '(:right-align nil :pad-right nil))
-         ("#" 0 multishell-list--collate-row-strings-as-numbers :pad-right 1)
-         ("! " 1 t :pad-right 1)
-         ("Name" 15 t)
-         ("Hops" 30 t)
-         ("Directory" 30 t)]
-        tabulated-list-sort-key '("#" . t)
-        tabulated-list-entries #'multishell-list-entries)
-  (tabulated-list-init-header))
-
-(defun multishell-list-cull-dups (entries)
-  "Return list of multishell ENTRIES sans ones with duplicate names.
-
-For duplicates, we prefer the ones that have paths."
-  (let ((tally (make-hash-table :test #'equal))
-        got name name-order-reversed already)
-    (dolist (entry entries)
-      (setq name (multishell-name-from-entry entry)
-            already (gethash name tally nil))
-      (when (not already)
-        (push name name-order-reversed))
-      (when (or (not already) (< (length already) (length entry)))
-        ;; Add new or replace shorter prior entry for name:
-        (puthash name entry tally)))
-    (dolist (name name-order-reversed)
-      (push (gethash name tally) got))
-    got))
-
-;;;###autoload
-(defun multishell-list (&optional completing)
-  "Edit your current and historic list of shell buffers.
-
-If optional COMPLETING is nil, we present the full
-`multishell-history' list in a popped buffer named `*Shells*'.
-
-In the buffer, hit ? or h for a list of commands.
-
-When optional COMPLETING is non-nil, it must be a list of
-multishell-history completion candidate entries, as provided by
-`completing-read'. Then we present the list as a part of
-minibuffer completion.
-
-You can get to the shells listing by recursively invoking
-\\[multishell-pop-to-shell] at the `multishell-pop-to-shell'
-`universal-argument' prompts."
-  (interactive)
-  (let ((from-entry (car (multishell-history-entries
-                          (multishell-unbracket (buffer-name
-                                                 (current-buffer))))))
-        (buffer (get-buffer-create (if completing
-                                       "*Completions*"
-                                     "*Shells*"))))
-    (if completing
-        (set-buffer buffer)
-      (pop-to-buffer buffer))
-    (multishell-list-mode)
-    (cl-progv
-        ;; Temporarily assign multishell-history only when completing:
-        (when completing '(multishell-history))
-        (when completing
-          (list (multishell-list-cull-dups (mapcar #'substring-no-properties
-                                                   completing))))
-      (tabulated-list-print))
-    (when completing
-      )
-    (when from-entry
-      (multishell-list-goto-item-by-entry from-entry))))
-
-(provide 'multishell-list)
-
-;;; multishell-list.el ends here
diff --git a/packages/multishell/multishell.el 
b/packages/multishell/multishell.el
deleted file mode 100644
index 6d93485..0000000
--- a/packages/multishell/multishell.el
+++ /dev/null
@@ -1,846 +0,0 @@
-;;; multishell.el --- Easily use multiple shell buffers, local and remote  -*- 
lexical-binding:t -*-
-
-;; Copyright (C) 1999-2020 Free Software Foundation, Inc. and Ken Manheimer
-
-;; Author: Ken Manheimer <ken.manheimer@gmail.com>
-;; Version: 1.1.9
-;; Created: 1999 -- first public availability
-;; Keywords: processes
-;; Package-Requires: ((cl-lib "0.5"))
-;; URL: https://github.com/kenmanheimer/EmacsMultishell
-;;
-;;; Commentary:
-;;
-;; Easily use and navigate multiple shell buffers, including remote shells.
-;; Fundamentally, multishell is the function `multishell-pop-to-shell' -
-;; a la `pop-to-buffer' - plus a keybinding. Together, they enable you to:
-;;
-;; * Get to the input point from wherever you are in a shell buffer,
-;;   ... or to any of your shell buffers, from anywhere inside emacs.
-;;
-;; * Use universal arguments to launch and choose among alternate shell 
buffers,
-;;   ... and change which is the current default.
-;;
-;; * Easily restart disconnected shells, or shells from prior sessions
-;;   ... the latter from Emacs builtin savehist minibuf history persistence
-;;
-;; * Append a path to a new shell name to launch a shell in that directory,
-;;   ... and use a path with Emacs tramp syntax to launch a remote shell -
-;;   for example:
-;;
-;;   * `#root/sudo:root@localhost:/etc` for a buffer named "*#root*" with a
-;;     root shell starting in /etc.
-;;
-;;   * `/ssh:example.net:` for a shell buffer in your homedir on example.net.
-;;     The buffer will be named "*example.net*".
-;;
-;;   * `#ex/ssh:example.net|sudo:root@example.net:/var/log` for a root shell
-;;     starting in /var/log on example.net named "*#ex*".
-;;
-;;   * 'interior/ssh:gateway.corp.com|ssh:interior.corp.com:' to go via
-;;     gateway.corp.com to your homedir on interior.corp.com.  The buffer
-;;     will be named "*interior*". You could append a sudo hop, and so on.
-;;
-;; * Thanks to tramp, file visits from the shell will seamlessly be in
-;;   the auspices of the target account, and relative to the current
-;;   directory, on the host where the shell is running.
-;;
-;; * Manage your list of shells, current and past, as a collection.
-;;
-;; See the `multishell-pop-to-shell' docstring for details.
-;;
-;; Customize-group `multishell' to select and activate a keybinding and set
-;; various behaviors. Customize-group `savehist' to preserve buffer
-;; names/paths across emacs restarts.
-;;
-;; Please use
-;; [the multishell repository](https://github.com/kenmanheimer/EmacsMultishell)
-;; issue tracker to report problems, suggestions, etc, and see that
-;; repository for a bit more documentation.
-;;
-;; Change Log:
-;;
-;; * 2020-10-30 1.1.9 Ken Manheimer:
-;;   - Require cl-lib when compiling for cl-letf macro.
-;; * 2020-10-28 1.1.8 Ken Manheimer:
-;;   - Change back to having multishell-list require multishell,
-;;     rather than the other way around, and remove now unnecessary
-;;     new autoloads.
-;;   - Bump version for ELPA release.
-;; * 2020-10-28 1.1.7 Ken Manheimer:
-;;   - Forward compatibility: 'cl-progv' rather than 'progv', resolves
-;;     multishell-list error in recent emacs versions.
-;;   - Incorporate gnu refinements (thanks!)
-;; * 2016-06-27 1.1.6 Ken Manheimer (unreleased):
-;;   - When starting a remote shell, if cd fails to an inital remote
-;;     directory, try again without the cd.
-;; * 2016-02-11 1.1.5 Ken Manheimer:
-;;   - Rectify multishell list sorting to preserve recentness
-;;   - Increment the actual multishell-version setting, neglected for 1.1.4.
-;; * 2016-02-11 1.1.4 Ken Manheimer:
-;;   - hookup multishell-list as completion help buffer.
-;;     Mouse and keyboard selections from help listing properly exits
-;;     minibuffer.
-;; * 2016-02-09 1.1.3 Ken Manheimer:
-;;   multishell-list:
-;;   - add some handy operations, like cloning new entry from existing
-;;   - add optional behaviors to existing operations for returning to
-;;     stopped shells without restarting them.
-;;   - solidify maintaining focus on current entry
-;;   - fix miscellaneous.
-;; * 2016-01-31 1.1.2 Ken Manheimer:
-;;   - Settle puzzling instability of multishell-all-entries
-;;     - The accumulations was putting items going from more to less active
-;;       categories to be put at the end, not beginning.
-;;     - Also, using history for prompting changes history - implement
-;;       no-record option to avoid this when needed.
-;;   - Implement simple edit-in-place multishell-replace-entry and use in
-;;     multishell-list-edit-entry.
-;;   - Remove now unnecessary multishell-list-revert-buffer-kludge.
-;;   - Rectify byte compiler offenses, and other fixes - thanks to Stefan
-;;     Monnier for pointing out many of the corrections.
-;;   - Avoid directly calling tramp functions unnecessarily.
-;; * 2016-01-30 1.1.1 Ken Manheimer:
-;;   - shake out initial multishell-list glitches:
-;;     - (Offer to) delete shell buffer, if present, when deleting entry.
-;;     - Set recency (numeric rank) as initial sort field
-;;     - Recompute list on most operations that affect the order, and try to
-;;       preserve stability. (Kludgy solution, needs work.)
-;;   - Set version to 1.1.1 - multishell-list addition should have been 1.1.0.
-;; * 2016-01-30 1.0.9 Ken Manheimer:
-;;   - Add multishell-list for managing the collection of current and
-;;     history-registered shells: edit, delete, and switch/pop to entries.
-;;     Easy access by invoking `multishell-pop-to-shell' from in the
-;;     `multishell-pop-to-shell' universal arg prompts.
-;;   - Duplicate existing shell buffer names in completions, for distinction.
-;;   - Add paths to buffers started without one, when multishell history dir
-;;     tracking is enabled.
-;;   - Major code cleanup:
-;;     - Simplify multishell-start-shell-in-buffer, in particular using
-;;       shell function, rather than unnecessarily going underneath it.
-;;     - Establish multishell-name-from-entry as canonical name resolver.
-;;     - Fallback to eval-after-load in emacs versions that lack
-;;       with-eval-after-load (eg, emacs 23).
-;;     - save-match-data, where match-string is used
-;;     - resituate some helpers
-;; * 2016-01-24 1.0.8 Ken Manheimer:
-;;   - Work around the shell/tramp mishandling of remote+sudo+homedir problem!
-;;     The work around is clean and simple, basically using high-level `cd'
-;;     API and not messing with the low-level default-directory setting.
-;;     (Turns out the problem was not in my local config. Good riddance to the
-;;     awkward failure handler!)
-;;   - Clean up code resolving the destination shell, starting to document the
-;;     decision tree in the process. See getting-to-a-shell.md in the
-;;     multishell repository, https://github.com/kenmanheimer/EmacsMultishell
-;;   - There may be some shake-out on resolving the destination shell, but
-;;     this release gets the fundamental functionality soundly in place.
-;; * 2016-01-23 1.0.7 Ken Manheimer:
-;;   - Remove notes about tramp remote+sudo+homedir problem. Apparently it's
-;;     due to something in my local site configuration (happens with -q but
-;;     not -Q).
-;; * 2016-01-22 1.0.6 Ken Manheimer:
-;;   - Add multishell-version function.
-;;   - Tweak commentary/comments/docstrings.
-;;   - Null old multishell-buffer-name-history var, if present.
-;; * 2016-01-16 1.0.5 Ken Manheimer:
-;;   - History now includes paths, when designated.
-;;   - Actively track current directory in history entries that have a path.
-;;     Custom control: multishell-history-entry-tracks-current-directory
-;;   - Offer to remove shell's history entry when buffer is killed.
-;;     (Currently the only UI mechanism to remove history entries.)
-;;   - Fix - prevent duplicate entries for same name but different paths
-;;   - Fix - recognize and respect tramp path syntax to start in home dir
-;;   - Simplify history var name, migrate existing history if any from old name
-;; * 2016-01-04 1.0.4 Ken Manheimer - Released to ELPA
-;; * 2016-01-02 Ken Manheimer - working on this in public, but not yet 
released.
-;;
-;; TODO and Known Issues:
-;;
-;; * Add custom shell launch prep actions
-;;   - for, eg, port knocking, interface activations
-;;   - shell commands to execute when shell name or path matches a regexp
-;;   - list of (regexp, which - name, path, or both, command)
-;; * Investigate whether we can recognize and provide for failed hops.
-;;   - Tramp doesn't provide useful reactions for any hop but the first
-;;   - Might be stuff we can do to detect and convey failures?
-;;   - Might be no recourse but to seek tramp changes.
-;; * Try minibuffer field boundary at beginning of tramp path, to see whether
-;;   the field boundary magically enables tramp path completion.
-
-;;; Code:
-
-(require 'comint)
-(require 'shell)
-(require 'savehist)
-(eval-when-compile (require 'cl-lib))
-
-(defvar multishell-version "1.1.9")
-(defun multishell-version (&optional here)
-  "Return string describing the loaded multishell version."
-  (interactive "P")
-  (let ((msg (concat "Multishell " multishell-version)))
-    (if here (insert msg)
-      (if (called-interactively-p 'interactive)
-          (message "%s" msg)
-        msg))))
-
-(defgroup multishell nil
-  "Allout extension that highlights outline structure graphically.
-
-Customize `allout-widgets-auto-activation' to activate allout-widgets
-with allout-mode."
-  :group 'shell)
-
-(defcustom multishell-command-key "\M- "
-  "The key to use if `multishell-activate-command-key' is true.
-
-You can instead manually bind `multishell-pop-to-shell' using emacs
-lisp, eg: (global-set-key \"\\M- \" \\='multishell-pop-to-shell)."
-  :type 'key-sequence)
-
-(defvar multishell--responsible-for-command-key nil
-  "Coordination for multishell key assignment.")
-(defun multishell-activate-command-key-setter (symbol setting)
-  "Implement `multishell-activate-command-key' choice."
-  (set-default symbol setting)
-  (when (or setting multishell--responsible-for-command-key)
-    (multishell-implement-command-key-choice (not setting))))
-(defun multishell-implement-command-key-choice (&optional unbind)
-  "If settings dicate, implement binding of multishell command key.
-
-If optional UNBIND is true, globally unbind the key.
-
-* `multishell-activate-command-key' - Set this to get the binding or not.
-* `multishell-command-key' - The key to use for the binding, if appropriate."
-  (when (bound-and-true-p multishell-command-key)
-    (if unbind
-        (global-unset-key multishell-command-key)
-      (when (bound-and-true-p multishell-activate-command-key)
-        (setq multishell--responsible-for-command-key t)
-        (global-set-key multishell-command-key 'multishell-pop-to-shell)))))
-
-(defcustom multishell-activate-command-key nil
-  "Set this to impose the `multishell-command-key' binding.
-
-You can instead manually bind `multishell-pop-to-shell' using emacs
-lisp, eg: (global-set-key \"\\M- \" \\='multishell-pop-to-shell)."
-  :type 'boolean
-  :set #'multishell-activate-command-key-setter)
-
-;; Implement the key customization whenever the package is loaded:
-(if (fboundp 'with-eval-after-load)
-    (with-eval-after-load "multishell"
-      (multishell-implement-command-key-choice))
-  (eval-after-load "multishell"
-    '(multishell-implement-command-key-choice)))
-
-(defcustom multishell-pop-to-frame nil
-  "*If non-nil, jump to a frame already showing the shell, if another one is.
-
-Otherwise, disregard already-open windows on the shell if they're
-in another frame, and open a new window on the shell in the
-current frame.
-
-\(Use `pop-up-windows' to change multishell other-window vs
-current-window behavior.)"
-  :type 'boolean)
-
-(defcustom multishell-history-entry-tracks-current-directory t
-  "Maintain shell's current directory in its multishell history entry.
-
-When set, the history entry for shells started with explicit
-paths will track the shell's current working directory.
-
-If `savehist-save-minibuffer-history' is enabled, the current
-working directory of shells will be conveyed between Emacs sessions."
- :type 'boolean)
-
-(defvar multishell-history nil
-  "Name/path entries, most recent first.")
-;; Migrate the few pre 1.0.5 users to changed history var:
-(when (and (not multishell-history)
-           (boundp 'multishell-buffer-name-history)
-           multishell-buffer-name-history)
-  (setq multishell-history multishell-buffer-name-history
-        multishell-buffer-name-history nil))
-
-(defvar multishell-primary-name "*shell*"
-  "Default shell name for un-modified multishell-pop-to-shell buffer target.
-
-This is set by `multishell-pop-to-shell' as the current default,
-when invoked with doubled universal argument.
-
-If you want the designated primary that you have at the end of
-one emacs session to be resumed at the next, customize
-`savehist-additional-variables' to include the
-`multishell-primary-name'.")
-
-(defvar multishell-completing-read nil
-  "Internal use, conveying whether or not we're in the midst of a multishell
-completing-read.")
-
-;; Multiple entries happen because completion also adds name to history.
-(defun multishell-register-name-to-path (name path)
-  "Add or replace entry associating NAME with PATH in `multishell-history'.
-
-If NAME already had a PATH and new PATH is empty, retain the prior one.
-
-Promote added/changed entry to the front of the list."
-  ;; Add or promote to the front, tracking path changes in the process.
-  (let* ((entries (multishell-history-entries name))
-         (path (or path "")))
-    (dolist (entry entries)
-      (when (string= path "")
-        ;; Retain explicit established path.
-        (setq path (cadr (multishell-split-entry entry))))
-      (setq multishell-history (delete entry multishell-history)))
-    (setq multishell-history (push (concat name path)
-                                   multishell-history))))
-
-(defun multishell-replace-entry (entry revised)
-  "Replace every instance of ENTRY in `multishell-history' with REVISED.
-
-Revised entry is situated where former one was.
-
-Returns non-nil iff any changes were made."
-  (let ((candidates multishell-history)
-        did-revisions)
-    (while (setq candidates (member entry candidates))
-      (setcar candidates revised)
-      (setq candidates (cdr candidates)
-            did-revisions t))
-    did-revisions))
-
-(defun multishell-history-entries (name)
-  "Return `multishell-history' entry that starts with NAME, or nil if none."
-  (let (got)
-    (dolist (entry multishell-history)
-      (when (and (string-equal name (multishell-name-from-entry entry))
-                 (not (member entry got)))
-        (push entry got)))
-    got))
-
-;;;###autoload
-(defun multishell-pop-to-shell (&optional arg name here)
-  "Easily navigate to and within multiple shell buffers, local and remote.
-
-Use a single `universal-argument' (\\[universal-argument]) to launch and 
choose between
-nalternate shell buffers, and a doubled universal argument to also set your
-choice as the ongoing default.  Append a path to a new shell name to launch
-a shell in that directory, and use Emacs tramp syntax to launch a remote
-shell. There is a shortcut to manage your list of current and
-historical shells, collectively, using `multishell-list' - see below.
-
-Customize-group `multishell' to set up a key binding and tweak behaviors.
-
-Manage your collection of current and historical shells by
-recursively invoking \\[multishell-pop-to-shell] at the 
`multishell-pop-to-shell'
-universal argument prompts, eg:
-
-  \\[universal-argument] \\[multishell-pop-to-shell] 
\\[multishell-pop-to-shell]
-
-\(That will be just a few keys if you do the above customization.)
-
-Hit ? in the listing buffer for editing commands.
-
-==== Basic operation:
-
- - If the current buffer is in shell-mode then focus is moved to
-   the process input point.
-
-   \(Use a universal argument go to a different shell buffer
-   when already in a buffer that has a process - see below.)
-
- - If not in a shell buffer, go to a window that is already
-   showing a shell buffer, if any.
-
-   In this case, the cursor is not moved to the process input
-   point. Repeating the command once you're in the buffer will
-   then move the cursor to the process input point.
-
-   We respect `pop-up-windows', so you can adjust it to set the
-   other-buffer/same-buffer behavior.
-
- - Otherwise, start a new shell buffer, using the current
-   directory as the working directory.
-
-If a buffer with the resulting name exists and its shell process
-was disconnected or otherwise stopped, it's resumed.
-
-===== Universal arg to start and select between named shell buffers:
-
-You can assign a distinct name to new shell buffers by prefixing
-your \\[multishell-pop-to-shell] invocation with a single or double
-`universal-argument', \\[universal-argument]:
-
- - With a single universal argument, prompt for the buffer name
-   to use (without the asterisks that shell mode will put around
-   the name), defaulting to `shell'.
-
-   Completion is available.
-
-   This combination makes it easy to start and switch across
-   multiple shell restarts.
-
- - A double universal argument will prompt for the name and set
-   the default to that name, so the target shell becomes the
-   primary.
-
-   See `multishell-primary-name' for info about preserving the
-   setting across emacs restarts.
-
- - Manage your collection of current and historical shells by
-   recursively invoking \\[multishell-pop-to-shell] at the 
`multishell-pop-to-shell'
-   universal argument prompts, or at any time via
-   \\[multishell-list]. Hit ? in the listing buffer for editing
-   commands.
-
-===== Select starting directory and remote host:
-
-The shell buffer name you give to the prompt for a universal arg
-can include an appended path. That will be used for the startup
-directory. You can use tramp remote syntax to specify a remote
-shell. If there is an element after a final `/', that's used for
-the buffer name. Otherwise, the host, domain, or path is used.
-
-For example:
-
-* `#root/sudo:root@localhost:/etc' for a buffer named \"*#root*\" with a
-  root shell starting in /etc.
-
-* `/ssh:example.net:' for a shell buffer in your homedir on example.net.
-  The buffer will be named \"*example.net*\".
-
-* `#ex/ssh:example.net|sudo:root@example.net:/var/log' for a root shell
-  starting in /var/log on example.net named \"*#ex*\".
-
-* `interior/ssh:gateway.corp.com|ssh:interior.corp.com:' to go
-  via gateway.corp.com to your homedir on interior.corp.com.  The
-  buffer will be named \"*interior*\". You could append a sudo
-  hop to the path, combining the previous example, and so on.
-
-File visits from the shell, and many common emacs activities like
-dired, will be on the host where the shell is running, in the
-auspices of the target account, and relative to the current
-directory.
-
-You can change the startup path for a shell buffer by editing it
-at the completion prompt. The new path will not take effect for
-an already-running shell.
-
-To remove a shell buffer's history entry, kill the buffer and
-affirm removal of the entry when prompted.
-
-===== Activate savehist to retain shell buffer names and paths across Emacs 
restarts:
-
-To have emacs maintain your history of shell buffer names and paths,
-customize the savehist group to activate savehist."
-
-  (interactive "P")
-
-  (let ((token '(token)))
-    (if (window-minibuffer-p)
-        (throw 'multishell-minibuffer-exit token)
-      (let ((got (catch 'multishell-minibuffer-exit
-                   (multishell-pop-to-shell-worker arg name here))))
-        ;; Handle catch or plain fall-through - see cond comments for protocol.
-        (cond
-         ;; Caught token from recursive invocation in minibuffer:
-         ((equal token got) (multishell-list))
-         ;; Caught specifaction of multishell args, eg from multishell-list:
-         ((listp got) (multishell-pop-to-shell-worker (nth 2 got)
-                                                      (nth 0 got)
-                                                      (nth 1 got)))
-         ;; Regular fallthrough - just relay the result:
-         (t got))))))
-
-(defun multishell-pop-to-shell-worker (&optional arg name here)
-  "Do real work of `multishell-pop-to-shell', which see."
-  (let* ((from-buffer (current-buffer))
-         (from-buffer-is-shell (derived-mode-p 'shell-mode))
-         (primary-name-unbracketed (multishell-unbracket
-                                    multishell-primary-name))
-         (fallthrough-name (if from-buffer-is-shell
-                               (buffer-name from-buffer)
-                             primary-name-unbracketed))
-         (doublearg (equal arg '(16)))
-         (target-name-and-path
-          (multishell-resolve-target-name-and-path
-           (cond (name name)
-                 (arg
-                  (or (multishell-read-unbracketed-entry
-                       (format "Shell buffer name [%s]%s "
-                               primary-name-unbracketed
-                               (if doublearg " <==" ":")))
-                      primary-name-unbracketed))
-                 (t fallthrough-name))))
-         (use-path (cadr target-name-and-path))
-         (target-shell-buffer-name (car target-name-and-path))
-         (target-buffer (get-buffer target-shell-buffer-name))
-         (curr-buff-proc (get-buffer-process from-buffer))
-         inwin
-         already-there)
-
-    ;; Register early so the entry is pushed to the front:
-    (multishell-register-name-to-path (multishell-unbracket
-                                       target-shell-buffer-name)
-                                      use-path)
-
-    (when doublearg
-      (setq multishell-primary-name target-shell-buffer-name))
-
-    ;; Situate:
-
-    (cond
-
-     ((and (or curr-buff-proc from-buffer-is-shell)
-           (not arg)
-           (eq from-buffer target-buffer)
-           (not (eq target-shell-buffer-name (buffer-name from-buffer))))
-      ;; In a shell buffer, but not named - stay in buffer, but go to end.
-      (setq already-there t))
-
-     ((string= (buffer-name) target-shell-buffer-name)
-      ;; Already in the specified shell buffer:
-      (setq already-there t))
-
-     ((or (not target-buffer)
-          (not (setq inwin
-                     (multishell-get-visible-window-for-buffer 
target-buffer))))
-      ;; No preexisting shell buffer, or not in a visible window:
-      (when (not (get-buffer target-shell-buffer-name))
-        (message "Creating new shell buffer '%s'" target-shell-buffer-name))
-      (if here
-          (switch-to-buffer target-shell-buffer-name)
-        (pop-to-buffer target-shell-buffer-name pop-up-windows)))
-
-     ;; Buffer exists and already has a window - jump to it:
-     (t (if (and multishell-pop-to-frame
-                 inwin
-                 (not (equal (window-frame (selected-window))
-                             (window-frame inwin))))
-            (select-frame-set-input-focus (window-frame inwin)))
-        (if (not (string= (buffer-name (current-buffer))
-                          target-shell-buffer-name))
-            (if here
-                (switch-to-buffer target-shell-buffer-name)
-              (pop-to-buffer target-shell-buffer-name t)))))
-
-    ;; We're in the buffer. Activate:
-
-    (if (not (comint-check-proc (current-buffer)))
-        (multishell-start-shell-in-buffer use-path))
-
-    ;; If the destination buffer has a stopped process, resume it:
-    (let ((process (get-buffer-process (current-buffer))))
-      (if (and process (equal 'stop (process-status process)))
-          (continue-process process)))
-
-    (when (or already-there
-             (equal (current-buffer) from-buffer))
-      (goto-char (point-max))
-      (and (get-buffer-process from-buffer)
-           (goto-char (process-mark (get-buffer-process from-buffer)))))))
-
-(defun multishell-delete-history-name (name &optional ask)
-  "Remove all multishell history entries for NAME.
-
-if optional ask is non-nil (default nil), ask before each deletion.
-
-Return the last entry deleted."
-  (let (got)
-    (dolist (entry (multishell-history-entries name) got)
-      (when (and entry
-                 (or (not ask)
-                     (y-or-n-p (format "Remove multishell history entry `%s'? "
-                                       entry))))
-        (setq got entry
-              multishell-history (delete entry multishell-history))))))
-
-(defun multishell-kill-buffer-query-function ()
-  "Offer to remove multishell-history entry for buffer."
-  ;; Removal choice is crucial, so users can, eg, kill a shell with huge
-  ;; output backlog, while keeping the history entry to easily restart it.
-  ;;
-  ;; We use kill-buffer-query-functions instead of kill-buffer-hook because:
-  ;;
-  ;; 1. It enables the user to remove the history without actually killing a
-  ;;    running buffer, by not confirming the subsequent running-proc query.
-  ;; 2. kill-buffer-hooks often fails to run when killing shell buffers!
-  ;;    It's probably due to failures in other hooks - beyond our control -
-  ;;    and anyway, I like the first reason well enough.
-
-  ;; (Use condition-case to avoid inadvertant disruption of kill-buffer
-  ;; activity.  kill-buffer happens behind the scenes a whole lot.)
-  (condition-case err
-      (and (derived-mode-p 'shell-mode)
-           (multishell-delete-history-name
-            (multishell-unbracket (buffer-name))
-            t))
-    (error
-     (message "multishell-kill-buffer-query-function error: %s" err)))
-  t)
-(add-hook 'kill-buffer-query-functions #'multishell-kill-buffer-query-function)
-
-(defun multishell-get-visible-window-for-buffer (buffer)
-  "Return visible window containing buffer."
-  (catch 'got-a-vis
-    (walk-windows
-     (function (lambda (win)
-                 (if (and (eq (window-buffer win) buffer)
-                          (equal (frame-parameter
-                                  (selected-frame) 'display)
-                                 (frame-parameter
-                                  (window-frame win) 'display)))
-                     (throw 'got-a-vis win))))
-     nil 'visible)
-    nil))
-
-(defun multishell-all-entries (&optional active-duplicated)
-  "Return multishell history, with active buffers listed first.
-
-Optional ACTIVE-DUPLICATED will return a copy of
-`multishell-history' with unbracketed names of active buffers,
-sans paths, appended to the list, so they have short and long
-completions."
-  ;; Reorder so active lead present lead historical entries:
-  (let (active-entries active-names present past splat name buffer)
-    (dolist (entry multishell-history)
-      (setq splat (multishell-split-entry entry)
-            name (car splat)
-            buffer (and name (get-buffer (multishell-bracket name))))
-      (if (buffer-live-p buffer)
-          (if (comint-check-proc buffer)
-              (setq active-entries (push entry active-entries)
-                    active-names (push name active-names))
-            (setq present (push entry present)))
-        (setq past (push entry past))))
-    ;; Reverse present and past lists
-    (setq multishell-history (append (reverse active-entries)
-                                     (reverse present)
-                                     (reverse past)))
-    (if active-duplicated
-        (append multishell-history active-names)
-      multishell-history)))
-
-(defun multishell-read-unbracketed-entry (prompt &optional initial no-record)
-  "PROMPT for shell buffer name, sans asterisks.
-
-Optional INITIAL is preliminary value to be edited.
-
-Optional NO-RECORD prevents changes to `multishell-history'
-across the activity.
-
-Input and completion can include associated path, if any.
-
-Return what's provided, if anything, else nil."
-  (let* ((was-multishell-history multishell-history)
-         (candidates (multishell-all-entries 'active-duplicated))
-         (multishell-completing-read t)
-         (got
-          ;; Use `cl-letf' to dynamically bind multishell-list to
-          ;; display-completion-list, so multishell-list is used when doing
-          ;; minibuffer-completion-help.
-          (cl-letf (((symbol-function 'display-completion-list)
-                     #'multishell-list))
-              (completing-read prompt
-                               ;; COLLECTION:
-                               (reverse candidates)
-                               ;; PREDICATE:
-                               nil
-                               ;; REQUIRE-MATCH:
-                               'confirm
-                               ;; INITIAL-INPUT
-                               initial
-                               ;; HIST:
-                               'multishell-history))))
-    (when no-record
-      (setq multishell-history was-multishell-history))
-    (if (not (string= got ""))
-        got
-      nil)))
-
-(defun multishell-resolve-target-name-and-path (shell-spec)
-  "Given name/tramp-style address shell spec, resolve buffer name and 
directory.
-
-The name is the part of the string up to the first `/' slash, if
-any. Missing pieces are filled in from remote path elements, if
-any, and multishell history. Given a tramp-style remote address
-and no name part, either the user@host is used for the buffer
-name, if a user is specified, or just the host.
-
-Return them as a list: (name path), with name asterisk-bracketed
-and path nil if none is resolved."
-  (let* ((splat (multishell-split-entry (or shell-spec "")))
-         (path (cadr splat))
-         (name (or (car splat) (multishell-name-from-entry path))))
-    (when (not path)
-      ;; Get path from history, if present.
-      (dolist (entry
-               (multishell-history-entries
-                (multishell-unbracket name)))
-        (when (or (not path) (string= path ""))
-          (setq path (cadr (multishell-split-entry entry))))))
-    (list (multishell-bracket name) path)))
-
-(defun multishell-name-from-entry (entry)
-  "Derive a name for a shell buffer according to ENTRY."
-  (if (not entry)
-      (multishell-unbracket multishell-primary-name)
-    (let* ((splat (multishell-split-entry entry))
-           (name (car splat))
-           (path (cadr splat)))
-      (or name
-          (if (file-remote-p path)
-              (let ((host (file-remote-p path 'host))
-                    (user (file-remote-p path 'user)))
-                (cond ((and host user)
-                       (format "%s@%s" user host))
-                      (host host)
-                      (user user)
-                      ((system-name))))
-            (multishell-unbracket multishell-primary-name))))))
-
-(declare-function tramp-dissect-file-name "tramp")
-(declare-function tramp-cleanup-connection "tramp")
-
-(defun multishell-start-shell-in-buffer (where)
-  "Start, restart, or continue a shell in current-buffer on WHERE.
-
-If WHERE is remote and includes a directory, cd to that directory on the
-remote host.
-
-If cd fails to an included remote directory, try again without the cd."
-  (let* ((is-active (comint-check-proc (current-buffer))))
-
-    (when (and where (not is-active))
-
-      ;; FIXME: file-remote-p does not imply Tramp.
-      ;; Why do we need to do something special for Tramp here?
-      (when (and (derived-mode-p 'shell-mode) (file-remote-p where))
-        ;; Returning to disconnected remote shell - do some tidying.
-        ;; FIXME: Without this cleanup, occasionally restarting a disconnected
-        ;; remote session, particularly one that includes sudo, results in
-        ;; an untraceable "Args out of range" error. That never happens if
-        ;; we precedeed connection attempts with this cleanup -
-        ;; prophylactic.
-        (tramp-cleanup-connection
-         (tramp-dissect-file-name default-directory 'noexpand)
-         'keep-debug 'keep-password))
-
-      (if (not (file-remote-p where))
-          (cd where)
-        (message "Connecting to %s" where)
-        (condition-case err
-            (cd where)
-          ;; "cd: No such directory found via CDPATH environment variable"
-          (error
-           (if (string=
-                (cadr err)
-                "No such directory found via CDPATH environment variable")
-               ;; Try again without dir part of remote where:
-               (let* ((final-colon-at (string-match ":[^:]+$" where))
-                      (sans-dir-path (substring where 0 (1+ final-colon-at)))
-                      (dir-path (substring where (1+ final-colon-at))))
-                 (message "Failed to cd to %s, trying again without..."
-                          dir-path)
-                 (sit-for .5)
-                 (cd sans-dir-path))
-             (signal (car err) (cdr err)))))))
-
-    (shell (current-buffer))))
-
-(defun multishell-homedir-shorthand-p (dirpath)
-  "t if dirpath is an unexpanded remote homedir spec."
-  ;; Workaround to recognize tramp-style homedir shorthand, "...:" and "...:~".
-  (let ((localname (file-remote-p dirpath 'localname)))
-    (and localname
-         (or
-          ;; No directory path and no connection to expand homedir:
-          (string= localname "")
-          ;; Original path doesn't equal expanded homedir:
-          (save-match-data
-            (not (string-match (concat (regexp-quote localname) "/?$")
-                               dirpath)))))))
-;; (assert (multishell-homedir-shorthand-p "/ssh:myhost.net:")
-;; (assert (not (multishell-homedir-shorthand-p "/home/klm")))
-;; (assert (not (multishell-homedir-shorthand-p "/ssh:myhost.net:/home/me")))
-
-(defun multishell-track-dirchange (name newpath)
-  "Change multishell history entry to track current directory."
-  (let* ((entries (multishell-history-entries name)))
-    (dolist (entry entries)
-      (let* ((name-path (multishell-split-entry entry))
-             (path (or (cadr name-path) "")))
-        (when path
-          (let* ((old-localname (or (file-remote-p path 'localname)
-                                    path))
-                 (newentry
-                  (if (multishell-homedir-shorthand-p path)
-                      (concat entry newpath)
-                    (replace-regexp-in-string (concat (regexp-quote
-                                                       old-localname)
-                                                      "$")
-                                              ;; REPLACEMENT
-                                              newpath
-                                              ;; STRING
-                                              entry
-                                              ;; FIXEDCASE
-                                              t
-                                              ;; LITERAL
-                                              t
-                                              )))
-                 (membership (member entry multishell-history)))
-            (when membership
-              (setcar membership newentry))))))))
-
-(defvar multishell-was-default-directory ()
-  "Provide for tracking directory changes.")
-(make-variable-buffer-local 'multishell-was-default-directory)
-(defun multishell-post-command-business ()
-  "Do multishell bookkeeping."
-  ;; Update multishell-history with dir changes.
-  (condition-case err
-      (when (and multishell-history-entry-tracks-current-directory
-                 (derived-mode-p 'shell-mode))
-        (let ((curdir (if (file-remote-p default-directory)
-                          (file-remote-p default-directory 'localname)
-                        default-directory)))
-          (when (not (string= curdir (or multishell-was-default-directory "")))
-            (multishell-track-dirchange (multishell-unbracket (buffer-name))
-                                        curdir))
-          (setq multishell-was-default-directory curdir)))
-    ;; To avoid disruption as a pervasive hook function, swallow all errors:
-    (error
-     (message "multishell-post-command-business error: %s" err))))
-(add-hook 'post-command-hook #'multishell-post-command-business)
-
-(defun multishell-split-entry (entry)
-  "Given multishell name/path ENTRY, return the separated name and path pair.
-
-Returns nil for empty parts, rather than the empty string."
-  (save-match-data
-    (string-match "^\\([^/]*\\)\\(/?.*\\)?" entry)
-    (let ((name (match-string 1 entry))
-          (path (match-string 2 entry)))
-      (and (string= name "") (setq name nil))
-      (and (string= path "") (setq path nil))
-      (list name path))))
-(defun multishell-bracket (name)
-  "Return a copy of name, ensuring it has an asterisk at the beginning and 
end."
-  (if (not (string= (substring name 0 1) "*"))
-      (setq name (concat "*" name)))
-  (if (not (string= (substring name -1) "*"))
-      (setq name (concat name "*")))
-  name)
-(defun multishell-unbracket (name)
-  "Return a copy of name, removing asterisks, if any, at beginning and end."
-  (if (string= (substring name 0 1) "*")
-      (setq name (substring name 1)))
-  (if (string= (substring name -1) "*")
-      (setq name (substring name 0 -1)))
-  name)
-
-(provide 'multishell)
-
-;;; multishell.el ends here
diff --git a/packages/paced/.bzrignore b/packages/paced/.bzrignore
deleted file mode 100644
index fd9ec13..0000000
--- a/packages/paced/.bzrignore
+++ /dev/null
@@ -1,8 +0,0 @@
-*.elc
-*~
-paced-autoloads.el
-Makefile
-.deps
-test-files/paced-dictionary-case-sensitive
-paced.html
-paced.texi
\ No newline at end of file
diff --git a/packages/paced/.elpaignore b/packages/paced/.elpaignore
deleted file mode 100644
index 264b3e6..0000000
--- a/packages/paced/.elpaignore
+++ /dev/null
@@ -1,5 +0,0 @@
-Project.ede
-Makefile
-test.mk
-test-files
-paced-tests.el
\ No newline at end of file
diff --git a/packages/paced/COPYING b/packages/paced/COPYING
deleted file mode 100644
index 94a9ed0..0000000
--- a/packages/paced/COPYING
+++ /dev/null
@@ -1,674 +0,0 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- 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.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    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 <http://www.gnu.org/licenses/>.
-
-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:
-
-    <program>  Copyright (C) <year>  <name of author>
-    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
-<http://www.gnu.org/licenses/>.
-
-  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
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/packages/paced/Project.ede b/packages/paced/Project.ede
deleted file mode 100644
index b4c6ed3..0000000
--- a/packages/paced/Project.ede
+++ /dev/null
@@ -1,48 +0,0 @@
-;; Object ede-proj-project
-
-;; Copyright (C) 2017-2018 Free Software Foundation, Inc.
-
-;; This file is part of GNU Emacs.
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 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 <http://www.gnu.org/licenses/>.
-
-;; EDE Project Files are auto generated: Do Not Edit
-
-(ede-proj-project "ede-proj-project"
-  :file "Project.ede"
-  :name "paced"
-  :targets
-  (list
-    (ede-proj-target-elisp "ede-proj-target-elisp"
-      :name "compile"
-      :path ""
-      :source '("paced.el" "paced-async.el")
-      :aux-packages '("async" "paced"))
-    (ede-proj-target-elisp-autoloads "ede-proj-target-elisp-autoloads"
-      :name "autoloads"
-      :path ""
-      :source '("paced.el" "paced-async.el")
-      :autoload-file "paced-autoloads.el")
-    (ede-proj-target-makefile-miscelaneous 
"ede-proj-target-makefile-miscelaneous"
-      :name "check"
-      :path ""
-      :source '("paced-tests.el" "test.mk" "test-files/first.txt" 
"test-files/second.cpp" "test-files/third.org")
-      :partofall nil
-      :submakefile "test.mk")
-    (ede-proj-target-aux "ede-proj-target-aux"
-      :name "extra"
-      :path ""
-      :source '("paced.org")))
-  :web-site-url "https://savannah.nongnu.org/projects/paced-el";
-  :configuration-variables nil)
diff --git a/packages/paced/dir b/packages/paced/dir
deleted file mode 100644
index 3424e60..0000000
--- a/packages/paced/dir
+++ /dev/null
@@ -1,19 +0,0 @@
-This is the file .../info/dir, which contains the
-topmost node of the Info hierarchy, called (dir)Top.
-The first time you invoke Info you start off looking at this node.
-
-File: dir,     Node: Top       This is the top of the INFO tree
-
-  This (the Directory node) gives a menu of major topics.
-  Typing "q" exits, "H" lists all Info commands, "d" returns here,
-  "h" gives a primer for first-timers,
-  "mEmacs<Return>" visits the Emacs manual, etc.
-
-  In Emacs, you can click mouse button 2 on a menu item or cross reference
-  to select it.
-
-* Menu:
-
-Emacs
-* Paced: (paced).               Predictive Abbreviation Completion and 
-                                  Expansion using Dictionaries.
diff --git a/packages/paced/paced-async.el b/packages/paced/paced-async.el
deleted file mode 100644
index a0d5382..0000000
--- a/packages/paced/paced-async.el
+++ /dev/null
@@ -1,111 +0,0 @@
-;;; paced-async.el --- Support for asynchronous population -*- 
lexical-binding: t; -*-
-
-;; Copyright (C) 2017-2018 Free Software Foundation, Inc.
-
-;; Author: Ian Dunn <dunni@gnu.org>
-;; Maintainer: Ian Dunn <dunni@gnu.org>
-;; Keywords: convenience, completion
-;; Package-Requires: ((emacs "25.1") (async "1.9.1"))
-;; URL: https://savannah.nongnu.org/projects/paced-el/
-;; Version: 1.1.1
-;; Created: 22 Jan 2017
-;; Modified: 05 Feb 2018
-
-;; This file is part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify it 
under
-;; the terms of the GNU General Public License as published by the Free 
Software
-;; Foundation; either version 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 this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Population can be a slow task.  The more files from which you want to
-;; populate a dictionary, the longer repopulation is going to take.
-
-;; This extension to paced takes advantage of John Wiegley's async package to
-;; repopulate a dictionary asynchronously.
-
-;;; Code:
-
-(require 'paced)
-(require 'async)
-
-(eval-when-compile (require 'subr-x))
-
-(defcustom paced-async-load-file (locate-user-emacs-file "paced-async.el")
-  "File to load with user-specific population settings.
-
-This may contain commands required for running each dictionary's
-population commmands, or load additional files."
-  :group 'paced
-  :type 'file)
-
-(cl-defmethod paced-dictionary-repopulate-async ((dictionary paced-dictionary))
-  "Repopulate DICTIONARY asynchronously.
-
-Note that DICTIONARY isn't modified directly by this process, but
-the updated dictionary is loaded when repopulation completes.
-Therefore, you can continue using it without issue during
-repopulation.
-
-Side note: All dictionaries are reloaded when this function
-finishes, so temporary changes to any dictionaries will be lost
-as a result."
-  (let* ((variables '("load-path"        ;; Find libraries, including paced
-                      ;; Settings
-                      "paced-thing-at-point-constituent"
-                      "paced-dictionary-directory"
-                      ;; The load file itself
-                      "paced-async-load-file"))
-         (inject-string (concat "^\\("
-                                (mapconcat 'identity variables "\\|")
-                                "\\)$")))
-    (message "Repopulating dictionary %s" (paced-dictionary-name dictionary))
-    (async-start
-     `(lambda ()
-        ;; Inject the environment to get `load-path' and user settings
-        ,(async-inject-variables inject-string)
-        ;; Require paced and load the async settings file
-        (require 'paced)
-        (load-file paced-async-load-file)
-        ;; Repopulate and save the dictionary
-        (paced-dictionary-repopulate ,dictionary)
-        (paced-dictionary-save ,dictionary))
-     (lambda (_result)
-       (message "Finished repopulating dictionary")
-       (paced-load-all-dictionaries)))))
-
-;;;###autoload
-(defun paced-repopulate-named-dictionary-async (key)
-  "Repopulate dictionary named KEY from its population commands, 
asynchronously.
-
-Population commands are stored in the field of the same name.
-
-Note that this will empty the dictionary's contents."
-  (interactive
-   (list (paced-read-dictionary)))
-  (paced-operate-on-named-dictionary key
-    (paced-dictionary-repopulate-async dict)))
-
-;;;###autoload
-(defun paced-repopulate-current-dictionary-async ()
-  "Repopulate current dictionary from its population commands, asynchronously.
-
-Population commands are stored in the field of the same name.
-
-Note that this will empty the dictionary's contents."
-  (interactive)
-  (paced-operate-on-current-dictionary
-   (paced-dictionary-repopulate-async dict)))
-
-(provide 'paced-async)
-
-;;; paced-async.el ends here
diff --git a/packages/paced/paced-tests.el b/packages/paced/paced-tests.el
deleted file mode 100644
index 3f8d0ea..0000000
--- a/packages/paced/paced-tests.el
+++ /dev/null
@@ -1,507 +0,0 @@
-;;; paced-tests.el --- Tests for paced -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2017-2018 Free Software Foundation, Inc.
-
-;; Author: Ian Dunn <dunni@gnu.org>
-;; Maintainer: Ian Dunn <dunni@gnu.org>
-;; Keywords: convenience, completion
-;; Package-Requires: ((emacs "25.1") (async "1.9.1"))
-;; URL: https://savannah.nongnu.org/projects/paced-el/
-;; Version: 1.1
-;; Created: 22 Jan 2017
-;; Modified: 04 Feb 2018
-
-;; This file is part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify it 
under
-;; the terms of the GNU General Public License as published by the Free 
Software
-;; Foundation; either version 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 this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-(require 'paced)
-(require 'ert)
-
-(defconst paced-test-dir
-  (expand-file-name "test-files" (file-name-directory (or load-file-name 
buffer-file-name))))
-
-(defsubst paced-test-file (base-name)
-  (expand-file-name base-name paced-test-dir))
-
-(defconst paced-first-test-file  (paced-test-file "first.txt"))
-(defconst paced-second-test-file (paced-test-file "second.cpp"))
-(defconst paced-third-test-file  (paced-test-file "third.org"))
-(defconst paced-fourth-test-file  (paced-test-file "fourth.org"))
-
-(defconst paced-test-dict-save-file (paced-test-file 
"paced-dictionary-case-sensitive"))
-(defconst paced-test-default-registered-map (make-hash-table :test 'equal))
-
-(ert-deftest paced-handle-word-case ()
-  (let* ((word "EiEiO"))
-    (should (string-equal (paced--handle-word-case 'preserve word) "EiEiO"))
-    (should (string-equal (paced--handle-word-case 'downcase word) "eieio"))
-    (should (string-equal (paced--handle-word-case 'upcase   word) "EIEIO"))
-    (should (string-equal (paced--handle-word-case 'downcase-first word) 
"eiEiO"))
-    (should (string-equal (paced--handle-word-case 'upcase-first word) 
"EiEiO"))
-    (should (string-equal (paced--handle-word-case 'mixed-case word) 
"EiEiO"))))
-
-(ert-deftest paced-mixed-case-word ()
-  (should-not (paced-mixed-case-word-p "HAS"))
-  (should     (paced-mixed-case-word-p "HAs"))
-  (should     (paced-mixed-case-word-p "HaS"))
-  (should-not (paced-mixed-case-word-p "Has"))
-  (should     (paced-mixed-case-word-p "hAS"))
-  (should     (paced-mixed-case-word-p "hAs"))
-  (should     (paced-mixed-case-word-p "haS"))
-  (should-not (paced-mixed-case-word-p "has")))
-
-(ert-deftest paced-create-dictionary ()
-  ;; Delete the old save file
-  (when (file-exists-p paced-test-dict-save-file)
-    (delete-file paced-test-dict-save-file))
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (new-dict (paced-make-dictionary "test-dict-case"
-                                          paced-test-dict-save-file
-                                          'downcase)))
-    (should (= (map-length paced--registered-dictionaries) 1))
-    (should (paced-dictionary-p new-dict))
-    (oset new-dict updated t) ;; Mark it as updated so it saves
-    (paced-dictionary-save new-dict)
-    (should (file-exists-p paced-test-dict-save-file)))
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map))
-    ;; Now verify that we can load it again
-    (paced-load-dictionary-from-file paced-test-dict-save-file)
-    (should (= (map-length paced--registered-dictionaries) 1))
-    (should (map-contains-key paced--registered-dictionaries "test-dict-case"))
-    (should (paced-dictionary-p (paced-named-dictionary "test-dict-case")))))
-
-(defvar paced-test-enable-symbol nil)
-
-(ert-deftest paced-enable-list-symbol ()
-  "Test case for `paced-dictionary-enable-alist' being an arbitrary symbol."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((paced-test-enable-symbol . 
"test-dict-case")))
-         (new-buffer (find-file-noselect paced-first-test-file)))
-    (paced-make-dictionary "test-dict-case"
-                           paced-test-dict-save-file
-                           'downcase)
-    (with-current-buffer new-buffer
-      (setq paced-test-enable-symbol nil)
-      (should-not (paced-current-dictionary))
-      (setq-local paced-test-enable-symbol t)
-      (should (paced-dictionary-p (paced-current-dictionary)))
-      (should (string-equal (paced-dictionary-name (paced-current-dictionary)) 
"test-dict-case")))
-    (kill-buffer new-buffer)))
-
-(ert-deftest paced-enable-list-mode ()
-  "Test case for `paced-dictionary-enable-alist' being a mode symbol."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (buffer-one (find-file-noselect paced-first-test-file))
-         (buffer-two (find-file-noselect paced-second-test-file)))
-    (paced-make-dictionary "test-dict-case"
-                           paced-test-dict-save-file
-                           'downcase)
-    (with-current-buffer buffer-two
-      (should-not (paced-current-dictionary)))
-    (kill-buffer buffer-two)
-    (with-current-buffer buffer-one
-      (should (paced-dictionary-p (paced-current-dictionary)))
-      (should (string-equal (paced-dictionary-name (paced-current-dictionary)) 
"test-dict-case")))
-    (kill-buffer buffer-one)))
-
-(defun paced-test-function-symbol ()
-  paced-test-enable-symbol)
-
-(ert-deftest paced-enable-list-function-symbol ()
-  "Test case for `paced-dictionary-enable-alist' being a function symbol."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((paced-test-function-symbol . 
"test-dict-case")))
-         (buffer-one (find-file-noselect paced-first-test-file)))
-    (paced-make-dictionary "test-dict-case"
-                           paced-test-dict-save-file
-                           'downcase)
-    (with-current-buffer buffer-one
-      (setq-local paced-test-enable-symbol nil)
-      (should-not (paced-current-dictionary))
-      (setq-local paced-test-enable-symbol t)
-      (should (paced-dictionary-p (paced-current-dictionary)))
-      (should (string-equal (paced-dictionary-name (paced-current-dictionary)) 
"test-dict-case")))
-    (kill-buffer buffer-one)))
-
-(ert-deftest paced-enable-list-lambda-function ()
-  "Test case for `paced-dictionary-enable-alist' being a lambda form."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '(((lambda nil 
paced-test-enable-symbol) . "test-dict-case")))
-         (buffer-one (find-file-noselect paced-first-test-file)))
-    (paced-make-dictionary "test-dict-case"
-                           paced-test-dict-save-file
-                           'downcase)
-    (with-current-buffer buffer-one
-      (setq-local paced-test-enable-symbol nil)
-      (should-not (paced-current-dictionary))
-      (setq-local paced-test-enable-symbol t)
-      (should (paced-dictionary-p (paced-current-dictionary)))
-      (should (string-equal (paced-dictionary-name (paced-current-dictionary)) 
"test-dict-case")))
-    (kill-buffer buffer-one)))
-
-(ert-deftest paced-enable-list-and-form ()
-  "Test case for `paced-dictionary-enable-alist' being an 'and' form."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '(((and text-mode 
paced-test-enable-symbol) . "test-dict-case")))
-         (buffer-one (find-file-noselect paced-first-test-file))
-         (buffer-two (find-file-noselect paced-second-test-file)))
-    (paced-make-dictionary "test-dict-case"
-                           paced-test-dict-save-file
-                           'downcase)
-    (with-current-buffer buffer-two
-      (setq-local paced-test-enable-symbol nil)
-      (should-not (paced-current-dictionary))
-      (setq-local paced-test-enable-symbol t)
-      (should-not (paced-current-dictionary)))
-    (kill-buffer buffer-two)
-    (with-current-buffer buffer-one
-      (setq-local paced-test-enable-symbol nil)
-      (should-not (paced-current-dictionary))
-      (setq-local paced-test-enable-symbol t)
-      (should (paced-dictionary-p (paced-current-dictionary)))
-      (should (string-equal (paced-dictionary-name (paced-current-dictionary)) 
"test-dict-case")))
-    (kill-buffer buffer-one)))
-
-(ert-deftest paced-enable-list-or-form ()
-  "Test case for `paced-dictionary-enable-alist' being an 'or' form."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '(((or text-mode 
paced-test-enable-symbol) . "test-dict-case")))
-         (buffer-one (find-file-noselect paced-first-test-file))
-         (buffer-two (find-file-noselect paced-second-test-file)))
-    (paced-make-dictionary "test-dict-case"
-                           paced-test-dict-save-file
-                           'downcase)
-    (with-current-buffer buffer-two
-      (setq-local paced-test-enable-symbol nil)
-      (should-not (paced-current-dictionary))
-      (setq-local paced-test-enable-symbol t)
-      (should (paced-dictionary-p (paced-current-dictionary)))
-      (should (string-equal (paced-dictionary-name (paced-current-dictionary)) 
"test-dict-case")))
-    (kill-buffer buffer-two)
-    (with-current-buffer buffer-one
-      (setq-local paced-test-enable-symbol nil)
-      (should (paced-dictionary-p (paced-current-dictionary)))
-      (should (string-equal (paced-dictionary-name (paced-current-dictionary)) 
"test-dict-case"))
-      (setq-local paced-test-enable-symbol t)
-      (should (paced-dictionary-p (paced-current-dictionary)))
-      (should (string-equal (paced-dictionary-name (paced-current-dictionary)) 
"test-dict-case")))
-    (kill-buffer buffer-one)))
-
-(ert-deftest paced-populate-file ()
-  "Test case for single file populator."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (cmd (paced-file-population-command :file paced-first-test-file))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (let ((usage-hash (oref test-dict usage-hash)))
-      (should (eq (map-length usage-hash) 4))
-      (should (seq-set-equal-p (map-keys usage-hash) '("one" "two" "three" 
"four")))
-      (should (eq (map-elt usage-hash "one") 1))
-      (should (eq (map-elt usage-hash "two") 2))
-      (should (eq (map-elt usage-hash "three") 3))
-      (should (eq (map-elt usage-hash "four") 4)))))
-
-(ert-deftest paced-populate-buffer ()
-  "Test case for single buffer populator."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (buffer "first.txt")
-         (buffer-one (find-file-noselect paced-first-test-file))
-         (cmd (paced-buffer-population-command :buffer buffer))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (let ((usage-hash (oref test-dict usage-hash)))
-      (should (eq (map-length usage-hash) 4))
-      (should (seq-set-equal-p (map-keys usage-hash) '("one" "two" "three" 
"four")))
-      (should (eq (map-elt usage-hash "one") 1))
-      (should (eq (map-elt usage-hash "two") 2))
-      (should (eq (map-elt usage-hash "three") 3))
-      (should (eq (map-elt usage-hash "four") 4)))
-    (kill-buffer buffer-one)))
-
-(ert-deftest paced-populate-file-function ()
-  "Test case for file-function populator."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (pre-func (lambda () (insert (buffer-string)) t))
-         (cmd (paced-file-function-population-command :file 
paced-first-test-file
-                                                      :setup-func pre-func))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (let ((usage-hash (oref test-dict usage-hash)))
-      (should (eq (map-length usage-hash) 4))
-      (should (seq-set-equal-p (map-keys usage-hash) '("one" "two" "three" 
"four")))
-      (should (eq (map-elt usage-hash "one") 2))
-      (should (eq (map-elt usage-hash "two") 4))
-      (should (eq (map-elt usage-hash "three") 6))
-      (should (eq (map-elt usage-hash "four") 8)))))
-
-(ert-deftest paced-populate-directory-regexp ()
-  "Test case for directory-regexp populator."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (cmd (paced-directory-regexp-population-command :directory 
paced-test-dir
-                                                         :regexp ".*\\.txt"
-                                                         :recursive t))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (let ((usage-hash (oref test-dict usage-hash)))
-      (should (eq (map-length usage-hash) 4))
-      (should (seq-set-equal-p (map-keys usage-hash) '("one" "two" "three" 
"four")))
-      (should (eq (map-elt usage-hash "one") 1))
-      (should (eq (map-elt usage-hash "two") 2))
-      (should (eq (map-elt usage-hash "three") 3))
-      (should (eq (map-elt usage-hash "four") 4)))))
-
-(ert-deftest paced-populate-file-list ()
-  "Test case for file-list populator."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (file-list (lambda () `(,paced-first-test-file)))
-         (cmd (paced-file-list-population-command :generator file-list))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                           paced-test-dict-save-file
-                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (let ((usage-hash (oref test-dict usage-hash)))
-      (should (eq (map-length usage-hash) 4))
-      (should (seq-set-equal-p (map-keys usage-hash) '("one" "two" "three" 
"four")))
-      (should (eq (map-elt usage-hash "one") 1))
-      (should (eq (map-elt usage-hash "two") 2))
-      (should (eq (map-elt usage-hash "three") 3))
-      (should (eq (map-elt usage-hash "four") 4)))))
-
-(ert-deftest paced-multiple-population-commands ()
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (cmd1 (paced-file-population-command :file paced-first-test-file))
-         (cmd2 (paced-file-population-command :file paced-third-test-file))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd1 cmd2))
-    (paced-dictionary-repopulate test-dict)
-    (let ((usage-hash (oref test-dict usage-hash)))
-      (should (eq (map-length usage-hash) 7))
-      (should (seq-set-equal-p (map-keys usage-hash) '("one" "two" "three" 
"four" "five" "six" "seven")))
-      (should (eq (map-elt usage-hash "one") 1))
-      (should (eq (map-elt usage-hash "two") 2))
-      (should (eq (map-elt usage-hash "three") 3))
-      (should (eq (map-elt usage-hash "four") 4))
-      (should (eq (map-elt usage-hash "five") 5))
-      (should (eq (map-elt usage-hash "six") 3))
-      (should (eq (map-elt usage-hash "seven") 1)))))
-
-(ert-deftest paced-populator-settings ()
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (exclude-command (lambda nil (nth 8 (syntax-ppss)))) ;; exclude 
comments
-         (cmd1 (paced-file-population-command :file paced-first-test-file))
-         (cmd2 (paced-file-population-command :file paced-second-test-file
-                                              :props `((paced-exclude-function 
quote ,exclude-command))))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd1 cmd2))
-    (paced-dictionary-repopulate test-dict)
-    (let ((usage-hash (oref test-dict usage-hash)))
-      (should (eq (map-length usage-hash) 4))
-      (should (seq-set-equal-p (map-keys usage-hash) '("one" "two" "three" 
"four")))
-      (should (eq (map-elt usage-hash "one") 1))
-      (should (eq (map-elt usage-hash "two") 2))
-      (should (eq (map-elt usage-hash "three") 3))
-      (should (eq (map-elt usage-hash "four") 4)))))
-
-(ert-deftest paced-populate-sort-order ()
-  "Test case for sorting after population."
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (cmd (paced-file-population-command :file paced-first-test-file))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (let ((usage-hash (oref test-dict usage-hash)))
-      (should (eq (map-length usage-hash) 4))
-      (should (equal (map-keys usage-hash) '("four" "three" "two" "one")))
-      (should (eq (map-elt usage-hash "one") 1))
-      (should (eq (map-elt usage-hash "two") 2))
-      (should (eq (map-elt usage-hash "three") 3))
-      (should (eq (map-elt usage-hash "four") 4)))))
-
-(ert-deftest paced-populate-non-existent-file ()
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (file "first.txt")
-         (cmd (paced-file-population-command :file file))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (let ((usage-hash (oref test-dict usage-hash)))
-      (should (map-empty-p usage-hash)))))
-
-(ert-deftest paced-populate-non-existent-buffer ()
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (buffer "first.txt")
-         (cmd (paced-buffer-population-command :buffer buffer))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (let ((usage-hash (oref test-dict usage-hash)))
-      (should (map-empty-p usage-hash)))))
-
-(ert-deftest paced-completions-try-completion ()
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (cmd (paced-file-population-command :file paced-first-test-file))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (let ((completions (paced-dictionary-completions test-dict "o" nil)))
-      (should (equal completions '("o"))))))
-
-(ert-deftest paced-completions-try-completion-mixed-case ()
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (cmd (paced-file-population-command :file paced-first-test-file))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'mixed-case)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (let ((completions (paced-dictionary-completions test-dict "o" nil)))
-      (should (equal completions '("o"))))))
-
-(ert-deftest paced-completions-all-completions ()
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (cmd (paced-file-population-command :file paced-first-test-file))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (should (equal (paced-dictionary-completions test-dict "o" t)
-                   '("one")))
-    (should (equal (paced-dictionary-completions test-dict "on" t)
-                   '("one")))
-    (should (equal (paced-dictionary-completions test-dict "t" t)
-                   '("three" "two")))
-    (should (equal (paced-dictionary-completions test-dict "v" t)
-                   nil))))
-
-(ert-deftest paced-completions-test-completion ()
-  (let* ((paced--registered-dictionaries paced-test-default-registered-map)
-         (paced-global-dictionary-enable-alist '((text-mode . 
"test-dict-case")))
-         (cmd (paced-file-population-command :file paced-first-test-file))
-         (test-dict (paced-make-dictionary "test-dict-case"
-                                           paced-test-dict-save-file
-                                           'downcase)))
-    (should (paced-dictionary-p test-dict))
-    (oset test-dict population-commands (list cmd))
-    (paced-dictionary-repopulate test-dict)
-    (should (paced-dictionary-completions test-dict "one" 'lambda))
-    (should-not (paced-dictionary-completions test-dict "o" 'lambda))))
-
-(ert-deftest paced-merge-properties ()
-  (let* ((prop-list-1 '((a . "abc") (b . "xyz")))
-         (prop-list-2 '((a . "def") (c . "ghi")))
-         (prop-list-3 nil)
-         (merged-1   (paced-merge-properties prop-list-1 prop-list-2))
-         (merged-2   (paced-merge-properties prop-list-3 prop-list-2)))
-    (should (equal (map-elt merged-1 'a) '("def")))
-    (should (equal (map-elt merged-1 'b) '("xyz")))
-    (should (equal (map-elt merged-1 'c) '("ghi")))
-    (should (equal (map-elt merged-2 'a) '("def")))
-    (should (equal (map-elt merged-2 'c) '("ghi")))))
-
-(ert-deftest paced-beginning-end-of-thing-at-point ()
-  "Test exclusion and `paced-point-in-thing-at-point-for-exclusion'."
-  (let* ((paced-exclude-function (lambda () (looking-at-p "one")))
-         (buffer-one (find-file-noselect paced-first-test-file)))
-    (with-current-buffer buffer-one
-      (goto-char (point-min))
-      (should (equal (paced-thing-at-point) "one"))
-      (let ((paced-point-in-thing-at-point-for-exclusion 'beginning))
-        (should (paced-excluded-p)))
-      (paced-forward-thing)
-      (should (equal (paced-thing-at-point) "one"))
-      (let ((paced-point-in-thing-at-point-for-exclusion 'end))
-        (should-not (paced-excluded-p))))))
-
-(ert-deftest paced-character-limit ()
-  "Test character limit."
-  (let* ((paced-exclude-function (lambda () nil))
-         (buffer-one (find-file-noselect paced-first-test-file)))
-    (with-current-buffer buffer-one
-      (goto-char (point-min))
-      (should (equal (paced-thing-at-point) "one"))
-      (let* ((paced-character-limit 0))
-        (should-not (paced-excluded-p)))
-      (let* ((paced-character-limit 1))
-        (should (paced-excluded-p)))
-      (let* ((paced-character-limit 3))
-        (should-not (paced-excluded-p))))))
-
-(ert-deftest paced-no-thing-at-point ()
-  "Test for non-existent thing at point."
-  (let* ((org-element-use-cache nil) ;; Causes crashes, so disable it
-         (paced-exclude-function (lambda () nil))
-         (buffer-four (find-file-noselect paced-fourth-test-file)))
-    (with-current-buffer buffer-four
-      (goto-char (point-min))
-      (should-not (paced-thing-at-point))
-      (should (paced-excluded-p)))))
-
-(provide 'paced-tests)
-
-;;; paced-tests.el ends here
diff --git a/packages/paced/paced.el b/packages/paced/paced.el
deleted file mode 100644
index 53b7870..0000000
--- a/packages/paced/paced.el
+++ /dev/null
@@ -1,1356 +0,0 @@
-;;; paced.el --- Predictive Abbreviation Completion and Expansion using 
Dictionaries -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2017-2018 Free Software Foundation, Inc.
-
-;; Author: Ian Dunn <dunni@gnu.org>
-;; Maintainer: Ian Dunn <dunni@gnu.org>
-;; Keywords: convenience, completion
-;; Package-Requires: ((emacs "25.1") (async "1.9.1"))
-;; URL: https://savannah.nongnu.org/projects/paced-el/
-;; Version: 1.1.3
-;; Created: 22 Jan 2017
-;; Modified: 05 Feb 2018
-
-;; This file is part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify it 
under
-;; the terms of the GNU General Public License as published by the Free 
Software
-;; Foundation; either version 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 this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Paced (Predictive Abbreviation Completion and Expansion using Dictionaries)
-;; scans a group of files (determined by "population commands") to construct a
-;; usage table (dictionary).  Words (or symbols) are sorted by their usage, and
-;; may be later presented to the user for completion.  A dictionary can then be
-;; saved to a file, to be loaded later.
-
-;; Population commands determine how a dictionary should be filled with words 
or
-;; symbols.  A dictionary may have multiple population commands, and population
-;; may be performed asynchronously.  Once population is finished, the contents
-;; are sorted, with more commonly used words at the front.  Dictionaries may be
-;; edited through EIEIO's customize-object interface.
-
-;; Completion is done through `completion-at-point'.  The dictionary to use for
-;; completion can be customized.
-
-;;; Code:
-
-(eval-when-compile (require 'subr-x))
-
-(require 'thingatpt)
-(require 'map)
-(require 'eieio-base)
-(require 'rx)
-
-;; Compatibility for Emacs < 26.1
-(unless (fboundp 'if-let*)
-  (defalias 'if-let* 'if-let))
-(unless (fboundp 'when-let*)
-  (defalias 'when-let* 'when-let))
-
-(defgroup paced nil
-  "Predictive Abbreviation Completion and Expansion using Dictionaries"
-  :group 'convenience)
-
-(defcustom paced-thing-at-point-constituent 'symbol
-  "Symbol defining THING which function `paced-mode' works on.
-This symbol should be understandable by
-`bounds-of-thing-at-point'.  This symbol defines what function `paced-mode'
-considers to be the basic unit of expansion.  If if it set to `symbol',
-for example, \"paced-mode\" would be offered as an expansion, while
-if it is set to `word' \"paced\" and \"mode\" would be offered."
-  :group 'paced
-  :type 'symbol
-  :options '(symbol word))
-
-(defcustom paced-completion-ignore-case t
-  "Non-nil to ignore case when completing.
-
-Note that this does not affect dictionary population."
-  :group 'paced
-  :type 'boolean)
-
-(defcustom paced-dictionary-directory (locate-user-emacs-file 
"paced-dictionaries/")
-  "Directory in which the dictionaries are saved.
-
-This is only used in `paced-load-all-dictionaries', so it's up to
-the user whether to save dictionaries here."
-  :group 'paced
-  :type 'directory)
-
-(defcustom paced-dictionary-directory-whitelist-regexp (rx (zero-or-more 
anything))
-  "Regexp to match when reading from the dictionary directory.
-
-Any files that match this regexp will be loaded by
-`paced-load-all-dictionaries'."
-  :group 'paced
-  :type 'regexp)
-
-(defcustom paced-dictionary-directory-blacklist-regexp (rx string-end 
string-start)
-  "Regexp to match for files NOT to load with `paced-load-all-dictionaries'.
-
-This regexp by default matches nothing, thus allowing all files."
-  :group 'paced
-  :type 'regexp)
-
-(defcustom paced-load-all-dictionaries-recursively nil
-  "Whether to recursively load all files with `paced-load-all-dictionaries'."
-  :group 'paced
-  :type 'boolean)
-
-(defcustom paced-repopulate-saves-dictionary t
-  "Whether to save a dictionary after repopulation."
-  :group 'paced
-  :type 'boolean)
-
-(defcustom paced-populate-warn-about-reset t
-  "Whether to warn the user about resetting a dictionary when repopulating."
-  :group 'paced
-  :type 'boolean)
-
-(defcustom paced-point-in-thing-at-point-for-exclusion 'beginning
-  "Symbol to indicate from where exclusion should occur.
-
-If 'beginning, exclusion is checked at the beginning of the thing
-at point.  If 'end, exclusion is checked at the end of the thing
-at point.
-
-See `paced-excluded-p' and `paced-exclude-function' for more
-information on exclusion."
-  :group 'paced
-  :type 'symbol
-  :options '(beginning end))
-
-(defcustom paced-character-limit 0
-  "Character limit for including things in paced.
-
-If set to 0, impose no limit.  Otherwise, include words whose
-length is less than or equal to the value."
-  :group 'paced
-  :type 'number)
-
-
-
-(defun paced--default-dictionary-sort-func (usage-hash)
-  "Default dictionary sort function.
-
-Sort hash-table USAGE-HASH by the weights (values) in the table."
-  ;; Unfortunately, there's no way to sort a hash-table, so we first convert it
-  ;; into an alist, and sort that.
-  (let ((seq (map-into usage-hash 'list)))
-    (setq seq
-          (seq-sort
-           (pcase-lambda (`(_ . ,usage-lhs)
-                          `(_ . ,usage-rhs))
-             (> usage-lhs usage-rhs))
-           seq))
-    (map-into seq 'hash-table)))
-
-(defclass paced-dictionary (eieio-named eieio-persistent)
-  ((object-name :initarg :object-name
-                :documentation "Symbol to use to refer to this dictionary.")
-   (usage-hash :initarg :usage-hash
-               :initform (make-hash-table :test #'equal)
-               :type hash-table
-               :documentation "Stores the usage data for this dictionary.
-
-This is a hash table, mapping a word to the times it has been used.")
-   (population-commands
-    :initarg :population-commands
-    :initform nil
-    :type (list-of paced-population-command)
-    :custom (repeat (object :objectcreatefcn 
paced-new-population-command-custom))
-    :label "Population Commands"
-    :documentation "Commands to use when populating this dictionary.
-
-Each entry is a `paced-population-command'.")
-   (file-header-line :type string
-                    :allocation :class
-                    :initform ";; Paced Dictionary"
-                    :documentation
-                    "Header line for the save file.
-This is used with the `object-write' method.")
-   (case-handling :initarg :case-handling
-                  :initform downcase
-                  :type (member downcase upcase preserve downcase-first 
upcase-first mixed-case)
-                  :custom (choice (const :tag "Downcase All Words" downcase)
-                                  (const :tag "Upcase All Words" upcase)
-                                  (const :tag "Preserve Case" preserve)
-                                  (const :tag "Downcase Just the First Letter" 
downcase-first)
-                                  (const :tag "Upcase Just the First Letter" 
upcase-first)
-                                  (const :tag "Preserve Case on Mixed-Case 
Words" mixed-case))
-                  :label "Case Handling"
-                  :documentation "How case should be handled during population.
-
-It can be one of the following:
-
-* downcase        Downcase every word
-* upcase          Upcase every word
-* preserve        Preserve case
-* downcase-first  Downcase the first letter of each word, leave the rest the 
same
-* upcase-first    Upcase the first letter of each word, leave the rest the same
-* mixed-case      Preserve case on mixed-case words; single-case words
-                  are downcased.  See `paced-mixed-case-word-p' for an
-                  explanation of how \"mixed-case\" is defined.")
-   (updated :initarg :updated
-            :initform nil
-            :type boolean
-            :documentation "Non-nil if this dictionary has been updated since 
it was last saved.")
-   (default-population-properties
-     :initarg :default-population-properties
-     :initform nil
-     :type list
-     :label "Default Properties"
-     :custom (alist :tag "Properties" :key-type variable :value-type sexp)
-     :documentation "Default properties for population commands.
-
-Each element is of the form (VAR VALUE).  Each VAR will be set to
-VALUE during population for this dictionary.
-
-Properties set in the individual population commands will
-override settings here.
-
-Some suggested variables for this are `paced-exclude-function'
-and `paced-thing-at-point-constituent'.")
-   (sort-method :initarg :sort-method
-                :initform 'paced--default-dictionary-sort-func
-                :type function
-                :label "Sort Method"
-                :custom function
-                :documentation "Method by which this dictionary should sort 
its usage table.
-
-This should be a function of one argument, the usage-hash slot,
-and return a sorted hash-table.
-
-This defaults to `paced--default-dictionary-sort-func'."))
-  "Paced dictionary.")
-
-(defvar paced--registered-dictionaries (make-hash-table :test 'equal)
-  "Internal list of registered dictionaries.
-
-Do not edit this list manually.  Use `paced-make-dictionary'
-instead.")
-
-(defun paced-reset-registered-dictionaries ()
-  "Reset the registered dictionary list.
-
-WARNING: This will result in the loss of all dictionaries.  Only
-do this if you know what you're doing, or are under the
-supervision of someone who does."
-  (interactive)
-  (when (yes-or-no-p
-         "Warning: This will result in loss of all dictionaries.  Continue?")
-    (setq paced--registered-dictionaries (make-hash-table :test 'equal))))
-
-(defsubst paced-named-dictionary (key)
-  "Return a registered dictionary with name KEY.
-
-If none exists, return nil."
-  (map-elt paced--registered-dictionaries key nil))
-
-(defsubst paced-dictionary-names ()
-  "Get the names of the registered dictionaries."
-  (map-keys paced--registered-dictionaries))
-
-(defsubst paced-read-dictionary ()
-  "Read the name of a registered dictionary."
-  (completing-read "Dictionary: " (map-keys paced--registered-dictionaries)))
-
-(defsubst paced-dictionary-key-registered-p (key)
-  "Return non-nil if a dictionary with name KEY has been registered."
-  (map-contains-key paced--registered-dictionaries key))
-
-(defvar paced-throw-error-on-no-registered t
-  "Whether to throw an error when a named dictionary can't be found.")
-
-(defmacro paced-operate-on-named-dictionary (name &rest form)
-  "Run FORM on the dictionary with name NAME, bound to `dict'.
-
-If no dictionary named NAME exists, throw an error."
-  (declare (indent 1))
-  `(if-let* ((dict (paced-named-dictionary ,name)))
-       (progn ,@form)
-     (when paced-throw-error-on-no-registered
-       (error "No paced dictionary called '%s' has been registered" ,name))))
-
-(cl-defmethod paced-dictionary-register ((dict paced-dictionary))
-  "Registered dictionary DICT."
-  (map-put paced--registered-dictionaries (oref dict object-name) dict))
-
-(defsubst paced--ensure-dictionary-directory ()
-  "Ensure that `paced-dictionary-directory' exists."
-  (make-directory paced-dictionary-directory t))
-
-(defun paced-make-dictionary (name filename case-handling)
-  "Make a paced dictionary called NAME.
-
-NAME is a string used to identify the new dictionary.
-
-If a paced dictionary is already registered with name NAME, then
-it is replaced with a new, empty one.
-
-FILENAME is a file in which to store the new dictionary.
-
-CASE-HANDLING is a symbol that denotes how to handle case during
-population.  See the case-handling slot of class
-`paced-dictionary' for details.
-
-Return value is the new dictionary."
-  (let ((new-dict (paced-dictionary
-                   :object-name name
-                   :file filename
-                   :case-handling case-handling)))
-    (paced-dictionary-register new-dict)
-    new-dict))
-
-(defun paced-create-new-dictionary (name file)
-  "Create a new dictionary called NAME.
-
-FILE is the file in which to store the new dictionary.
-
-Once named, the dictionary can be edited through the EIEIO
-customization interface."
-  (declare (interactive-only paced-make-dictionary))
-  (interactive (list (read-string "Name: ")
-                     (read-file-name "Storage File: " 
paced-dictionary-directory)))
-  (let ((new-dict (paced-dictionary :object-name name
-                                    :file file)))
-    (customize-object new-dict)))
-
-(cl-defmethod paced-dictionary-name ((obj paced-dictionary))
-  "Return the name of dictionary OBJ."
-  (oref obj object-name))
-
-(cl-defmethod paced-dictionary-empty-p ((dict paced-dictionary))
-  "Return non-nil if DICT is empty."
-  (map-empty-p (oref dict usage-hash)))
-
-;;; Current Dictionary
-
-(defcustom paced-global-dictionary-enable-alist nil
-  "List that determines which dictionaries should be active.
-
-Each entry has the form (CONDITION . DICT-KEY), where CONDITION
-is one of the following forms:
-
-- A mode name, such as `org-mode' or `text-mode', indicating that
-  the named dictionary should be active in any mode derived from
-  that mode.
-
-- A symbol, in which case the named dictionary is active whenever
-  the value of that symbol is non-nil.
-
-- A function symbol, in which case the function is called with no
-  arguments to determine if the given dictionary should be
-  enabled.  If the function returns non-nil the dictionary is enabled.
-
-- A lambda function, in which case it is called with no
-  arguments, and if it returns non-nil, the dictionary is
-  enabled.
-
-- The form (or CONDITION1 CONDITION2 ...), which enables the
-  given dictionary if any of the conditions are met.
-
-- The form (and CONDITION1 CONDITION2 ...), which enables the
-  given dictionary if all of the conditions are met.
-
-No matter what this list indicates, dictionaries will not be
-enabled unless `paced-mode' is active."
-  :group 'paced
-  :type '(alist :key-type sexp :value-type string))
-
-(define-obsolete-variable-alias 'paced-global-dict-enable-alist
-  'paced-global-dictionary-enable-alist
-  "1.1")
-
-(defvar-local paced-local-dictionary-enable-alist nil
-  "Local enable list.
-
-Has the same form as and takes priority over
-`paced-global-dictionary-enable-alist'.")
-
-(define-obsolete-variable-alias 'paced-local-dict-enable-alist
-  'paced-local-dictionary-enable-alist
-  "1.1")
-
-(defun paced-dictionary-enable-list ()
-  "Return the combination of the local and global enable-alists.
-
-See `paced-local-dictionary-enable-alist' and
-`paced-global-dictionary-enable-alist' for more information."
-  (append paced-local-dictionary-enable-alist
-          paced-global-dictionary-enable-alist))
-
-(define-obsolete-function-alias 'paced-dict-enable-list
-  'paced-dictionary-enable-list
-  "1.1")
-
-(defun paced-mode-symbol-p (sym)
-  "Return non-nil if SYM is a mode symbol."
-  (string-match-p (rx "-mode" string-end) (symbol-name sym)))
-
-(defun paced-test-dictionary-enable-condition (condition)
-  "Determines if CONDITION passes in the current buffer.
-
-See `paced-global-dictionary-enable-alist' for an explanation."
-  (pcase condition
-    ((and (pred symbolp)
-          (pred paced-mode-symbol-p))
-     (derived-mode-p condition))
-    ((and (pred symbolp)
-          (pred boundp))
-     (symbol-value condition))
-    ((and (pred symbolp)
-          (pred fboundp))
-     (funcall condition))
-    ((pred functionp)
-     (funcall condition))
-    (`(or . ,rest)
-     (seq-some 'paced-test-dictionary-enable-condition rest))
-    (`(and . ,rest)
-     (seq-every-p 'paced-test-dictionary-enable-condition rest))))
-
-(defun paced-current-dictionary ()
-  "Determine the current dictionary.
-
-Returns nil if no dictionary should be enabled.
-
-If a dictionary is found in the list that doesn't exist, it will
-be skipped.
-
-See `paced-global-dictionary-enable-alist' or
-`paced-local-dictionary-enable-alist' for how to set the current
-dictionary conditions."
-  (let ((conditions (paced-dictionary-enable-list))
-        (dictionary))
-    (while (and conditions
-                (not dictionary))
-      (pcase-let* ((`(,condition . ,dict) (pop conditions)))
-        (when (and (paced-dictionary-key-registered-p dict)
-                   (paced-test-dictionary-enable-condition condition))
-          (setq dictionary dict))))
-    (when dictionary
-      (paced-named-dictionary dictionary))))
-
-(defvar paced-throw-error-on-no-current nil
-  "Whether to throw an error when no current dictionary can be found.")
-
-(defmacro paced-operate-on-current-dictionary (&rest form)
-  "Run FORM with the current dictionary bound to `dict'.
-
-If no dictionary can be found for the buffer, throw an error.  To
-suppress the error, set `paced-throw-error-on-no-current' to
-nil."
-  `(if-let* ((dict (paced-current-dictionary)))
-       (progn ,@form)
-     (when paced-throw-error-on-no-current
-       (user-error "No dictionary found for current buffer"))))
-
-;;; Saving and Loading
-
-(cl-defmethod paced-dictionary-save ((dict paced-dictionary) &optional force)
-  "Save dictionary DICT according to its filename.
-
-If FORCE is non-nil, ignore the `updated' flag in DICT and save
-it anyway."
-  (when (or force (oref dict updated))
-    (eieio-persistent-save dict))
-  (oset dict updated nil))
-
-(defun paced-save-named-dictionary (key force)
-  "Save dictionary named KEY.
-
-If FORCE is non-nil (given with a prefix arg), forcibly save the
-dictionary if found."
-  (declare (interactive-only paced-dictionary-save))
-  (interactive (list (paced-read-dictionary) current-prefix-arg))
-  (paced-operate-on-named-dictionary key
-    (paced-dictionary-save dict force)))
-
-(defun paced-save-current-dictionary (force)
-  "Save the dictionary for the current buffer.
-
-For how the current dictionary is determined, see
-`paced-current-dictionary'.
-
-With prefix argument FORCE, save the dictionary even if it hasn't
-been modified."
-  (interactive "P")
-  (paced-operate-on-current-dictionary
-   (paced-dictionary-save dict force)))
-
-(defun paced-load-dictionary-from-file (file)
-  "Load dictionary from FILE."
-  (interactive
-   (list (read-file-name "Dictionary File: " paced-dictionary-directory)))
-  (when-let* ((new-dict (eieio-persistent-read file 'paced-dictionary)))
-    (paced-dictionary-register new-dict)))
-
-(defun paced-save-all-dictionaries (&optional force)
-  "Save all registered dictionaries.
-
-With prefix argument FORCE, save the dictionaries regardless of
-whether they've been modified."
-  (interactive "P")
-  (map-apply
-   (lambda (_ dict)
-     (paced-dictionary-save dict force))
-   paced--registered-dictionaries))
-
-;;;###autoload
-(defun paced-load-all-dictionaries ()
-  "Load all dictionaries in `paced-dictionary-directory'."
-  (interactive)
-  (message "Loading all dictionaries from %s" paced-dictionary-directory)
-  (paced--ensure-dictionary-directory)
-  (let ((files-to-load
-         (if paced-load-all-dictionaries-recursively
-             (directory-files-recursively paced-dictionary-directory
-                                          
paced-dictionary-directory-whitelist-regexp)
-           (directory-files paced-dictionary-directory t
-                            paced-dictionary-directory-whitelist-regexp))))
-    (dolist (dict-file files-to-load)
-      (when (and (file-regular-p dict-file)
-                 (not (string-match-p 
paced-dictionary-directory-blacklist-regexp dict-file)))
-        (paced-load-dictionary-from-file dict-file)))))
-
-(cl-defmethod eieio-done-customizing ((dict paced-dictionary))
-  (paced-dictionary-register dict)
-  (paced--ensure-dictionary-directory)
-  (paced-dictionary-save dict t))
-
-
-;;; Handling of Thing at Point
-
-(defun paced-bounds-of-thing-at-point ()
-  "Get the bounds of the thing at point."
-  (bounds-of-thing-at-point paced-thing-at-point-constituent))
-
-(defun paced-thing-at-point ()
-  "Return the current thing at point.
-
-The thing is determined by `paced-thing-at-point-constituent'.
-
-Text properties are excluded."
-  (when-let* ((bounds (paced-bounds-of-thing-at-point)))
-    (buffer-substring-no-properties
-     (car bounds) (cdr bounds))))
-
-(defun paced-forward-thing (&optional number)
-  "Move forward NUMBER things.
-
-Things is based on `paced-thing-at-point-constituent'."
-  (interactive "p")
-  (forward-thing paced-thing-at-point-constituent number))
-
-(defun paced-goto-beginning-of-thing-at-point ()
-  "Move to the start of the current thing at point.
-
-Thing is based on `paced-thing-at-point-constituent'."
-  (goto-char (car (paced-bounds-of-thing-at-point))))
-
-(defun paced-goto-end-of-thing-at-point ()
-  "Move to the end of the current thing at point.
-
-Thing is based on `paced-thing-at-point-constituent'."
-  (goto-char (cdr (paced-bounds-of-thing-at-point))))
-
-;;; Character Limits
-
-(defun paced-length-of-thing-at-point ()
-  "Return the length, in characters, of the current thing at point."
-  (length (paced-thing-at-point)))
-
-(defun paced-thing-meets-limit-p ()
-  "Return non-nil if the current thing at point meets the limit requirement.
-
-The limit requirement is set with `paced-character-limit'."
-  (or (eq paced-character-limit 0)
-      (<= (paced-length-of-thing-at-point) paced-character-limit)))
-
-;;; Exclusion
-
-(defvar-local paced-exclude-function (lambda () nil)
-  "Local predicate to determine if thing at point should be excluded.
-
-This should be a function of no arguments that returns non-nil if
-the current thing-at-point should be excluded from paced
-dictionaries.  Exclusion is checked from the start or the end of
-the current thing, depending on `paced-point-in-thing-at-point-for-exclusion'.
-Point returns to its original position after the function is
-called.
-
-By default, this allows everything.
-
-A useful function for this is `paced-in-comment-p'.")
-
-(defun paced-in-comment-p (&optional pos)
-  "Return non-nil if POS is in a comment.
-
-If POS is not specified, defaults to `point'."
-  (nth 8 (syntax-ppss (or pos (point)))))
-
-(defun paced-excluded-p ()
-  "Return non-nil to exclude current thing at point.
-
-See `paced-exclude-function' for more.
-
-Exclusion can be performed from either the beginning or end of
-the thing at point.  See
-`paced-point-in-thing-at-point-for-exclusion' for how to set
-this.
-
-If there is no current \"thing\" at point, the text under point
-will be excluded, and paced will move on.
-
-This also handles character limits set by
-`paced-character-limit'."
-  (or (not (paced-thing-meets-limit-p))
-      (not (paced-bounds-of-thing-at-point)) ;; There's no thing at point
-      (save-excursion
-        (pcase paced-point-in-thing-at-point-for-exclusion
-          (`beginning
-           (paced-goto-beginning-of-thing-at-point))
-          (`end
-           (paced-goto-end-of-thing-at-point)))
-        (funcall paced-exclude-function))))
-
-;;; Case Handling
-
-(defun paced-mixed-case-word-p (word)
-  "Return non-nil if WORD is mixed-case.
-
-A mixed-case word is one with both uppercase and lowercase
-letters, but ignoring the first letter if it's uppercase.  This
-is due to assuming the first letter is unimportant, as per
-sentence starting."
-  ;; Mixed case would typically be an uppercase letter followed by a lowercase
-  ;; letter, or a lowercase letter followed by an uppercase letter.  Since 
we're
-  ;; ignoring the first letter of a word if it's uppercase, we need to check 
for
-  ;; two distinct uppercase letters, followed by a lowercase letter.
-  (let ((case-fold-search nil)) ;; Case is important
-    (string-match-p (rx (or (and lower upper) ;; lower followed by upper
-                            ;; Two distinct uppercase letters, as in HAs
-                            (and upper upper lower)))
-                    word)))
-
-(defun paced--handle-word-case (case-handling word)
-  "Process WORD based on CASE-HANDLING.
-
-This is a separate function only for testing; use
-`paced-dictionary-process-word' instead."
-  (pcase case-handling
-    (`preserve word)
-    (`downcase (downcase word))
-    (`upcase (upcase word))
-    (`downcase-first
-     ;; Downcase the first letter
-     (concat (downcase (substring word 0 1))
-             (substring word 1)))
-    ;; Upcase the first letter
-    (`upcase-first
-     (concat (upcase (substring word 0 1))
-             (substring word 1)))
-    (`mixed-case
-     (if (paced-mixed-case-word-p word) word (downcase word)))))
-
-(cl-defmethod paced-dictionary-process-word ((dict paced-dictionary) word)
-  "Return WORD, modified based on DICT's case handling."
-  (paced--handle-word-case (oref dict case-handling) word))
-
-;;; Population
-
-(defvar-local paced--current-source nil
-  "The source from which a dictionary is being populated.
-
-This is used internally to inform the user of the current source,
-since population mostly uses temporary buffers.")
-
-(cl-defmethod paced-dictionary-add-word ((dict paced-dictionary) word)
-  "Add WORD to paced dictionary DICT."
-  (let ((new-word (paced-dictionary-process-word dict word)))
-    ;; Use the full name here to silence the byte-compiler
-    (cl-incf (map-elt (oref dict usage-hash) new-word 0))
-    (oset dict updated t)))
-
-(defun paced-add-word-to-current-dictionary (word)
-  "Add WORD to the current dictionary.
-
-For how the current dictionary is determined, see
-`paced-current-dictionary'."
-  (paced-operate-on-current-dictionary
-   (paced-dictionary-add-word dict word)))
-
-(cl-defmethod paced-dictionary-populate-from-buffer ((dict paced-dictionary) 
&optional buffer)
-  "Repopulate DICT from BUFFER.
-
-If BUFFER is nil, use the current one."
-  (with-current-buffer (or buffer (current-buffer))
-    (save-excursion
-      (goto-char (point-min))
-      (let* ((reporter-string
-              (concat (format "Populating dictionary %s" 
(paced-dictionary-name dict))
-                      (when paced--current-source (format " from %s"
-                                                          
paced--current-source))
-                      "..."))
-             (reporter (make-progress-reporter reporter-string 0 100)))
-        (while (paced-forward-thing)
-          (progress-reporter-do-update
-           reporter
-           (floor (* 100.0 (/ (float (point)) (point-max)))))
-          (unless (paced-excluded-p)
-            (paced-dictionary-add-word dict (paced-thing-at-point))))
-        (progress-reporter-done reporter)))))
-
-(defun paced-populate-current-dictionary-from-buffer (&optional buffer)
-  "Populate the current dictionary from BUFFER.
-
-This means add a usage of each included thing in BUFFER.
-
-BUFFER is either the name of a buffer, or the buffer itself.  If
-not given, use the current buffer.
-
-In order to only populate the dictionary from a region,
-`paced-populate-current-dictionary-from-region'.
-
-Note that this doesn't add the buffer to the dictionary's
-population commands, so if it is later repopulated using
-`paced-dictionary-repopulate' or
-`paced-repopulate-named-dictionary', anything added with this
-command will be lost.
-
-In order to make changes permanent, use
-`paced-add-buffer-file-to-dictionary'.
-
-For how the current dictionary is determined, see
-`paced-current-dictionary'."
-  (interactive "b")
-  (paced-operate-on-current-dictionary
-   (paced-dictionary-populate-from-buffer dict buffer)))
-
-(define-obsolete-function-alias 'paced-populate-buffer-dictionary
-  'paced-populate-current-dictionary-from-buffer
-  "1.1")
-
-(defun paced-populate-named-dictionary-from-buffer (name &optional buffer)
-  "Populate the dictionary named NAME from BUFFER.
-
-This means add a usage of each included thing in BUFFER.
-
-BUFFER is either the name of a buffer, or the buffer itself.  If
-not given, use the current buffer.
-
-In order to only populate the dictionary from a region,
-`paced-populate-current-dictionary-from-region'.
-
-Note that this doesn't add the buffer to the dictionary's
-population commands, so if it is later repopulated using
-`paced-dictionary-repopulate' or
-`paced-repopulate-named-dictionary', anything added with this
-command will be lost.
-
-In order to make changes permanent, use
-`paced-add-buffer-file-to-dictionary'.
-
-For how the current dictionary is determined, see
-`paced-current-dictionary'."
-  (interactive
-   (list (paced-read-dictionary) (read-buffer "Buffer: " nil t)))
-  (paced-operate-on-named-dictionary name
-    (paced-dictionary-populate-from-buffer dict buffer)))
-
-(cl-defmethod paced-dictionary-populate-from-region ((dict paced-dictionary) 
start end)
-  "Populate DICT from the region in the current buffer between START and END.
-
-Note that this doesn't add the current buffer to DICT's
-population commands, so if DICT is later repopulated using
-`paced-dictionary-repopulate' or
-`paced-repopulate-named-dictionary', anything added with this
-command will be lost."
-  (save-restriction
-    (narrow-to-region start end)
-    (paced-dictionary-populate-from-buffer dict)))
-
-(defun paced-populate-current-dictionary-from-region (start end)
-  "Populate the current dictionary from the region START to END.
-
-Note that this doesn't add the current buffer to the dictionary's
-population commands, so if it is later repopulated using
-`paced-dictionary-repopulate' or
-`paced-repopulate-named-dictionary', anything added with this
-command will be lost."
-  (interactive "r")
-  (paced-operate-on-current-dictionary
-   (paced-dictionary-populate-from-region dict start end)))
-
-(define-obsolete-function-alias 'paced-populate-from-region
-  'paced-populate-current-dictionary-from-region
-  "1.1")
-
-(defun paced-add-current-thing-to-dictionary ()
-  "Add the current thing at point to the current dictionary.
-
-No check is done to determine if the current thing should be
-excluded.
-
-Note that this doesn't add anything to the dictionary's
-population commands, so if it is later repopulated using
-`paced-dictionary-repopulate' or
-`paced-repopulate-named-dictionary', anything added with this
-command will be lost."
-  (interactive)
-  (paced-operate-on-current-dictionary
-   (paced-dictionary-add-word dict (paced-thing-at-point))))
-
-;;; Dictionary Reset
-
-(cl-defmethod paced-dictionary-reset ((dict paced-dictionary))
-  "Reset the usage-hash of paced-dictionary DICT."
-  (oset dict usage-hash (oref-default dict usage-hash)))
-
-(defun paced-reset-named-dictionary (key)
-  "Reset the paced dictionary with key KEY."
-  (declare (interactive-only paced-dictionary-reset))
-  (interactive
-   (list (paced-read-dictionary)))
-  (paced-operate-on-named-dictionary key
-    (paced-dictionary-reset dict)))
-
-(defun paced-reset-current-dictionary ()
-  "Reset the current dictionary.
-
-For how the current dictionary is determined, see
-`paced-current-dictionary'."
-  (interactive)
-  (paced-operate-on-current-dictionary
-   (paced-dictionary-reset dict)))
-
-;;; Dictionary Sorting
-
-(cl-defmethod paced-dictionary-sort ((dict paced-dictionary))
-  "Sort the words in dictionary DICT by usage."
-  (oset dict usage-hash
-        (funcall (oref dict sort-method)
-                 (oref dict usage-hash))))
-
-(defun paced-sort-named-dictionary (key)
-  "Sort the paced dictionary with key KEY."
-  (declare (interactive-only paced-dictionary-sort))
-  (interactive (list (paced-read-dictionary)))
-  (paced-operate-on-named-dictionary key
-    (paced-dictionary-sort dict)))
-
-(defun paced-sort-current-dictionary ()
-  "Sort the current paced dictionary.
-
-For how the current dictionary is determined, see
-`paced-current-dictionary'."
-  (interactive)
-  (paced-operate-on-current-dictionary
-   (paced-dictionary-sort dict)))
-
-
-;;; The Minor Mode
-
-(define-minor-mode paced-mode
-  "Toggle paced mode.
-
-This adds `paced-completion-at-point' to
-`completion-at-point-functions'."
-  :init-value nil
-  :lighter " paced"
-  :group 'paced
-  (if paced-mode
-      (add-hook 'completion-at-point-functions 'paced-completion-at-point 
'append 'local)
-    (remove-hook 'completion-at-point-functions 'paced-completion-at-point 
'local)))
-
-(define-globalized-minor-mode global-paced-mode paced-mode paced-mode
-  :group 'paced)
-
-;;; Completion
-
-(cl-defmethod paced-dictionary-fix-completion-case ((dict paced-dictionary) 
prefix completions)
-  "Account for case differences in the prefix by prepending PREFIX to 
COMPLETIONS.
-
-The specific case differences should mirror those handled by
-case-handling in `paced-dictionary-process-word'."
-  ;; Anything we changed during population, we want to maintain that part of 
the
-  ;; prefix during completion.
-  (if (not (listp completions))
-      ;; If completions is not a list, it's likely 't', in which
-      ;; case just return the original prefix.
-      (list prefix)
-    (pcase (oref dict case-handling)
-      (`preserve completions)
-      ((or `downcase `upcase)
-       ;; Changed entire word, so maintain entire prefix
-       (let ((prefix-length (length prefix)))
-         (mapcar
-          (lambda (completion)
-            (when (stringp completion)
-              (concat prefix (substring-no-properties completion 
prefix-length))))
-          completions)))
-      ((or `downcase-first `upcase-first)
-       ;; Only changed the first letter, so maintain just one letter of the
-       ;; original prefix
-       (let ((prefix-length 1))
-         (mapcar
-          (lambda (completion)
-            (when (stringp completion)
-              (concat (substring prefix 0 prefix-length)
-                      (substring-no-properties completion prefix-length))))
-          completions)))
-      (`mixed-case
-       ;; Only change prefix on single-case completion options
-       (let ((prefix-length (length prefix)))
-         (mapcar
-          (lambda (completion)
-            (when (stringp completion)
-              (if (paced-mixed-case-word-p completion)
-                  completion
-                (concat (substring prefix 0 prefix-length)
-                        (substring-no-properties completion prefix-length)))))
-          completions))))))
-
-(cl-defmethod paced-dictionary-completions ((dict paced-dictionary) prefix 
action &optional pred)
-  "Get the completions for PREFIX in DICT.
-
-ACTION is a completion action, one of 'nil, 't, or 'lambda.  See
-Info node `(elisp)Programmed Completion' for an explanation of
-each of them.
-
-PRED is a predicate to supply to completion, and will return
-non-nil if the completion option should be allowed.
-
-Case handling is handled here; any part of a word that was
-modified by `paced-dictionary-process-word' will be replaced with
-the prefix before completions are returned."
-  (let* ((completion-ignore-case paced-completion-ignore-case)
-         (usage-hash (oref dict usage-hash))
-         completions)
-    (pcase action
-      (`nil
-       (setq completions (try-completion prefix usage-hash pred)))
-      (`t
-       (setq completions (all-completions prefix usage-hash pred)))
-      (`lambda
-        (setq completions (test-completion prefix usage-hash pred))))
-    (paced-dictionary-fix-completion-case dict prefix completions)))
-
-(defun paced-completion-table-function (string pred action)
-  "Completion table function for paced dictionaries."
-  (let* ((completion-ignore-case paced-completion-ignore-case))
-    (pcase action
-      ((or `nil `t `lambda)
-       ;; Intentionally don't throw an error here, so as not to disrupt
-       ;; completion.
-       (when-let* ((dict (paced-current-dictionary)))
-         (paced-dictionary-completions dict string action pred)))
-      (`(boundaries . _) nil)
-      (`metadata
-       `(metadata . ((category . paced)
-                     (annotation-function . nil)
-                     (display-sort-function . identity)
-                     (cycle-sort-function . identity)))))))
-
-(defcustom paced-auto-update-p nil
-  "Whether to update from completions.
-
-This only works for an existing entry."
-  :group 'paced
-  :type 'boolean)
-
-(defun paced-completion-auto-update (word status)
-  "Automatically update the current dictionary with WORD depending on STATUS.
-
-This should only be called from `paced-completion-at-point'."
-  (cl-case status
-    (sole
-     ;; We're done with completion, but the user may still be typing.
-     ;; Therefore, don't add it.
-     )
-    (exact
-     ;; Might not be the entire completion, so don't add it.
-     )
-    (finished
-     ;; We know there's a current dictionary, since this should only be called
-     ;; from `paced-completion-at-point'.
-     (when paced-auto-update-p
-       (paced-add-word-to-current-dictionary word)))))
-
-(defun paced-completion-at-point ()
-  "Function for `completion-at-point-functions' to get the paced completions."
-  ;; Don't expand unless we're in a buffer with paced-mode enabled.
-  (when (and paced-mode)
-    (when-let* ((bounds (paced-bounds-of-thing-at-point)))
-      (list (car bounds) (cdr bounds) 'paced-completion-table-function
-            :exit-function 'paced-completion-auto-update
-            :exclusive 'no))))
-
-
-;;; Repopulation
-
-(defun paced--insert-file-contents (file)
-  "Insert the contents of FILE into the current buffer.
-
-Unlike `insert-file-contents', this handles mode hooks, which
-paced requires for repopulation (syntax tables, exclude functions, etc.).
-
-Returns nil if FILE doesn't exist."
-  (if (not (file-exists-p file))
-      (progn (message "Paced couldn't find file %s" file) nil)
-    (insert-file-contents file)
-    (let ((buffer-file-name file))
-      (after-find-file))
-    t))
-
-(defclass paced-population-command ()
-  ((props :initarg :props
-          :initform nil
-          :type list
-          :label "Properties"
-          :custom (alist :tag "Options" :key-type variable :value-type sexp)
-          :documentation "A list of variables to set during population.
-
-Each element is of the form (VAR VALUE).
-
-Some suggested variables for this are `paced-exclude-function'
-and `paced-thing-at-point-constituent'.")))
-
-(defun paced-merge-properties (&rest props)
-  "Merge the properties in PROPS to a single form understood by `let'.
-
-PROPS is a list of alists, each mapping a variable to a value for
-that variable
-
-The maps in the end of PROPS take precedence over the beginning."
-  (let ((merged-map (apply 'map-merge 'list props)))
-    (map-apply (lambda (var val) (list var val)) merged-map)))
-
-(cl-defmethod paced-dictionary-prepare-properties ((dict paced-dictionary)
-                                                   (cmd  
paced-population-command))
-  "Merge the properties of DICT and CMD into a single form understood by `let'.
-
-Properties in CMD take precedence over those in DICT."
-  (paced-merge-properties (oref dict default-population-properties)
-                          (oref cmd props)))
-
-(cl-defgeneric paced-population-command-source-list ((_cmd 
paced-population-command)))
-
-(cl-defgeneric paced-population-command-setup-buffer ((_cmd 
paced-population-command) _source)
-  "Prepare a temporary buffer with SOURCE.
-
-Return non-nil if setup was successful and population can continue.")
-
-(cl-defmethod paced-population-command-populate-dictionary ((dict 
paced-dictionary) (cmd paced-population-command))
-  "Populate DICT from CMD."
-  (let ((sources (paced-population-command-source-list cmd))
-        ;; Turn props into a form understood by `let'.
-        (props (paced-dictionary-prepare-properties dict cmd)))
-    (dolist (source sources)
-      (with-temp-buffer
-        ;; If pre is nil, continue.
-        ;; Otherwise, continue if pre returns non-nil
-        ;; This allows users to specify conditions under which repopulation
-        ;; should be disabled.
-        (let ((paced--current-source source))
-          (when (paced-population-command-setup-buffer cmd source)
-            (eval (macroexp-let* props `(paced-dictionary-populate-from-buffer 
,dict)))))))))
-
-(defclass paced-file-population-command (paced-population-command)
-  ((file :initarg :file
-         :initform ""
-         :type string
-         :label "File"
-         :custom (file :tag "File")
-         :documentation "File from which to populate."))
-  "Populates a dictionary from all words in a single file.")
-
-(cl-defmethod paced-population-command-source-list ((cmd 
paced-file-population-command))
-  (list (oref cmd file)))
-
-(cl-defmethod paced-population-command-setup-buffer ((_cmd 
paced-file-population-command) source)
-  (paced--insert-file-contents source))
-
-(defclass paced-buffer-population-command (paced-population-command)
-  ((buffer :initarg :buffer
-           :initform ""
-           :type string
-           :label "Buffer"
-           :custom (string :tag "Buffer")
-           :documentation "Name of the buffer from which to populate."))
-  "Populates a dictionary from all words in a given buffer.
-
-That buffer must be a string, and must exist during population.")
-
-(cl-defmethod paced-population-command-source-list ((cmd 
paced-buffer-population-command))
-  (list (oref cmd buffer)))
-
-(cl-defmethod paced-population-command-setup-buffer ((_cmd 
paced-buffer-population-command) source)
-  (cond
-   ((not (stringp source))
-    (message "Paced buffer populator got an invalid argument: %s" source)
-    nil)
-   ((not (get-buffer source))
-    (message "Paced buffer populator got a buffer that doesn't exist: %s" 
source)
-    nil)
-   (t
-    (set-buffer source))))
-
-(defclass paced-file-function-population-command (paced-population-command)
-  ((file :initarg :file
-         :initform ""
-         :type string
-         :label "File"
-         :custom (file :tag "File")
-         :documentation "File from which to populate.")
-   (setup-func :initarg :setup-func
-               :initform (lambda () t)
-               :type function
-               :label "Setup Function"
-               :custom (function :tag "Setup Function")
-               :documentation "Additional setup function."))
-  "Populate from a given file, using a setup function.
-
-That function is called with no arguments, with a temporary
-buffer containing the file's contents, and must return non-nil if
-population may continue.")
-
-(cl-defmethod paced-population-command-source-list ((cmd 
paced-file-function-population-command))
-  (list (oref cmd file)))
-
-(cl-defmethod paced-population-command-setup-buffer ((cmd 
paced-file-function-population-command) source)
-  (and (paced--insert-file-contents source)
-       (funcall (oref cmd setup-func))))
-
-(defclass paced-directory-regexp-population-command (paced-population-command)
-  ((directory :initarg :directory
-              :initform ""
-              :type string
-              :label "Directory"
-              :custom (directory :tag "Directory")
-              :documentation "Directory to search for files from which to 
populate.")
-   (regexp :initarg :regexp
-           :initform ".*"
-           :type string
-           :label "File Regexp"
-           :custom (string :tag "File Regexp")
-           :documentation "Regular expression to match files.")
-   (recursive :initarg :recursive
-              :initform t
-              :type boolean
-              :label "Recursive"
-              :custom boolean
-              :documentation "Whether to search through the directory 
recursively."))
-  "Population command to populate from files in a directory that
-match a regular expression.")
-
-(cl-defmethod paced-population-command-source-list ((cmd 
paced-directory-regexp-population-command))
-  (with-slots (directory regexp recursive) cmd
-    (if recursive
-        (directory-files-recursively directory regexp)
-      (directory-files directory t regexp))))
-
-(cl-defmethod paced-population-command-setup-buffer ((_cmd 
paced-directory-regexp-population-command) source)
-  (paced--insert-file-contents source))
-
-(defclass paced-file-list-population-command (paced-population-command)
-  ((generator :initarg :generator
-              :initform (lambda () nil)
-              :type function
-              :label "Generator"
-              :custom (function :tag "Generator")
-              :documentation "Function of no arguments that returns a list of 
files."))
-  "Populate a dictionary from a list of files.")
-
-(cl-defmethod paced-population-command-source-list ((cmd 
paced-file-list-population-command))
-  (funcall (oref cmd generator)))
-
-(cl-defmethod paced-population-command-setup-buffer ((_cmd 
paced-file-list-population-command) source)
-  (paced--insert-file-contents source))
-
-(defun paced-new-population-command-custom ()
-  "Prompt for a population command type and create a new command of that type."
-  (let* ((type (completing-read "Command Type: "
-                                (eieio-class-children 
'paced-population-command))))
-    (funcall (intern type))))
-
-(cl-defmethod paced-dictionary-repopulate ((dict paced-dictionary))
-  "Repopulate dictionary DICT from its population commands.
-
-Population commands are stored in the field of the same name.
-
-Note that this will empty the dictionary's contents before
-repopulating it."
-  ;; Empty the dictionary
-  (paced-dictionary-reset dict)
-  (dolist (cmd (oref dict population-commands))
-    (paced-population-command-populate-dictionary dict cmd))
-  (paced-dictionary-sort dict)
-  (when paced-repopulate-saves-dictionary
-    (paced-dictionary-save dict)))
-
-(defun paced-repopulate-named-dictionary (key)
-  "Repopulate dictionary named KEY from its population commands.
-
-Population commands are stored in the field of the same name.
-
-Note that this will empty the dictionary's contents before
-repopulating it.  If `paced-populate-warn-about-reset' is
-non-nil, confirmation will be requested before continuing."
-  (interactive
-   (list (paced-read-dictionary)))
-  (paced-operate-on-named-dictionary key
-    (when (or (not paced-populate-warn-about-reset)
-              (y-or-n-p "Warning: Repopulating dictionary will reset it.  
Continue? "))
-      (paced-dictionary-repopulate dict))))
-
-(defun paced-repopulate-current-dictionary ()
-  "Repopulate the current dictionary.
-
-Note that this will empty the dictionary's contents before
-repopulating it.  If `paced-populate-warn-about-reset' is
-non-nil, confirmation will be requested before continuing."
-  (interactive)
-  (paced-operate-on-current-dictionary
-   (when (or (not paced-populate-warn-about-reset)
-             (y-or-n-p "Warning: Repopulating dictionary will reset it.  
Continue? "))
-     (paced-dictionary-repopulate dict))))
-
-(cl-defmethod paced-dictionary-add-population-command ((dict paced-dictionary)
-                                                       (cmd 
paced-population-command))
-  "Add population command CMD to dictionary DICT."
-  (cl-pushnew cmd (oref dict population-commands) :test 'equal))
-
-(defun paced-add-buffer-file-to-dictionary (&optional buffer)
-  "Populate the current dictionary of BUFFER with BUFFER.
-
-The file corresponding to BUFFER is then added to the current
-dictionary's population commands.
-
-Custom settings for the populator, such as the exclude function,
-must be set with `paced-edit-named-dictionary' or
-`paced-edit-current-dictionary'."
-  (interactive)
-  (with-current-buffer (or buffer (current-buffer))
-    (unless (buffer-file-name)
-      (user-error "paced-add-buffer-file-to-dictionary called inside a 
non-file buffer."))
-    (paced-operate-on-current-dictionary
-     (let* ((file-name (buffer-file-name))
-            (cmd (paced-file-population-command :file file-name)))
-       (paced-dictionary-populate-from-buffer dict buffer)
-       (paced-dictionary-add-population-command dict cmd)))))
-
-
-
-;;; Edit a Dictionary
-
-(cl-defmethod paced-dictionary-edit ((dict paced-dictionary))
-  "Edit paced-dictionary DICT."
-  (customize-object dict))
-
-(defun paced-edit-named-dictionary (name)
-  "Edit the `paced-dictionary' named NAME."
-  (declare (interactive-only paced-dictionary-edit))
-  (interactive (list (paced-read-dictionary)))
-  (paced-operate-on-named-dictionary name
-    (paced-dictionary-edit dict)))
-
-(defun paced-edit-current-dictionary ()
-  "Edit the current paced dictionary.
-
-For how the current dictionary is determined, see
-`paced-current-dictionary'."
-  (interactive)
-  (paced-operate-on-current-dictionary
-   (paced-dictionary-edit dict)))
-
-
-
-;;; Print a Dictionary in a Dedicated Buffer
-
-(defvar-local paced-tabulated-list-dictionary nil
-  "Dictionary printed in a tabulated list buffer.")
-
-(cl-defmethod paced-dictionary-length-of-longest-word ((dict paced-dictionary))
-  "Return the length of the longest word in DICT."
-  (cond
-   ;; If DICT is empty, seq-max throws an error.
-   ((paced-dictionary-empty-p dict) 0)
-   (t
-    (seq-max
-     (map-apply
-      (lambda (key _value)
-        (length key))
-      (oref dict usage-hash))))))
-
-(cl-defmethod paced-dictionary-tabulated-list-entries ((dict paced-dictionary))
-  "Create a value for `tabulated-list-entries' from DICT."
-  (map-apply
-   (lambda (key value)
-     (list key (vector key (number-to-string value))))
-   (oref dict usage-hash)))
-
-(defun paced-tabulated-list-revert ()
-  "Revert a `tabulated-list-mode' buffer from its dictionary."
-  (let* ((dict paced-tabulated-list-dictionary)
-         (longest-length (paced-dictionary-length-of-longest-word dict)))
-    (setq tabulated-list-format
-          (vector `("Word" ,longest-length t . (:right-align t))
-                  `("Count" 10 t)))
-    (setq tabulated-list-entries (paced-dictionary-tabulated-list-entries 
dict))))
-
-(cl-defmethod paced-dictionary-print ((dict paced-dictionary))
-  "Print the contents of DICT in a dedicated buffer."
-  (let* ((buffer-name (format "*Paced Dictionary - %s*" (paced-dictionary-name 
dict)))
-         (buffer (get-buffer-create buffer-name)))
-    (with-current-buffer buffer
-      (tabulated-list-mode)
-      (setq paced-tabulated-list-dictionary dict)
-      (paced-tabulated-list-revert)
-      (tabulated-list-init-header)
-      (tabulated-list-print))
-    (display-buffer buffer)))
-
-(defun paced-print-current-dictionary ()
-  "Print the contents of the current dictionary in a dedicated buffer."
-  (interactive)
-  (paced-operate-on-current-dictionary
-   (paced-dictionary-print dict)))
-
-(defun paced-print-named-dictionary (name)
-  "Print the contents of the dictionary with name NAME."
-  (declare (interactive-only paced-dictionary-print))
-  (interactive (list (paced-read-dictionary)))
-  (paced-operate-on-named-dictionary name
-    (paced-dictionary-print dict)))
-
-
-
-(declare-function lm-report-bug "lisp-mnt" (topic))
-
-(defun paced-submit-bug-report (topic)
-  "Report a bug with topic TOPIC."
-  (interactive "sTopic: ")
-  (require 'lisp-mnt)
-  (let* ((src-file (locate-library "paced.el" t))
-         (src-buf-live (find-buffer-visiting src-file))
-         (src-buf (find-file-noselect src-file)))
-    (with-current-buffer src-buf
-      (lm-report-bug topic))
-    ;; Kill the buffer if it wasn't live
-    (unless src-buf-live
-      (kill-buffer src-buf))))
-
-(provide 'paced)
-
-;;; paced.el ends here
diff --git a/packages/paced/paced.info b/packages/paced/paced.info
deleted file mode 100644
index 17249d1..0000000
--- a/packages/paced/paced.info
+++ /dev/null
@@ -1,1029 +0,0 @@
-This is paced.info, produced by makeinfo version 6.5 from paced.texi.
-
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* Paced: (paced).       Predictive Abbreviation Completion and Expansion using 
Dictionaries.
-END-INFO-DIR-ENTRY
-
-
-File: paced.info,  Node: Top,  Next: Copying,  Up: (dir)
-
-Paced
-*****
-
-* Menu:
-
-* Copying::
-* Introduction::                 Brief Introduction to paced
-* Dictionaries::                 Paced’s bread and butter
-* Population Commands::          The good stuff
-* Example Setups::               Some examples
-* Contributing::                 I wanna help!
-* Changelog::                    List of changes by version
-
-— The Detailed Node Listing —
-
-Introduction
-
-* Similar Packages::             Packages with similar goals
-* Installation::                 How to install paced
-* Basic Setup::                  The simplest setup
-
-Similar Packages
-
-* pabbrev::
-* predictive::
-
-
-Dictionaries
-
-* Creating a Dictionary::        First steps
-* Editing a Dictionary::         How to edit your new dictionary
-* Selective Dictionaries::       Enabling certain dictionaries under certain 
conditions
-* Dictionary Files::             Loading and Saving the Dictionaries
-* Printing a Dictionary::        Seeing the contents of a dictionary
-
-Population Commands
-
-* Built-in Commands::            Basics
-* Properties::                   Tweaking the defaults
-* Custom Commands::              Defining new population commands
-* Asynchronous Population::      Populating without blocking
-
-Example Setups
-
-* Org Agenda Files::
-* Project Files::
-* Markdown Files::
-* Repopulating Dictionary After Saving::
-* Repopulating Dictionary After Spellchecking the Buffer::
-
-Contributing
-
-* Bugs::                         Submitting bug reports
-* Development::                  Helping with development
-* Documentation::                Improving the documentation
-* Working with EDE::             And all its quirks
-
-Changelog
-
-* 1.1.3: 113.
-* 1.1.2: 112.
-* 1.1.1: 111.
-* 1.1: 11.
-* 1.0.1: 101.
-* 1.0: 10.
-
-
-
-File: paced.info,  Node: Copying,  Next: Introduction,  Prev: Top,  Up: Top
-
-Copying
-*******
-
-Copyright (C) 2017-2018 Free Software Foundation, Inc.
-
-     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
-     <http://www.gnu.org/licenses/>.
-
-
-File: paced.info,  Node: Introduction,  Next: Dictionaries,  Prev: Copying,  
Up: Top
-
-Introduction
-************
-
-Paced (Predictive Abbreviation Completion and Expansion using
-Dictionaries) scans a group of files (determined by “population
-commands”) to construct a usage table (dictionary).  Words (or symbols)
-are sorted by their usage, and may be later presented to the user for
-completion.  A dictionary can then be saved to a file, to be loaded
-later.
-
-   Population commands determine how a dictionary should be filled with
-words or symbols.  A dictionary may have multiple population commands,
-and population may be performed asynchronously.  Once population is
-finished, the contents are sorted, with more commonly used words at the
-front.  Dictionaries may be edited through EIEIO’s customize-object
-interface.
-
-   Completion is done through ‘completion-at-point’.  The dictionary to
-use for completion can be customized.
-
-* Menu:
-
-* Similar Packages::             Packages with similar goals
-* Installation::                 How to install paced
-* Basic Setup::                  The simplest setup
-
-
-File: paced.info,  Node: Similar Packages,  Next: Installation,  Up: 
Introduction
-
-Similar Packages
-================
-
-There are a few Emacs packages that have similar goals to paced, and
-provided some of the inspiration and motivation behind it.
-
-* Menu:
-
-* pabbrev::
-* predictive::
-
-
-File: paced.info,  Node: pabbrev,  Next: predictive,  Up: Similar Packages
-
-pabbrev
--------
-
-The pabbrev (https://github.com/phillord/pabbrev) package by Phillip
-Lord automatically scans text of the current buffer while Emacs is idle
-and presents the user with the most common completions.
-
-   One of the major downsides to pabbrev is that the data it collects
-doesn’t persist between Emacs sessions.  For a few files that are always
-open, such as org agenda files, pabbrev works great.  If you want to
-train it from a few files that aren’t always open, you’ll have to open
-each file and retrain pabbrev from that file.  And you’ll have to do
-this every time you restart Emacs.
-
-   It keeps up-to-date usage and prefix hashes of all buffers of the
-same mode, and scanning, or “scavenging”, blends seamlessly into the
-background.  Completion is just a hash table lookup, so it can handle
-completion in microseconds.  There’s also no setup required; it will
-start working right away.  The downside to this is that dictionaries
-aren’t flexible; each dictionary corresponds to a major mode, and
-there’s no way to change that.
-
-
-File: paced.info,  Node: predictive,  Prev: pabbrev,  Up: Similar Packages
-
-predictive
-----------
-
-The predictive (https://www.dr-qubit.org/predictive.html) package by
-Toby Cubitt scans text of the current buffer on user command.  The usage
-data is stored in a dictionary, which can then be saved to a disk.
-Extensions are provided to ‘completion-at-point’, or predictive’s
-built-in frontend can be used.  It has a safety precaution where it only
-adds existing words to a dictionary, unless the user allows this.  This
-is to avoid adding typos to a dictionary.
-
-   Completion was also done intelligently, grouping commonly used words
-together and optionally suggesting shorter words before longer words.
-
-   While the frontend and backend are separate, the frontend is required
-to populate a dictionary.  There is no way to exclude part of the
-buffer’s text from dictionary population.  The safety precaution
-predictive has where it only adds a word to a dictionary if it already
-exists was tedious, since I didn’t need it to do that.
-
-
-File: paced.info,  Node: Installation,  Next: Basic Setup,  Prev: Similar 
Packages,  Up: Introduction
-
-Installation
-============
-
-*Requirements*
-
-Emacs   25.1
-async   1.9.1
-
-   Paced may be installed from source, or from GNU ELPA.
-
-   From ELPA:
-
-     M-x package-install RET paced RET
-
-   From Source:
-
-     bzr branch https://bzr.savannah.gnu.org/r/paced-el paced
-
-   After installing from source, add the following to your init file
-(typically .emacs):
-
-     (add-to-list 'load-path "/full/path/to/paced/")
-     (require 'paced)
-
-   However you install paced, you must also make sure dictionaries are
-loaded on startup:
-
-     (paced-load-all-dictionaries)
-
-
-File: paced.info,  Node: Basic Setup,  Prev: Installation,  Up: Introduction
-
-Basic Setup
-===========
-
-Paced needn’t have a lot of setup to run.  In fact, the simplest setup
-is as follows:
-
-  1. Create a new dictionary, “Default” (See *note Creating a
-     Dictionary::)
-  2. Set ‘paced-global-dictionary-enable-alist’ to ‘((t . "Default"))’
-     (See *note Selective Dictionaries::)
-  3. Run ‘M-x global-paced-mode’
-  4. To add a file to the dictionary, use ‘M-x
-     paced-add-buffer-file-to-dictionary’
-
-   This will create a default dictionary and populate it from buffers
-you specify.
-
-
-File: paced.info,  Node: Dictionaries,  Next: Population Commands,  Prev: 
Introduction,  Up: Top
-
-Dictionaries
-************
-
-* Menu:
-
-* Creating a Dictionary::        First steps
-* Editing a Dictionary::         How to edit your new dictionary
-* Selective Dictionaries::       Enabling certain dictionaries under certain 
conditions
-* Dictionary Files::             Loading and Saving the Dictionaries
-* Printing a Dictionary::        Seeing the contents of a dictionary
-
-
-File: paced.info,  Node: Creating a Dictionary,  Next: Editing a Dictionary,  
Up: Dictionaries
-
-Creating a Dictionary
-=====================
-
-Now that you’ve got paced installed, it’s time to create a new
-dictionary.
-
-     M-x paced-create-new-dictionary RET DICTIONARY_NAME RET DICTIONARY_FILE 
RET
-
-   Let’s explain those two arguments:
-
-   First, you’ve got DICTIONARY_NAME. This is a string that will be used
-to reference the new dictionary.  We recommend something short, like
-’new-dict’, ’my-dict’, ’writing’, etc.
-
-   Next is the file where the dictionary will be stored.  This is
-typically stored in ‘paced-dictionary-directory’, from which all
-dictionaries will be loaded with ‘paced-load-all-dictionaries’ (more on
-that later).  For now, it’s important to know that
-‘paced-load-all-dictionaries’ is the easiest way to load dictionaries
-when paced is loaded.
-
-   After you’ve run the above command, you will be taken to the
-customization buffer.  This is where you can set population commands.
-
-
-File: paced.info,  Node: Editing a Dictionary,  Next: Selective Dictionaries,  
Prev: Creating a Dictionary,  Up: Dictionaries
-
-Editing a Dictionary
-====================
-
-In order to edit a dictionary, paced provides
-‘paced-edit-named-dictionary’ and ‘paced-edit-current-dictionary’.
-
-   The edit buffer provides the options to change the population
-commands, case handling, dictionary storage name, and sort method.  Each
-of these is documented in the edit buffer.
-
-
-File: paced.info,  Node: Selective Dictionaries,  Next: Dictionary Files,  
Prev: Editing a Dictionary,  Up: Dictionaries
-
-Selective Dictionaries
-======================
-
-Paced provides a mechanism called the “enable list”, that allows a user
-to enable certain dictionaries for completion given certain conditions.
-
-   There are two enable lists: a global
-(‘paced-global-dictionary-enable-alist’) and local
-(‘paced-local-dictionary-enable-alist’) one.  They both work the same,
-with the local one taking precedence.  Each entry in the list has a
-condition and a key.
-
-   The conditions are one of the following:
-
-   • A mode name, such as ‘org-mode’ or ‘text-mode’, indicating that the
-     named dictionary should be active in any mode derived from that
-     mode.
-
-   • A symbol, in which case the named dictionary is active whenever the
-     value of that symbol is non-nil.  This includes the symbol ‘t’.
-
-   • A function symbol, in which case the function is called with no
-     arguments to determine if the given dictionary should be enabled.
-     If the function returns non-nil the dictionary is enabled.
-
-   • A lambda function, in which case it is called with no arguments,
-     and if it returns non-nil, the dictionary is enabled.
-
-   • The form (or CONDITION1 CONDITION2 ...), which enables the given
-     dictionary if any of the conditions are met.
-
-   • The form (and CONDITION1 CONDITION2 ...), which enables the given
-     dictionary if all of the conditions are met.
-
-   Remember that paced-mode must be active for completion to occur.
-Neither list will activate it, just determine which dictionary is
-active.
-
-   The key is the dictionary name you set during dictionary creation.
-
-
-File: paced.info,  Node: Dictionary Files,  Next: Printing a Dictionary,  
Prev: Selective Dictionaries,  Up: Dictionaries
-
-Dictionary Files
-================
-
-Paced provides ‘paced-load-all-dictionaries’ to load all dictionaries in
-‘paced-dictionary-directory’.  Paced determines which dictionaries to
-load based on two variables:
-‘paced-dictionary-directory-whitelist-regexp’ and
-‘paced-dictionary-directory-blacklist-regexp’.  Paced can also be told
-to search recursively by setting
-‘paced-load-all-dictionaries-recursively’ to t.  All four of these
-variables may be set using Emacs’s customization interface.
-
-   An individual dictionary file may also be loaded:
-
-     M-x paced-load-dictionary-from-file RET /path/to/file RET
-
-   Once a file has been modified, it may then be saved:
-
-     M-x paced-save-named-dictionary RET dictionary name RET
-
-   Or, all dictionaries may be saved:
-
-     M-x paced-save-all-dictionaries RET
-
-   Dictionaries may also be automatically saved whenever changed by
-setting ‘paced-repopulate-saves-dictionary’ to t.  Population is covered
-in the next section.
-
-
-File: paced.info,  Node: Printing a Dictionary,  Prev: Dictionary Files,  Up: 
Dictionaries
-
-Printing a Dictionary
-=====================
-
-Paced allows a user to print the contents of a dictionary to a buffer.
-Uses for this might be to tweak population commands or exclude
-functions, or to simply make sure a dictionary is populating correctly.
-
-   To use this feature, run:
-
-     M-x paced-print-named-dictionary RET NAME-OF-DICTIONARY RET
-
-   Or for the current dictionary:
-
-     M-x paced-print-current-dictionary RET
-
-
-File: paced.info,  Node: Population Commands,  Next: Example Setups,  Prev: 
Dictionaries,  Up: Top
-
-Population Commands
-*******************
-
-Part of the beauty of paced is the ease of reconstructing a dictionary.
-When you’ve got a bunch of files from which you want to populate your
-dictionary, it’d be a pain to go to each of them and say “populate from
-this one, next, populate from this one, next”.
-
-   Instead, paced provides population commands.  Each dictionary has one
-or more population commands it uses to recreate its contents, run in
-order during population.
-
-   In order to trigger population, run the following:
-
-     M-x paced-repopulate-named-dictionary RET DICTIONARY-NAME RET
-
-* Menu:
-
-* Built-in Commands::            Basics
-* Properties::                   Tweaking the defaults
-* Custom Commands::              Defining new population commands
-* Asynchronous Population::      Populating without blocking
-
-
-File: paced.info,  Node: Built-in Commands,  Next: Properties,  Up: Population 
Commands
-
-Built-in Commands
-=================
-
-There are five built-in population commands:
-
-file
-     Populates a dictionary from all words in a given file
-buffer
-     Populates a dictionary from all words in a given buffer, which must
-     exist during population
-file-function
-     Like the file command, but allows a custom setup function.  This
-     function is called with no arguments in a temporary buffer
-     containing the file’s contents, and must return non-nil if
-     population may continue.
-directory-regexp
-     Populates from all files in a directory that match the given
-     regexp.  Also optionally allows recursion.
-file-list
-     Populates from all files returned by a generator function.
-
-
-File: paced.info,  Node: Properties,  Next: Custom Commands,  Prev: Built-in 
Commands,  Up: Population Commands
-
-Properties
-==========
-
-When setting the population commands of a dictionary, one may also set
-certain properties.  Each property is a variable binding, bound while
-the population command runs.
-
-   A few variables are of note here:
-
-paced-exclude-function
-     Function of no arguments that returns non-nil if the thing at point
-     should be excluded from population.
-paced-thing-at-point-constituent
-     Symbol defining thing on which population works.  Typically set to
-     either ’symbol or ’word.
-paced-character-limit
-     Maximum length of a thing to include it in a dictionary.  If set to
-     0 (default), no limit is imposed.
-
-   For convenience, properties that are intended for all population
-commands of a given dictionary may be set in the dictionary itself.  In
-the event of a conflict, population command properties take precedence
-over dictionary properties.
-
-
-File: paced.info,  Node: Custom Commands,  Next: Asynchronous Population,  
Prev: Properties,  Up: Population Commands
-
-Custom Commands
-===============
-
-Since the population commands all derive from paced-population-command,
-it’s possible to add additional commands.
-
-   As an example, let’s make a population command that populates a
-dictionary from a file like so:
-
-     alpha 5
-     beta 7
-     gamma 21
-     delta 54
-     epsilon 2
-
-   We want to make a population command that takes a file like this,
-with word in one column and weight in the other, and add it to a
-dictionary.
-
-   There are two ways to approach this, but we’re going to start with
-the basic one.
-
-   We need to define two functions: paced-population-command-source-list
-and paced-population-command-setup-buffer.  The first returns a list of
-sources from which to populate, and the second sets up a temporary
-buffer based on those sources.
-
-   For our command, we want to return the specified file, and replicate
-each word by the amount given.
-
-   Inheriting from ‘paced-file-population-command’ gives us the source
-list and file slot for free.
-
-     (defclass paced-weight-file-population-command 
(paced-file-population-command))
-
-   Now, we need to set up the buffer to replicate the words.
-
-     (cl-defmethod paced-population-command-setup-buffer ((cmd 
paced-weight-file-population-command) source)
-       ;; Use the built-in `paced--insert-file-contents' to insert contents.
-       (paced--insert-file-contents source)
-       ;; Jump to the start of the buffer
-       (goto-char (point-min))
-       ;; Search for lines with the form WORD WEIGHT
-       (while (re-search-forward (rx line-start ;; Start of line
-                                     (submatch (one-or-more (not (syntax 
whitespace)))) ;; Our word
-                                     (syntax whitespace) ;; Space between word 
and weight
-                                     (submatch (one-or-more (any digit))) ;; 
Weight
-                                     line-end) ;; End of line
-                                 nil t)
-         (let* ((word (match-string 1))
-                (weight (string-to-number (match-string 2)))
-                ;; Repeat WORD WEIGHT times
-                (new-text (string-join (make-list weight word) " ")))
-           ;; Replace the matched text with our repeated word
-           (replace-match new-text))))
-
-   That’s all there is to it.  When you go to edit a dictionary, the
-“weight-file” population command will automatically be added as an
-option for a population command.
-
-   The even easier way to do this would’ve been to use
-‘paced-file-function-population-command’, but it doesn’t make for a good
-example in this case.
-
-
-File: paced.info,  Node: Asynchronous Population,  Prev: Custom Commands,  Up: 
Population Commands
-
-Asynchronous Population
-=======================
-
-A common problem is that population can take a long time.  Some of us
-populate dictionaries from org agenda files, which can get pretty big.
-
-   To solve this, paced uses the async
-(https://github.com/jwiegley/emacs-async) package.  Setup is seamless;
-just stick whatever code you need in ‘~/.emacs.d/paced-async.el’, and
-use one of the two population commands:
-
-   A named dictionary:
-
-     M-x paced-repopulate-named-dictionary-async RET NAME RET
-
-   Or the current dictionary:
-
-     M-x paced-repopulate-current-dictionary-async RET
-
-   A few things to note about this:
-
-  1. Dictionaries will be automatically saved by this method after
-     population
-  2. Asynchronous population doesn’t change anything until after
-     population is finished, so a user may continue to use their
-     dictionary while population is happening.  This also means that
-     multiple populations may run in parallel without interfering with
-     one another.
-  3. Because async runs population in a separate Emacs process, any
-     custom code required for population must be in paced-async.el.
-     This includes additional population command types, but doesn’t
-     include the following variables:
-
-        • load-path
-        • paced-thing-at-point-constituent
-        • paced-async-load-file
-
-
-File: paced.info,  Node: Example Setups,  Next: Contributing,  Prev: 
Population Commands,  Up: Top
-
-Example Setups
-**************
-
-* Menu:
-
-* Org Agenda Files::
-* Project Files::
-* Markdown Files::
-* Repopulating Dictionary After Saving::
-* Repopulating Dictionary After Spellchecking the Buffer::
-
-
-File: paced.info,  Node: Org Agenda Files,  Next: Project Files,  Up: Example 
Setups
-
-Org Agenda Files
-================
-
-As some of us record everything about our lives in our agenda files, it
-might be helpful to have a dictionary tuned to ourselves.
-
-   We use a file-list command that returns the agenda files, and an
-exclude command to block out all of Org’s extra features such as source
-code and drawers.
-
-   The generator for file-list is easy:
-
-     org-agenda-files
-
-   Done.
-
-   Now, the exclude command, which sits inside the properties option.
-This can be added to ‘paced-async.el’:
-
-     (require 'org)
-
-     (defun org-at-tag-p ()
-       (let* ((p (point)))
-         ;; Ignore errors from `org-get-tags-string'.
-         (ignore-errors
-           ;; Checks the match string for a tag heading, setting match-string 
1 to the
-           ;; tags.  Also sets match-beginning and match-end.
-           (org-get-tags-string)
-           (when (match-string 1)
-             (<= (match-beginning 1) p (match-end 1))))))
-
-     (defun org-at-keyword-p ()
-       "Return non-nil if point is at a keyword such as #+TITLE."
-       (save-excursion
-         (beginning-of-line)
-         (looking-at-p "^#\\+")))
-
-     (defun org-at-heading-prefix-p ()
-       "Return non-nil if looking at the leading stars of a heading."
-       (looking-at outline-regexp))
-
-     (defun org-at-hline-p ()
-       (save-excursion
-         (beginning-of-line)
-         (looking-at-p "^-----")))
-
-     (defun org-paced-exclude ()
-       (or
-        ;; Drawers
-        (org-between-regexps-p org-drawer-regexp ":END:") ;; Doesn't catch END
-        (org-in-regexp ":END:") ;; but this does
-
-        (org-at-tag-p) ;; tags
-        (org-at-keyword-p) ;; Keywords, such as #+TITLE
-        (org-at-heading-prefix-p) ;; Leading stars of a heading
-        (org-at-item-bullet-p) ;; Item Bullets
-        (org-at-timestamp-p) ;; Timestamps
-        (looking-at-p org-todo-regexp) ;; TODO keywords
-        (org-at-hline-p) ;; H-lines
-
-        (org-at-comment-p) ;; comments
-        (org-in-regexp org-any-link-re) ;; links
-        (org-in-block-p '("src" "quote" "verse")) ;; blocks
-        (org-at-planning-p) ;; deadline, etc.
-        (org-at-table-p) ;; tables
-        ))
-
-   As explained earlier, this can be put inside properties in the
-customize buffer as such:
-
-     Properties :
-     [INS] [DEL] Variable: paced-exclude-function
-     Lisp expression: 'org-paced-exclude
-
-   And you’re done.  See how easy that was?
-
-
-File: paced.info,  Node: Project Files,  Next: Markdown Files,  Prev: Org 
Agenda Files,  Up: Example Setups
-
-Project Files
-=============
-
-Now we get to the interesting one.  There are tons of ways to collect
-project files in Emacs, so we’re going to stick with one for now, being
-Emacs’s built-in VC package.
-
-     (defun vc-paced-find-project-files (path-to-project-root)
-       "Use VC to collect all version-controlled files."
-       (let ((file-list))
-         (vc-file-tree-walk path-to-project-root (lambda (f) (push f 
file-list)))
-         file-list))
-
-   We’d then need to use the following for our file-list generator:
-
-     Generator : (lambda nil (vc-paced-find-project-files 
"/home/me/programming/paced"))
-
-   Now, we (probably) don’t want commented code to get in our way, so
-we’ll use a small function for excluding those:
-
-     (defun paced-at-comment-p ()
-       (nth 8 (syntax-ppss)))
-
-   Use that for paced-exclude-function, and you’re done.  We can’t
-necessarily recommend this for any programming language, as there are
-dedicated solutions for almost everything, but it makes an excellent
-fallback.
-
-
-File: paced.info,  Node: Markdown Files,  Next: Repopulating Dictionary After 
Saving,  Prev: Project Files,  Up: Example Setups
-
-Markdown Files
-==============
-
-Another common request is markdown files.  In order for this to work,
-you’ll need to install ‘markdown-mode’:
-
-     M-x package-install RET markdown-mode RET
-
-   After that, add the following to your ‘paced-async.el’ file:
-
-     (require 'markdown-mode)
-
-     (defun paced-markdown-exclude-p ()
-       "Taken from `markdown-flyspell-check-word-p'."
-       ;; Exclude anything markdown mode thinks flyspell should skip.
-       (or
-        ;; Ignore code blocks
-        (markdown-code-block-at-point-p)
-        (markdown-inline-code-at-point-p)
-        ;; Ignore comments
-        (markdown-in-comment-p)
-        ;; Ignore special text
-        (let ((faces (get-text-property (point) 'face)))
-          (if (listp faces)
-              (or (memq 'markdown-reference-face faces)
-                  (memq 'markdown-markup-face faces)
-                  (memq 'markdown-plain-url-face faces)
-                  (memq 'markdown-inline-code-face faces)
-                  (memq 'markdown-url-face faces))
-            (memq faces '(markdown-reference-face
-                          markdown-markup-face
-                          markdown-plain-url-face
-                          markdown-inline-code-face
-                          markdown-url-face))))))
-
-   That excludes anything that the developers of markdown-mode felt
-should be excluded from flyspell.
-
-   Set this as your exclude function in your dictionary’s settings, then
-add each markdown file by hand.
-
-
-File: paced.info,  Node: Repopulating Dictionary After Saving,  Next: 
Repopulating Dictionary After Spellchecking the Buffer,  Prev: Markdown Files,  
Up: Example Setups
-
-Repopulating Dictionary After Saving
-====================================
-
-This is a common request, although with the power of async, it’s an easy
-one to fulfill.  This will repopulate the current buffer’s dictionary
-every time you save a file with a dictionary.  This may seem daunting,
-but the dictionary will remain usable during population, and multiple
-populations won’t interfere with one another.
-
-     ;; Repopulate the current dictionary after saving
-     (add-hook 'after-save-hook 'paced-repopulate-current-dictionary-async)
-
-   Add that to your .emacs file, and paced will take it from there.
-
-   If you decide that’s too much, do the following:
-
-     M-: (remove-hook 'after-save-hook 
'paced-repopulate-current-dictionary-async) RET
-
-
-File: paced.info,  Node: Repopulating Dictionary After Spellchecking the 
Buffer,  Prev: Repopulating Dictionary After Saving,  Up: Example Setups
-
-Repopulating Dictionary After Spellchecking the Buffer
-======================================================
-
-Another request, although much trickier to do.  This one involves using
-Emacs’s advice mechanism:
-
-     (define-advice ispell-pdict-save (:after (&optional _no-query 
_force-save) paced-populate)
-       ;; Repopulate the current dictionary after running spell check
-       (paced-repopulate-current-dictionary-async))
-
-   If you decide this isn’t for you, do the following to revert the
-changes:
-
-     M-: (advice-remove #'ispell-pdict-save 
#'ispell-pdict-save@paced-populate) RET
-
-
-File: paced.info,  Node: Contributing,  Next: Changelog,  Prev: Example 
Setups,  Up: Top
-
-Contributing
-************
-
-We are all happy for any help you may provide.
-
-   First, check out the source code on Savannah:
-<https://savannah.nongnu.org/projects/paced-el>
-
-     bzr branch https://bzr.savannah.gnu.org/r/paced-el/ paced
-
-   Build the Makefile with EDE:
-
-  1. Open any file from paced (See *note Working with EDE:: if you
-     encounter “Corrupt object on disk” error)
-  2. Run ‘C-c . C’ or ‘M-x ede-compile-project’
-
-* Menu:
-
-* Bugs::                         Submitting bug reports
-* Development::                  Helping with development
-* Documentation::                Improving the documentation
-* Working with EDE::             And all its quirks
-
-
-File: paced.info,  Node: Bugs,  Next: Development,  Up: Contributing
-
-Bugs
-====
-
-There are two ways to submit bug reports:
-
-  1. Using the bug tracker at Savannah
-  2. Sending an email using ‘paced-submit-bug-report’
-
-   When submitting a bug report, be sure to include a description of the
-dictionary or population command that caused the problem, with as much
-detail as possible.
-
-
-File: paced.info,  Node: Development,  Next: Documentation,  Prev: Bugs,  Up: 
Contributing
-
-Development
-===========
-
-If you’re new to bazaar, we recommend using Emacs’s built-in VC package.
-It eases the overhead of dealing with a brand new VCS with a few
-standard commands.  For more information, see the info page on it (In
-Emacs, this is C-h r m Introduction to VC RET).
-
-   To contribute with bazaar, you can do the following:
-
-     # Hack away and make your changes
-     $ bzr commit -m "Changes I've made"
-     $ bzr send -o file-name.txt
-
-   Then, use ‘paced-submit-bug-report’ and attach “file-name.txt”.  We
-can then merge that into the main development branch.
-
-   There are a few rules to follow:
-
-   • New population commands should be named
-     paced-POPULATION-COMMAND-TYPE-population-command
-   • Run ’make check’ to verify that your mods don’t break anything
-   • Avoid additional or altered dependencies if at all possible
-   • Dictionary commands come in threes (“the operation triad”):
-       1. paced-dictionary-OPERATION, a cl-defmethod which performs
-          OPERATION on a dictionary
-       2. paced-OPERATION-on-named-dictionary, an interactive only
-          function that prompts for a dictionary name and performs
-          OPERATION on that dictionary:
-                    (interactive (list (paced-read-dictionary)))
-                    (paced-ensure-registered name)
-                    (paced-dictionary-OPERATION (paced-named-dictionary name))
-       3. paced-OPERATION-on-current-dictionary, an interactive function
-          that performs OPERATION on the current dictionary
-                    (interactive)
-                    (paced-dictionary-OPERATION 
(paced-current-dictionary-or-die))
-
-
-File: paced.info,  Node: Documentation,  Next: Working with EDE,  Prev: 
Development,  Up: Contributing
-
-Documentation
-=============
-
-Documentation is always helpful to us.  Please be sure to do the
-following after making any changes:
-
-  1. Update the info page in the repository with ‘C-c C-e i i’
-  2. If you’re updating the HTML documentation, switch to a theme that
-     can easily be read on a white background; we recommend the
-     “adwaita” theme
-
-
-File: paced.info,  Node: Working with EDE,  Prev: Documentation,  Up: 
Contributing
-
-Working with EDE
-================
-
-EDE can be a little finicky at times, but we feel the benefits, namely
-package dependency handling and Makefile generation, outweigh the costs.
-
-   One of the issues that many will likely encounter is the error
-“Corrupt file on disk”.  This is most often due to EDE not loading all
-its subprojects as needed.  If you find yourself dealing with this error
-often, place the following in your .emacs file:
-
-     ;; Target types needed for working with paced
-     (require 'ede/proj-elisp)
-     (require 'ede/proj-aux)
-     (require 'ede/proj-misc)
-
-   These are the three target types that paced uses: elisp for
-compilation and autoloads; aux for auxiliary files such as
-documentation; and misc for tests.
-
-   When creating a new file, EDE will ask if you want to add it to a
-target.  Consult with one of the paced devs for guidance, but usually
-selecting “none” and letting one of us handle it is a good way to go.
-
-
-File: paced.info,  Node: Changelog,  Prev: Contributing,  Up: Top
-
-Changelog
-*********
-
-* Menu:
-
-* 1.1.3: 113.
-* 1.1.2: 112.
-* 1.1.1: 111.
-* 1.1: 11.
-* 1.0.1: 101.
-* 1.0: 10.
-
-
-File: paced.info,  Node: 113,  Next: 112,  Up: Changelog
-
-1.1.3
-=====
-
-   • Fixed bug with printing an empty dictionary
-   • Fixed bug with paced crashing on non-existent thing at point
-
-
-File: paced.info,  Node: 112,  Next: 111,  Prev: 113,  Up: Changelog
-
-1.1.2
-=====
-
-   • Fixed bug with printing dictionaries
-
-
-File: paced.info,  Node: 111,  Next: 11,  Prev: 112,  Up: Changelog
-
-1.1.1
-=====
-
-   • Fixed bug with asynchronous population throwing an error on no
-     dictionary
-
-   • Set ‘paced-throw-error-on-no-current’ to nil by default
-
-
-File: paced.info,  Node: 11,  Next: 101,  Prev: 111,  Up: Changelog
-
-1.1
-===
-
-   • Cleaned up the code to reflect the “operation triad”
-        • -OP, OP-on-named, OP-on-current
-        • Retained backwards compatibility by obsoleting a bunch of
-          functions, but didn’t remove any of them
-        • Also removed the use of dict- in global variables and
-          functions
-
-   • Added the ability to print the contents of a dictionary in a
-     separate buffer
-
-   • Added the option to limit the words added during population by size
-
-   • Various documentation improvements
-
-
-File: paced.info,  Node: 101,  Next: 10,  Prev: 11,  Up: Changelog
-
-1.0.1
-=====
-
-Bug fix release
-   • Save dictionaries right after they’re created
-   • Added “force” parameter to save functions
-
-
-File: paced.info,  Node: 10,  Prev: 101,  Up: Changelog
-
-1.0
-===
-
-Initial release.
-
-
-
-Tag Table:
-Node: Top228
-Node: Copying2013
-Node: Introduction2832
-Node: Similar Packages3952
-Node: pabbrev4238
-Node: predictive5381
-Node: Installation6429
-Node: Basic Setup7091
-Node: Dictionaries7706
-Node: Creating a Dictionary8179
-Node: Editing a Dictionary9219
-Node: Selective Dictionaries9695
-Node: Dictionary Files11433
-Node: Printing a Dictionary12554
-Node: Population Commands13076
-Node: Built-in Commands14012
-Node: Properties14809
-Node: Custom Commands15807
-Node: Asynchronous Population18534
-Node: Example Setups19983
-Node: Org Agenda Files20284
-Node: Project Files22782
-Node: Markdown Files23918
-Node: Repopulating Dictionary After Saving25543
-Node: Repopulating Dictionary After Spellchecking the Buffer26471
-Node: Contributing27216
-Node: Bugs27990
-Node: Development28379
-Node: Documentation30140
-Node: Working with EDE30607
-Node: Changelog31650
-Node: 11331828
-Node: 11232021
-Node: 11132151
-Node: 1132390
-Node: 10132997
-Node: 1033205
-
-End Tag Table
-
-
-Local Variables:
-coding: utf-8
-End:
diff --git a/packages/paced/paced.org b/packages/paced/paced.org
deleted file mode 100644
index 3ce0f44..0000000
--- a/packages/paced/paced.org
+++ /dev/null
@@ -1,783 +0,0 @@
-#+TITLE: Paced
-#+AUTHOR: Ian Dunn
-#+EMAIL: dunni@gnu.org
-#+DATE: {{{modification-time}}}
-
-#+STARTUP: overview
-#+STARTUP: indent
-#+TODO: FIXME | FIXED
-#+OPTIONS: toc:2 num:nil timestamp:nil \n:nil |:t ':t email:t
-#+OPTIONS: *:t <:t d:nil todo:nil pri:nil tags:not-in-toc
-
-#+TEXINFO_DIR_CATEGORY: Emacs
-#+TEXINFO_DIR_TITLE: Paced: (paced)
-#+TEXINFO_DIR_DESC: Predictive Abbreviation Completion and Expansion using 
Dictionaries
-
-* Copying
-Copyright (C) 2017-2018 Free Software Foundation, Inc.
-
-#+BEGIN_QUOTE
-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 <http://www.gnu.org/licenses/>.
-#+END_QUOTE
-* Introduction
-:PROPERTIES:
-:DESCRIPTION: Brief Introduction to paced
-:END:
-Paced (Predictive Abbreviation Completion and Expansion using Dictionaries)
-scans a group of files (determined by "population commands") to construct a
-usage table (dictionary).  Words (or symbols) are sorted by their usage, and 
may
-be later presented to the user for completion.  A dictionary can then be saved
-to a file, to be loaded later.
-
-Population commands determine how a dictionary should be filled with words or
-symbols.  A dictionary may have multiple population commands, and population 
may
-be performed asynchronously.  Once population is finished, the contents are
-sorted, with more commonly used words at the front.  Dictionaries may be edited
-through EIEIO's customize-object interface.
-
-Completion is done through ~completion-at-point~.  The dictionary to use for
-completion can be customized.
-
-** Similar Packages
-:PROPERTIES:
-:DESCRIPTION: Packages with similar goals
-:END:
-There are a few Emacs packages that have similar goals to paced, and provided
-some of the inspiration and motivation behind it.
-*** pabbrev
-The [[https://github.com/phillord/pabbrev][pabbrev]] package by Phillip Lord 
automatically scans text of the current
-buffer while Emacs is idle and presents the user with the most common
-completions.
-
-One of the major downsides to pabbrev is that the data it collects doesn't
-persist between Emacs sessions.  For a few files that are always open, such as
-org agenda files, pabbrev works great.  If you want to train it from a few 
files
-that aren't always open, you'll have to open each file and retrain pabbrev from
-that file.  And you'll have to do this every time you restart Emacs.
-
-It keeps up-to-date usage and prefix hashes of all buffers of the same mode, 
and
-scanning, or "scavenging", blends seamlessly into the background.  Completion 
is
-just a hash table lookup, so it can handle completion in microseconds.  There's
-also no setup required; it will start working right away.  The downside to this
-is that dictionaries aren't flexible; each dictionary corresponds to a major
-mode, and there's no way to change that.
-*** predictive
-The [[https://www.dr-qubit.org/predictive.html][predictive]] package by Toby 
Cubitt scans text of the current buffer on user
-command.  The usage data is stored in a dictionary, which can then be saved to 
a
-disk.  Extensions are provided to ~completion-at-point~, or predictive's 
built-in
-frontend can be used.  It has a safety precaution where it only adds existing
-words to a dictionary, unless the user allows this.  This is to avoid adding
-typos to a dictionary.
-
-Completion was also done intelligently, grouping commonly used words together
-and optionally suggesting shorter words before longer words.
-
-While the frontend and backend are separate, the frontend is required to
-populate a dictionary.  There is no way to exclude part of the buffer's text
-from dictionary population.  The safety precaution predictive has where it only
-adds a word to a dictionary if it already exists was tedious, since I didn't
-need it to do that.
-** Installation
-:PROPERTIES:
-:DESCRIPTION: How to install paced
-:END:
-
-*Requirements*
-
-| Emacs |  25.1 |
-| async | 1.9.1 |
-
-Paced may be installed from source, or from GNU ELPA.
-
-From ELPA:
-
-#+begin_example
-M-x package-install RET paced RET
-#+end_example
-
-From Source:
-
-#+begin_src shell
-bzr branch https://bzr.savannah.gnu.org/r/paced-el paced
-#+end_src
-
-After installing from source, add the following to your init file (typically 
.emacs):
-
-#+BEGIN_SRC emacs-lisp
-(add-to-list 'load-path "/full/path/to/paced/")
-(require 'paced)
-#+END_SRC
-
-However you install paced, you must also make sure dictionaries are loaded on
-startup:
-
-#+begin_src emacs-lisp
-(paced-load-all-dictionaries)
-#+end_src
-
-** Basic Setup
-:PROPERTIES:
-:DESCRIPTION: The simplest setup
-:END:
-
-Paced needn't have a lot of setup to run.  In fact, the simplest setup is as
-follows:
-
-1. Create a new dictionary, "Default" (See [[#dictionary_creation][Creating a 
Dictionary]])
-2. Set ~paced-global-dictionary-enable-alist~ to ~((t . "Default"))~ (See 
[[#selective_dictionaries][Selective Dictionaries]])
-3. Run ~M-x global-paced-mode~
-4. To add a file to the dictionary, use ~M-x 
paced-add-buffer-file-to-dictionary~
-
-This will create a default dictionary and populate it from buffers you specify.
-
-* Dictionaries
-:PROPERTIES:
-:DESCRIPTION: Paced's bread and butter
-:END:
-** Creating a Dictionary
-:PROPERTIES:
-:DESCRIPTION: First steps
-:CUSTOM_ID: dictionary_creation
-:END:
-
-Now that you've got paced installed, it's time to create a new dictionary.
-
-#+begin_example
-M-x paced-create-new-dictionary RET DICTIONARY_NAME RET DICTIONARY_FILE RET
-#+end_example
-
-Let's explain those two arguments:
-
-First, you've got DICTIONARY_NAME.  This is a string that will be used to
-reference the new dictionary.  We recommend something short, like 'new-dict',
-'my-dict', 'writing', etc.
-
-Next is the file where the dictionary will be stored.  This is typically stored
-in ~paced-dictionary-directory~, from which all dictionaries will be loaded 
with
-~paced-load-all-dictionaries~ (more on that later).  For now, it's important to
-know that ~paced-load-all-dictionaries~ is the easiest way to load dictionaries
-when paced is loaded.
-
-After you've run the above command, you will be taken to the customization
-buffer.  This is where you can set population commands.
-** Editing a Dictionary
-:PROPERTIES:
-:DESCRIPTION: How to edit your new dictionary
-:END:
-In order to edit a dictionary, paced provides ~paced-edit-named-dictionary~ and
-~paced-edit-current-dictionary~.
-
-The edit buffer provides the options to change the population commands, case
-handling, dictionary storage name, and sort method.  Each of these is
-documented in the edit buffer.
-** Selective Dictionaries
-:PROPERTIES:
-:DESCRIPTION: Enabling certain dictionaries under certain conditions
-:CUSTOM_ID: selective_dictionaries
-:END:
-
-Paced provides a mechanism called the "enable list", that allows a user to
-enable certain dictionaries for completion given certain conditions.
-
-There are two enable lists: a global (~paced-global-dictionary-enable-alist~)
-and local (~paced-local-dictionary-enable-alist~) one.  They both work the 
same,
-with the local one taking precedence.  Each entry in the list has a condition
-and a key.
-
-The conditions are one of the following:
-
-- A mode name, such as ~org-mode~ or ~text-mode~, indicating that the named
-  dictionary should be active in any mode derived from that mode.
-
-- A symbol, in which case the named dictionary is active whenever the value of
-  that symbol is non-nil.  This includes the symbol ~t~.
-
-- A function symbol, in which case the function is called with no arguments to
-  determine if the given dictionary should be enabled.  If the function returns
-  non-nil the dictionary is enabled.
-
-- A lambda function, in which case it is called with no arguments, and if it
-  returns non-nil, the dictionary is enabled.
-
-- The form (or CONDITION1 CONDITION2 ...), which enables the given dictionary 
if
-  any of the conditions are met.
-
-- The form (and CONDITION1 CONDITION2 ...), which enables the given dictionary
-  if all of the conditions are met.
-
-Remember that paced-mode must be active for completion to occur.  Neither list
-will activate it, just determine which dictionary is active.
-
-The key is the dictionary name you set during dictionary creation.
-** Dictionary Files
-:PROPERTIES:
-:DESCRIPTION: Loading and Saving the Dictionaries
-:END:
-
-Paced provides ~paced-load-all-dictionaries~ to load all dictionaries in
-~paced-dictionary-directory~.  Paced determines which dictionaries to load 
based
-on two variables: ~paced-dictionary-directory-whitelist-regexp~ and
-~paced-dictionary-directory-blacklist-regexp~.  Paced can also be told to 
search
-recursively by setting ~paced-load-all-dictionaries-recursively~ to t.  All 
four
-of these variables may be set using Emacs's customization interface.
-
-An individual dictionary file may also be loaded:
-
-#+begin_example
-M-x paced-load-dictionary-from-file RET /path/to/file RET
-#+end_example
-
-Once a file has been modified, it may then be saved:
-
-#+begin_example
-M-x paced-save-named-dictionary RET dictionary name RET
-#+end_example
-
-Or, all dictionaries may be saved:
-
-#+begin_example
-M-x paced-save-all-dictionaries RET
-#+end_example
-
-Dictionaries may also be automatically saved whenever changed by setting
-~paced-repopulate-saves-dictionary~ to t.  Population is covered in the next
-section.
-** Printing a Dictionary
-:PROPERTIES:
-:DESCRIPTION: Seeing the contents of a dictionary
-:END:
-
-Paced allows a user to print the contents of a dictionary to a buffer.  Uses 
for
-this might be to tweak population commands or exclude functions, or to simply
-make sure a dictionary is populating correctly.
-
-To use this feature, run:
-
-#+begin_example
-M-x paced-print-named-dictionary RET NAME-OF-DICTIONARY RET
-#+end_example
-
-Or for the current dictionary:
-
-#+begin_example
-M-x paced-print-current-dictionary RET
-#+end_example
-
-* Population Commands
-:PROPERTIES:
-:DESCRIPTION: The good stuff
-:END:
-
-Part of the beauty of paced is the ease of reconstructing a dictionary.  When
-you've got a bunch of files from which you want to populate your dictionary,
-it'd be a pain to go to each of them and say "populate from this one, next,
-populate from this one, next".
-
-Instead, paced provides population commands.  Each dictionary has one or more
-population commands it uses to recreate its contents, run in order during
-population.
-
-In order to trigger population, run the following:
-
-#+begin_example
-M-x paced-repopulate-named-dictionary RET DICTIONARY-NAME RET
-#+end_example
-
-** Built-in Commands
-:PROPERTIES:
-:DESCRIPTION: Basics
-:END:
-
-There are five built-in population commands:
-
-- file :: Populates a dictionary from all words in a given file
-- buffer :: Populates a dictionary from all words in a given buffer, which must
-            exist during population
-- file-function :: Like the file command, but allows a custom setup function.
-                   This function is called with no arguments in a temporary
-                   buffer containing the file's contents, and must return
-                   non-nil if population may continue.
-- directory-regexp :: Populates from all files in a directory that match the
-     given regexp.  Also optionally allows recursion.
-- file-list :: Populates from all files returned by a generator function.
-
-** Properties
-:PROPERTIES:
-:DESCRIPTION: Tweaking the defaults
-:END:
-
-When setting the population commands of a dictionary, one may also set certain
-properties.  Each property is a variable binding, bound while the population
-command runs.
-
-A few variables are of note here:
-
-- paced-exclude-function :: Function of no arguments that returns non-nil if 
the
-     thing at point should be excluded from population.
-- paced-thing-at-point-constituent :: Symbol defining thing on which population
-     works.  Typically set to either 'symbol or 'word.
-- paced-character-limit :: Maximum length of a thing to include it in a
-     dictionary.  If set to 0 (default), no limit is imposed.
-
-For convenience, properties that are intended for all population commands of a
-given dictionary may be set in the dictionary itself.  In the event of a
-conflict, population command properties take precedence over dictionary
-properties.
-
-** Custom Commands
-:PROPERTIES:
-:DESCRIPTION: Defining new population commands
-:END:
-Since the population commands all derive from paced-population-command, it's
-possible to add additional commands.
-
-As an example, let's make a population command that populates a dictionary from
-a file like so:
-
-#+begin_example
-alpha 5
-beta 7
-gamma 21
-delta 54
-epsilon 2
-#+end_example
-
-We want to make a population command that takes a file like this, with word in
-one column and weight in the other, and add it to a dictionary.
-
-There are two ways to approach this, but we're going to start with the basic 
one.
-
-We need to define two functions: paced-population-command-source-list and
-paced-population-command-setup-buffer.  The first returns a list of sources 
from
-which to populate, and the second sets up a temporary buffer based on those
-sources.
-
-For our command, we want to return the specified file, and replicate each word
-by the amount given.
-
-Inheriting from ~paced-file-population-command~ gives us the source list and 
file
-slot for free.
-
-#+begin_src emacs-lisp
-(defclass paced-weight-file-population-command (paced-file-population-command))
-#+end_src
-
-Now, we need to set up the buffer to replicate the words.
-
-#+begin_src emacs-lisp
-(cl-defmethod paced-population-command-setup-buffer ((cmd 
paced-weight-file-population-command) source)
-  ;; Use the built-in `paced--insert-file-contents' to insert contents.
-  (paced--insert-file-contents source)
-  ;; Jump to the start of the buffer
-  (goto-char (point-min))
-  ;; Search for lines with the form WORD WEIGHT
-  (while (re-search-forward (rx line-start ;; Start of line
-                                (submatch (one-or-more (not (syntax 
whitespace)))) ;; Our word
-                                (syntax whitespace) ;; Space between word and 
weight
-                                (submatch (one-or-more (any digit))) ;; Weight
-                                line-end) ;; End of line
-                            nil t)
-    (let* ((word (match-string 1))
-           (weight (string-to-number (match-string 2)))
-           ;; Repeat WORD WEIGHT times
-           (new-text (string-join (make-list weight word) " ")))
-      ;; Replace the matched text with our repeated word
-      (replace-match new-text))))
-#+end_src
-
-That's all there is to it.  When you go to edit a dictionary, the "weight-file"
-population command will automatically be added as an option for a population
-command.
-
-The even easier way to do this would've been to use
-~paced-file-function-population-command~, but it doesn't make for a good 
example
-in this case.
-
-** Asynchronous Population
-:PROPERTIES:
-:DESCRIPTION: Populating without blocking
-:END:
-A common problem is that population can take a long time.  Some of us populate
-dictionaries from org agenda files, which can get pretty big.
-
-To solve this, paced uses the 
[[https://github.com/jwiegley/emacs-async][async]] package.  Setup is seamless; 
just stick
-whatever code you need in ~~/.emacs.d/paced-async.el~, and use one of the two
-population commands:
-
-A named dictionary:
-
-#+begin_example
-M-x paced-repopulate-named-dictionary-async RET NAME RET
-#+end_example
-
-Or the current dictionary:
-
-#+begin_example
-M-x paced-repopulate-current-dictionary-async RET
-#+end_example
-
-A few things to note about this:
-
-1. Dictionaries will be automatically saved by this method after population
-2. Asynchronous population doesn't change anything until after population is
-   finished, so a user may continue to use their dictionary while population is
-   happening.  This also means that multiple populations may run in parallel
-   without interfering with one another.
-3. Because async runs population in a separate Emacs process, any custom code
-   required for population must be in paced-async.el.  This includes additional
-   population command types, but doesn't include the following variables:
-
-   - load-path
-   - paced-thing-at-point-constituent
-   - paced-async-load-file
-
-* Example Setups
-:PROPERTIES:
-:DESCRIPTION: Some examples
-:END:
-** Org Agenda Files
-As some of us record everything about our lives in our agenda files, it might 
be
-helpful to have a dictionary tuned to ourselves.
-
-We use a file-list command that returns the agenda files, and an exclude 
command
-to block out all of Org's extra features such as source code and drawers.
-
-The generator for file-list is easy:
-
-#+begin_src emacs-lisp
-org-agenda-files
-#+end_src
-
-Done.
-
-Now, the exclude command, which sits inside the properties option.  This can be
-added to ~paced-async.el~:
-
-#+begin_src emacs-lisp
-(require 'org)
-
-(defun org-at-tag-p ()
-  (let* ((p (point)))
-    ;; Ignore errors from `org-get-tags-string'.
-    (ignore-errors
-      ;; Checks the match string for a tag heading, setting match-string 1 to 
the
-      ;; tags.  Also sets match-beginning and match-end.
-      (org-get-tags-string)
-      (when (match-string 1)
-        (<= (match-beginning 1) p (match-end 1))))))
-
-(defun org-at-keyword-p ()
-  "Return non-nil if point is at a keyword such as #+TITLE."
-  (save-excursion
-    (beginning-of-line)
-    (looking-at-p "^#\\+")))
-
-(defun org-at-heading-prefix-p ()
-  "Return non-nil if looking at the leading stars of a heading."
-  (looking-at outline-regexp))
-
-(defun org-at-hline-p ()
-  (save-excursion
-    (beginning-of-line)
-    (looking-at-p "^-----")))
-
-(defun org-paced-exclude ()
-  (or
-   ;; Drawers
-   (org-between-regexps-p org-drawer-regexp ":END:") ;; Doesn't catch END
-   (org-in-regexp ":END:") ;; but this does
-
-   (org-at-tag-p) ;; tags
-   (org-at-keyword-p) ;; Keywords, such as #+TITLE
-   (org-at-heading-prefix-p) ;; Leading stars of a heading
-   (org-at-item-bullet-p) ;; Item Bullets
-   (org-at-timestamp-p) ;; Timestamps
-   (looking-at-p org-todo-regexp) ;; TODO keywords
-   (org-at-hline-p) ;; H-lines
-
-   (org-at-comment-p) ;; comments
-   (org-in-regexp org-any-link-re) ;; links
-   (org-in-block-p '("src" "quote" "verse")) ;; blocks
-   (org-at-planning-p) ;; deadline, etc.
-   (org-at-table-p) ;; tables
-   ))
-#+end_src
-
-As explained earlier, this can be put inside properties in the customize 
buffer as such:
-
-#+begin_example
-Properties :
-[INS] [DEL] Variable: paced-exclude-function
-Lisp expression: 'org-paced-exclude
-#+end_example
-
-And you're done.  See how easy that was?
-** Project Files
-Now we get to the interesting one.  There are tons of ways to collect project
-files in Emacs, so we're going to stick with one for now, being Emacs's 
built-in
-VC package.
-
-#+begin_src emacs-lisp
-(defun vc-paced-find-project-files (path-to-project-root)
-  "Use VC to collect all version-controlled files."
-  (let ((file-list))
-    (vc-file-tree-walk path-to-project-root (lambda (f) (push f file-list)))
-    file-list))
-#+end_src
-
-We'd then need to use the following for our file-list generator:
-
-#+begin_example
-Generator : (lambda nil (vc-paced-find-project-files 
"/home/me/programming/paced"))
-#+end_example
-
-Now, we (probably) don't want commented code to get in our way, so we'll use a
-small function for excluding those:
-
-#+begin_src emacs-lisp
-(defun paced-at-comment-p ()
-  (nth 8 (syntax-ppss)))
-#+end_src
-
-Use that for paced-exclude-function, and you're done.  We can't necessarily
-recommend this for any programming language, as there are dedicated solutions
-for almost everything, but it makes an excellent fallback.
-** Markdown Files
-
-Another common request is markdown files.  In order for this to work, you'll 
need to install ~markdown-mode~:
-
-#+begin_example
-M-x package-install RET markdown-mode RET
-#+end_example
-
-After that, add the following to your ~paced-async.el~ file:
-
-#+begin_src emacs-lisp
-(require 'markdown-mode)
-
-(defun paced-markdown-exclude-p ()
-  "Taken from `markdown-flyspell-check-word-p'."
-  ;; Exclude anything markdown mode thinks flyspell should skip.
-  (or
-   ;; Ignore code blocks
-   (markdown-code-block-at-point-p)
-   (markdown-inline-code-at-point-p)
-   ;; Ignore comments
-   (markdown-in-comment-p)
-   ;; Ignore special text
-   (let ((faces (get-text-property (point) 'face)))
-     (if (listp faces)
-         (or (memq 'markdown-reference-face faces)
-             (memq 'markdown-markup-face faces)
-             (memq 'markdown-plain-url-face faces)
-             (memq 'markdown-inline-code-face faces)
-             (memq 'markdown-url-face faces))
-       (memq faces '(markdown-reference-face
-                     markdown-markup-face
-                     markdown-plain-url-face
-                     markdown-inline-code-face
-                     markdown-url-face))))))
-#+end_src
-
-That excludes anything that the developers of markdown-mode felt should be
-excluded from flyspell.
-
-Set this as your exclude function in your dictionary's settings, then add each
-markdown file by hand.
-
-** Repopulating Dictionary After Saving
-
-This is a common request, although with the power of async, it's an easy one to
-fulfill.  This will repopulate the current buffer's dictionary every time you
-save a file with a dictionary.  This may seem daunting, but the dictionary will
-remain usable during population, and multiple populations won't interfere with
-one another.
-
-#+begin_src emacs-lisp
-;; Repopulate the current dictionary after saving
-(add-hook 'after-save-hook 'paced-repopulate-current-dictionary-async)
-#+end_src
-
-Add that to your .emacs file, and paced will take it from there.
-
-If you decide that's too much, do the following:
-
-#+begin_example
-M-: (remove-hook 'after-save-hook 'paced-repopulate-current-dictionary-async) 
RET
-#+end_example
-
-** Repopulating Dictionary After Spellchecking the Buffer
-
-Another request, although much trickier to do.  This one involves using Emacs's
-advice mechanism:
-
-#+begin_src emacs-lisp
-(define-advice ispell-pdict-save (:after (&optional _no-query _force-save) 
paced-populate)
-  ;; Repopulate the current dictionary after running spell check
-  (paced-repopulate-current-dictionary-async))
-#+end_src
-
-If you decide this isn't for you, do the following to revert the changes:
-
-#+begin_example
-M-: (advice-remove #'ispell-pdict-save #'ispell-pdict-save@paced-populate) RET
-#+end_example
-
-* Contributing
-:PROPERTIES:
-:DESCRIPTION: I wanna help!
-:CUSTOM_ID: contributing
-:END:
-
-We are all happy for any help you may provide.
-
-First, check out the source code on Savannah: 
https://savannah.nongnu.org/projects/paced-el
-
-#+BEGIN_SRC shell
-bzr branch https://bzr.savannah.gnu.org/r/paced-el/ paced
-#+END_SRC
-
-Build the Makefile with EDE:
-
-1. Open any file from paced (See [[#ede][Working with EDE]] if you encounter 
"Corrupt object on disk" error)
-2. Run ~C-c . C~ or ~M-x ede-compile-project~
-
-** Bugs
-:PROPERTIES:
-:CUSTOM_ID: bugs
-:DESCRIPTION: Submitting bug reports
-:END:
-
-There are two ways to submit bug reports:
-
-1. Using the bug tracker at Savannah
-2. Sending an email using ~paced-submit-bug-report~
-
-When submitting a bug report, be sure to include a description of the 
dictionary
-or population command that caused the problem, with as much detail as possible.
-
-** Development
-:PROPERTIES:
-:CUSTOM_ID: development
-:DESCRIPTION: Helping with development
-:END:
-
-If you're new to bazaar, we recommend using Emacs's built-in VC package.  It
-eases the overhead of dealing with a brand new VCS with a few standard 
commands.
-For more information, see the info page on it (In Emacs, this is
-C-h r m Introduction to VC RET).
-
-To contribute with bazaar, you can do the following:
-
-#+begin_src shell
-# Hack away and make your changes
-$ bzr commit -m "Changes I've made"
-$ bzr send -o file-name.txt
-#+end_src
-
-Then, use ~paced-submit-bug-report~ and attach "file-name.txt".  We can then 
merge
-that into the main development branch.
-
-There are a few rules to follow:
-
-- New population commands should be named 
paced-POPULATION-COMMAND-TYPE-population-command
-- Run 'make check' to verify that your mods don't break anything
-- Avoid additional or altered dependencies if at all possible
-- Dictionary commands come in threes ("the operation triad"):
-  1. paced-dictionary-OPERATION, a cl-defmethod which performs OPERATION on a 
dictionary
-  2. paced-OPERATION-on-named-dictionary, an interactive only function that 
prompts
-     for a dictionary name and performs OPERATION on that dictionary:
-     #+begin_src emacs-lisp
-     (interactive (list (paced-read-dictionary)))
-     (paced-ensure-registered name)
-     (paced-dictionary-OPERATION (paced-named-dictionary name))
-     #+end_src
-  3. paced-OPERATION-on-current-dictionary, an interactive function that
-     performs OPERATION on the current dictionary
-     #+begin_src emacs-lisp
-     (interactive)
-     (paced-dictionary-OPERATION (paced-current-dictionary-or-die))
-     #+end_src
-
-** Documentation
-:PROPERTIES:
-:CUSTOM_ID: docs
-:DESCRIPTION: Improving the documentation
-:END:
-
-Documentation is always helpful to us.  Please be sure to do the following 
after
-making any changes:
-
-1. Update the info page in the repository with ~C-c C-e i i~
-2. If you're updating the HTML documentation, switch to a theme that can easily
-   be read on a white background; we recommend the "adwaita" theme
-
-** Working with EDE
-:PROPERTIES:
-:CUSTOM_ID: ede
-:DESCRIPTION: And all its quirks
-:END:
-
-EDE can be a little finicky at times, but we feel the benefits, namely package
-dependency handling and Makefile generation, outweigh the costs.
-
-One of the issues that many will likely encounter is the error "Corrupt file on
-disk".  This is most often due to EDE not loading all its subprojects as 
needed.
-If you find yourself dealing with this error often, place the following in your
-.emacs file:
-
-#+begin_src emacs-lisp
-;; Target types needed for working with paced
-(require 'ede/proj-elisp)
-(require 'ede/proj-aux)
-(require 'ede/proj-misc)
-#+end_src
-
-These are the three target types that paced uses: elisp for compilation and
-autoloads; aux for auxiliary files such as documentation; and misc for tests.
-
-When creating a new file, EDE will ask if you want to add it to a target.
-Consult with one of the paced devs for guidance, but usually selecting "none"
-and letting one of us handle it is a good way to go.
-
-* Changelog
-:PROPERTIES:
-:DESCRIPTION: List of changes by version
-:END:
-** 1.1.3
-- Fixed bug with printing an empty dictionary
-- Fixed bug with paced crashing on non-existent thing at point
-** 1.1.2
-- Fixed bug with printing dictionaries
-** 1.1.1
-- Fixed bug with asynchronous population throwing an error on no dictionary
-
-- Set ~paced-throw-error-on-no-current~ to nil by default
-** 1.1
-- Cleaned up the code to reflect the "operation triad"
-  - -OP, OP-on-named, OP-on-current
-  - Retained backwards compatibility by obsoleting a bunch of functions, but 
didn't remove any of them
-  - Also removed the use of dict- in global variables and functions
-
-- Added the ability to print the contents of a dictionary in a separate buffer
-
-- Added the option to limit the words added during population by size
-
-- Various documentation improvements
-** 1.0.1
-Bug fix release
-- Save dictionaries right after they're created
-- Added "force" parameter to save functions
-** 1.0
-Initial release.
diff --git a/packages/paced/test-files/first.txt 
b/packages/paced/test-files/first.txt
deleted file mode 100644
index d20283f..0000000
--- a/packages/paced/test-files/first.txt
+++ /dev/null
@@ -1 +0,0 @@
-one two three four two three four three four four
diff --git a/packages/paced/test-files/fourth.org 
b/packages/paced/test-files/fourth.org
deleted file mode 100644
index 2d7b9ad..0000000
--- a/packages/paced/test-files/fourth.org
+++ /dev/null
@@ -1,2 +0,0 @@
-#+CATEGORY: Testing
-Test1 Test2
diff --git a/packages/paced/test-files/second.cpp 
b/packages/paced/test-files/second.cpp
deleted file mode 100644
index 2078554..0000000
--- a/packages/paced/test-files/second.cpp
+++ /dev/null
@@ -1 +0,0 @@
-// empty file that doesn't inherit from text mode
diff --git a/packages/paced/test-files/third.org 
b/packages/paced/test-files/third.org
deleted file mode 100644
index 8c15311..0000000
--- a/packages/paced/test-files/third.org
+++ /dev/null
@@ -1 +0,0 @@
-five five five five five six six seven six
diff --git a/packages/paced/test.mk b/packages/paced/test.mk
deleted file mode 100644
index fa886a3..0000000
--- a/packages/paced/test.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2017-2018 Free Software Foundation, Inc.
-
-# 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 <http://www.gnu.org/licenses/>.
-
-# EDE only allows arbitrary code from an external makefile, so this is how 
we've
-# got to do testing.
-
-test: compile
-       @$(EMACS) \
-       $(EMACSFLAGS) \
-       -L "." \
-       -l "ert" \
-       -l "paced-tests.el" \
-       -f ert-run-tests-batch-and-exit
-
-include Makefile
diff --git a/packages/swiper/swiper.el b/packages/swiper/swiper.el
deleted file mode 100644
index 10813a4..0000000
--- a/packages/swiper/swiper.el
+++ /dev/null
@@ -1,1673 +0,0 @@
-;;; swiper.el --- Isearch with an overview. Oh, man! -*- lexical-binding: t -*-
-
-;; Copyright (C) 2015-2019  Free Software Foundation, Inc.
-
-;; Author: Oleh Krehel <ohwoeowho@gmail.com>
-;; URL: https://github.com/abo-abo/swiper
-;; Version: 0.13.1
-;; Package-Requires: ((emacs "24.5") (ivy "0.13.1"))
-;; Keywords: matching
-
-;; This file is part of GNU Emacs.
-
-;; This file 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.
-
-;; For a full copy of the GNU General Public License
-;; see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This package gives an overview of the current regex search
-;; candidates.  The search regex can be split into groups with a
-;; space.  Each group is highlighted with a different face.
-;;
-;; It can double as a quick `regex-builder', although only single
-;; lines will be matched.
-
-;;; Code:
-
-(require 'ivy)
-
-(defgroup swiper nil
-  "`isearch' with an overview."
-  :group 'matching
-  :prefix "swiper-")
-
-(defface swiper-match-face-1
-  '((t (:inherit lazy-highlight)))
-  "The background face for `swiper' matches."
-  :group 'ivy-faces)
-
-(defface swiper-match-face-2
-  '((t (:inherit isearch)))
-  "Face for `swiper' matches modulo 1."
-  :group 'ivy-faces)
-
-(defface swiper-match-face-3
-  '((t (:inherit match)))
-  "Face for `swiper' matches modulo 2."
-  :group 'ivy-faces)
-
-(defface swiper-match-face-4
-  '((t (:inherit isearch-fail)))
-  "Face for `swiper' matches modulo 3."
-  :group 'ivy-faces)
-
-(defface swiper-background-match-face-1
-  '((t (:inherit swiper-match-face-1)))
-  "The background face for non-current `swiper' matches."
-  :group 'ivy-faces)
-
-(defface swiper-background-match-face-2
-  '((t (:inherit swiper-match-face-2)))
-  "Face for non-current `swiper' matches modulo 1."
-  :group 'ivy-faces)
-
-(defface swiper-background-match-face-3
-  '((t (:inherit swiper-match-face-3)))
-  "Face for non-current `swiper' matches modulo 2."
-  :group 'ivy-faces)
-
-(defface swiper-background-match-face-4
-  '((t (:inherit swiper-match-face-4)))
-  "Face for non-current `swiper' matches modulo 3."
-  :group 'ivy-faces)
-
-(defface swiper-line-face
-  '((t (:inherit highlight)))
-  "Face for current `swiper' line."
-  :group 'ivy-faces)
-
-(defcustom swiper-faces '(swiper-match-face-1
-                          swiper-match-face-2
-                          swiper-match-face-3
-                          swiper-match-face-4)
-  "List of `swiper' faces for group matches."
-  :group 'ivy-faces
-  :type '(repeat face))
-
-(defvar swiper-background-faces
-  '(swiper-background-match-face-1
-    swiper-background-match-face-2
-    swiper-background-match-face-3
-    swiper-background-match-face-4)
-  "Like `swiper-faces', but used for all matches except the current one.")
-
-(defun swiper--recompute-background-faces ()
-  (let ((faces '(swiper-background-match-face-1
-                 swiper-background-match-face-2
-                 swiper-background-match-face-3
-                 swiper-background-match-face-4))
-        (colir-compose-method #'colir-compose-soft-light))
-    (cl-mapc (lambda (f1 f2)
-               (let ((bg (face-background f1)))
-                 (when bg
-                   (set-face-background
-                    f2
-                    (colir-blend
-                     (colir-color-parse bg)
-                     (colir-color-parse "#ffffff"))))))
-             swiper-faces
-             faces)))
-(swiper--recompute-background-faces)
-
-(defcustom swiper-min-highlight 2
-  "Only highlight matches for regexps at least this long."
-  :type 'integer)
-
-(defcustom swiper-include-line-number-in-search nil
-  "Include line number in text of search candidates."
-  :type 'boolean
-  :group 'swiper)
-
-(defcustom swiper-goto-start-of-match nil
-  "When non-nil, go to the start of the match, not its end.
-Treated as non-nil when searching backwards."
-  :type 'boolean
-  :group 'swiper)
-
-(defvar swiper-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "M-q") 'swiper-query-replace)
-    (define-key map (kbd "C-l") 'swiper-recenter-top-bottom)
-    (define-key map (kbd "C-'") 'swiper-avy)
-    (define-key map (kbd "C-7") 'swiper-mc)
-    (define-key map (kbd "C-c C-f") 'swiper-toggle-face-matching)
-    map)
-  "Keymap for swiper.")
-
-(defvar swiper--query-replace-overlays nil)
-
-(defun swiper--query-replace-updatefn ()
-  (let ((lisp (ignore-errors (nth 2 (query-replace-compile-replacement 
ivy-text t)))))
-    (dolist (ov swiper--query-replace-overlays)
-      (when lisp
-        (dolist (x (overlay-get ov 'matches))
-          (setq lisp (cl-subst (cadr x) (car x) lisp :test #'equal)))
-        (setq lisp (ignore-errors (eval lisp))))
-      (overlay-put
-       ov 'after-string
-       (propertize
-        (if (stringp lisp)
-            lisp
-          ivy-text)
-        'face 'error)))))
-
-(defun swiper--query-replace-cleanup ()
-  (while swiper--query-replace-overlays
-    (delete-overlay (pop swiper--query-replace-overlays))))
-
-(defun swiper--query-replace-setup ()
-  (with-ivy-window
-    (let ((end (window-end (selected-window) t))
-          (re (ivy--regex ivy-text)))
-      (save-excursion
-        (beginning-of-line)
-        (while (and (re-search-forward re end t)
-                    (not (eobp)))
-          (let ((ov (make-overlay (1- (match-end 0)) (match-end 0)))
-                (md (match-data)))
-            (overlay-put
-             ov 'matches
-             (mapcar
-              (lambda (x)
-                (list `(match-string ,x) (match-string x)))
-              (number-sequence 0 (1- (/ (length md) 2)))))
-            (push ov swiper--query-replace-overlays))
-          (unless (> (match-end 0) (match-beginning 0))
-            (forward-char)))))))
-
-(defun swiper-query-replace ()
-  "Start `query-replace' with string to replace from last search string."
-  (interactive)
-  (cond ((null (window-minibuffer-p))
-         (user-error "Should only be called in the minibuffer through 
`swiper-map'"))
-        ((string= "" ivy-text)
-         (user-error "Empty input"))
-        (t
-         (swiper--query-replace-setup)
-         (unwind-protect
-              (let* ((enable-recursive-minibuffers t)
-                     (from (ivy--regex ivy-text))
-                     (default
-                      (format "\\,(concat %s)"
-                              (if (<= ivy--subexps 1)
-                                  "\\&"
-                                (mapconcat (lambda (i) (format "\\%d" i))
-                                           (number-sequence 1 ivy--subexps)
-                                           " \" \" "))))
-                     (to
-                      (query-replace-compile-replacement
-                       (ivy-read
-                        (format "Query replace %s with: " from) nil
-                        :def default
-                        :caller 'swiper-query-replace)
-                       t)))
-                (swiper--cleanup)
-                (ivy-exit-with-action
-                 (lambda (_)
-                   (with-ivy-window
-                     (move-beginning-of-line 1)
-                     (let ((inhibit-read-only t))
-                       (perform-replace from to
-                                        t t nil))))))
-           (swiper--query-replace-cleanup)))))
-
-(ivy-configure 'swiper-query-replace
-  :update-fn #'swiper--query-replace-updatefn)
-
-(defvar inhibit-message)
-
-(defun swiper-all-query-replace ()
-  "Start `query-replace' with string to replace from last search string."
-  (interactive)
-  (if (null (window-minibuffer-p))
-      (user-error
-       "Should only be called in the minibuffer through `swiper-all-map'")
-    (let* ((enable-recursive-minibuffers t)
-           (from (ivy--regex ivy-text))
-           (to (query-replace-read-to from "Query replace" t)))
-      (swiper--cleanup)
-      (ivy-exit-with-action
-       (lambda (_)
-         (let ((wnd-conf (current-window-configuration))
-               (inhibit-message t))
-           (unwind-protect
-                (dolist (cand ivy--old-cands)
-                  (let ((buffer (get-text-property 0 'buffer cand)))
-                    (switch-to-buffer buffer)
-                    (goto-char (point-min))
-                    (perform-replace from to t t nil)))
-             (set-window-configuration wnd-conf))))))))
-
-(defvar avy-all-windows)
-(defvar avy-style)
-(defvar avy-keys)
-(declare-function avy--overlay-post "ext:avy")
-(declare-function avy-action-goto "ext:avy")
-(declare-function avy-candidate-beg "ext:avy")
-(declare-function avy--done "ext:avy")
-(declare-function avy--make-backgrounds "ext:avy")
-(declare-function avy-window-list "ext:avy")
-(declare-function avy-read "ext:avy")
-(declare-function avy-read-de-bruijn "ext:avy")
-(declare-function avy-tree "ext:avy")
-(declare-function avy-push-mark "ext:avy")
-(declare-function avy--remove-leading-chars "ext:avy")
-
-(defun swiper--avy-candidates ()
-  (let* (
-         ;; We'll have overlapping overlays, so we sort all the
-         ;; overlays in the visible region by their start, and then
-         ;; throw out non-Swiper overlays or overlapping Swiper
-         ;; overlays.
-         (visible-overlays (cl-sort (with-ivy-window
-                                      (overlays-in (window-start)
-                                                   (window-end)))
-                                    #'< :key #'overlay-start))
-         (min-overlay-start 0)
-         (overlays-for-avy
-          (cl-remove-if-not
-           (lambda (ov)
-             (when (and (>= (overlay-start ov)
-                            min-overlay-start)
-                        (memq (overlay-get ov 'face)
-                              (append swiper-faces swiper-background-faces)))
-               (setq min-overlay-start (overlay-start ov))))
-           visible-overlays))
-         (offset (if (eq (ivy-state-caller ivy-last) 'swiper) 1 0)))
-    (nconc
-     (mapcar (lambda (ov)
-               (cons (overlay-start ov)
-                     (overlay-get ov 'window)))
-             overlays-for-avy)
-     (save-excursion
-       (save-restriction
-         (narrow-to-region (window-start) (window-end))
-         (goto-char (point-min))
-         (forward-line)
-         (let ((win (selected-window))
-               cands)
-           (while (not (eobp))
-             (push (cons (+ (point) offset) win)
-                   cands)
-             (forward-line))
-           cands))))))
-
-(defun swiper--avy-candidate ()
-  (let ((candidates (swiper--avy-candidates))
-        (avy-all-windows nil))
-    (unwind-protect
-         (prog2
-             (avy--make-backgrounds
-              (append (avy-window-list)
-                      (list (ivy-state-window ivy-last))))
-             (if (eq avy-style 'de-bruijn)
-                 (avy-read-de-bruijn candidates avy-keys)
-               (avy-read (avy-tree candidates avy-keys)
-                         #'avy--overlay-post
-                         #'avy--remove-leading-chars))
-           (avy-push-mark))
-      (avy--done))))
-
-(defun swiper--avy-goto (candidate)
-  (cond ((let ((win (cdr-safe candidate)))
-           (and win (window-minibuffer-p win)))
-         (let ((nlines (count-lines (point-min) (point-max))))
-           (ivy-set-index
-            (+ (car (ivy--minibuffer-index-bounds
-                     ivy--index ivy--length ivy-height))
-               (line-number-at-pos (car candidate))
-               (if (or (= nlines (1+ ivy-height))
-                       (< ivy--length ivy-height))
-                   0
-                 (- ivy-height nlines))
-               -2)))
-         (ivy--exhibit)
-         (ivy-done)
-         (ivy-call))
-        ((or (consp candidate)
-             (number-or-marker-p candidate))
-         (ivy-quit-and-run
-           (avy-action-goto (avy-candidate-beg candidate))))))
-
-;;;###autoload
-(defun swiper-avy ()
-  "Jump to one of the current swiper candidates."
-  (interactive)
-  (unless (require 'avy nil 'noerror)
-    (error "Package avy isn't installed"))
-  (cl-case (length ivy-text)
-    (0
-     (user-error "Need at least one char of input"))
-    (1
-     (let ((swiper-min-highlight 1))
-       (swiper--update-input-ivy))))
-  (swiper--avy-goto (swiper--avy-candidate)))
-
-(declare-function mc/create-fake-cursor-at-point "ext:multiple-cursors-core")
-(declare-function multiple-cursors-mode "ext:multiple-cursors-core")
-
-(defun swiper-mc ()
-  "Create a fake cursor for each `swiper' candidate.
-Make sure `swiper-mc' is on `mc/cmds-to-run-once' list."
-  (interactive)
-  (unless (require 'multiple-cursors nil t)
-    (error "Multiple-cursors isn't installed"))
-  (unless (window-minibuffer-p)
-    (error "Call me only from `swiper'"))
-  (let ((cands (nreverse ivy--old-cands))
-        (action (ivy--get-action ivy-last)))
-    (unless (string= ivy-text "")
-      (ivy-exit-with-action
-       (lambda (_)
-         (let (cand)
-           (while (setq cand (pop cands))
-             (funcall action cand)
-             (when cands
-               (mc/create-fake-cursor-at-point))))
-         (multiple-cursors-mode 1))))))
-
-(defvar swiper--current-window-start nil
-  "Store `window-start' to restore it later.
-This prevents a \"jumping\" behavior which occurs when variables
-such as `scroll-conservatively' are set to a high value.")
-
-(defun swiper-recenter-top-bottom (&optional arg)
-  "Call (`recenter-top-bottom' ARG)."
-  (interactive "P")
-  (with-ivy-window
-    (recenter-top-bottom arg)
-    (setq swiper--current-window-start (window-start))))
-
-(defvar swiper-font-lock-exclude
-  '(Man-mode
-    adoc-mode
-    bbdb-mode
-    bongo-library-mode
-    bongo-mode
-    bongo-playlist-mode
-    bookmark-bmenu-mode
-    circe-channel-mode
-    circe-query-mode
-    circe-server-mode
-    deadgrep-mode
-    debbugs-gnu-mode
-    dired-mode
-    elfeed-search-mode
-    elfeed-show-mode
-    emms-playlist-mode
-    emms-stream-mode
-    erc-mode
-    eshell-mode
-    eww-mode
-    forth-block-mode
-    forth-mode
-    fundamental-mode
-    gnus-article-mode
-    gnus-group-mode
-    gnus-summary-mode
-    help-mode
-    helpful-mode
-    jabber-chat-mode
-    magit-popup-mode
-    matrix-client-mode
-    matrix-client-room-list-mode
-    mu4e-headers-mode
-    mu4e-view-mode
-    nix-mode
-    notmuch-search-mode
-    notmuch-tree-mode
-    occur-edit-mode
-    occur-mode
-    org-agenda-mode
-    package-menu-mode
-    rcirc-mode
-    sauron-mode
-    treemacs-mode
-    twittering-mode
-    vc-dir-mode
-    w3m-mode
-    woman-mode
-    xref--xref-buffer-mode)
-  "List of major-modes that are incompatible with `font-lock-ensure'.")
-
-(defun swiper-font-lock-ensure-p ()
-  "Return non-nil if we should `font-lock-ensure'."
-  (or (derived-mode-p 'magit-mode)
-      (bound-and-true-p magit-blame-mode)
-      (memq major-mode swiper-font-lock-exclude)
-      (not (derived-mode-p 'prog-mode))))
-
-(defun swiper-font-lock-ensure ()
-  "Ensure the entire buffer is highlighted."
-  (unless (swiper-font-lock-ensure-p)
-    (unless (or (> (buffer-size) 100000) (null font-lock-mode))
-      (if (fboundp 'font-lock-ensure)
-          (font-lock-ensure)
-        (with-no-warnings (font-lock-fontify-buffer))))))
-
-(defvar swiper--format-spec ""
-  "Store the current candidates format spec.")
-
-(defvar swiper--width nil
-  "Store the number of digits needed for the longest line number.")
-
-(defvar swiper-use-visual-line nil
-  "When non-nil, use `line-move' instead of `forward-line'.")
-
-(defvar dired-isearch-filenames)
-(declare-function dired-move-to-filename "dired")
-
-(defun swiper--line ()
-  (let* ((beg (cond ((and (eq major-mode 'dired-mode)
-                          (bound-and-true-p dired-isearch-filenames))
-                     (dired-move-to-filename)
-                     (point))
-                    (swiper-use-visual-line
-                     (save-excursion
-                       (beginning-of-visual-line)
-                       (point)))
-                    (t
-                     (point))))
-         (end (if swiper-use-visual-line
-                  (save-excursion
-                    (end-of-visual-line)
-                    (point))
-                (line-end-position))))
-
-    (concat
-     " "
-     (buffer-substring beg end))))
-
-(declare-function outline-show-all "outline")
-
-(defvar swiper-use-visual-line-p
-  (lambda (n-lines)
-    (and visual-line-mode
-         ;; super-slow otherwise
-         (< (buffer-size) 20000)
-         (< n-lines 400)))
-  "A predicate that decides whether `line-move' or `forward-line' is used.
-Note that `line-move' can be very slow.")
-
-(defun swiper--candidates (&optional numbers-width)
-  "Return a list of this buffer lines.
-
-NUMBERS-WIDTH, when specified, is used for width spec of line
-numbers; replaces calculating the width from buffer line count."
-  (let* ((inhibit-field-text-motion t)
-         (n-lines (count-lines (point-min) (point-max))))
-    (if (funcall swiper-use-visual-line-p n-lines)
-        (progn
-          (when (eq major-mode 'org-mode)
-            (require 'outline)
-            (if (fboundp 'outline-show-all)
-                (outline-show-all)
-              (with-no-warnings
-                (show-all))))
-          (setq swiper-use-visual-line t))
-      (setq swiper-use-visual-line nil))
-    (unless (zerop n-lines)
-      (setq swiper--width (or numbers-width
-                              (1+ (floor (log n-lines 10)))))
-      (setq swiper--format-spec
-            (format "%%-%dd " swiper--width))
-      (let ((line-number 1)
-            (advancer (if swiper-use-visual-line
-                          (lambda (arg) (line-move arg t))
-                        #'forward-line))
-            candidates)
-        (save-excursion
-          (goto-char (point-min))
-          (swiper-font-lock-ensure)
-          (while (< (point) (point-max))
-            (when (swiper-match-usable-p)
-              (let ((str (swiper--line)))
-                (setq str (ivy-cleanup-string str))
-                (let ((line-number-str
-                       (format swiper--format-spec line-number)))
-                  (if swiper-include-line-number-in-search
-                      (setq str (concat line-number-str str))
-                    (put-text-property
-                     0 1 'display line-number-str str))
-                  (put-text-property
-                   0 1 'swiper-line-number line-number str))
-                (push str candidates)))
-            (funcall advancer 1)
-            (cl-incf line-number))
-          (nreverse candidates))))))
-
-(defvar swiper--opoint 1
-  "The point when `swiper' starts.")
-
-;;;###autoload
-(defun swiper-backward (&optional initial-input)
-  "`isearch-backward' with an overview.
-When non-nil, INITIAL-INPUT is the initial search pattern."
-  (interactive)
-  (let ((ivy-index-functions-alist
-         '((swiper . ivy-recompute-index-swiper-backward))))
-    (swiper initial-input)))
-
-;;;###autoload
-(defun swiper-thing-at-point ()
-  "`swiper' with `ivy-thing-at-point'."
-  (interactive)
-  (let ((thing (ivy-thing-at-point)))
-    (when (use-region-p)
-      (deactivate-mark))
-    (swiper thing)))
-
-;;;###autoload
-(defun swiper-all-thing-at-point ()
-  "`swiper-all' with `ivy-thing-at-point'."
-  (interactive)
-  (let ((thing (ivy-thing-at-point)))
-    (when (use-region-p)
-      (deactivate-mark))
-    (swiper-all thing)))
-
-(defun swiper--extract-matches (regex cands)
-  "Extract captured REGEX groups from CANDS."
-  (let (res)
-    (dolist (cand cands)
-      (setq cand (substring cand 1))
-      (when (string-match regex cand)
-        (push (mapconcat (lambda (n) (match-string-no-properties n cand))
-                         (number-sequence
-                          1
-                          (/ (- (length (match-data)) 2) 2))
-                         " ")
-              res)))
-    (nreverse res)))
-
-(defun swiper--occur-cands (fname cands)
-  (when cands
-    (with-current-buffer (ivy-state-buffer ivy-last)
-      (when (eq (ivy-state-caller ivy-last) 'swiper-isearch)
-        (setq cands (mapcar #'swiper--line-at-point cands)))
-      (let* ((pt-min (point-min))
-             (line-delta
-              (save-restriction
-                (widen)
-                (1- (line-number-at-pos pt-min))))
-             (lines
-              (if (eq (ivy-state-caller ivy-last) 'swiper-isearch)
-                  (swiper--isearch-occur-cands cands)
-                (mapcar (lambda (s)
-                          (let ((n (get-text-property 0 'swiper-line-number 
s)))
-                            (setq s (substring s 1))
-                            (add-text-properties 0 1 (list 'swiper-line-number 
n) s)
-                            (cons n s)))
-                        cands)))
-             (offset (+ (length fname) 2)))
-        (mapcar (lambda (x)
-                  (let ((nn (number-to-string
-                             (+ (car x) line-delta))))
-                    (remove-text-properties 0 1 '(display) (cdr x))
-                    (put-text-property 0 (length nn) 'face 
'ivy-grep-line-number nn)
-                    (put-text-property 0 1 'offset (+ offset (length nn)) 
fname)
-                    (format "%s:%s:%s" fname nn (cdr x))))
-                lines)))))
-
-(defun swiper--isearch-occur-cands (cands)
-  (let* ((last-pt (get-text-property 0 'point (car cands)))
-         (line (1+ (line-number-at-pos last-pt)))
-         res pt)
-    (dolist (cand cands)
-      (setq pt (get-text-property 0 'point cand))
-      (cl-incf line (1- (count-lines last-pt pt)))
-      (push (cons line cand) res)
-      (setq last-pt pt))
-    (nreverse res)))
-
-(defun swiper--occur-insert-lines (cands)
-  (let ((inhibit-read-only t))
-    ;; Need precise number of header lines for `wgrep' to work.
-    (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n"
-                    default-directory))
-    (insert (format "%d candidates:\n" (length cands)))
-    (ivy--occur-insert-lines cands)
-    (goto-char (point-min))
-    (forward-line 4)))
-
-(defun swiper--occur-buffer ()
-  (let ((buffer (ivy-state-buffer ivy-last)))
-    (unless (buffer-live-p buffer)
-      (setq buffer
-            (setf (ivy-state-buffer ivy-last)
-                  (find-file-noselect
-                   (plist-get (ivy-state-extra-props ivy-last) :fname))))
-      (save-selected-window
-        (pop-to-buffer buffer))
-      (setf (ivy-state-window ivy-last) (selected-window)))
-    buffer))
-
-(defun swiper-occur (&optional cands)
-  "Generate a custom occur buffer for `swiper'.
-When capture groups are present in the input, print them instead of lines."
-  (let* ((buffer (swiper--occur-buffer))
-         (fname (propertize
-                 (with-ivy-window
-                   (if (buffer-file-name buffer)
-                       (file-name-nondirectory
-                        (buffer-file-name buffer))
-                     (buffer-name buffer)))
-                 'face
-                 'ivy-grep-info))
-         (ivy-text (progn (string-match "\"\\(.*\\)\"" (buffer-name))
-                          (match-string 1 (buffer-name))))
-         (re (mapconcat #'identity (ivy--split ivy-text) ".*?"))
-         (cands
-          (swiper--occur-cands
-           fname
-           (or cands
-               (save-window-excursion
-                 (setq ivy--old-re nil)
-                 (switch-to-buffer buffer)
-                 (if (eq (ivy-state-caller ivy-last) 'swiper)
-                     (let ((ivy--regex-function 'swiper--re-builder))
-                       (ivy--filter re (swiper--candidates)))
-                   (swiper-isearch-function ivy-text)))))))
-    (if (string-match-p "\\\\(" re)
-        (insert
-         (mapconcat #'identity
-                    (swiper--extract-matches
-                     re (with-current-buffer buffer
-                          (swiper--candidates)))
-                    "\n"))
-      (unless (eq major-mode 'ivy-occur-grep-mode)
-        (ivy-occur-grep-mode)
-        (font-lock-mode -1))
-      (swiper--occur-insert-lines
-       (mapcar (lambda (cand) (concat "./" cand)) cands)))))
-
-(declare-function evil-set-jump "ext:evil-jumps")
-
-(defvar swiper--current-line nil)
-(defvar swiper--current-match-start nil)
-(defvar swiper--point-min nil)
-(defvar swiper--point-max nil)
-(defvar swiper--reveal-mode nil)
-
-(defun swiper--init ()
-  "Perform initialization common to both completion methods."
-  (setq swiper--current-line nil)
-  (setq swiper--current-match-start nil)
-  (setq swiper--current-window-start nil)
-  (setq swiper--opoint (point))
-  (setq swiper--point-min (point-min))
-  (setq swiper--point-max (point-max))
-  (when (setq swiper--reveal-mode
-              (bound-and-true-p reveal-mode))
-    (reveal-mode -1))
-  (lazy-highlight-cleanup t)
-  (setq isearch-opened-overlays nil)
-  (when (bound-and-true-p evil-mode)
-    (evil-set-jump)))
-
-(declare-function char-fold-to-regexp "char-fold")
-
-(defun swiper--re-builder (str)
-  "Transform STR into a swiper regex.
-This is the regex used in the minibuffer where candidates have
-line numbers.  For the buffer, use `ivy--regex' instead."
-  (let* ((re-builder (ivy-alist-setting ivy-re-builders-alist))
-         (re (cond
-               ((equal str "")
-                "")
-               ((equal str "^")
-                (setq ivy--subexps 0)
-                ".")
-               ((= (aref str 0) ?^)
-                (let* ((re (funcall re-builder (substring str 1)))
-                       (re (if (listp re)
-                               (mapconcat (lambda (x)
-                                            (format "\\(%s\\)" (car x)))
-                                          (cl-remove-if-not #'cdr re)
-                                          ".*?")
-                             re)))
-                  (cond
-                    ((string= re "$")
-                     "^$")
-                    ((zerop ivy--subexps)
-                     (prog1 (format "^ ?\\(%s\\)" re)
-                       (setq ivy--subexps 1)))
-                    (t
-                     (format "^ %s" re)))))
-               ((eq (bound-and-true-p search-default-mode) 
'char-fold-to-regexp)
-                (if (string-match "\\`\\\\_<\\(.+\\)\\\\_>\\'" str)
-                    (concat
-                     "\\_<"
-                     (char-fold-to-regexp (match-string 1 str))
-                     "\\_>")
-                  (let ((subs (ivy--split str)))
-                    (setq ivy--subexps (length subs))
-                    (mapconcat
-                     (lambda (s) (format "\\(%s\\)" (char-fold-to-regexp s)))
-                     subs
-                     ".*?"))))
-               (t
-                (funcall re-builder str)))))
-    re))
-
-(defvar swiper-history nil
-  "History for `swiper'.")
-
-(defvar swiper-invocation-face nil
-  "The face at the point of invocation of `swiper'.")
-
-(defcustom swiper-stay-on-quit nil
-  "When non-nil don't go back to search start on abort."
-  :type 'boolean)
-
-;;;###autoload
-(defun swiper (&optional initial-input)
-  "`isearch-forward' with an overview.
-When non-nil, INITIAL-INPUT is the initial search pattern."
-  (interactive)
-  (let ((candidates (swiper--candidates)))
-    (swiper--init)
-    (setq swiper-invocation-face
-          (plist-get (text-properties-at (point)) 'face))
-    (let ((preselect
-           (if (or swiper-use-visual-line (null search-invisible))
-               (count-screen-lines
-                (point-min)
-                (save-excursion (beginning-of-visual-line) (point)))
-             (1- (line-number-at-pos))))
-          (minibuffer-allow-text-properties t)
-          res)
-      (unwind-protect
-           (and
-            (setq res
-                  (ivy-read
-                   "Swiper: "
-                   candidates
-                   :initial-input initial-input
-                   :keymap swiper-map
-                   :preselect
-                   (if initial-input
-                       (cl-position-if
-                        (lambda (x)
-                          (= (1+ preselect) (get-text-property 0 
'swiper-line-number x)))
-                        (progn
-                          (setq ivy--old-re nil)
-                          (ivy--filter initial-input candidates)))
-                     preselect)
-                   :require-match t
-                   :action #'swiper--action
-                   :re-builder #'swiper--re-builder
-                   :history 'swiper-history
-                   :extra-props (list :fname (buffer-file-name))
-                   :caller 'swiper))
-            (point))
-        (unless (or res swiper-stay-on-quit)
-          (goto-char swiper--opoint))
-        (unless (or res (string= ivy-text ""))
-          (cl-pushnew ivy-text swiper-history))
-        (setq swiper--current-window-start nil)
-        (when swiper--reveal-mode
-          (reveal-mode 1))))))
-
-(ivy-configure 'swiper
-  :occur #'swiper-occur
-  :update-fn #'swiper--update-input-ivy
-  :unwind-fn #'swiper--cleanup
-  :index-fn #'ivy-recompute-index-swiper)
-
-(defun swiper-toggle-face-matching ()
-  "Toggle matching only the candidates with `swiper-invocation-face'."
-  (interactive)
-  (setf (ivy-state-matcher ivy-last)
-        (if (ivy-state-matcher ivy-last)
-            nil
-          #'swiper--face-matcher))
-  (setq ivy--old-re nil))
-
-(defun swiper--face-matcher (regexp candidates)
-  "Return REGEXP matching CANDIDATES.
-Matched candidates should have `swiper-invocation-face'."
-  (cl-remove-if-not
-   (lambda (x)
-     (and (string-match regexp x)
-          (let* ((s (match-string 0 x))
-                 (n (length s))
-                 (i 0))
-            (while (and (< i n)
-                        (text-property-any
-                         i (1+ i)
-                         'face swiper-invocation-face
-                         s))
-              (cl-incf i))
-            (= i n))))
-   candidates))
-
-(defun swiper--ensure-visible ()
-  "Remove overlays hiding point."
-  (let ((overlays (overlays-at (1- (point))))
-        ov expose)
-    (while (setq ov (pop overlays))
-      (if (and (invisible-p (overlay-get ov 'invisible))
-               (setq expose (overlay-get ov 'isearch-open-invisible)))
-          (funcall expose ov)))))
-
-(defvar swiper--overlays nil
-  "Store overlays.")
-
-(defvar swiper--isearch-highlight-timer nil
-  "This timer used by `swiper--delayed-add-overlays'.")
-
-(defun swiper--cleanup ()
-  "Clean up the overlays."
-  (while swiper--overlays
-    (delete-overlay (pop swiper--overlays)))
-  ;; force cleanup unless it's :unwind
-  (lazy-highlight-cleanup
-   (if (eq ivy-exit 'done) lazy-highlight-cleanup t))
-  (when (timerp swiper--isearch-highlight-timer)
-    (cancel-timer swiper--isearch-highlight-timer)
-    (setq swiper--isearch-highlight-timer nil)))
-
-(defun swiper--add-cursor-overlay (wnd)
-  (let* ((special (or (eolp) (looking-at "\t")))
-         (ov (make-overlay (point) (if special (point) (1+ (point))))))
-    (if special
-        (overlay-put ov 'after-string (propertize " " 'face 'ivy-cursor))
-      (overlay-put ov 'face 'ivy-cursor))
-    (overlay-put ov 'window wnd)
-    (overlay-put ov 'priority 2)
-    (push ov swiper--overlays)))
-
-(defun swiper--add-line-overlay (wnd)
-  (let ((beg (if visual-line-mode
-                 (save-excursion
-                   (beginning-of-visual-line)
-                   (point))
-               (line-beginning-position)))
-        (end (if visual-line-mode
-                 (save-excursion
-                   (end-of-visual-line)
-                   (point))
-               (1+ (line-end-position)))))
-    (push (swiper--make-overlay beg end 'swiper-line-face wnd 0)
-          swiper--overlays)))
-
-(defun swiper--make-overlay (beg end face wnd priority)
-  "Create an overlay bound by BEG and END.
-FACE, WND and PRIORITY are properties corresponding to
-the face, window and priority of the overlay."
-  (let ((overlay (make-overlay beg end)))
-    (overlay-put overlay 'face face)
-    (overlay-put overlay 'window wnd)
-    (overlay-put overlay 'priority priority)
-    overlay))
-
-(defun swiper--recenter-p ()
-  (or (display-graphic-p)
-      (not recenter-redisplay)))
-
-(defun swiper--positive-regexps (str)
-  (let ((regexp-or-regexps
-         (funcall ivy--regex-function str)))
-    (if (listp regexp-or-regexps)
-        (mapcar #'car (cl-remove-if-not #'cdr regexp-or-regexps))
-      (list regexp-or-regexps))))
-
-(defun swiper--update-input-ivy ()
-  "Called when `ivy' input is updated."
-  (with-ivy-window
-    (swiper--cleanup)
-    (when (> (length (ivy-state-current ivy-last)) 0)
-      (let ((regexps (swiper--positive-regexps ivy-text))
-            (re-idx -1)
-            (case-fold-search (ivy--case-fold-p ivy-text)))
-        (dolist (re regexps)
-          (setq re-idx (1+ re-idx))
-          (let* ((re (replace-regexp-in-string
-                      "    " "\t"
-                      re))
-                 (num (get-text-property 0 'swiper-line-number 
(ivy-state-current ivy-last))))
-            (unless (memq this-command '(ivy-yank-word
-                                         ivy-yank-symbol
-                                         ivy-yank-char
-                                         scroll-other-window))
-              (when (cl-plusp num)
-                (unless (if swiper--current-line
-                            (eq swiper--current-line num)
-                          (eq (line-number-at-pos) num))
-                  (goto-char swiper--point-min)
-                  (if swiper-use-visual-line
-                      (line-move (1- num))
-                    (forward-line (1- num))))
-                (if (and (equal ivy-text "")
-                         (>= swiper--opoint (line-beginning-position))
-                         (<= swiper--opoint (line-end-position)))
-                    (goto-char swiper--opoint)
-                  (if (eq swiper--current-line num)
-                      (when swiper--current-match-start
-                        (goto-char swiper--current-match-start))
-                    (setq swiper--current-line num))
-                  (when (re-search-forward re (line-end-position) t)
-                    (setq swiper--current-match-start (match-beginning 0))))
-                (isearch-range-invisible (line-beginning-position)
-                                         (line-end-position))
-                (swiper--maybe-recenter)))
-            (swiper--add-overlays
-             re
-             (max
-              (if (swiper--recenter-p)
-                  (window-start)
-                (line-beginning-position (- (window-height))))
-              swiper--point-min)
-             (min
-              (if (swiper--recenter-p)
-                  (window-end (selected-window) t)
-                (line-end-position (window-height)))
-              swiper--point-max)
-             nil
-             re-idx)))))))
-
-(defun swiper--add-overlays (re &optional beg end wnd re-idx)
-  "Add overlays for RE regexp in visible part of the current buffer.
-BEG and END, when specified, are the point bounds.
-WND, when specified is the window."
-  (setq wnd (or wnd (ivy-state-window ivy-last)))
-  (swiper--add-line-overlay wnd)
-  (let* ((pt (point))
-         (wh (window-height))
-         (beg (or beg (save-excursion
-                        (forward-line (- wh))
-                        (point))))
-         (end (or end (save-excursion
-                        (forward-line wh)
-                        (point))))
-         (case-fold-search (ivy--case-fold-p re)))
-    (when (>= (length re) swiper-min-highlight)
-      (save-excursion
-        (goto-char beg)
-        ;; RE can become an invalid regexp
-        (while (and (ignore-errors (re-search-forward re end t))
-                    (> (- (match-end 0) (match-beginning 0)) 0))
-          ;; Don't highlight a match if it spans multiple
-          ;; lines. `count-lines' returns 1 if the match is within a
-          ;; single line, even if it includes the newline, and 2 or
-          ;; greater otherwise. We hope that the inclusion of the
-          ;; newline will not ever be a problem in practice.
-          (when (< (count-lines (match-beginning 0) (match-end 0)) 2)
-            (let* ((faces (if (= (match-end 0) pt)
-                              swiper-faces
-                            swiper-background-faces))
-                   (adder-fn (lambda (beg end face priority)
-                               (push (swiper--make-overlay beg end face wnd 
priority)
-                                     isearch-lazy-highlight-overlays))))
-              (unless (and (consp ivy--old-re)
-                           (null
-                            (save-match-data
-                              (ivy--re-filter ivy--old-re
-                                              (list
-                                               (buffer-substring-no-properties
-                                                (line-beginning-position)
-                                                (line-end-position)))))))
-                (swiper--add-properties faces adder-fn re-idx)))))))))
-
-(defun swiper--add-properties (faces adder-fn &optional re-idx)
-  (let ((mb (match-beginning 0))
-        (me (match-end 0)))
-    (unless (> (- me mb) 2017)
-      (funcall adder-fn
-               mb me
-               (if (zerop ivy--subexps)
-                   (nth (1+ (mod (or re-idx 0) (1- (length faces)))) faces)
-                 (car faces))
-               0)))
-  (let ((i 1)
-        (j 0))
-    (while (<= (cl-incf j) ivy--subexps)
-      (let ((bm (match-beginning j))
-            (em (match-end j)))
-        (when (and (integerp em)
-                   (integerp bm))
-          (while (and (< j ivy--subexps)
-                      (integerp (match-beginning (+ j 1)))
-                      (= em (match-beginning (+ j 1))))
-            (setq em (match-end (cl-incf j))))
-          (funcall adder-fn
-                   bm em
-                   (nth (1+ (mod (+ i 2) (1- (length faces))))
-                        faces)
-                   i)
-          (cl-incf i))))))
-
-(defcustom swiper-action-recenter nil
-  "When non-nil, recenter after exiting `swiper'."
-  :type 'boolean)
-(defvar evil-search-module)
-(defvar evil-ex-search-pattern)
-(defvar evil-ex-search-persistent-highlight)
-(defvar evil-ex-search-direction)
-(declare-function evil-ex-search-activate-highlight "evil-ex")
-
-(defun swiper--maybe-recenter ()
-  (cond (swiper-action-recenter
-         (recenter))
-        ((swiper--recenter-p)
-         (when swiper--current-window-start
-           (set-window-start (selected-window) swiper--current-window-start))
-         (when (or
-                (< (point) (window-start))
-                (> (point) (window-end (ivy-state-window ivy-last) t)))
-           (recenter))))
-  (setq swiper--current-window-start (window-start)))
-
-(defun swiper--action (x)
-  "Goto line X."
-  (let ((ln (1- (get-text-property 0 'swiper-line-number x)))
-        (re (ivy--regex ivy-text))
-        (case-fold-search (ivy--case-fold-p ivy-text)))
-    (if (null x)
-        (user-error "No candidates")
-      (with-ivy-window
-        (unless (equal (current-buffer)
-                       (ivy-state-buffer ivy-last))
-          (switch-to-buffer (ivy-state-buffer ivy-last)))
-        (goto-char
-         (if (buffer-narrowed-p)
-             swiper--point-min
-           (point-min)))
-        (funcall (if swiper-use-visual-line
-                     #'line-move
-                   #'forward-line)
-                 ln)
-        (when (and (re-search-forward re (line-end-position) t) 
swiper-goto-start-of-match)
-          (goto-char (match-beginning 0)))
-        (swiper--ensure-visible)
-        (swiper--maybe-recenter)
-        (when (/= (point) swiper--opoint)
-          (unless (and transient-mark-mode mark-active)
-            (when (eq ivy-exit 'done)
-              (push-mark swiper--opoint t)
-              (message "Mark saved where search started"))))
-        (add-to-history
-         'regexp-search-ring
-         re
-         regexp-search-ring-max)
-        ;; integration with evil-mode's search
-        (when (bound-and-true-p evil-mode)
-          (when (eq evil-search-module 'isearch)
-            (setq isearch-string ivy-text))
-          (when (eq evil-search-module 'evil-search)
-            (add-to-history 'evil-ex-search-history re)
-            (setq evil-ex-search-pattern (list re t t))
-            (setq evil-ex-search-direction 'forward)
-            (when evil-ex-search-persistent-highlight
-              (evil-ex-search-activate-highlight evil-ex-search-pattern))))))))
-
-(defun swiper-from-isearch ()
-  "Invoke `swiper' from isearch."
-  (interactive)
-  (let ((query (if isearch-regexp
-                   isearch-string
-                 (regexp-quote isearch-string))))
-    (isearch-exit)
-    (swiper query)))
-
-(defvar swiper-multi-buffers nil
-  "Store the current list of buffers.")
-
-(defvar swiper-multi-candidates nil
-  "Store the list of candidates for `swiper-multi'.")
-
-(defun swiper-multi-prompt ()
-  "Return prompt for `swiper-multi'."
-  (format "Buffers (%s): "
-          (mapconcat #'identity swiper-multi-buffers ", ")))
-
-(defvar swiper-window-width 80)
-
-(defun swiper-multi ()
-  "Select one or more buffers.
-Run `swiper' for those buffers."
-  (interactive)
-  (setq swiper-multi-buffers nil)
-  (let ((ivy-use-virtual-buffers nil))
-    (ivy-read (swiper-multi-prompt)
-              #'internal-complete-buffer
-              :action #'swiper-multi-action-1))
-  (let ((swiper-window-width (- (- (frame-width) (if (display-graphic-p) 0 1)) 
4)))
-    (ivy-read "Swiper: " swiper-multi-candidates
-              :action #'swiper-multi-action-2
-              :caller 'swiper-multi)))
-
-(ivy-configure 'swiper-multi
-  :unwind-fn #'swiper--cleanup
-  :index-fn #'ivy-recompute-index-swiper
-  :format-fn #'swiper--all-format-function)
-
-(defun swiper-multi-action-1 (x)
-  "Add X to list of selected buffers `swiper-multi-buffers'.
-If X is already part of the list, remove it instead.  Quit the selection if
-X is selected by either `ivy-done', `ivy-alt-done' or `ivy-immediate-done',
-otherwise continue prompting for buffers."
-  (if (member x swiper-multi-buffers)
-      (progn
-        (setq swiper-multi-buffers (delete x swiper-multi-buffers)))
-    (unless (equal x "")
-      (setq swiper-multi-buffers (append swiper-multi-buffers (list x)))))
-  (let ((prompt (swiper-multi-prompt)))
-    (setf (ivy-state-prompt ivy-last) prompt)
-    (setq ivy--prompt (concat "%-4d " prompt)))
-  (cond ((memq this-command '(ivy-done
-                              ivy-alt-done
-                              ivy-immediate-done))
-         (setq swiper-multi-candidates
-               (swiper--multi-candidates
-                (mapcar #'get-buffer swiper-multi-buffers))))
-        ((eq this-command 'ivy-call)
-         (with-selected-window (active-minibuffer-window)
-           (delete-minibuffer-contents)))))
-
-(defun swiper-multi-action-2 (x)
-  "Move to candidate X from `swiper-multi'."
-  (when (> (length x) 0)
-    (let ((buffer-name (get-text-property 0 'buffer x)))
-      (when buffer-name
-        (with-ivy-window
-          (switch-to-buffer buffer-name)
-          (goto-char (point-min))
-          (forward-line (1- (get-text-property 0 'swiper-line-number x)))
-          (re-search-forward
-           (ivy--regex ivy-text)
-           (line-end-position) t)
-          (isearch-range-invisible (line-beginning-position)
-                                   (line-end-position))
-          (unless (eq ivy-exit 'done)
-            (swiper--cleanup)
-            (swiper--add-overlays (ivy--regex ivy-text))))))))
-
-(defun swiper-all-buffer-p (buffer)
-  "Return non-nil if BUFFER should be considered by `swiper-all'."
-  (let ((mode (buffer-local-value 'major-mode (get-buffer buffer))))
-    (cond
-      ;; Ignore TAGS buffers, they tend to add duplicate results.
-      ((eq mode #'tags-table-mode) nil)
-      ;; Always consider dired buffers, even though they're not backed
-      ;; by a file.
-      ((eq mode #'dired-mode) t)
-      ;; Always consider stash buffers too, as they may have
-      ;; interesting content not present in any buffers. We don't #'
-      ;; quote to satisfy the byte-compiler.
-      ((eq mode 'magit-stash-mode) t)
-      ;; Email buffers have no file, but are useful to search
-      ((eq mode 'gnus-article-mode) t)
-      ;; Otherwise, only consider the file if it's backed by a file.
-      (t (buffer-file-name buffer)))))
-
-;;* `swiper-all'
-(defun swiper-all-function (str)
-  "Search in all open buffers for STR."
-  (or
-   (ivy-more-chars)
-   (let* ((buffers (cl-remove-if-not #'swiper-all-buffer-p (buffer-list)))
-          (re-full (funcall ivy--regex-function str))
-          re re-tail
-          cands match
-          (case-fold-search (ivy--case-fold-p str)))
-     (setq re (ivy-re-to-str re-full))
-     (when (consp re-full)
-       (setq re-tail (cdr re-full)))
-     (dolist (buffer buffers)
-       (with-current-buffer buffer
-         (save-excursion
-           (goto-char (point-min))
-           (while (re-search-forward re nil t)
-             (setq match (if (memq major-mode '(org-mode dired-mode))
-                             (buffer-substring-no-properties
-                              (line-beginning-position)
-                              (line-end-position))
-                           (buffer-substring
-                            (line-beginning-position)
-                            (line-end-position))))
-             (put-text-property
-              0 1 'buffer
-              (buffer-name)
-              match)
-             (put-text-property 0 1 'point (point) match)
-             (when (or (null re-tail) (ivy-re-match re-tail match))
-               (push match cands))))))
-     (setq ivy--old-re re-full)
-     (if (null cands)
-         (list "")
-       (setq ivy--old-cands (nreverse cands))))))
-
-(defun swiper--all-format-function (cands)
-  "Format CANDS for `swiper-all'.
-See `ivy-format-functions-alist' for further information."
-  (let* ((ww swiper-window-width)
-         (col2 1)
-         (cands-with-buffer
-          (mapcar (lambda (s)
-                    (let ((buffer (get-text-property 0 'buffer s)))
-                      (setq col2 (max col2 (length buffer)))
-                      (cons s buffer))) cands))
-         (col1 (- ww 4 col2)))
-    (setq cands
-          (mapcar (lambda (x)
-                    (if (cdr x)
-                        (let ((s (ivy--truncate-string (car x) col1)))
-                          (concat
-                           s
-                           (make-string
-                            (max 0
-                                 (- ww (string-width s) (length (cdr x))))
-                            ?\ )
-                           (cdr x)))
-                      (car x)))
-                  cands-with-buffer))
-    (ivy--format-function-generic
-     (lambda (str)
-       (ivy--add-face str 'ivy-current-match))
-     (lambda (str)
-       str)
-     cands
-     "\n")))
-
-(defvar swiper-all-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "M-q") 'swiper-all-query-replace)
-    map)
-  "Keymap for `swiper-all'.")
-
-;;;###autoload
-(defun swiper-all (&optional initial-input)
-  "Run `swiper' for all open buffers."
-  (interactive)
-  (let ((swiper-window-width (- (frame-width) (if (display-graphic-p) 0 1))))
-    (ivy-read "swiper-all: " 'swiper-all-function
-              :action #'swiper-all-action
-              :dynamic-collection t
-              :keymap swiper-all-map
-              :initial-input initial-input
-              :caller 'swiper-all)))
-
-(ivy-configure 'swiper-all
-  :update-fn 'auto
-  :unwind-fn #'swiper--cleanup
-  :format-fn #'swiper--all-format-function)
-
-(defun swiper-all-action (x)
-  "Move to candidate X from `swiper-all'."
-  (when (> (length x) 0)
-    (let ((buffer-name (get-text-property 0 'buffer x)))
-      (when buffer-name
-        (with-ivy-window
-          (switch-to-buffer buffer-name)
-          (goto-char (get-text-property 0 'point x))
-          (isearch-range-invisible (line-beginning-position)
-                                   (line-end-position))
-          (unless (eq ivy-exit 'done)
-            (swiper--cleanup)
-            (swiper--add-overlays (ivy--regex ivy-text))))))))
-
-(defun swiper--multi-candidates (buffers)
-  "Extract candidates from BUFFERS."
-  (let ((res nil))
-    (dolist (buf buffers)
-      (with-current-buffer buf
-        (setq res
-              (nconc
-               (mapcar
-                (lambda (s) (put-text-property 0 1 'buffer (buffer-name) s) s)
-                (swiper--candidates 4))
-               res))))
-    res))
-
-;;* `swiper-isearch'
-(defun swiper-isearch-function (str)
-  "Collect STR matches in the current buffer for `swiper-isearch'."
-  (with-ivy-window
-    (swiper--isearch-function str)))
-
-(defun swiper-match-usable-p ()
-  (or search-invisible
-      (not (cl-find-if
-            (lambda (ov)
-              (invisible-p (overlay-get ov 'invisible)))
-            (overlays-at (point))))))
-
-(defvar swiper--isearch-backward nil)
-(defvar swiper--isearch-start-point nil)
-
-(defun swiper--isearch-function-1 (re backward)
-  (unless (string= re ".")
-    (let (cands)
-      (save-excursion
-        (goto-char (if backward (point-max) (point-min)))
-        (while (and (funcall (if backward #'re-search-backward 
#'re-search-forward) re nil t)
-                    (not (if backward (bobp) (eobp))))
-          (when (swiper-match-usable-p)
-            (let ((pos (if (or backward swiper-goto-start-of-match)
-                           (match-beginning 0)
-                         (point))))
-              (push pos cands)))
-          (when (= (match-beginning 0) (match-end 0))
-            (if backward
-                (backward-char)
-              (forward-char)))))
-      (if backward
-          cands
-        (nreverse cands)))))
-
-(defun swiper--isearch-next-item (re cands)
-  (if swiper--isearch-backward
-      (or
-       (cl-position-if
-        (lambda (x)
-          (and
-           (< x swiper--isearch-start-point)
-           (eq 0 (string-match-p
-                  re
-                  (buffer-substring-no-properties
-                   x swiper--isearch-start-point)))))
-        cands
-        :from-end t)
-       0)
-    (or
-     (cl-position-if
-      (lambda (x) (> x swiper--isearch-start-point))
-      cands)
-     0)))
-
-(defun swiper--isearch-filter-ignore-order (re-full cands)
-  (let (filtered-cands)
-    (dolist (re-cons re-full cands)
-      (save-excursion
-        (dolist (cand cands)
-          (goto-char cand)
-          (beginning-of-line)
-          (unless (if (re-search-forward (car re-cons) (line-end-position) t)
-                      (not (cdr re-cons))
-                    (cdr re-cons))
-            (push cand filtered-cands))))
-      (setq cands (nreverse filtered-cands))
-      (setq filtered-cands nil))))
-
-(defun swiper--isearch-function (str)
-  (let ((re-full (funcall ivy--regex-function str)))
-    (unless (equal re-full "")
-      (let* ((case-fold-search (ivy--case-fold-p str))
-             (re
-              (if (stringp re-full)
-                  re-full
-                (mapconcat
-                 #'ivy--regex-or-literal
-                 (delq nil (mapcar (lambda (x) (and (cdr x) (car x))) re-full))
-                 "\\|")))
-             (cands (swiper--isearch-function-1 re swiper--isearch-backward)))
-        (when (consp re-full)
-          (setq cands (swiper--isearch-filter-ignore-order re-full cands)))
-        (setq ivy--old-re re)
-        (ivy-set-index (swiper--isearch-next-item re cands))
-        (setq ivy--old-cands cands)))))
-
-(defcustom swiper-isearch-highlight-delay '(2 0.2)
-  "When `ivy-text' is too short, delay showing the overlay.
-
-The default value will delay showing the overlay by 0.2 seconds
-if `ivy-text' is shorter than 2 characters.
-
-The aim is to reduce the visual clutter, since it's very rare
-that we search only for one character."
-  :type '(list
-          (integer :tag "Text length")
-          (float :tag "Delay in seconds")))
-
-(defun swiper--delayed-add-overlays ()
-  (if (and swiper-isearch-highlight-delay
-           (< (length ivy-text) (car swiper-isearch-highlight-delay)))
-      (setq swiper--isearch-highlight-timer
-            (run-with-idle-timer
-             (cadr swiper-isearch-highlight-delay) nil
-             (lambda ()
-               (with-ivy-window
-                 (swiper--add-overlays (ivy--regex ivy-text))))))
-    (dolist (re (swiper--positive-regexps ivy-text))
-      (swiper--add-overlays re))))
-
-(defun swiper-isearch-action (x)
-  "Move to X for `swiper-isearch'."
-  (if (or (numberp x)
-          (and (> (length x) 0)
-               (setq x (get-text-property 0 'point x))))
-      (with-ivy-window
-        (goto-char x)
-        (when (and (or (eq this-command 'ivy-previous-line-or-history)
-                       (and (eq this-command 'ivy-done)
-                            (eq last-command 'ivy-previous-line-or-history)))
-                   (looking-back ivy--old-re (line-beginning-position)))
-          (goto-char (match-beginning 0)))
-        (isearch-range-invisible (point) (1+ (point)))
-        (swiper--maybe-recenter)
-        (unless (eq ivy-exit 'done)
-          (swiper--cleanup)
-          (swiper--delayed-add-overlays)
-          (swiper--add-cursor-overlay
-           (ivy-state-window ivy-last))))
-    (swiper--cleanup)))
-
-(defun swiper-action-copy (_x)
-  "Copy line at point and go back."
-  (kill-new
-   (buffer-substring-no-properties
-    (line-beginning-position) (line-end-position)))
-  (goto-char swiper--opoint))
-
-(ivy-add-actions 'swiper-isearch '(("w" swiper-action-copy "copy")))
-(ivy-add-actions 'swiper '(("w" swiper-action-copy "copy")))
-
-(defun swiper-isearch-thing-at-point ()
-  "Insert `symbol-at-point' into the minibuffer of `swiper-isearch'.
-When not running `swiper-isearch' already, start it."
-  (interactive)
-  (if (window-minibuffer-p)
-      (let (bnd str regionp)
-        (with-ivy-window
-          (setq bnd
-                (if (setq regionp (region-active-p))
-                    (prog1 (cons (region-beginning) (region-end))
-                      (deactivate-mark))
-                  (bounds-of-thing-at-point 'symbol)))
-          (setq str (buffer-substring-no-properties (car bnd) (cdr bnd))))
-        (insert str)
-        (unless regionp
-          (ivy--insert-symbol-boundaries)))
-    (let (thing)
-      (if (use-region-p)
-          (progn
-            (setq thing (buffer-substring-no-properties
-                         (region-beginning) (region-end)))
-            (goto-char (region-beginning))
-            (deactivate-mark))
-        (let ((bnd (bounds-of-thing-at-point 'symbol)))
-          (when bnd
-            (goto-char (car bnd)))
-          (setq thing (ivy-thing-at-point))))
-      (swiper-isearch thing))))
-
-(defvar swiper-isearch-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map swiper-map)
-    (define-key map (kbd "M-n") 'swiper-isearch-thing-at-point)
-    map)
-  "Keymap for `swiper-isearch'.")
-
-(defun swiper--isearch-same-line-p (s1 s2)
-  "Check if S1 and S2 are equal and on the same line."
-  (and (equal s1 s2)
-       (<= (count-lines
-            (get-text-property 0 'point s2)
-            (get-text-property 0 'point s1))
-           1)))
-
-(defun swiper-isearch-format-function (cands)
-  (if (numberp (car-safe cands))
-      (if (string= ivy--old-re "^$")
-          ""
-        (swiper--isearch-format
-         ivy--index ivy--length ivy--old-cands
-         ivy--old-re
-         (ivy-state-current ivy-last)
-         (ivy-state-buffer ivy-last)))
-    (ivy-format-function-default cands)))
-
-(defun swiper--line-at-point (pt)
-  (save-excursion
-    (goto-char pt)
-    (let ((s (buffer-substring
-              (line-beginning-position)
-              (line-end-position))))
-      (put-text-property 0 1 'point pt s)
-      (ivy-cleanup-string s))))
-
-(defun swiper--isearch-highlight (str &optional current)
-  (let ((start 0)
-        (i 0))
-    (while (string-match ivy--old-re str start)
-      (setq start (match-end 0))
-      (swiper--add-properties
-       (if (eq current i)
-           swiper-faces
-         swiper-background-faces)
-       (lambda (beg end face _priority)
-         (ivy-add-face-text-property
-          beg end face str)))
-      (cl-incf i))
-    str))
-
-(defun swiper--isearch-format (index length cands regex current buffer)
-  (let* ((half-height (/ ivy-height 2))
-         (i (1- index))
-         (j 0)
-         (len 0)
-         res s)
-    (with-current-buffer buffer
-      (while (and (>= i 0)
-                  (swiper--isearch-same-line-p
-                   (swiper--line-at-point (nth i cands))
-                   (swiper--line-at-point current)))
-        (cl-decf i)
-        (cl-incf j))
-      (while (and (>= i 0)
-                  (< len half-height))
-        (setq s (swiper--line-at-point (nth i cands)))
-        (unless (swiper--isearch-same-line-p s (car res))
-          (push (swiper--isearch-highlight s) res)
-          (cl-incf len))
-        (cl-decf i))
-      (setq res (nreverse res))
-      (let ((current-str
-             (swiper--line-at-point current))
-            (start 0))
-        (dotimes (_ (1+ j))
-          (string-match regex current-str start)
-          (setq start (match-end 0)))
-        (swiper--isearch-highlight current-str j)
-        (font-lock-append-text-property
-         0 (length current-str)
-         'face 'swiper-line-face current-str)
-        (push current-str res))
-      (cl-incf len)
-      (setq i (1+ index))
-      (while (and (< i length)
-                  (swiper--isearch-same-line-p
-                   (swiper--line-at-point (nth i cands))
-                   (swiper--line-at-point current)))
-        (cl-incf i))
-      (while (and (< i length)
-                  (< len ivy-height))
-        (setq s (swiper--line-at-point (nth i cands)))
-        (unless (swiper--isearch-same-line-p s (car res))
-          (push (swiper--isearch-highlight s) res)
-          (cl-incf len))
-        (cl-incf i))
-      (mapconcat #'identity (nreverse res) "\n"))))
-
-;;;###autoload
-(defun swiper-isearch (&optional initial-input)
-  "A `swiper' that's not line-based."
-  (interactive)
-  (swiper--init)
-  (setq swiper--isearch-start-point (point))
-  (swiper-font-lock-ensure)
-  (let ((ivy-fixed-height-minibuffer t)
-        (cursor-in-non-selected-windows nil)
-        (swiper-min-highlight 1)
-        res)
-    (unwind-protect
-         (and
-          (setq res
-                (ivy-read
-                 "Swiper: "
-                 #'swiper-isearch-function
-                 :initial-input initial-input
-                 :keymap swiper-isearch-map
-                 :dynamic-collection t
-                 :require-match t
-                 :action #'swiper-isearch-action
-                 :re-builder #'swiper--re-builder
-                 :history 'swiper-history
-                 :extra-props (list :fname (buffer-file-name))
-                 :caller 'swiper-isearch))
-          (point))
-      (unless (or res swiper-stay-on-quit)
-        (goto-char swiper--opoint))
-      (isearch-clean-overlays)
-      (swiper--ensure-visible)
-      (unless (or res (string= ivy-text ""))
-        (cl-pushnew ivy-text swiper-history)))))
-
-(ivy-configure 'swiper-isearch
-  :occur #'swiper-occur
-  :update-fn 'auto
-  :unwind-fn #'swiper--cleanup
-  :format-fn #'swiper-isearch-format-function)
-
-;;;###autoload
-(defun swiper-isearch-backward (&optional initial-input)
-  "Like `swiper-isearch' but the first result is before the point."
-  (interactive)
-  (let ((swiper--isearch-backward t))
-    (swiper-isearch initial-input)))
-
-(defun swiper-isearch-toggle ()
-  "Two-way toggle between `swiper-isearch' and isearch.
-Intended to be bound in `isearch-mode-map' and `swiper-map'."
-  (interactive)
-  (if isearch-mode
-      (let ((query (if isearch-regexp
-                       isearch-string
-                     (regexp-quote isearch-string))))
-        (isearch-exit)
-        (goto-char (or (and isearch-forward isearch-other-end)
-                       (point)))
-        (swiper-isearch query))
-    (ivy-exit-with-action
-     (lambda (_)
-       (when (looking-back ivy--old-re (line-beginning-position))
-         (goto-char (match-beginning 0)))
-       (isearch-mode t)
-       (unless (string= ivy-text "")
-         (isearch-yank-string ivy-text))))))
-
-(provide 'swiper)
-
-;;; swiper.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]