diff options
| -rw-r--r-- | LICENSE | 674 | ||||
| -rw-r--r-- | README.org | 221 | ||||
| -rw-r--r-- | cape.el | 1030 | ||||
| -rw-r--r-- | cape.png | bin | 0 -> 160562 bytes | |||
| -rw-r--r-- | orig.png | bin | 0 -> 148560 bytes |
5 files changed, 0 insertions, 1925 deletions
diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/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: - - <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/README.org b/README.org deleted file mode 100644 index 55f7330..0000000 --- a/README.org +++ /dev/null @@ -1,221 +0,0 @@ -#+title: cape.el - Let your completions fly! -#+author: Daniel Mendler -#+language: en -#+export_file_name: cape.texi -#+texinfo_dir_category: Emacs -#+texinfo_dir_title: Cape: (cape). -#+texinfo_dir_desc: Completion At Point Extensions - -#+html: <a href="https://www.gnu.org/software/emacs/"><img alt="GNU Emacs" src="https://github.com/minad/corfu/blob/screenshots/emacs.svg?raw=true"/></a> -#+html: <a href="http://elpa.gnu.org/packages/cape.html"><img alt="GNU ELPA" src="https://elpa.gnu.org/packages/cape.svg"/></a> -#+html: <a href="http://elpa.gnu.org/devel/cape.html"><img alt="GNU-devel ELPA" src="https://elpa.gnu.org/devel/cape.svg"/></a> -#+html: <a href="https://melpa.org/#/cape"><img alt="MELPA" src="https://melpa.org/packages/cape-badge.svg"/></a> -#+html: <a href="https://stable.melpa.org/#/cape"><img alt="MELPA Stable" src="https://stable.melpa.org/packages/cape-badge.svg"/></a> -#+html: <img src="https://upload.wikimedia.org/wikipedia/en/3/35/Supermanflying.png" align="right"> - -* Introduction - -Cape provides a bunch of Completion At Point Extensions which can be used in -combination with my [[https://github.com/minad/corfu][Corfu]] completion UI or the default completion UI. The -completion backends used by ~completion-at-point~ are so called -~completion-at-point-functions~ (Capfs). In principle, the Capfs provided by Cape -can also be used by [[https://github.com/company-mode/company-mode][Company]]. - -You can register the ~cape-*~ functions in the ~completion-at-point-functions~ list. -This makes the backends available for completion, which is usually invoked by -pressing ~TAB~ or ~M-TAB~. The functions can also be invoked interactively to -trigger the respective completion at point. You can bind them directly to a key -in your user configuration. Notable commands/capfs are ~cape-line~ for completion -of a line from the current buffer and ~cape-file~ for completion of a file name. -The command ~cape-symbol~ is particularily useful for documentation of Elisp -packages or configurations, since it completes elisp symbols anywere. - -On the more experimental side, Cape has the super power to transform Company -backends into Capfs and merge multiple Capfs into a Super-Capf! These -transformers allow you to still take advantage of Company backends even if you -are not using Company as frontend. - -* Available Capfs - -+ ~cape-dabbrev~: Complete word from current buffers -+ ~cape-file~: Complete file name -+ ~cape-keyword~: Complete programming language keyword -+ ~cape-symbol~: Complete Elisp symbol -+ ~cape-abbrev~: Complete abbreviation (~add-global-abbrev~, ~add-mode-abbrev~) -+ ~cape-ispell~: Complete word from Ispell dictionary -+ ~cape-dict~: Complete word from dictionary file -+ ~cape-line~: Complete entire line from file -+ ~cape-tex~: Complete unicode char from TeX command, e.g. ~\hbar~. -+ ~cape-sgml~: Complete unicode char from Sgml entity, e.g., ~&alpha~. -+ ~cape-rfc1345~: Complete unicode char using RFC 1345 mnemonics. - -* Configuration - -Cape is available from MELPA. In the long term some of the Capfs provided by -this package should be upstreamed into Emacs itself. - -#+begin_src emacs-lisp - ;; Enable Corfu completion UI - ;; See the Corfu README for more configuration tips. - (use-package corfu - :init - (corfu-global-mode)) - - ;; Add extensions - (use-package cape - ;; Bind dedicated completion commands - :bind (("C-c p p" . completion-at-point) ;; capf - ("C-c p t" . complete-tag) ;; etags - ("C-c p d" . cape-dabbrev) ;; or dabbrev-completion - ("C-c p f" . cape-file) - ("C-c p k" . cape-keyword) - ("C-c p s" . cape-symbol) - ("C-c p a" . cape-abbrev) - ("C-c p i" . cape-ispell) - ("C-c p l" . cape-line) - ("C-c p w" . cape-dict) - ("C-c p \\" . cape-tex) - ("C-c p &" . cape-sgml) - ("C-c p r" . cape-rfc1345)) - :init - ;; Add `completion-at-point-functions', used by `completion-at-point'. - (add-to-list 'completion-at-point-functions #'cape-file) - (add-to-list 'completion-at-point-functions #'cape-tex) - (add-to-list 'completion-at-point-functions #'cape-dabbrev) - (add-to-list 'completion-at-point-functions #'cape-keyword) - ;;(add-to-list 'completion-at-point-functions #'cape-sgml) - ;;(add-to-list 'completion-at-point-functions #'cape-rfc1345) - ;;(add-to-list 'completion-at-point-functions #'cape-abbrev) - ;;(add-to-list 'completion-at-point-functions #'cape-ispell) - ;;(add-to-list 'completion-at-point-functions #'cape-dict) - ;;(add-to-list 'completion-at-point-functions #'cape-symbol) - ;;(add-to-list 'completion-at-point-functions #'cape-line) - ) -#+end_src - -* Experimental features - -** Company adapter - -/Wrap your Company backend in a Cape and turn it into a Capf!/ - -Cape provides an adapter for Company backends ~cape-company-to-capf~. The adapter -transforms Company backends to Capfs which are understood by the built-in Emacs -completion mechanism. The function is approximately the inverse of the -~company-capf~ backend from Company. The adapter is still experimental and may -have certain edge cases. The adapter can be used as follows: - -#+begin_src emacs-lisp - ;; Use Company backends as Capfs. - (setq-local completion-at-point-functions - (mapcar #'cape-company-to-capf - (list #'company-files #'company-ispell #'company-dabbrev))) -#+end_src - -Note that the adapter does not require Company to be installed. Backends -implementing the Company specification do not necessarily have to depend on -Company, however in practice most backends do. The following shows a small -example completion backend, which can be used with both ~completion-at-point~ -(Corfu, default completion) and Company. - -#+begin_src emacs-lisp - (defvar emojis - '((":-D" . "😀") - (";-)" . "😉") - (":-/" . "😕") - (":-(" . "🙁") - (":-*" . "😙"))) - - (defun emoji-backend (action &optional arg &rest _) - (pcase action - ('prefix (and (memq (char-before) '(?: ?\;)) - (cons (string (char-before)) t))) - ('candidates (all-completions arg emojis)) - ('annotation (concat " " (cdr (assoc arg emojis)))) - ('post-completion - (let ((str (buffer-substring (- (point) 3) (point)))) - (delete-region (- (point) 3) (point)) - (insert (cdr (assoc str emojis))))))) - - ;; Register emoji backend with `completion-at-point' - (setq completion-at-point-functions - (list (cape-company-to-capf #'emoji-backend))) - - ;; Register emoji backend with Company. - (setq company-backends '(emoji-backend)) -#+end_src - -It is possible to merge/group multiple Company backends and use them as a single -Capf using the ~company--multi-backend-adapter~ function from Company. The adapter -transforms multiple Company backends into a single Company backend, which can -then be used as a Capf via ~cape-company-to-capf~. - -#+begin_src emacs-lisp - (require 'company) - ;; Use the company-dabbrev and company-elisp backends together. - (setq completion-at-point-functions - (list - (cape-company-to-capf - (apply-partially #'company--multi-backend-adapter - '(company-dabbrev company-elisp))))) -#+end_src - -** Super-Capf - Merging multiple Capfs - -/Throw multiple Capfs under the Cape and get a Super-Capf!/ - -Cape supports merging multiple Capfs using the function ~cape-super-capf~. This -feature is experimental and should only be used in special scenarios. - -Note that ~cape-super-capf~ is not needed if you want to use multiple Capfs which -are tried one by one, e.g., it is perfectly possible to use ~cape-file~ together -with the lsp-mode Capf or other programming mode Capfs by adding ~cape-file~ to -the ~completion-at-point-functions~ list. The file completion will be available in -comments and string literals. ~cape-super-capf~ is only needed if you want to -combine multiple Capfs, such that the candidates from multiple sources appear -/together/ in the completion list at the same time. - -Completion table merging works only for tables which are sufficiently -well-behaved and tables which do not define completion boundaries. -~cape-super-capf~ has the same restrictions as ~completion-table-merge~ and -~completion-table-in-turn~. - -#+begin_src emacs-lisp - ;; Merge the dabbrev, dict and keyword capfs, display candidates together. - (setq-local completion-at-point-functions - (list (cape-super-capf #'cape-dabbrev #'cape-dict #'cape-keyword))) -#+end_src - -See also the aforementioned ~company--multi-backend-adapter~ from Company, which -allows you to merge multiple Company backends. - -** Capf-Buster - Cache busting - -/The Capf-Buster ensures that you always get a fresh set of candidates!/ - -If a Capf caches the candidates for too long we can use a cache busting -Capf-transformer. For example the Capf merging function ~cape-super-capf~ creates -a Capf, which caches the candidates for the whole lifetime of the Capf. -Therefore you may want to combine a merged Capf with a cache buster under some -circumstances. It is noteworthy that the ~company-capf~ backend from Company -refreshes the completion table frequently. With the ~cape-capf-buster~ we can -achieve a similarly refreshing strategy. - -#+begin_src emacs-lisp - (setq-local completion-at-point-functions - (list (cape-capf-buster #'some-caching-capf))) -#+end_src - -** Other Capf transformers - -- ~cape-silent-capf~: Wrap a chatty Capf and silence it. -- ~cape-noninterruptible-capf~: Protect a Capf which does not like to be interrupted. -- ~cape-interactive-capf~: Create a Capf which can be called interactively. -- ~cape-capf-case-fold~: Create a Capf which is case insensitive. -- ~cape-capf-with-properties~: Add completion properties to a Capf. -- ~cape-capf-with-predicate~: Add candidate predicate to a Capf. - -* Contributions - -Since this package is part of [[http://elpa.gnu.org/packages/marginalia.html][GNU ELPA]] contributions require a copyright -assignment to the FSF. diff --git a/cape.el b/cape.el deleted file mode 100644 index 9ddcc17..0000000 --- a/cape.el +++ /dev/null @@ -1,1030 +0,0 @@ -;;; cape.el --- Completion At Point Extensions -*- lexical-binding: t -*- - -;; Copyright (C) 2021 Free Software Foundation, Inc. - -;; Author: Daniel Mendler <mail@daniel-mendler.de> -;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> -;; Created: 2021 -;; Version: 0.5 -;; Package-Requires: ((emacs "27.1")) -;; Homepage: https://github.com/minad/cape - -;; 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/>. - -;;; Commentary: - -;; Let your completions fly! This package provides additional completion -;; backends in the form of Capfs (completion-at-point-functions). -;; -;; cape-dabbrev: Complete word from current buffers -;; cape-file: Complete file name -;; cape-keyword: Complete programming language keyword -;; cape-symbol: Complete Elisp symbol -;; cape-abbrev: Complete abbreviation (add-global-abbrev, add-mode-abbrev) -;; cape-ispell: Complete word from Ispell dictionary -;; cape-dict: Complete word from dictionary file -;; cape-line: Complete entire line from file -;; cape-tex: Complete unicode char from TeX command, e.g. \hbar. -;; cape-sgml: Complete unicode char from Sgml entity, e.g., &alpha. -;; cape-rfc1345: Complete unicode char using RFC 1345 mnemonics. - -;;; Code: - -(eval-when-compile - (require 'cl-lib) - (require 'subr-x)) - -(autoload 'thing-at-point-looking-at "thingatpt") - -;;;; Customization - -(defgroup cape nil - "Completion At Point Extensions." - :group 'convenience - :prefix "cape-") - -(defcustom cape-dict-file "/etc/dictionaries-common/words" - "Dictionary word list file." - :type 'string) - -(defcustom cape-company-timeout 5.0 - "Company asynchronous timeout." - :type '(choice nil float)) - -(defcustom cape-dabbrev-min-length 4 - "Minimum length of dabbrev expansions." - :type 'integer) - -(defcustom cape-dabbrev-check-other-buffers t - "Buffers to check for dabbrev." - :type 'boolean) - -(defcustom cape-file-directory-must-exist t - "The parent directory must exist for file completion." - :type 'integer) - -(defcustom cape-keywords - ;; This variable was taken from company-keywords.el. - ;; Please contribute corrections or additions to both Cape and Company. - '((c++-mode ;; https://en.cppreference.com/w/cpp/keyword - "alignas" "alignof" "and" "and_eq" "asm" "atomic_cancel" "atomic_commit" - "atomic_noexcept" "auto" "bitand" "bitor" "bool" "break" "case" "catch" - "char" "char16_t" "char32_t" "char8_t" "class" "co_await" "co_return" - "co_yield" "compl" "concept" "const" "const_cast" "consteval" "constexpr" - "constinit" "continue" "decltype" "default" "delete" "do" "double" - "dynamic_cast" "else" "enum" "explicit" "export" "extern" "false" "final" - "float" "for" "friend" "goto" "if" "import" "inline" "int" "long" "module" - "mutable" "namespace" "new" "noexcept" "not" "not_eq" "nullptr" "operator" - "or" "or_eq" "override" "private" "protected" "public" "reflexpr" "register" - "reinterpret_cast" "requires" "return" "short" "signed" "sizeof" "static" - "static_assert" "static_cast" "struct" "switch" "synchronized" "template" - "this" "thread_local" "throw" "true" "try" "typedef" "typeid" "typename" - "union" "unsigned" "using" "virtual" "void" "volatile" "wchar_t" "while" - "xor" "xor_eq") - (c-mode ;; https://en.cppreference.com/w/c/keyword - "_Alignas" "_Alignof" "_Atomic" "_Bool" "_Complex" "_Generic" "_Imaginary" - "_Noreturn" "_Static_assert" "_Thread_local" - "auto" "break" "case" "char" "const" "continue" "default" "do" - "double" "else" "enum" "extern" "float" "for" "goto" "if" "inline" - "int" "long" "register" "restrict" "return" "short" "signed" "sizeof" - "static" "struct" "switch" "typedef" "union" "unsigned" "void" "volatile" - "while") - (csharp-mode - "abstract" "add" "alias" "as" "base" "bool" "break" "byte" "case" - "catch" "char" "checked" "class" "const" "continue" "decimal" "default" - "delegate" "do" "double" "else" "enum" "event" "explicit" "extern" - "false" "finally" "fixed" "float" "for" "foreach" "get" "global" "goto" - "if" "implicit" "in" "int" "interface" "internal" "is" "lock" "long" - "namespace" "new" "null" "object" "operator" "out" "override" "params" - "partial" "private" "protected" "public" "readonly" "ref" "remove" - "return" "sbyte" "sealed" "set" "short" "sizeof" "stackalloc" "static" - "string" "struct" "switch" "this" "throw" "true" "try" "typeof" "uint" - "ulong" "unchecked" "unsafe" "ushort" "using" "value" "var" "virtual" - "void" "volatile" "where" "while" "yield") - (d-mode ;; http://www.digitalmars.com/d/2.0/lex.html - "abstract" "alias" "align" "asm" - "assert" "auto" "body" "bool" "break" "byte" "case" "cast" "catch" - "cdouble" "cent" "cfloat" "char" "class" "const" "continue" "creal" - "dchar" "debug" "default" "delegate" "delete" "deprecated" "do" - "double" "else" "enum" "export" "extern" "false" "final" "finally" - "float" "for" "foreach" "foreach_reverse" "function" "goto" "idouble" - "if" "ifloat" "import" "in" "inout" "int" "interface" "invariant" - "ireal" "is" "lazy" "long" "macro" "mixin" "module" "new" "nothrow" - "null" "out" "override" "package" "pragma" "private" "protected" - "public" "pure" "real" "ref" "return" "scope" "short" "static" "struct" - "super" "switch" "synchronized" "template" "this" "throw" "true" "try" - "typedef" "typeid" "typeof" "ubyte" "ucent" "uint" "ulong" "union" - "unittest" "ushort" "version" "void" "volatile" "wchar" "while" "with") - (f90-mode ;; f90.el - "abs" "abstract" "achar" "acos" "adjustl" "adjustr" "aimag" "aint" - "align" "all" "all_prefix" "all_scatter" "all_suffix" "allocatable" - "allocate" "allocated" "and" "anint" "any" "any_prefix" "any_scatter" - "any_suffix" "asin" "assign" "assignment" "associate" "associated" - "asynchronous" "atan" "atan2" "backspace" "bind" "bit_size" "block" - "btest" "c_alert" "c_associated" "c_backspace" "c_bool" - "c_carriage_return" "c_char" "c_double" "c_double_complex" "c_f_pointer" - "c_f_procpointer" "c_float" "c_float_complex" "c_form_feed" "c_funloc" - "c_funptr" "c_horizontal_tab" "c_int" "c_int16_t" "c_int32_t" "c_int64_t" - "c_int8_t" "c_int_fast16_t" "c_int_fast32_t" "c_int_fast64_t" - "c_int_fast8_t" "c_int_least16_t" "c_int_least32_t" "c_int_least64_t" - "c_int_least8_t" "c_intmax_t" "c_intptr_t" "c_loc" "c_long" - "c_long_double" "c_long_double_complex" "c_long_long" "c_new_line" - "c_null_char" "c_null_funptr" "c_null_ptr" "c_ptr" "c_short" - "c_signed_char" "c_size_t" "c_vertical_tab" "call" "case" "ceiling" - "char" "character" "character_storage_size" "class" "close" "cmplx" - "command_argument_count" "common" "complex" "conjg" "contains" "continue" - "copy_prefix" "copy_scatter" "copy_suffix" "cos" "cosh" "count" - "count_prefix" "count_scatter" "count_suffix" "cpu_time" "cshift" - "cycle" "cyclic" "data" "date_and_time" "dble" "deallocate" "deferred" - "digits" "dim" "dimension" "distribute" "do" "dot_product" "double" - "dprod" "dynamic" "elemental" "else" "elseif" "elsewhere" "end" "enddo" - "endfile" "endif" "entry" "enum" "enumerator" "eoshift" "epsilon" "eq" - "equivalence" "eqv" "error_unit" "exit" "exp" "exponent" "extends" - "extends_type_of" "external" "extrinsic" "false" "file_storage_size" - "final" "floor" "flush" "forall" "format" "fraction" "function" "ge" - "generic" "get_command" "get_command_argument" "get_environment_variable" - "goto" "grade_down" "grade_up" "gt" "hpf_alignment" "hpf_distribution" - "hpf_template" "huge" "iachar" "iall" "iall_prefix" "iall_scatter" - "iall_suffix" "iand" "iany" "iany_prefix" "iany_scatter" "iany_suffix" - "ibclr" "ibits" "ibset" "ichar" "ieee_arithmetic" "ieee_exceptions" - "ieee_features" "ieee_get_underflow_mode" "ieee_set_underflow_mode" - "ieee_support_underflow_control" "ieor" "if" "ilen" "implicit" - "import" "include" "independent" "index" "inherit" "input_unit" - "inquire" "int" "integer" "intent" "interface" "intrinsic" "ior" - "iostat_end" "iostat_eor" "iparity" "iparity_prefix" "iparity_scatter" - "iparity_suffix" "ishft" "ishftc" "iso_c_binding" "iso_fortran_env" - "kind" "lbound" "le" "leadz" "len" "len_trim" "lge" "lgt" "lle" "llt" - "log" "log10" "logical" "lt" "matmul" "max" "maxexponent" "maxloc" - "maxval" "maxval_prefix" "maxval_scatter" "maxval_suffix" "merge" - "min" "minexponent" "minloc" "minval" "minval_prefix" "minval_scatter" - "minval_suffix" "mod" "module" "modulo" "move_alloc" "mvbits" "namelist" - "ne" "nearest" "neqv" "new" "new_line" "nint" "non_intrinsic" - "non_overridable" "none" "nopass" "not" "null" "nullify" - "number_of_processors" "numeric_storage_size" "only" "onto" "open" - "operator" "optional" "or" "output_unit" "pack" "parameter" "parity" - "parity_prefix" "parity_scatter" "parity_suffix" "pass" "pause" - "pointer" "popcnt" "poppar" "precision" "present" "print" "private" - "procedure" "processors" "processors_shape" "product" "product_prefix" - "product_scatter" "product_suffix" "program" "protected" "public" - "pure" "radix" "random_number" "random_seed" "range" "read" "real" - "realign" "recursive" "redistribute" "repeat" "reshape" "result" - "return" "rewind" "rrspacing" "same_type_as" "save" "scale" "scan" - "select" "selected_char_kind" "selected_int_kind" "selected_real_kind" - "sequence" "set_exponent" "shape" "sign" "sin" "sinh" "size" "spacing" - "spread" "sqrt" "stop" "subroutine" "sum" "sum_prefix" "sum_scatter" - "sum_suffix" "system_clock" "tan" "tanh" "target" "template" "then" - "tiny" "transfer" "transpose" "trim" "true" "type" "ubound" "unpack" - "use" "value" "verify" "volatile" "wait" "where" "while" "with" "write") - (go-mode ;; https://golang.org/ref/spec#Keywords, https://golang.org/pkg/builtin/ - "append" "bool" "break" "byte" "cap" "case" "chan" "close" "complex" "complex128" - "complex64" "const" "continue" "copy" "default" "defer" "delete" "else" "error" - "fallthrough" "false" "float32" "float64" "for" "func" "go" "goto" "if" "imag" - "import" "int" "int16" "int32" "int64" "int8" "interface" "len" "make" - "map" "new" "nil" "package" "panic" "print" "println" "range" "real" "recover" - "return" "rune" "select" "string" "struct" "switch" "true" "type" "uint" "uint16" - "uint32" "uint64" "uint8" "uintptr" "var") - (java-mode - "abstract" "assert" "boolean" "break" "byte" "case" "catch" "char" "class" - "continue" "default" "do" "double" "else" "enum" "extends" "final" - "finally" "float" "for" "if" "implements" "import" "instanceof" "int" - "interface" "long" "native" "new" "package" "private" "protected" "public" - "return" "short" "static" "strictfp" "super" "switch" "synchronized" - "this" "throw" "throws" "transient" "try" "void" "volatile" "while") - (javascript-mode ;; https://tc39.github.io/ecma262/ - "async" "await" "break" "case" "catch" "class" "const" "continue" - "debugger" "default" "delete" "do" "else" "enum" "export" "extends" "false" - "finally" "for" "function" "if" "import" "in" "instanceof" "let" "new" - "null" "return" "static" "super" "switch" "this" "throw" "true" "try" - "typeof" "undefined" "var" "void" "while" "with" "yield") - (kotlin-mode - "abstract" "annotation" "as" "break" "by" "catch" "class" "companion" - "const" "constructor" "continue" "data" "do" "else" "enum" "false" "final" - "finally" "for" "fun" "if" "import" "in" "init" "inner" "interface" - "internal" "is" "lateinit" "nested" "null" "object" "open" "out" "override" - "package" "private" "protected" "public" "return" "super" "this" "throw" - "trait" "true" "try" "typealias" "val" "var" "when" "while") - (lua-mode ;; https://www.lua.org/manual/5.3/manual.html - "and" "break" "do" "else" "elseif" "end" "false" "for" "function" "goto" "if" - "in" "local" "nil" "not" "or" "repeat" "return" "then" "true" "until" "while") - (objc-mode - "@catch" "@class" "@encode" "@end" "@finally" "@implementation" - "@interface" "@private" "@protected" "@protocol" "@public" - "@selector" "@synchronized" "@throw" "@try" "alloc" "autorelease" - "bycopy" "byref" "in" "inout" "oneway" "out" "release" "retain") - (perl-mode ;; cperl.el - "AUTOLOAD" "BEGIN" "CHECK" "CORE" "DESTROY" "END" "INIT" "__END__" - "__FILE__" "__LINE__" "abs" "accept" "alarm" "and" "atan2" "bind" - "binmode" "bless" "caller" "chdir" "chmod" "chomp" "chop" "chown" "chr" - "chroot" "close" "closedir" "cmp" "connect" "continue" "cos" - "crypt" "dbmclose" "dbmopen" "defined" "delete" "die" "do" "dump" "each" - "else" "elsif" "endgrent" "endhostent" "endnetent" "endprotoent" - "endpwent" "endservent" "eof" "eq" "eval" "exec" "exists" "exit" "exp" - "fcntl" "fileno" "flock" "for" "foreach" "fork" "format" "formline" - "ge" "getc" "getgrent" "getgrgid" "getgrnam" "gethostbyaddr" - "gethostbyname" "gethostent" "getlogin" "getnetbyaddr" "getnetbyname" - "getnetent" "getpeername" "getpgrp" "getppid" "getpriority" - "getprotobyname" "getprotobynumber" "getprotoent" "getpwent" "getpwnam" - "getpwuid" "getservbyname" "getservbyport" "getservent" "getsockname" - "getsockopt" "glob" "gmtime" "goto" "grep" "gt" "hex" "if" "index" "int" - "ioctl" "join" "keys" "kill" "last" "lc" "lcfirst" "le" "length" - "link" "listen" "local" "localtime" "lock" "log" "lstat" "lt" "map" - "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "my" "ne" "next" "no" - "not" "oct" "open" "opendir" "or" "ord" "our" "pack" "package" "pipe" - "pop" "pos" "print" "printf" "push" "q" "qq" "quotemeta" "qw" "qx" - "rand" "read" "readdir" "readline" "readlink" "readpipe" "recv" "redo" - "ref" "rename" "require" "reset" "return" "reverse" "rewinddir" "rindex" - "rmdir" "scalar" "seek" "seekdir" "select" "semctl" "semget" "semop" - "send" "setgrent" "sethostent" "setnetent" "setpgrp" "setpriority" - "setprotoent" "setpwent" "setservent" "setsockopt" "shift" "shmctl" - "shmget" "shmread" "shmwrite" "shutdown" "sin" "sleep" "socket" - "socketpair" "sort" "splice" "split" "sprintf" "sqrt" "srand" "stat" - "study" "sub" "substr" "symlink" "syscall" "sysopen" "sysread" "system" - "syswrite" "tell" "telldir" "tie" "time" "times" "tr" "truncate" "uc" - "ucfirst" "umask" "undef" "unless" "unlink" "unpack" "unshift" "untie" - "until" "use" "utime" "values" "vec" "wait" "waitpid" - "wantarray" "warn" "while" "write" "x" "xor" "y") - (php-mode - "__CLASS__" "__DIR__" "__FILE__" "__FUNCTION__" "__LINE__" "__METHOD__" - "__NAMESPACE__" "_once" "abstract" "and" "array" "as" "break" "case" - "catch" "cfunction" "class" "clone" "const" "continue" "declare" - "default" "die" "do" "echo" "else" "elseif" "empty" "enddeclare" - "endfor" "endforeach" "endif" "endswitch" "endwhile" "eval" "exception" - "exit" "extends" "final" "for" "foreach" "function" "global" - "goto" "if" "implements" "include" "instanceof" "interface" - "isset" "list" "namespace" "new" "old_function" "or" "php_user_filter" - "print" "private" "protected" "public" "require" "require_once" "return" - "static" "switch" "this" "throw" "try" "unset" "use" "var" "while" "xor") - (python-mode ;; https://docs.python.org/3/reference/lexical_analysis.html#keywords - "False" "None" "True" "and" "as" "assert" "break" "class" "continue" "def" - "del" "elif" "else" "except" "exec" "finally" "for" "from" "global" "if" - "import" "in" "is" "lambda" "nonlocal" "not" "or" "pass" "print" "raise" - "return" "try" "while" "with" "yield") - (ruby-mode - "BEGIN" "END" "alias" "and" "begin" "break" "case" "class" "def" "defined?" - "do" "else" "elsif" "end" "ensure" "false" "for" "if" "in" "module" - "next" "nil" "not" "or" "redo" "rescue" "retry" "return" "self" "super" - "then" "true" "undef" "unless" "until" "when" "while" "yield") - (rust-mode ;; https://doc.rust-lang.org/grammar.html#keywords - "Self" "as" "box" "break" "const" "continue" "crate" "else" "enum" "extern" - "false" "fn" "for" "if" "impl" "in" "let" "loop" "macro" "match" "mod" - "move" "mut" "pub" "ref" "return" "self" "static" "struct" "super" - "trait" "true" "type" "unsafe" "use" "where" "while") - (scala-mode - "abstract" "case" "catch" "class" "def" "do" "else" "extends" "false" - "final" "finally" "for" "forSome" "if" "implicit" "import" "lazy" "match" - "new" "null" "object" "override" "package" "private" "protected" - "return" "sealed" "super" "this" "throw" "trait" "true" "try" "type" "val" - "var" "while" "with" "yield") - (swift-mode - "Protocol" "Self" "Type" "and" "as" "assignment" "associatedtype" - "associativity" "available" "break" "case" "catch" "class" "column" "continue" - "convenience" "default" "defer" "deinit" "didSet" "do" "dynamic" "dynamicType" - "else" "elseif" "endif" "enum" "extension" "fallthrough" "false" "file" - "fileprivate" "final" "for" "func" "function" "get" "guard" "higherThan" "if" - "import" "in" "indirect" "infix" "init" "inout" "internal" "is" "lazy" "left" - "let" "line" "lowerThan" "mutating" "nil" "none" "nonmutating" "open" - "operator" "optional" "override" "postfix" "precedence" "precedencegroup" - "prefix" "private" "protocol" "public" "repeat" "required" "rethrows" "return" - "right" "selector" "self" "set" "static" "struct" "subscript" "super" "switch" - "throw" "throws" "true" "try" "typealias" "unowned" "var" "weak" "where" - "while" "willSet") - (julia-mode - "abstract" "break" "case" "catch" "const" "continue" "do" "else" "elseif" - "end" "eval" "export" "false" "finally" "for" "function" "global" "if" - "ifelse" "immutable" "import" "importall" "in" "let" "macro" "module" - "otherwise" "quote" "return" "switch" "throw" "true" "try" "type" - "typealias" "using" "while") - (thrift-mode ;; https://github.com/apache/thrift/blob/master/contrib/thrift.el - "binary" "bool" "byte" "const" "double" "enum" "exception" "extends" - "i16" "i32" "i64" "include" "list" "map" "oneway" "optional" "required" - "service" "set" "string" "struct" "throws" "typedef" "void") - ;; Aliases - (js2-mode javascript-mode) - (js2-jsx-mode javascript-mode) - (espresso-mode javascript-mode) - (js-mode javascript-mode) - (js-jsx-mode javascript-mode) - (rjsx-mode javascript-mode) - (cperl-mode perl-mode) - (jde-mode java-mode) - (ess-julia-mode julia-mode) - (enh-ruby-mode ruby-mode)) - "Alist of major modes and keywords." - :type 'alist) - -;;;; Helpers - -(defmacro cape--silent (&rest body) - "Silence BODY." - (declare (indent 0)) - `(cl-letf ((inhibit-message t) - (message-log-max nil) - ((symbol-function #'minibuffer-message) #'ignore)) - (ignore-errors ,@body))) - -(defun cape--bounds (thing) - "Return bounds of THING." - (or (bounds-of-thing-at-point thing) (cons (point) (point)))) - -(defun cape--interactive (capf) - "Complete with CAPF." - (let ((completion-at-point-functions (list capf))) - (or (completion-at-point) (user-error "%s: No completions" capf)))) - -(defun cape--noninterruptible-table (table) - "Create non-interruptible completion TABLE." - (lambda (str pred action) - (let (throw-on-input) - (complete-with-action action table str pred)))) - -(defun cape--silent-table (table) - "Create a new completion TABLE which is silent (no messages, no errors)." - (lambda (str pred action) - (cape--silent - (complete-with-action action table str pred)))) - -(cl-defun cape--table-with-properties (table &key category (sort t) &allow-other-keys) - "Create completion TABLE with properties. -CATEGORY is the optional completion category. -SORT should be nil to disable sorting." - (if (or (not table) (and (not category) sort)) - table - (let ((metadata `(metadata - ,@(and category `((category . ,category))) - ,@(and (not sort) '((display-sort-function . identity) - (cycle-sort-function . identity)))))) - (lambda (str pred action) - (if (eq action 'metadata) - metadata - (complete-with-action action table str pred)))))) - -(defun cape--input-valid-p (old-input new-input cmp) - "Return non-nil if the NEW-INPUT is valid in comparison to OLD-INPUT. -The CMP argument determines how the new input is compared to the old input. -- never: Never treat the input as valid. -- prefix/nil: The old input is a prefix of the new input. -- equal: The old input is equal to the new input. -- substring: The old input is a substring of the new input." - ;; Treat input as not changed if it contains space to allow - ;; Orderless completion style filtering. - (or (string-match-p "\\s-" new-input) - (pcase-exhaustive cmp - ('never nil) - ((or 'prefix 'nil) (string-prefix-p old-input new-input)) - ('equal (equal old-input new-input)) - ('substring (string-match-p (regexp-quote old-input) new-input))))) - -(defun cape--cached-table (beg end fun valid) - "Create caching completion table. -BEG and END are the input bounds. -FUN is the function which computes the candidates. -VALID is the input comparator, see `cape--input-valid-p'." - (let ((input 'init) - (beg (copy-marker beg)) - (end (copy-marker end t)) - (table nil)) - (lambda (str pred action) - (let ((new-input (buffer-substring-no-properties beg end))) - (when (or (eq input 'init) (not (cape--input-valid-p input new-input valid))) - ;; NOTE: We have to make sure that the completion table is interruptible. - ;; An interruption should not happen between the setqs. - (setq table (funcall fun new-input) - input new-input))) - (complete-with-action action table str pred)))) - -;;;; Capfs - -;;;;; cape-file - -(defvar cape--file-properties - (list :annotation-function (lambda (s) (if (string-suffix-p "/" s) " Folder" " File")) - :company-kind (lambda (s) (if (string-suffix-p "/" s) 'folder 'file))) - "Completion extra properties for `cape-file'.") - -;;;###autoload -(defun cape-file (&optional interactive) - "Complete file name at point. -If INTERACTIVE is nil the function acts like a capf." - (interactive (list t)) - (if interactive - (let (cape-file-directory-must-exist) - (cape--interactive #'cape-file)) - (let* ((bounds (cape--bounds 'filename)) - (file (buffer-substring (car bounds) (cdr bounds)))) - (when (or (not cape-file-directory-must-exist) - (and (string-match-p "/" file) (file-exists-p (file-name-directory file)))) - `(,(car bounds) ,(cdr bounds) ,#'read-file-name-internal - ,@(and (not (equal file "/")) (string-suffix-p "/" file) - '(:company-prefix-length t)) - :exclusive no ,@cape--file-properties))))) - -;;;;; cape-symbol - -(defvar cape--symbol-properties - (list :annotation-function #'cape--symbol-annotation - :company-kind #'cape--symbol-kind) - "Completion extra properties for `cape-symbol'.") - -(defun cape--symbol-kind (sym) - "Return kind of SYM." - (setq sym (intern-soft sym)) - (cond - ((or (macrop sym) (special-form-p sym)) 'keyword) - ((fboundp sym) 'function) - ((boundp sym) 'variable) - ((featurep sym) 'module) - ((facep sym) 'color) - (t 'text))) - -(defun cape--symbol-annotation (sym) - "Return kind of SYM." - (setq sym (intern-soft sym)) - (cond - ((or (macrop sym) (special-form-p sym)) " Macro") - ((fboundp sym) " Function") - ((boundp sym) " Variable") - ((featurep sym) " Feature") - ((facep sym) " Face") - (t " Symbol"))) - -;;;###autoload -(defun cape-symbol (&optional interactive) - "Complete symbol at point. -If INTERACTIVE is nil the function acts like a capf." - (interactive (list t)) - (if interactive - (cape--interactive #'cape-symbol) - (pcase-let ((`(,beg . ,end) (cape--bounds 'symbol))) - (when (eq (char-after beg) ?') - (setq beg (1+ beg) end (max beg end))) - `(,beg ,end - ,(cape--table-with-properties obarray :category 'symbol) - :exclusive no ,@cape--symbol-properties)))) - -;;;;; cape-dabbrev - -(defvar cape--dabbrev-properties - (list :annotation-function (lambda (_) " Dabbrev") - :company-kind (lambda (_) 'text)) - "Completion extra properties for `cape-dabbrev'.") - -(defvar dabbrev-check-all-buffers) -(defvar dabbrev-check-other-buffers) -(declare-function dabbrev--ignore-case-p "dabbrev") -(declare-function dabbrev--find-all-expansions "dabbrev") -(declare-function dabbrev--reset-global-variables "dabbrev") - -;;;###autoload -(defun cape-dabbrev (&optional interactive) - "Complete with Dabbrev at point. -If INTERACTIVE is nil the function acts like a capf." - (interactive (list t)) - (if interactive - (let ((cape-dabbrev-min-length 0)) - (cape--interactive #'cape-dabbrev)) - (when (thing-at-point-looking-at "\\(?:\\sw\\|\\s_\\)+") - (let ((beg (match-beginning 0)) - (end (match-end 0))) - `(,beg ,end - ,(cape--table-with-properties - ;; Use equal, if candidates must be longer than cape-dabbrev-min-length. - (cape--cached-table beg end - #'cape--dabbrev-list - (if (> cape-dabbrev-min-length 0) - 'equal 'prefix)) - :category 'cape-dabbrev) - :exclusive no ,@cape--dabbrev-properties))))) - -(defun cape--dabbrev-list (word) - "Find all dabbrev expansions for WORD." - (require 'dabbrev) - (cape--silent - (let ((dabbrev-check-all-buffers cape-dabbrev-check-other-buffers) - (dabbrev-check-other-buffers cape-dabbrev-check-other-buffers)) - (dabbrev--reset-global-variables)) - (cl-loop with min-len = (+ cape-dabbrev-min-length (length word)) - for w in (dabbrev--find-all-expansions word (dabbrev--ignore-case-p word)) - if (>= (length w) min-len) collect w))) - -;;;;; cape-ispell - -(defvar cape--ispell-properties - (list :annotation-function (lambda (_) " Ispell") - :company-kind (lambda (_) 'text)) - "Completion extra properties for `cape-ispell'.") - -(declare-function ispell-lookup-words "ispell") -(defun cape--ispell-words (str) - "Return all words from Ispell matching STR." - (with-demoted-errors "Ispell Error: %S" - (require 'ispell) - (cape--silent (ispell-lookup-words (format "*%s*" str))))) - -;;;###autoload -(defun cape-ispell (&optional interactive) - "Complete with Ispell at point. -If INTERACTIVE is nil the function acts like a capf." - (interactive (list t)) - (if interactive - (cape--interactive #'cape-ispell) - (let ((bounds (cape--bounds 'word))) - `(,(car bounds) ,(cdr bounds) - ,(cape--table-with-properties - (cape--cached-table (car bounds) (cdr bounds) #'cape--ispell-words 'substring) - :category 'cape-ispell) - :exclusive no ,@cape--ispell-properties)))) - -;;;;; cape-dict - -(defvar cape--dict-properties - (list :annotation-function (lambda (_) " Dict") - :company-kind (lambda (_) 'text)) - "Completion extra properties for `cape-dict'.") - -(defvar cape--dict-words nil) -(defun cape--dict-words () - "Dictionary words." - (or cape--dict-words - (setq cape--dict-words - (split-string (with-temp-buffer - (insert-file-contents-literally cape-dict-file) - (buffer-string)) - "\n" 'omit-nulls)))) - -;;;###autoload -(defun cape-dict (&optional interactive) - "Complete word at point. -If INTERACTIVE is nil the function acts like a capf." - (interactive (list t)) - (if interactive - (cape--interactive #'cape-dict) - (let ((bounds (cape--bounds 'word))) - `(,(car bounds) ,(cdr bounds) - ,(cape--table-with-properties (cape--dict-words) :category 'cape-dict) - :exclusive no ,@cape--dict-properties)))) - -;;;;; cape-tex, cape-sgml, cape-rfc1345 - -;; Declare as pure function which is evaluated at compile time. We don't use a -;; macro for this computation since packages like `helpful' will -;; `macroexpand-all' the expensive `cape--define-char' macro calls. -(eval-when-compile - (defun cape--char-translation (method prefix) - "Return character translation alist for METHOD. -PREFIX is the prefix regular expression." - (declare (pure t)) - (save-window-excursion - (describe-input-method method) - (with-current-buffer "*Help*" - (let ((lines - (split-string - (replace-regexp-in-string - "\n\n\\(\n\\|.\\)*" "" - (replace-regexp-in-string - "\\`\\(\n\\|.\\)*?----\n" "" - (replace-regexp-in-string - "\\`\\(\n\\|.\\)*?KEY SEQUENCE\n-+\n" "" - (buffer-string)))) - "\n")) - (regexp (concat "\\`" prefix)) - (list nil)) - (dolist (line lines) - (let ((beg 0) (len (length line))) - (while (< beg len) - (let* ((ename (next-single-property-change beg 'face line len)) - (echar (next-single-property-change ename 'face line len))) - (when (and (get-text-property beg 'face line) (< ename len) (<= echar len)) - (let ((name (string-trim (substring-no-properties line beg ename))) - (char (string-trim (substring-no-properties line ename echar)))) - (when (and (string-match-p regexp name) (= (length char) 1)) - (push (cons name (aref char 0)) list)))) - (setq beg echar))))) - (kill-buffer) - (sort list (lambda (x y) (string< (car x) (car y))))))))) - -(defmacro cape--char-define (name method prefix) - "Define character translation capf. -NAME is the name of the capf. -METHOD is the input method. -PREFIX is the prefix regular expression." - (let ((capf (intern (format "cape-%s" name))) - (prefix-required (intern (format "cape-%s-prefix-required" name))) - (list (intern (format "cape--%s-list" name))) - (ann (intern (format "cape--%s-annotation" name))) - (docsig (intern (format "cape--%s-docsig" name))) - (exit (intern (format "cape--%s-exit" name))) - (properties (intern (format "cape--%s-properties" name)))) - `(progn - (defvar ,list (cape--char-translation ,method ,prefix)) - (defcustom ,prefix-required t - ,(format "Initial prefix is required for `%s' to trigger." capf) - :type 'boolean) - (defun ,ann (name) - (when-let (char (cdr (assoc name ,list))) - (format " %c" char))) - (defun ,docsig (name) - (when-let (char (cdr (assoc name ,list))) - (format "%s (%s)" - (get-char-code-property char 'name) - (char-code-property-description - 'general-category - (get-char-code-property char 'general-category))))) - (defun ,exit (name status) - (unless (eq status 'exact) - (when-let (char (cdr (assoc name ,list))) - (delete-region (max (point-min) (- (point) (length name))) (point)) - (insert (char-to-string char))))) - (defvar ,properties - (list :annotation-function #',ann - :company-docsig #',docsig - :exit-function #',exit - :company-kind (lambda (_) 'text)) - ,(format "Completion extra properties for `%s'." name)) - (defun ,capf (&optional interactive) - ,(format "Complete unicode character at point. -Uses the same input format as the %s input method, -see (describe-input-method %S). If INTERACTIVE -is nil the function acts like a capf." method method) - (interactive (list t)) - (if interactive - ;; NOTE: Disable cycling since replacement breaks it. - (let (completion-cycle-threshold ,prefix-required) - (cape--interactive #',capf)) - (when-let (bounds - (cond - ((thing-at-point-looking-at ,(format "%s[^ \n\t]*" prefix)) - (cons (match-beginning 0) (match-end 0))) - ((not ,prefix-required) (cons (point) (point))))) - (append - (list (car bounds) (cdr bounds) - (cape--table-with-properties ,list :category ',capf) - :exclusive 'no) - ,properties))))))) - -;;;###autoload (autoload 'cape-tex "cape" nil t) -;;;###autoload (autoload 'cape-sgml "cape" nil t) -;;;###autoload (autoload 'cape-rfc1345 "cape" nil t) -(cape--char-define tex "TeX" "[\\\\^_]") -(cape--char-define sgml "sgml" "&") -(cape--char-define rfc1345 "rfc1345" "&") - -;;;;; cape-abbrev - -(defun cape--abbrev-tables () - "Return list of all active abbrev tables, including parents." - ;; Emacs 28: See abbrev--suggest-get-active-tables-including-parents. - (let ((tables (abbrev--active-tables))) - (append tables (cl-loop for table in tables - append (abbrev-table-get table :parents))))) - -(defun cape--abbrev-list () - "Abbreviation list." - (delete "" (cl-loop for table in (cape--abbrev-tables) - nconc (all-completions "" table)))) - -(defun cape--abbrev-annotation (abbrev) - "Annotate ABBREV with expansion." - (concat " " - (truncate-string-to-width - (format - "%s" - (symbol-value - (cl-loop for table in (cape--abbrev-tables) - thereis (abbrev--symbol abbrev table)))) - 30 0 nil t))) - -(defun cape--abbrev-exit (_str status) - "Expand expansion if STATUS is not exact." - (unless (eq status 'exact) - (expand-abbrev))) - -(defvar cape--abbrev-properties - (list :annotation-function #'cape--abbrev-annotation - :exit-function #'cape--abbrev-exit - :company-kind (lambda (_) 'snippet)) - "Completion extra properties for `cape-abbrev'.") - -;;;###autoload -(defun cape-abbrev (&optional interactive) - "Complete abbreviation at point. -If INTERACTIVE is nil the function acts like a capf." - (interactive (list t)) - (if interactive - ;; NOTE: Disable cycling since abbreviation replacement breaks it. - (let (completion-cycle-threshold) - (cape--interactive #'cape-abbrev)) - (when-let (abbrevs (cape--abbrev-list)) - (let ((bounds (cape--bounds 'symbol))) - `(,(car bounds) ,(cdr bounds) - ,(cape--table-with-properties abbrevs :category 'cape-abbrev) - :exclusive no ,@cape--abbrev-properties))))) - -;;;;; cape-keyword - -(defun cape--keyword-list () - "Return keywords for current major mode." - (when-let (kw (alist-get major-mode cape-keywords)) - (if (symbolp (cadr kw)) (alist-get (cadr kw) cape-keywords) kw))) - -(defvar cape--keyword-properties - (list :annotation-function (lambda (_) " Keyword") - :company-kind (lambda (_) 'keyword)) - "Completion extra properties for `cape-keyword'.") - -;;;###autoload -(defun cape-keyword (&optional interactive) - "Complete word at point. -If INTERACTIVE is nil the function acts like a capf." - (interactive (list t)) - (if interactive - (cape--interactive #'cape-keyword) - (when-let (keywords (cape--keyword-list)) - (let ((bounds (cape--bounds 'symbol))) - `(,(car bounds) ,(cdr bounds) - ,(cape--table-with-properties keywords :category 'cape-keyword) - :exclusive no ,@cape--keyword-properties))))) - -;;;;; cape-line - -(defvar cape--line-properties nil - "Completion extra properties for `cape-line'.") - -(defun cape--line-list () - "Return all lines from buffer." - (let ((beg (point-min)) - (max (point-max)) - (pt (point)) - (ht (make-hash-table :test #'equal)) - end lines) - (save-excursion - (while (< beg max) - (goto-char beg) - (setq end (line-end-position)) - (unless (<= beg pt end) - (let ((line (buffer-substring-no-properties beg end))) - (unless (or (string-blank-p line) (gethash line ht)) - (puthash line t ht) - (push line lines)))) - (setq beg (1+ end)))) - (nreverse lines))) - -;;;###autoload -(defun cape-line (&optional interactive) - "Complete current line from other lines in buffer. -If INTERACTIVE is nil the function acts like a capf." - (interactive (list t)) - (if interactive - (cape--interactive #'cape-line) - `(,(line-beginning-position) ,(point) - ,(cape--table-with-properties (cape--line-list) :sort nil) - ,@cape--line-properties))) - -;;;; Capf combinators - -;;;###autoload -(defun cape-super-capf (&rest capfs) - "Merge CAPFS and return new Capf which includes all candidates." - (lambda () - (when-let (results (delq nil (mapcar #'funcall capfs))) - (pcase-let* ((`((,beg ,end . ,_)) results) - (cache-candidates nil) - (cache-str nil) - (cache-ht (make-hash-table :test #'equal)) - (extra-fun - (lambda (prop) - (lambda (cand &rest args) - (when-let (fun (plist-get (gethash cand cache-ht) prop)) - (apply fun cand args))))) - (tables nil) - (prefix-len nil)) - (cl-loop for (beg2 end2 . rest) in results do - (when (and (= beg beg2) (= end end2)) - (push rest tables) - (let ((plen (plist-get (cdr rest) :company-prefix-length))) - (cond - ((eq plen t) - (setq prefix-len t)) - ((and (not prefix-len) (integerp plen)) - (setq prefix-len plen)) - ((and (integerp prefix-len) (integerp plen)) - (setq prefix-len (max prefix-len plen))))))) - (setq tables (nreverse tables)) - (list beg end - (lambda (str pred action) - (pcase action - (`(boundaries . ,_) nil) - ('metadata - '(metadata (category . cape-super) - (display-sort-function . identity) - (cycle-sort-function . identity))) - ('t - (unless (equal str cache-str) - (let ((ht (make-hash-table :test #'equal)) - (candidates nil)) - (cl-loop for (table . plist) in tables do - (let* ((pr (plist-get plist :predicate)) - (md (completion-metadata "" table pr)) - (sort (or (completion-metadata-get md 'display-sort-function) - #'identity)) - (cands (funcall sort (all-completions str table pr)))) - (cl-loop for cell on cands - for cand = (car cell) do - (if (and (eq (gethash cand ht t) t) - (or (not pred) (funcall pred cand))) - (puthash cand plist ht) - (setcar cell nil))) - (setq candidates (nconc candidates cands)))) - (setq cache-str str - cache-candidates (delq nil candidates) - cache-ht ht))) - (copy-sequence cache-candidates)) - (_ - (completion--some - (lambda (table) - (complete-with-action action table str pred)) - tables)))) - :exclusive 'no - :company-prefix-length prefix-len - :company-doc-buffer (funcall extra-fun :company-doc-buffer) - :company-location (funcall extra-fun :company-location) - :company-docsig (funcall extra-fun :company-docsig) - :company-deprecated (funcall extra-fun :company-deprecated) - :company-kind (funcall extra-fun :company-kind) - :annotation-function (funcall extra-fun :annotation-function) - :exit-function (lambda (x s) (funcall (funcall extra-fun :exit-function) x s))))))) - -(defun cape--company-call (&rest app) - "Apply APP and handle future return values." - ;; Backends are non-interruptible. Disable interrupts! - (let ((toi throw-on-input) - (throw-on-input nil)) - (pcase (apply app) - ;; Handle async future return values. - (`(:async . ,fetch) - (let ((res 'cape--waiting) - (start (time-to-seconds))) - (unwind-protect - (progn - (funcall fetch (lambda (arg) - (when (eq res 'cape--waiting) - (push 'cape--done unread-command-events)) - (setq res arg))) - ;; Force synchronization. - (while (eq res 'cape--waiting) - ;; When we've got input, interrupt the computation. - (when (and unread-command-events toi) - (throw toi nil)) - (when (and cape-company-timeout - (> (- (time-to-seconds) start) cape-company-timeout)) - (error "Cape company backend async timeout")) - (sit-for 0.1 'noredisplay))) - ;; Remove cape--done introduced by future callback - (setq unread-command-events - (delq 'cape--done unread-command-events))) - res)) - ;; Plain old synchronous return value. - (res res)))) - -;;;###autoload -(defun cape-company-to-capf (backend &optional valid) - "Convert Company BACKEND function to Capf. -VALID is the input comparator, see `cape--input-valid-p'. -This feature is experimental." - (let ((init (make-variable-buffer-local (make-symbol "cape--company-init")))) - (lambda () - (unless (symbol-value init) - (cape--company-call backend 'init) - (set init t)) - (when-let* ((prefix (cape--company-call backend 'prefix)) - (initial-input (if (stringp prefix) prefix (car-safe prefix)))) - (let* ((end (point)) (beg (- end (length initial-input)))) - (list beg end - (funcall - (if (cape--company-call backend 'ignore-case) - #'completion-table-case-fold - #'identity) - (cape--table-with-properties - (cape--cached-table beg end - (if (cape--company-call backend 'duplicates) - (lambda (input) - (delete-dups (cape--company-call backend 'candidates input))) - (apply-partially #'cape--company-call backend 'candidates)) - (if (cape--company-call backend 'no-cache initial-input) 'never valid)) - :category backend - :sort (not (cape--company-call backend 'sorted)))) - :exclusive 'no - :company-prefix-length (cdr-safe prefix) - :company-doc-buffer (lambda (x) (cape--company-call backend 'doc-buffer x)) - :company-location (lambda (x) (cape--company-call backend 'location x)) - :company-docsig (lambda (x) (cape--company-call backend 'meta x)) - :company-deprecated (lambda (x) (cape--company-call backend 'deprecated x)) - :company-kind (lambda (x) (cape--company-call backend 'kind x)) - :annotation-function (lambda (x) (cape--company-call backend 'annotation x)) - :exit-function (lambda (x _status) (cape--company-call backend 'post-completion x)))))))) - -;;;###autoload -(defun cape-capf-buster (capf &optional valid) - "Return transformed CAPF where the cache is busted on input change. -VALID is the input comparator, see `cape--input-valid-p'." - (lambda () - (pcase (funcall capf) - (`(,beg ,end ,table . ,plist) - `(,beg ,end - ,(let* ((beg (copy-marker beg)) - (end (copy-marker end t)) - (input (buffer-substring-no-properties beg end))) - (lambda (str pred action) - (let ((new-input (buffer-substring-no-properties beg end))) - (unless (cape--input-valid-p input new-input valid) - (pcase (funcall capf) - (`(,_beg ,_end ,new-table . ,_plist) - ;; NOTE: We have to make sure that the completion table is interruptible. - ;; An interruption should not happen between the setqs. - (setq table new-table input new-input))))) - (complete-with-action action table str pred))) - ,@plist))))) - -;;;###autoload -(defun cape-capf-with-properties (capf &rest properties) - "Return a new CAPF with additional completion PROPERTIES. -Completion properties include for example :exclusive, :annotation-function and -the various :company-* extensions. Furthermore a boolean :sort flag and a -completion :category symbol can be specified." - (lambda () - (pcase (funcall capf) - (`(,beg ,end ,table . ,plist) - `(,beg ,end - ,(apply #'cape--table-with-properties table properties) - ,@properties ,@plist))))) - -;;;###autoload -(defun cape-capf-with-predicate (capf predicate) - "Return a new CAPF with an additional candidate PREDICATE. -The PREDICATE is passed the candidate symbol or string." - (lambda () - (pcase (funcall capf) - (`(,beg ,end ,table . ,plist) - `(,beg ,end ,table - :predicate - ,(if-let (pred (plist-get plist :predicate)) - ;; First argument is key, second is value for hash tables. - ;; The first argument can be a cons cell for alists. Then - ;; the candidate itself is either a string or a symbol. We - ;; normalize the calling convention here such that PREDICATE - ;; always receives a string or a symbol. - (lambda (&rest args) - (when (apply pred args) - (setq args (car args)) - (funcall predicate (if (consp args) (car args) args)))) - (lambda (key &optional _val) - (funcall predicate (if (consp key) (car key) key)))) - ,@plist))))) - -;;;###autoload -(defun cape-silent-capf (capf) - "Create a new CAPF which is silent (no messages, no errors)." - (lambda () - (pcase (cape--silent (funcall capf)) - (`(,beg ,end ,table . ,plist) - `(,beg ,end ,(cape--silent-table table) ,@plist))))) - -;;;###autoload -(defun cape-capf-case-fold (capf &optional dont-fold) - "Create a new CAPF which is case insensitive. -If DONT-FOLD is non-nil, return a completion table that is -case sensitive instead." - (lambda () - (pcase (funcall capf) - (`(,beg ,end ,table . ,plist) - `(,beg ,end ,(completion-table-case-fold table dont-fold) ,@plist))))) - -;;;###autoload -(defun cape-noninterruptible-capf (capf) - "Create a new CAPF which is non-interruptible silent by input." - (lambda () - (pcase (funcall capf) - (`(,beg ,end ,table . ,plist) - `(,beg ,end ,(cape--noninterruptible-table table) ,@plist))))) - -;;;###autoload -(defun cape-interactive-capf (capf) - "Create interactive completion function from CAPF." - (lambda (&optional interactive) - (interactive (list t)) - (if interactive (cape--interactive capf) (funcall capf)))) - -(provide 'cape) -;;; cape.el ends here diff --git a/cape.png b/cape.png Binary files differnew file mode 100644 index 0000000..d952077 --- /dev/null +++ b/cape.png diff --git a/orig.png b/orig.png Binary files differnew file mode 100644 index 0000000..498da1f --- /dev/null +++ b/orig.png |
